diff --git a/thirdparty/rexglue-sdk/.gitignore b/thirdparty/rexglue-sdk/.gitignore index 041d9843..1efd8cfa 100644 --- a/thirdparty/rexglue-sdk/.gitignore +++ b/thirdparty/rexglue-sdk/.gitignore @@ -24,6 +24,10 @@ mono_crash.* [Rr]eleases/ x64/ x86/ +!thirdparty/FFmpeg/libavutil/x86/ +!thirdparty/FFmpeg/libavutil/x86/** +!thirdparty/FFmpeg/libavcodec/x86/ +!thirdparty/FFmpeg/libavcodec/x86/** [Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/Makefile b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/Makefile new file mode 100644 index 00000000..63611611 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/Makefile @@ -0,0 +1,203 @@ +OBJS += x86/constants.o \ + +# subsystems +OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp_init.o +OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp_init.o +OBJS-$(CONFIG_BLOCKDSP) += x86/blockdsp_init.o +OBJS-$(CONFIG_BSWAPDSP) += x86/bswapdsp_init.o +OBJS-$(CONFIG_DCT) += x86/dct_init.o +OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp_init.o \ + x86/dirac_dwt_init.o +OBJS-$(CONFIG_FDCTDSP) += x86/fdctdsp_init.o +OBJS-$(CONFIG_FFT) += x86/fft_init.o +OBJS-$(CONFIG_FLACDSP) += x86/flacdsp_init.o +OBJS-$(CONFIG_FMTCONVERT) += x86/fmtconvert_init.o +OBJS-$(CONFIG_H263DSP) += x86/h263dsp_init.o +OBJS-$(CONFIG_H264CHROMA) += x86/h264chroma_init.o +OBJS-$(CONFIG_H264DSP) += x86/h264dsp_init.o +OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred_init.o +OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel.o +OBJS-$(CONFIG_HPELDSP) += x86/hpeldsp_init.o +OBJS-$(CONFIG_LLAUDDSP) += x86/lossless_audiodsp_init.o +OBJS-$(CONFIG_LLVIDDSP) += x86/lossless_videodsp_init.o +OBJS-$(CONFIG_LLVIDENCDSP) += x86/lossless_videoencdsp_init.o +OBJS-$(CONFIG_HUFFYUVDSP) += x86/huffyuvdsp_init.o +OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp_init.o +OBJS-$(CONFIG_IDCTDSP) += x86/idctdsp_init.o +OBJS-$(CONFIG_LPC) += x86/lpc.o +OBJS-$(CONFIG_MDCT15) += x86/mdct15_init.o +OBJS-$(CONFIG_ME_CMP) += x86/me_cmp_init.o +OBJS-$(CONFIG_MPEGAUDIODSP) += x86/mpegaudiodsp.o +OBJS-$(CONFIG_MPEGVIDEO) += x86/mpegvideo.o \ + x86/mpegvideodsp.o +OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoenc.o \ + x86/mpegvideoencdsp_init.o +OBJS-$(CONFIG_PIXBLOCKDSP) += x86/pixblockdsp_init.o +OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp_init.o +OBJS-$(CONFIG_RV34DSP) += x86/rv34dsp_init.o +OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_init.o +OBJS-$(CONFIG_VIDEODSP) += x86/videodsp_init.o +OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp_init.o +OBJS-$(CONFIG_VP8DSP) += x86/vp8dsp_init.o +OBJS-$(CONFIG_XMM_CLOBBER_TEST) += x86/w64xmmtest.o + +# decoders/encoders +OBJS-$(CONFIG_AAC_DECODER) += x86/aacpsdsp_init.o \ + x86/sbrdsp_init.o +OBJS-$(CONFIG_AAC_ENCODER) += x86/aacencdsp_init.o +OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp_init.o +OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp_init.o +OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp_init.o +OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp_init.o +OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsdsp.o +OBJS-$(CONFIG_CFHD_DECODER) += x86/cfhddsp_init.o +OBJS-$(CONFIG_CFHD_ENCODER) += x86/cfhdencdsp_init.o +OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp_init.o x86/synth_filter_init.o +OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc_init.o +OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp_init.o +OBJS-$(CONFIG_OPUS_DECODER) += x86/opusdsp_init.o +OBJS-$(CONFIG_OPUS_ENCODER) += x86/celt_pvq_init.o +OBJS-$(CONFIG_HEVC_DECODER) += x86/hevcdsp_init.o +OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp_init.o +OBJS-$(CONFIG_LSCR_DECODER) += x86/pngdsp_init.o +OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp_init.o +OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct_init.o +OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp_init.o +OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp_init.o +OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp_init.o +OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp_init.o +OBJS-$(CONFIG_SBC_ENCODER) += x86/sbcdsp_init.o +OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc_init.o +OBJS-$(CONFIG_TAK_DECODER) += x86/takdsp_init.o +OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp_init.o +OBJS-$(CONFIG_TTA_DECODER) += x86/ttadsp_init.o +OBJS-$(CONFIG_TTA_ENCODER) += x86/ttaencdsp_init.o +OBJS-$(CONFIG_UTVIDEO_DECODER) += x86/utvideodsp_init.o +OBJS-$(CONFIG_V210_DECODER) += x86/v210-init.o +OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc_init.o +OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp_init.o +OBJS-$(CONFIG_VP3_DECODER) += x86/hpeldsp_vp3_init.o +OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp_init.o +OBJS-$(CONFIG_VP9_DECODER) += x86/vp9dsp_init.o \ + x86/vp9dsp_init_10bpp.o \ + x86/vp9dsp_init_12bpp.o \ + x86/vp9dsp_init_16bpp.o +OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp_init.o + + +# GCC inline assembly optimizations +# subsystems +MMX-OBJS-$(CONFIG_FDCTDSP) += x86/fdct.o +MMX-OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_mmx.o + +# decoders/encoders +MMX-OBJS-$(CONFIG_SNOW_DECODER) += x86/snowdsp.o +MMX-OBJS-$(CONFIG_SNOW_ENCODER) += x86/snowdsp.o + +# subsystems +X86ASM-OBJS-$(CONFIG_AC3DSP) += x86/ac3dsp.o \ + x86/ac3dsp_downmix.o +X86ASM-OBJS-$(CONFIG_AUDIODSP) += x86/audiodsp.o +X86ASM-OBJS-$(CONFIG_BLOCKDSP) += x86/blockdsp.o +X86ASM-OBJS-$(CONFIG_BSWAPDSP) += x86/bswapdsp.o +X86ASM-OBJS-$(CONFIG_DCT) += x86/dct32.o +X86ASM-OBJS-$(CONFIG_FFT) += x86/fft.o +X86ASM-OBJS-$(CONFIG_FMTCONVERT) += x86/fmtconvert.o +X86ASM-OBJS-$(CONFIG_H263DSP) += x86/h263_loopfilter.o +X86ASM-OBJS-$(CONFIG_H264CHROMA) += x86/h264_chromamc.o \ + x86/h264_chromamc_10bit.o +X86ASM-OBJS-$(CONFIG_H264DSP) += x86/h264_deblock.o \ + x86/h264_deblock_10bit.o \ + x86/h264_idct.o \ + x86/h264_idct_10bit.o \ + x86/h264_weight.o \ + x86/h264_weight_10bit.o +X86ASM-OBJS-$(CONFIG_H264PRED) += x86/h264_intrapred.o \ + x86/h264_intrapred_10bit.o +X86ASM-OBJS-$(CONFIG_H264QPEL) += x86/h264_qpel_8bit.o \ + x86/h264_qpel_10bit.o \ + x86/fpel.o \ + x86/qpel.o +X86ASM-OBJS-$(CONFIG_HPELDSP) += x86/fpel.o \ + x86/hpeldsp.o +X86ASM-OBJS-$(CONFIG_HUFFYUVDSP) += x86/huffyuvdsp.o +X86ASM-OBJS-$(CONFIG_HUFFYUVENCDSP) += x86/huffyuvencdsp.o +X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/idctdsp.o +X86ASM-OBJS-$(CONFIG_LLAUDDSP) += x86/lossless_audiodsp.o +X86ASM-OBJS-$(CONFIG_LLVIDDSP) += x86/lossless_videodsp.o +X86ASM-OBJS-$(CONFIG_LLVIDENCDSP) += x86/lossless_videoencdsp.o +X86ASM-OBJS-$(CONFIG_MDCT15) += x86/mdct15.o +X86ASM-OBJS-$(CONFIG_ME_CMP) += x86/me_cmp.o +X86ASM-OBJS-$(CONFIG_MPEGAUDIODSP) += x86/imdct36.o +X86ASM-OBJS-$(CONFIG_MPEGVIDEOENC) += x86/mpegvideoencdsp.o +X86ASM-OBJS-$(CONFIG_OPUS_DECODER) += x86/opusdsp.o +X86ASM-OBJS-$(CONFIG_OPUS_ENCODER) += x86/celt_pvq_search.o +X86ASM-OBJS-$(CONFIG_PIXBLOCKDSP) += x86/pixblockdsp.o +X86ASM-OBJS-$(CONFIG_QPELDSP) += x86/qpeldsp.o \ + x86/fpel.o \ + x86/qpel.o +X86ASM-OBJS-$(CONFIG_RV34DSP) += x86/rv34dsp.o +X86ASM-OBJS-$(CONFIG_VC1DSP) += x86/vc1dsp_loopfilter.o \ + x86/vc1dsp_mc.o +X86ASM-OBJS-$(CONFIG_IDCTDSP) += x86/simple_idct10.o \ + x86/simple_idct.o +X86ASM-OBJS-$(CONFIG_VIDEODSP) += x86/videodsp.o +X86ASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o +X86ASM-OBJS-$(CONFIG_VP8DSP) += x86/vp8dsp.o \ + x86/vp8dsp_loopfilter.o + +# decoders/encoders +X86ASM-OBJS-$(CONFIG_AAC_DECODER) += x86/aacpsdsp.o \ + x86/sbrdsp.o +X86ASM-OBJS-$(CONFIG_AAC_ENCODER) += x86/aacencdsp.o +X86ASM-OBJS-$(CONFIG_ADPCM_G722_DECODER) += x86/g722dsp.o +X86ASM-OBJS-$(CONFIG_ADPCM_G722_ENCODER) += x86/g722dsp.o +X86ASM-OBJS-$(CONFIG_ALAC_DECODER) += x86/alacdsp.o +X86ASM-OBJS-$(CONFIG_APNG_DECODER) += x86/pngdsp.o +X86ASM-OBJS-$(CONFIG_CAVS_DECODER) += x86/cavsidct.o +X86ASM-OBJS-$(CONFIG_CFHD_ENCODER) += x86/cfhdencdsp.o +X86ASM-OBJS-$(CONFIG_CFHD_DECODER) += x86/cfhddsp.o +X86ASM-OBJS-$(CONFIG_DCA_DECODER) += x86/dcadsp.o x86/synth_filter.o +X86ASM-OBJS-$(CONFIG_DIRAC_DECODER) += x86/diracdsp.o \ + x86/dirac_dwt.o +X86ASM-OBJS-$(CONFIG_DNXHD_ENCODER) += x86/dnxhdenc.o +X86ASM-OBJS-$(CONFIG_EXR_DECODER) += x86/exrdsp.o +X86ASM-OBJS-$(CONFIG_FLAC_DECODER) += x86/flacdsp.o +ifdef CONFIG_GPL +X86ASM-OBJS-$(CONFIG_FLAC_ENCODER) += x86/flac_dsp_gpl.o +endif +X86ASM-OBJS-$(CONFIG_HEVC_DECODER) += x86/hevc_add_res.o \ + x86/hevc_deblock.o \ + x86/hevc_idct.o \ + x86/hevc_mc.o \ + x86/hevc_sao.o \ + x86/hevc_sao_10bit.o +X86ASM-OBJS-$(CONFIG_JPEG2000_DECODER) += x86/jpeg2000dsp.o +X86ASM-OBJS-$(CONFIG_LSCR_DECODER) += x86/pngdsp.o +X86ASM-OBJS-$(CONFIG_MLP_DECODER) += x86/mlpdsp.o +X86ASM-OBJS-$(CONFIG_MPEG4_DECODER) += x86/xvididct.o +X86ASM-OBJS-$(CONFIG_PNG_DECODER) += x86/pngdsp.o +X86ASM-OBJS-$(CONFIG_PRORES_DECODER) += x86/proresdsp.o +X86ASM-OBJS-$(CONFIG_PRORES_LGPL_DECODER) += x86/proresdsp.o +X86ASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv40dsp.o +X86ASM-OBJS-$(CONFIG_SBC_ENCODER) += x86/sbcdsp.o +X86ASM-OBJS-$(CONFIG_SVQ1_ENCODER) += x86/svq1enc.o +X86ASM-OBJS-$(CONFIG_TAK_DECODER) += x86/takdsp.o +X86ASM-OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp.o +X86ASM-OBJS-$(CONFIG_TTA_DECODER) += x86/ttadsp.o +X86ASM-OBJS-$(CONFIG_TTA_ENCODER) += x86/ttaencdsp.o +X86ASM-OBJS-$(CONFIG_UTVIDEO_DECODER) += x86/utvideodsp.o +X86ASM-OBJS-$(CONFIG_V210_ENCODER) += x86/v210enc.o +X86ASM-OBJS-$(CONFIG_V210_DECODER) += x86/v210.o +X86ASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o +X86ASM-OBJS-$(CONFIG_VP3_DECODER) += x86/hpeldsp_vp3.o +X86ASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp6dsp.o +X86ASM-OBJS-$(CONFIG_VP9_DECODER) += x86/vp9intrapred.o \ + x86/vp9intrapred_16bpp.o \ + x86/vp9itxfm.o \ + x86/vp9itxfm_16bpp.o \ + x86/vp9lpf.o \ + x86/vp9lpf_16bpp.o \ + x86/vp9mc.o \ + x86/vp9mc_16bpp.o +X86ASM-OBJS-$(CONFIG_WEBP_DECODER) += x86/vp8dsp.o diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacencdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacencdsp.asm new file mode 100644 index 00000000..97af571e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacencdsp.asm @@ -0,0 +1,86 @@ +;****************************************************************************** +;* SIMD optimized AAC encoder DSP functions +;* +;* Copyright (C) 2016 Rostislav Pehlivanov +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +float_abs_mask: times 4 dd 0x7fffffff + +SECTION .text + +;******************************************************************* +;void ff_abs_pow34(float *out, const float *in, const int size); +;******************************************************************* +INIT_XMM sse +cglobal abs_pow34, 3, 3, 3, out, in, size + mova m2, [float_abs_mask] + shl sizeq, 2 + add inq, sizeq + add outq, sizeq + neg sizeq +.loop: + andps m0, m2, [inq+sizeq] + sqrtps m1, m0 + mulps m0, m1 + sqrtps m0, m0 + mova [outq+sizeq], m0 + add sizeq, mmsize + jl .loop + RET + +;******************************************************************* +;void ff_aac_quantize_bands(int *out, const float *in, const float *scaled, +; int size, int is_signed, int maxval, const float Q34, +; const float rounding) +;******************************************************************* +INIT_XMM sse2 +cglobal aac_quantize_bands, 5, 5, 6, out, in, scaled, size, is_signed, maxval, Q34, rounding +%if UNIX64 == 0 + movss m0, Q34m + movss m1, roundingm + cvtsi2ss m3, dword maxvalm +%else + cvtsi2ss m3, maxvald +%endif + shufps m0, m0, 0 + shufps m1, m1, 0 + shufps m3, m3, 0 + shl is_signedd, 31 + movd m4, is_signedd + shufps m4, m4, 0 + shl sized, 2 + add inq, sizeq + add outq, sizeq + add scaledq, sizeq + neg sizeq +.loop: + mulps m2, m0, [scaledq+sizeq] + addps m2, m1 + minps m2, m3 + andps m5, m4, [inq+sizeq] + orps m2, m5 + cvttps2dq m2, m2 + mova [outq+sizeq], m2 + add sizeq, mmsize + jl .loop + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacencdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacencdsp_init.c new file mode 100644 index 00000000..d761c3c5 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacencdsp_init.c @@ -0,0 +1,43 @@ +/* + * AAC encoder assembly optimizations + * Copyright (C) 2016 Rostislav Pehlivanov + * + * 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.h" + +#include "libavutil/float_dsp.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/aacenc.h" + +void ff_abs_pow34_sse(float *out, const float *in, const int size); + +void ff_aac_quantize_bands_sse2(int *out, const float *in, const float *scaled, + int size, int is_signed, int maxval, const float Q34, + const float rounding); + +av_cold void ff_aac_dsp_init_x86(AACEncContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) + s->abs_pow34 = ff_abs_pow34_sse; + + if (EXTERNAL_SSE2(cpu_flags)) + s->quant_bands = ff_aac_quantize_bands_sse2; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacpsdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacpsdsp.asm new file mode 100644 index 00000000..4acd087c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacpsdsp.asm @@ -0,0 +1,487 @@ +;****************************************************************************** +;* SIMD optimized MPEG-4 Parametric Stereo decoding functions +;* +;* Copyright (C) 2015 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +ps_p1m1p1m1: dd 0, 0x80000000, 0, 0x80000000 + +SECTION .text + +;************************************************************************* +;void ff_ps_add_squares_(float *dst, const float (*src)[2], int n); +;************************************************************************* +%macro PS_ADD_SQUARES 1 +cglobal ps_add_squares, 3, 3, %1, dst, src, n + shl nd, 3 + add srcq, nq + neg nq + +align 16 +.loop: + movaps m0, [srcq+nq] + movaps m1, [srcq+nq+mmsize] + mulps m0, m0 + mulps m1, m1 + HADDPS m0, m1, m2 + addps m0, [dstq] + movaps [dstq], m0 + add dstq, mmsize + add nq, mmsize*2 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +PS_ADD_SQUARES 2 +INIT_XMM sse3 +PS_ADD_SQUARES 3 + +;******************************************************************* +;void ff_ps_mul_pair_single_sse(float (*dst)[2], float (*src0)[2], +; float *src1, int n); +;******************************************************************* +INIT_XMM sse +cglobal ps_mul_pair_single, 4, 4, 4, dst, src1, src2, n + shl nd, 3 + add src1q, nq + add dstq, nq + neg nq + +align 16 +.loop: + movu m0, [src1q+nq] + movu m1, [src1q+nq+mmsize] + mova m2, [src2q] + mova m3, m2 + unpcklps m2, m2 + unpckhps m3, m3 + mulps m0, m2 + mulps m1, m3 + mova [dstq+nq], m0 + mova [dstq+nq+mmsize], m1 + add src2q, mmsize + add nq, mmsize*2 + jl .loop + REP_RET + +;*********************************************************************** +;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], +; float h[2][4], float h_step[2][4], +; int len); +;*********************************************************************** +INIT_XMM sse3 +cglobal ps_stereo_interpolate, 5, 5, 6, l, r, h, h_step, n + movaps m0, [hq] + movaps m1, [h_stepq] + unpcklps m4, m0, m0 + unpckhps m0, m0 + unpcklps m5, m1, m1 + unpckhps m1, m1 + shl nd, 3 + add lq, nq + add rq, nq + neg nq + +align 16 +.loop: + addps m4, m5 + addps m0, m1 + movddup m2, [lq+nq] + movddup m3, [rq+nq] + mulps m2, m4 + mulps m3, m0 + addps m2, m3 + movsd [lq+nq], m2 + movhps [rq+nq], m2 + add nq, 8 + jl .loop + REP_RET + +;*************************************************************************** +;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], +; float h[2][4], float h_step[2][4], +; int len); +;*************************************************************************** +INIT_XMM sse3 +cglobal ps_stereo_interpolate_ipdopd, 5, 5, 10, l, r, h, h_step, n + movaps m0, [hq] + movaps m1, [hq+mmsize] +%if ARCH_X86_64 + movaps m8, [h_stepq] + movaps m9, [h_stepq+mmsize] + %define H_STEP0 m8 + %define H_STEP1 m9 +%else + %define H_STEP0 [h_stepq] + %define H_STEP1 [h_stepq+mmsize] +%endif + shl nd, 3 + add lq, nq + add rq, nq + neg nq + +align 16 +.loop: + addps m0, H_STEP0 + addps m1, H_STEP1 + movddup m2, [lq+nq] + movddup m3, [rq+nq] + shufps m4, m2, m2, q2301 + shufps m5, m3, m3, q2301 + unpcklps m6, m0, m0 + unpckhps m7, m0, m0 + mulps m2, m6 + mulps m3, m7 + unpcklps m6, m1, m1 + unpckhps m7, m1, m1 + mulps m4, m6 + mulps m5, m7 + addps m2, m3 + addsubps m2, m4 + addsubps m2, m5 + movsd [lq+nq], m2 + movhps [rq+nq], m2 + add nq, 8 + jl .loop + REP_RET + +;********************************************************** +;void ps_hybrid_analysis_ileave_sse(float out[2][38][64], +; float (*in)[32][2], +; int i, int len) +;********************************************************** +INIT_XMM sse +cglobal ps_hybrid_analysis_ileave, 3, 7, 5, out, in, i, len, in0, in1, tmp + movsxdifnidn iq, id + mov lend, 32 << 3 + lea inq, [inq+iq*4] + mov tmpd, id + shl tmpd, 8 + add outq, tmpq + mov tmpd, 64 + sub tmpd, id + mov id, tmpd + + test id, 1 + jne .loop4 + test id, 2 + jne .loop8 + +align 16 +.loop16: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop16: + movaps m0, [in0q] + movaps m1, [in1q] + movaps m2, [in0q+lenq] + movaps m3, [in1q+lenq] + TRANSPOSE4x4PS 0, 1, 2, 3, 4 + movaps [outq], m0 + movaps [outq+lenq], m1 + movaps [outq+lenq*2], m2 + movaps [outq+3*32*2*4], m3 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop16 + add inq, 16 + add outq, 3*32*2*4 + sub id, 4 + jg .loop16 + RET + +align 16 +.loop8: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop8: + movlps m0, [in0q] + movlps m1, [in1q] + movhps m0, [in0q+lenq] + movhps m1, [in1q+lenq] + SBUTTERFLYPS 0, 1, 2 + SBUTTERFLYPD 0, 1, 2 + movaps [outq], m0 + movaps [outq+lenq], m1 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop8 + add inq, 8 + add outq, lenq + sub id, 2 + jg .loop16 + RET + +align 16 +.loop4: + mov in0q, inq + mov in1q, 38*64*4 + add in1q, in0q + mov tmpd, lend + +.inner_loop4: + movss m0, [in0q] + movss m1, [in1q] + movss m2, [in0q+lenq] + movss m3, [in1q+lenq] + movlhps m0, m1 + movlhps m2, m3 + shufps m0, m2, q2020 + movaps [outq], m0 + lea in0q, [in0q+lenq*2] + lea in1q, [in1q+lenq*2] + add outq, mmsize + sub tmpd, mmsize + jg .inner_loop4 + add inq, 4 + sub id, 1 + test id, 2 + jne .loop8 + cmp id, 4 + jge .loop16 + RET + +;*********************************************************** +;void ps_hybrid_synthesis_deint_sse4(float out[2][38][64], +; float (*in)[32][2], +; int i, int len) +;*********************************************************** +%macro HYBRID_SYNTHESIS_DEINT 0 +cglobal ps_hybrid_synthesis_deint, 3, 7, 5, out, in, i, len, out0, out1, tmp +%if cpuflag(sse4) +%define MOVH movsd +%else +%define MOVH movlps +%endif + movsxdifnidn iq, id + mov lend, 32 << 3 + lea outq, [outq+iq*4] + mov tmpd, id + shl tmpd, 8 + add inq, tmpq + mov tmpd, 64 + sub tmpd, id + mov id, tmpd + + test id, 1 + jne .loop4 + test id, 2 + jne .loop8 + +align 16 +.loop16: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop16: + movaps m0, [inq] + movaps m1, [inq+lenq] + movaps m2, [inq+lenq*2] + movaps m3, [inq+3*32*2*4] + TRANSPOSE4x4PS 0, 1, 2, 3, 4 + movaps [out0q], m0 + movaps [out1q], m1 + movaps [out0q+lenq], m2 + movaps [out1q+lenq], m3 + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop16 + add outq, 16 + add inq, 3*32*2*4 + sub id, 4 + jg .loop16 + RET + +align 16 +.loop8: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop8: + movaps m0, [inq] + movaps m1, [inq+lenq] + SBUTTERFLYPS 0, 1, 2 + SBUTTERFLYPD 0, 1, 2 + MOVH [out0q], m0 + MOVH [out1q], m1 + movhps [out0q+lenq], m0 + movhps [out1q+lenq], m1 + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop8 + add outq, 8 + add inq, lenq + sub id, 2 + jg .loop16 + RET + +align 16 +.loop4: + mov out0q, outq + mov out1q, 38*64*4 + add out1q, out0q + mov tmpd, lend + +.inner_loop4: + movaps m0, [inq] + movss [out0q], m0 +%if cpuflag(sse4) + extractps [out1q], m0, 1 + extractps [out0q+lenq], m0, 2 + extractps [out1q+lenq], m0, 3 +%else + movhlps m1, m0 + movss [out0q+lenq], m1 + shufps m0, m0, 0xb1 + movss [out1q], m0 + movhlps m1, m0 + movss [out1q+lenq], m1 +%endif + lea out0q, [out0q+lenq*2] + lea out1q, [out1q+lenq*2] + add inq, mmsize + sub tmpd, mmsize + jg .inner_loop4 + add outq, 4 + sub id, 1 + test id, 2 + jne .loop8 + cmp id, 4 + jge .loop16 + RET +%endmacro + +INIT_XMM sse +HYBRID_SYNTHESIS_DEINT +INIT_XMM sse4 +HYBRID_SYNTHESIS_DEINT + +;******************************************************************* +;void ff_ps_hybrid_analysis_(float (*out)[2], float (*in)[2], +; const float (*filter)[8][2], +; ptrdiff_t stride, int n); +;******************************************************************* +%macro PS_HYBRID_ANALYSIS_LOOP 3 + movu %1, [inq+mmsize*%3] + movu m1, [inq+mmsize*(5-%3)+8] +%if cpuflag(sse3) + pshufd %2, %1, q2301 + pshufd m4, m1, q0123 + pshufd m1, m1, q1032 + pshufd m2, [filterq+nq+mmsize*%3], q2301 + addsubps %2, m4 + addsubps %1, m1 +%else + mova m2, [filterq+nq+mmsize*%3] + mova %2, %1 + mova m4, m1 + shufps %2, %2, q2301 + shufps m4, m4, q0123 + shufps m1, m1, q1032 + shufps m2, m2, q2301 + xorps m4, m7 + xorps m1, m7 + subps %2, m4 + subps %1, m1 +%endif + mulps %2, m2 + mulps %1, m2 +%if %3 + addps m3, %2 + addps m0, %1 +%endif +%endmacro + +%macro PS_HYBRID_ANALYSIS 0 +cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n +%if cpuflag(sse3) +%define MOVH movsd +%else +%define MOVH movlps +%endif + shl strideq, 3 + shl nd, 6 + add filterq, nq + neg nq + mova m7, [ps_p1m1p1m1] + +align 16 +.loop: + PS_HYBRID_ANALYSIS_LOOP m0, m3, 0 + PS_HYBRID_ANALYSIS_LOOP m5, m6, 1 + PS_HYBRID_ANALYSIS_LOOP m5, m6, 2 + +%if cpuflag(sse3) + pshufd m3, m3, q2301 + xorps m0, m7 + hsubps m3, m0 + pshufd m1, m3, q0020 + pshufd m3, m3, q0031 + addps m1, m3 + movsd m2, [inq+6*8] +%else + mova m1, m3 + mova m2, m0 + shufps m1, m1, q2301 + shufps m2, m2, q2301 + subps m1, m3 + addps m2, m0 + unpcklps m3, m1, m2 + unpckhps m1, m2 + addps m1, m3 + movu m2, [inq+6*8] ; faster than movlps and no risk of overread +%endif + movss m3, [filterq+nq+8*6] + SPLATD m3 + mulps m2, m3 + addps m1, m2 + MOVH [outq], m1 + add outq, strideq + add nq, 64 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +PS_HYBRID_ANALYSIS +INIT_XMM sse3 +PS_HYBRID_ANALYSIS diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacpsdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacpsdsp_init.c new file mode 100644 index 00000000..21f00efa --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/aacpsdsp_init.c @@ -0,0 +1,72 @@ +/* + * SIMD optimized MPEG-4 Parametric Stereo decoding functions + * + * 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 + +#include "config.h" + +#include "libavutil/x86/cpu.h" +#include "libavutil/attributes.h" +#include "libavcodec/aacpsdsp.h" + +void ff_ps_add_squares_sse (float *dst, const float (*src)[2], int n); +void ff_ps_add_squares_sse3 (float *dst, const float (*src)[2], int n); +void ff_ps_mul_pair_single_sse (float (*dst)[2], float (*src0)[2], + float *src1, int n); +void ff_ps_hybrid_analysis_sse (float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_hybrid_analysis_sse3(float (*out)[2], float (*in)[2], + const float (*filter)[8][2], + ptrdiff_t stride, int n); +void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2], + float h[2][4], float h_step[2][4], + int len); +void ff_ps_hybrid_synthesis_deint_sse(float out[2][38][64], float (*in)[32][2], + int i, int len); +void ff_ps_hybrid_synthesis_deint_sse4(float out[2][38][64], float (*in)[32][2], + int i, int len); +void ff_ps_hybrid_analysis_ileave_sse(float (*out)[32][2], float L[2][38][64], + int i, int len); + +av_cold void ff_psdsp_init_x86(PSDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->add_squares = ff_ps_add_squares_sse; + s->mul_pair_single = ff_ps_mul_pair_single_sse; + s->hybrid_analysis_ileave = ff_ps_hybrid_analysis_ileave_sse; + s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_sse; + s->hybrid_analysis = ff_ps_hybrid_analysis_sse; + } + if (EXTERNAL_SSE3(cpu_flags)) { + s->add_squares = ff_ps_add_squares_sse3; + s->stereo_interpolate[0] = ff_ps_stereo_interpolate_sse3; + s->stereo_interpolate[1] = ff_ps_stereo_interpolate_ipdopd_sse3; + s->hybrid_analysis = ff_ps_hybrid_analysis_sse3; + } + if (EXTERNAL_SSE4(cpu_flags)) { + s->hybrid_synthesis_deint = ff_ps_hybrid_synthesis_deint_sse4; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp.asm new file mode 100644 index 00000000..4ddaa943 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp.asm @@ -0,0 +1,294 @@ +;***************************************************************************** +;* x86-optimized AC-3 DSP functions +;* Copyright (c) 2011 Justin Ruggles +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +; 16777216.0f - used in ff_float_to_fixed24() +pf_1_24: times 4 dd 0x4B800000 + +; used in ff_ac3_compute_mantissa_size() +cextern ac3_bap_bits +pw_bap_mul1: dw 21846, 21846, 0, 32768, 21846, 21846, 0, 32768 +pw_bap_mul2: dw 5, 7, 0, 7, 5, 7, 0, 7 + +; used in ff_ac3_extract_exponents() +cextern pd_1 +pd_151: times 4 dd 151 + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_ac3_exponent_min(uint8_t *exp, int num_reuse_blocks, int nb_coefs) +;----------------------------------------------------------------------------- + +%macro AC3_EXPONENT_MIN 0 +cglobal ac3_exponent_min, 3, 4, 2, exp, reuse_blks, expn, offset + shl reuse_blksq, 8 + jz .end + LOOP_ALIGN +.nextexp: + mov offsetq, reuse_blksq + mova m0, [expq+offsetq] + sub offsetq, 256 + LOOP_ALIGN +.nextblk: + PMINUB m0, [expq+offsetq], m1 + sub offsetq, 256 + jae .nextblk + mova [expq], m0 + add expq, mmsize + sub expnq, mmsize + jg .nextexp +.end: + REP_RET +%endmacro + +%define LOOP_ALIGN +INIT_MMX mmx +AC3_EXPONENT_MIN +%if HAVE_MMXEXT_EXTERNAL +%define LOOP_ALIGN ALIGN 16 +INIT_MMX mmxext +AC3_EXPONENT_MIN +%endif +%if HAVE_SSE2_EXTERNAL +INIT_XMM sse2 +AC3_EXPONENT_MIN +%endif +%undef LOOP_ALIGN + +;----------------------------------------------------------------------------- +; void ff_float_to_fixed24(int32_t *dst, const float *src, unsigned int len) +;----------------------------------------------------------------------------- + +; The 3DNow! version is not bit-identical because pf2id uses truncation rather +; than round-to-nearest. +INIT_MMX 3dnow +cglobal float_to_fixed24, 3, 3, 0, dst, src, len + movq m0, [pf_1_24] +.loop: + movq m1, [srcq ] + movq m2, [srcq+8 ] + movq m3, [srcq+16] + movq m4, [srcq+24] + pfmul m1, m0 + pfmul m2, m0 + pfmul m3, m0 + pfmul m4, m0 + pf2id m1, m1 + pf2id m2, m2 + pf2id m3, m3 + pf2id m4, m4 + movq [dstq ], m1 + movq [dstq+8 ], m2 + movq [dstq+16], m3 + movq [dstq+24], m4 + add srcq, 32 + add dstq, 32 + sub lend, 8 + ja .loop + femms + RET + +INIT_XMM sse +cglobal float_to_fixed24, 3, 3, 3, dst, src, len + movaps m0, [pf_1_24] +.loop: + movaps m1, [srcq ] + movaps m2, [srcq+16] + mulps m1, m0 + mulps m2, m0 + cvtps2pi mm0, m1 + movhlps m1, m1 + cvtps2pi mm1, m1 + cvtps2pi mm2, m2 + movhlps m2, m2 + cvtps2pi mm3, m2 + movq [dstq ], mm0 + movq [dstq+ 8], mm1 + movq [dstq+16], mm2 + movq [dstq+24], mm3 + add srcq, 32 + add dstq, 32 + sub lend, 8 + ja .loop + emms + RET + +INIT_XMM sse2 +cglobal float_to_fixed24, 3, 3, 9, dst, src, len + movaps m0, [pf_1_24] +.loop: + movaps m1, [srcq ] + movaps m2, [srcq+16 ] + movaps m3, [srcq+32 ] + movaps m4, [srcq+48 ] +%ifdef m8 + movaps m5, [srcq+64 ] + movaps m6, [srcq+80 ] + movaps m7, [srcq+96 ] + movaps m8, [srcq+112] +%endif + mulps m1, m0 + mulps m2, m0 + mulps m3, m0 + mulps m4, m0 +%ifdef m8 + mulps m5, m0 + mulps m6, m0 + mulps m7, m0 + mulps m8, m0 +%endif + cvtps2dq m1, m1 + cvtps2dq m2, m2 + cvtps2dq m3, m3 + cvtps2dq m4, m4 +%ifdef m8 + cvtps2dq m5, m5 + cvtps2dq m6, m6 + cvtps2dq m7, m7 + cvtps2dq m8, m8 +%endif + movdqa [dstq ], m1 + movdqa [dstq+16 ], m2 + movdqa [dstq+32 ], m3 + movdqa [dstq+48 ], m4 +%ifdef m8 + movdqa [dstq+64 ], m5 + movdqa [dstq+80 ], m6 + movdqa [dstq+96 ], m7 + movdqa [dstq+112], m8 + add srcq, 128 + add dstq, 128 + sub lenq, 32 +%else + add srcq, 64 + add dstq, 64 + sub lenq, 16 +%endif + ja .loop + REP_RET + +;------------------------------------------------------------------------------ +; int ff_ac3_compute_mantissa_size(uint16_t mant_cnt[6][16]) +;------------------------------------------------------------------------------ + +%macro PHADDD4 2 ; xmm src, xmm tmp + movhlps %2, %1 + paddd %1, %2 + pshufd %2, %1, 0x1 + paddd %1, %2 +%endmacro + +INIT_XMM sse2 +cglobal ac3_compute_mantissa_size, 1, 2, 4, mant_cnt, sum + movdqa m0, [mant_cntq ] + movdqa m1, [mant_cntq+ 1*16] + paddw m0, [mant_cntq+ 2*16] + paddw m1, [mant_cntq+ 3*16] + paddw m0, [mant_cntq+ 4*16] + paddw m1, [mant_cntq+ 5*16] + paddw m0, [mant_cntq+ 6*16] + paddw m1, [mant_cntq+ 7*16] + paddw m0, [mant_cntq+ 8*16] + paddw m1, [mant_cntq+ 9*16] + paddw m0, [mant_cntq+10*16] + paddw m1, [mant_cntq+11*16] + pmaddwd m0, [ac3_bap_bits ] + pmaddwd m1, [ac3_bap_bits+16] + paddd m0, m1 + PHADDD4 m0, m1 + movd sumd, m0 + movdqa m3, [pw_bap_mul1] + movhpd m0, [mant_cntq +2] + movlpd m0, [mant_cntq+1*32+2] + movhpd m1, [mant_cntq+2*32+2] + movlpd m1, [mant_cntq+3*32+2] + movhpd m2, [mant_cntq+4*32+2] + movlpd m2, [mant_cntq+5*32+2] + pmulhuw m0, m3 + pmulhuw m1, m3 + pmulhuw m2, m3 + paddusw m0, m1 + paddusw m0, m2 + pmaddwd m0, [pw_bap_mul2] + PHADDD4 m0, m1 + movd eax, m0 + add eax, sumd + RET + +;------------------------------------------------------------------------------ +; void ff_ac3_extract_exponents(uint8_t *exp, int32_t *coef, int nb_coefs) +;------------------------------------------------------------------------------ + +%macro PABSD 1-2 ; src/dst, unused +%if cpuflag(ssse3) + pabsd %1, %1 +%else ; src/dst, tmp + pxor %2, %2 + pcmpgtd %2, %1 + pxor %1, %2 + psubd %1, %2 +%endif +%endmacro + +%macro AC3_EXTRACT_EXPONENTS 0 +cglobal ac3_extract_exponents, 3, 3, 4, exp, coef, len + add expq, lenq + lea coefq, [coefq+4*lenq] + neg lenq + mova m2, [pd_1] + mova m3, [pd_151] +.loop: + ; move 4 32-bit coefs to xmm0 + mova m0, [coefq+4*lenq] + ; absolute value + PABSD m0, m1 + ; convert to float and extract exponents + pslld m0, 1 + por m0, m2 + cvtdq2ps m1, m0 + psrld m1, 23 + mova m0, m3 + psubd m0, m1 + ; move the lowest byte in each of 4 dwords to the low dword + ; NOTE: We cannot just extract the low bytes with pshufb because the dword + ; result for 16777215 is -1 due to float inaccuracy. Using packuswb + ; clips this to 0, which is the correct exponent. + packssdw m0, m0 + packuswb m0, m0 + movd [expq+lenq], m0 + + add lenq, 4 + jl .loop + REP_RET +%endmacro + +%if HAVE_SSE2_EXTERNAL +INIT_XMM sse2 +AC3_EXTRACT_EXPONENTS +%endif +%if HAVE_SSSE3_EXTERNAL +INIT_XMM ssse3 +AC3_EXTRACT_EXPONENTS +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp_downmix.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp_downmix.asm new file mode 100644 index 00000000..057cc606 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp_downmix.asm @@ -0,0 +1,187 @@ +;***************************************************************************** +;* x86-optimized AC-3 downmixing +;* Copyright (c) 2012 Justin Ruggles +;* +;* 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 +;****************************************************************************** + +;****************************************************************************** +;* This is based on the channel mixing asm in libavresample, but it is +;* simplified for only float coefficients and only 3 to 6 channels. +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; functions to downmix from 3 to 6 channels to mono or stereo +; void ff_ac3_downmix_*(float **samples, float **matrix, int len); +;----------------------------------------------------------------------------- + +%macro AC3_DOWNMIX 2 ; %1 = in channels, %2 = out channels +; define some names to make the code clearer +%assign in_channels %1 +%assign out_channels %2 +%assign stereo out_channels - 1 + +; determine how many matrix elements must go on the stack vs. mmregs +%assign matrix_elements in_channels * out_channels +%if stereo + %assign needed_mmregs 4 +%else + %assign needed_mmregs 3 +%endif +%assign matrix_elements_mm num_mmregs - needed_mmregs +%if matrix_elements < matrix_elements_mm + %assign matrix_elements_mm matrix_elements +%endif +%assign total_mmregs needed_mmregs+matrix_elements_mm +%if matrix_elements_mm < matrix_elements + %assign matrix_elements_stack matrix_elements - matrix_elements_mm +%else + %assign matrix_elements_stack 0 +%endif + +cglobal ac3_downmix_%1_to_%2, 3,in_channels+1,total_mmregs,0-matrix_elements_stack*mmsize, src0, src1, len, src2, src3, src4, src5 + +; load matrix pointers +%define matrix0q r1q +%define matrix1q r3q +%if stereo + mov matrix1q, [matrix0q+gprsize] +%endif + mov matrix0q, [matrix0q] + +; define matrix coeff names +%assign %%i 0 +%assign %%j needed_mmregs +%rep in_channels + %if %%i >= matrix_elements_mm + CAT_XDEFINE mx_stack_0_, %%i, 1 + CAT_XDEFINE mx_0_, %%i, [rsp+(%%i-matrix_elements_mm)*mmsize] + %else + CAT_XDEFINE mx_stack_0_, %%i, 0 + CAT_XDEFINE mx_0_, %%i, m %+ %%j + %assign %%j %%j+1 + %endif + %assign %%i %%i+1 +%endrep +%if stereo +%assign %%i 0 +%rep in_channels + %if in_channels + %%i >= matrix_elements_mm + CAT_XDEFINE mx_stack_1_, %%i, 1 + CAT_XDEFINE mx_1_, %%i, [rsp+(in_channels+%%i-matrix_elements_mm)*mmsize] + %else + CAT_XDEFINE mx_stack_1_, %%i, 0 + CAT_XDEFINE mx_1_, %%i, m %+ %%j + %assign %%j %%j+1 + %endif + %assign %%i %%i+1 +%endrep +%endif + +; load/splat matrix coeffs +%assign %%i 0 +%rep in_channels + %if mx_stack_0_ %+ %%i + VBROADCASTSS m0, [matrix0q+4*%%i] + mova mx_0_ %+ %%i, m0 + %else + VBROADCASTSS mx_0_ %+ %%i, [matrix0q+4*%%i] + %endif + %if stereo + %if mx_stack_1_ %+ %%i + VBROADCASTSS m0, [matrix1q+4*%%i] + mova mx_1_ %+ %%i, m0 + %else + VBROADCASTSS mx_1_ %+ %%i, [matrix1q+4*%%i] + %endif + %endif + %assign %%i %%i+1 +%endrep + + lea lenq, [4*r2d] + ; load channel pointers to registers +%assign %%i 1 +%rep (in_channels - 1) + mov src %+ %%i %+ q, [src0q+%%i*gprsize] + add src %+ %%i %+ q, lenq + %assign %%i %%i+1 +%endrep + mov src0q, [src0q] + add src0q, lenq + neg lenq +.loop: + %if stereo || mx_stack_0_0 + mova m0, [src0q+lenq] + %endif + %if stereo + mulps m1, m0, mx_1_0 + %endif + %if stereo || mx_stack_0_0 + mulps m0, m0, mx_0_0 + %else + mulps m0, mx_0_0, [src0q+lenq] + %endif +%assign %%i 1 +%rep (in_channels - 1) + %define src_ptr src %+ %%i %+ q + ; avoid extra load for mono if matrix is in a mm register + %if stereo || mx_stack_0_ %+ %%i + mova m2, [src_ptr+lenq] + %endif + %if stereo + FMULADD_PS m1, m2, mx_1_ %+ %%i, m1, m3 + %endif + %if stereo || mx_stack_0_ %+ %%i + FMULADD_PS m0, m2, mx_0_ %+ %%i, m0, m2 + %else + FMULADD_PS m0, mx_0_ %+ %%i, [src_ptr+lenq], m0, m1 + %endif + %assign %%i %%i+1 +%endrep + mova [src0q+lenq], m0 + %if stereo + mova [src1q+lenq], m1 + %endif + + add lenq, mmsize + jl .loop + RET +%endmacro + +%macro AC3_DOWNMIX_FUNCS 0 +%assign %%i 3 +%rep 4 + INIT_XMM sse + AC3_DOWNMIX %%i, 1 + AC3_DOWNMIX %%i, 2 + INIT_YMM avx + AC3_DOWNMIX %%i, 1 + AC3_DOWNMIX %%i, 2 + %if HAVE_FMA3_EXTERNAL + INIT_YMM fma3 + AC3_DOWNMIX %%i, 1 + AC3_DOWNMIX %%i, 2 + %endif + %assign %%i %%i+1 +%endrep +%endmacro + +AC3_DOWNMIX_FUNCS diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp_init.c new file mode 100644 index 00000000..2ae762af --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ac3dsp_init.c @@ -0,0 +1,114 @@ +/* + * x86-optimized AC-3 DSP functions + * Copyright (c) 2011 Justin Ruggles + * + * 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 "libavutil/attributes.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/ac3.h" +#include "libavcodec/ac3dsp.h" + +void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs); +void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs); + +void ff_float_to_fixed24_3dnow(int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_sse (int32_t *dst, const float *src, unsigned int len); +void ff_float_to_fixed24_sse2 (int32_t *dst, const float *src, unsigned int len); + +int ff_ac3_compute_mantissa_size_sse2(uint16_t mant_cnt[6][16]); + +void ff_ac3_extract_exponents_sse2 (uint8_t *exp, int32_t *coef, int nb_coefs); +void ff_ac3_extract_exponents_ssse3(uint8_t *exp, int32_t *coef, int nb_coefs); + +av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->ac3_exponent_min = ff_ac3_exponent_min_mmx; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + if (!bit_exact) { + c->float_to_fixed24 = ff_float_to_fixed24_3dnow; + } + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->ac3_exponent_min = ff_ac3_exponent_min_mmxext; + } + if (EXTERNAL_SSE(cpu_flags)) { + c->float_to_fixed24 = ff_float_to_fixed24_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->ac3_exponent_min = ff_ac3_exponent_min_sse2; + c->float_to_fixed24 = ff_float_to_fixed24_sse2; + c->compute_mantissa_size = ff_ac3_compute_mantissa_size_sse2; + c->extract_exponents = ff_ac3_extract_exponents_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + if (!(cpu_flags & AV_CPU_FLAG_ATOM)) + c->extract_exponents = ff_ac3_extract_exponents_ssse3; + } +} + +#define DOWNMIX_FUNC_OPT(ch, opt) \ +void ff_ac3_downmix_ ## ch ## _to_1_ ## opt(float **samples, \ + float **matrix, int len); \ +void ff_ac3_downmix_ ## ch ## _to_2_ ## opt(float **samples, \ + float **matrix, int len); + +#define DOWNMIX_FUNCS(opt) \ + DOWNMIX_FUNC_OPT(3, opt) \ + DOWNMIX_FUNC_OPT(4, opt) \ + DOWNMIX_FUNC_OPT(5, opt) \ + DOWNMIX_FUNC_OPT(6, opt) + +DOWNMIX_FUNCS(sse) +DOWNMIX_FUNCS(avx) +DOWNMIX_FUNCS(fma3) + +void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#define SET_DOWNMIX(ch, suf, SUF) \ + if (ch == c->in_channels) { \ + if (EXTERNAL_ ## SUF (cpu_flags)) { \ + if (c->out_channels == 1) \ + c->downmix = ff_ac3_downmix_ ## ch ## _to_1_ ## suf; \ + else \ + c->downmix = ff_ac3_downmix_ ## ch ## _to_2_ ## suf; \ + } \ + } + +#define SET_DOWNMIX_ALL(suf, SUF) \ + SET_DOWNMIX(3, suf, SUF) \ + SET_DOWNMIX(4, suf, SUF) \ + SET_DOWNMIX(5, suf, SUF) \ + SET_DOWNMIX(6, suf, SUF) + + SET_DOWNMIX_ALL(sse, SSE) + if (!(cpu_flags & AV_CPU_FLAG_AVXSLOW)) { + SET_DOWNMIX_ALL(avx, AVX) + SET_DOWNMIX_ALL(fma3, FMA3) + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/alacdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/alacdsp.asm new file mode 100644 index 00000000..bb2069f7 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/alacdsp.asm @@ -0,0 +1,133 @@ +;****************************************************************************** +;* ALAC DSP SIMD optimizations +;* +;* Copyright (C) 2015 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 "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_XMM sse4 +%if ARCH_X86_64 +cglobal alac_decorrelate_stereo, 2, 5, 8, buf0, len, shift, weight, buf1 +%else +cglobal alac_decorrelate_stereo, 2, 3, 8, buf0, len, shift, weight +%define buf1q r2q +%endif + movd m6, shiftm + movd m7, weightm + SPLATD m7 + shl lend, 2 + mov buf1q, [buf0q + gprsize] + mov buf0q, [buf0q] + add buf1q, lenq + add buf0q, lenq + neg lenq + +align 16 +.loop: + mova m0, [buf0q + lenq] + mova m1, [buf0q + lenq + mmsize] + mova m2, [buf1q + lenq] + mova m3, [buf1q + lenq + mmsize] + pmulld m4, m2, m7 + pmulld m5, m3, m7 + psrad m4, m6 + psrad m5, m6 + psubd m0, m4 + psubd m1, m5 + paddd m2, m0 + paddd m3, m1 + mova [buf1q + lenq], m0 + mova [buf1q + lenq + mmsize], m1 + mova [buf0q + lenq], m2 + mova [buf0q + lenq + mmsize], m3 + + add lenq, mmsize*2 + jl .loop + RET + +INIT_XMM sse2 +cglobal alac_append_extra_bits_stereo, 2, 5, 5, buf0, exbuf0, buf1, exbuf1, len + movifnidn lend, lenm + movd m4, r2m ; exbits + shl lend, 2 + mov buf1q, [buf0q + gprsize] + mov buf0q, [buf0q] + mov exbuf1q, [exbuf0q + gprsize] + mov exbuf0q, [exbuf0q] + add buf1q, lenq + add buf0q, lenq + add exbuf1q, lenq + add exbuf0q, lenq + neg lenq + +align 16 +.loop: + mova m0, [buf0q + lenq] + mova m1, [buf0q + lenq + mmsize] + pslld m0, m4 + pslld m1, m4 + mova m2, [buf1q + lenq] + mova m3, [buf1q + lenq + mmsize] + pslld m2, m4 + pslld m3, m4 + por m0, [exbuf0q + lenq] + por m1, [exbuf0q + lenq + mmsize] + por m2, [exbuf1q + lenq] + por m3, [exbuf1q + lenq + mmsize] + mova [buf0q + lenq ], m0 + mova [buf0q + lenq + mmsize], m1 + mova [buf1q + lenq ], m2 + mova [buf1q + lenq + mmsize], m3 + + add lenq, mmsize*2 + jl .loop + REP_RET + +%if ARCH_X86_64 +cglobal alac_append_extra_bits_mono, 2, 5, 3, buf, exbuf, exbits, ch, len +%else +cglobal alac_append_extra_bits_mono, 2, 3, 3, buf, exbuf, len +%define exbitsm r2m +%endif + movifnidn lend, r4m + movd m2, exbitsm + shl lend, 2 + mov bufq, [bufq] + mov exbufq, [exbufq] + add bufq, lenq + add exbufq, lenq + neg lenq + +align 16 +.loop: + mova m0, [bufq + lenq] + mova m1, [bufq + lenq + mmsize] + pslld m0, m2 + pslld m1, m2 + por m0, [exbufq + lenq] + por m1, [exbufq + lenq + mmsize] + mova [bufq + lenq], m0 + mova [bufq + lenq + mmsize], m1 + + add lenq, mmsize*2 + jl .loop + REP_RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/alacdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/alacdsp_init.c new file mode 100644 index 00000000..18f7308a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/alacdsp_init.c @@ -0,0 +1,44 @@ +/* + * 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 "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/alacdsp.h" +#include "config.h" + +void ff_alac_decorrelate_stereo_sse4(int32_t *buffer[2], int nb_samples, + int decorr_shift, int decorr_left_weight); +void ff_alac_append_extra_bits_stereo_sse2(int32_t *buffer[2], int32_t *extra_bits_buffer[2], + int extra_bits, int channels, int nb_samples); +void ff_alac_append_extra_bits_mono_sse2(int32_t *buffer[2], int32_t *extra_bits_buffer[2], + int extra_bits, int channels, int nb_samples); + +av_cold void ff_alacdsp_init_x86(ALACDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->append_extra_bits[0] = ff_alac_append_extra_bits_mono_sse2; + c->append_extra_bits[1] = ff_alac_append_extra_bits_stereo_sse2; + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->decorrelate_stereo = ff_alac_decorrelate_stereo_sse4; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/audiodsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/audiodsp.asm new file mode 100644 index 00000000..de395e5f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/audiodsp.asm @@ -0,0 +1,174 @@ +;****************************************************************************** +;* optimized audio functions +;* Copyright (c) 2008 Loren Merritt +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro SCALARPRODUCT 0 +; int ff_scalarproduct_int16(int16_t *v1, int16_t *v2, int order) +cglobal scalarproduct_int16, 3,3,3, v1, v2, order + add orderd, orderd + add v1q, orderq + add v2q, orderq + neg orderq + pxor m2, m2 +.loop: + movu m0, [v1q + orderq] + movu m1, [v1q + orderq + mmsize] + pmaddwd m0, [v2q + orderq] + pmaddwd m1, [v2q + orderq + mmsize] + paddd m2, m0 + paddd m2, m1 + add orderq, mmsize*2 + jl .loop + HADDD m2, m0 + movd eax, m2 +%if mmsize == 8 + emms +%endif + RET +%endmacro + +INIT_MMX mmxext +SCALARPRODUCT +INIT_XMM sse2 +SCALARPRODUCT + + +;----------------------------------------------------------------------------- +; void ff_vector_clip_int32(int32_t *dst, const int32_t *src, int32_t min, +; int32_t max, unsigned int len) +;----------------------------------------------------------------------------- + +; %1 = number of xmm registers used +; %2 = number of inline load/process/store loops per asm loop +; %3 = process 4*mmsize (%3=0) or 8*mmsize (%3=1) bytes per loop +; %4 = CLIPD function takes min/max as float instead of int (SSE2 version) +; %5 = suffix +%macro VECTOR_CLIP_INT32 4-5 +cglobal vector_clip_int32%5, 5,5,%1, dst, src, min, max, len +%if %4 + cvtsi2ss m4, minm + cvtsi2ss m5, maxm +%else + movd m4, minm + movd m5, maxm +%endif + SPLATD m4 + SPLATD m5 +.loop: +%assign %%i 0 +%rep %2 + mova m0, [srcq + mmsize * (0 + %%i)] + mova m1, [srcq + mmsize * (1 + %%i)] + mova m2, [srcq + mmsize * (2 + %%i)] + mova m3, [srcq + mmsize * (3 + %%i)] +%if %3 + mova m7, [srcq + mmsize * (4 + %%i)] + mova m8, [srcq + mmsize * (5 + %%i)] + mova m9, [srcq + mmsize * (6 + %%i)] + mova m10, [srcq + mmsize * (7 + %%i)] +%endif + CLIPD m0, m4, m5, m6 + CLIPD m1, m4, m5, m6 + CLIPD m2, m4, m5, m6 + CLIPD m3, m4, m5, m6 +%if %3 + CLIPD m7, m4, m5, m6 + CLIPD m8, m4, m5, m6 + CLIPD m9, m4, m5, m6 + CLIPD m10, m4, m5, m6 +%endif + mova [dstq + mmsize * (0 + %%i)], m0 + mova [dstq + mmsize * (1 + %%i)], m1 + mova [dstq + mmsize * (2 + %%i)], m2 + mova [dstq + mmsize * (3 + %%i)], m3 +%if %3 + mova [dstq + mmsize * (4 + %%i)], m7 + mova [dstq + mmsize * (5 + %%i)], m8 + mova [dstq + mmsize * (6 + %%i)], m9 + mova [dstq + mmsize * (7 + %%i)], m10 +%endif +%assign %%i (%%i + 4 * (1 + %3)) +%endrep + add srcq, mmsize*4*(%2+%3) + add dstq, mmsize*4*(%2+%3) + sub lend, mmsize*(%2+%3) + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +VECTOR_CLIP_INT32 0, 1, 0, 0 +INIT_XMM sse2 +VECTOR_CLIP_INT32 6, 1, 0, 0, _int +VECTOR_CLIP_INT32 6, 2, 0, 1 +INIT_XMM sse4 +%ifdef m8 +VECTOR_CLIP_INT32 11, 1, 1, 0 +%else +VECTOR_CLIP_INT32 6, 1, 0, 0 +%endif + +; void ff_vector_clipf_sse(float *dst, const float *src, +; int len, float min, float max) +INIT_XMM sse +cglobal vector_clipf, 3, 3, 6, dst, src, len, min, max +%if ARCH_X86_32 + VBROADCASTSS m0, minm + VBROADCASTSS m1, maxm +%elif WIN64 + SWAP 0, 3 + VBROADCASTSS m0, m0 + VBROADCASTSS m1, maxm +%else ; 64bit sysv + VBROADCASTSS m0, m0 + VBROADCASTSS m1, m1 +%endif + + movsxdifnidn lenq, lend + +.loop: + mova m2, [srcq + 4 * lenq - 4 * mmsize] + mova m3, [srcq + 4 * lenq - 3 * mmsize] + mova m4, [srcq + 4 * lenq - 2 * mmsize] + mova m5, [srcq + 4 * lenq - 1 * mmsize] + + maxps m2, m0 + maxps m3, m0 + maxps m4, m0 + maxps m5, m0 + + minps m2, m1 + minps m3, m1 + minps m4, m1 + minps m5, m1 + + mova [dstq + 4 * lenq - 4 * mmsize], m2 + mova [dstq + 4 * lenq - 3 * mmsize], m3 + mova [dstq + 4 * lenq - 2 * mmsize], m4 + mova [dstq + 4 * lenq - 1 * mmsize], m5 + + sub lenq, mmsize + jg .loop + + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/audiodsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/audiodsp_init.c new file mode 100644 index 00000000..98e296c2 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/audiodsp_init.c @@ -0,0 +1,66 @@ +/* + * 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 + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/audiodsp.h" + +int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2, + int order); +int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2, + int order); + +void ff_vector_clip_int32_mmx(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clip_int32_sse2(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clip_int32_sse4(int32_t *dst, const int32_t *src, + int32_t min, int32_t max, unsigned int len); +void ff_vector_clipf_sse(float *dst, const float *src, + int len, float min, float max); + +av_cold void ff_audiodsp_init_x86(AudioDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) + c->vector_clip_int32 = ff_vector_clip_int32_mmx; + + if (EXTERNAL_MMXEXT(cpu_flags)) + c->scalarproduct_int16 = ff_scalarproduct_int16_mmxext; + + if (EXTERNAL_SSE(cpu_flags)) + c->vector_clipf = ff_vector_clipf_sse; + + if (EXTERNAL_SSE2(cpu_flags)) { + c->scalarproduct_int16 = ff_scalarproduct_int16_sse2; + if (cpu_flags & AV_CPU_FLAG_ATOM) + c->vector_clip_int32 = ff_vector_clip_int32_int_sse2; + else + c->vector_clip_int32 = ff_vector_clip_int32_sse2; + } + + if (EXTERNAL_SSE4(cpu_flags)) + c->vector_clip_int32 = ff_vector_clip_int32_sse4; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/blockdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/blockdsp.asm new file mode 100644 index 00000000..9d203df8 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/blockdsp.asm @@ -0,0 +1,88 @@ +;****************************************************************************** +;* SIMD-optimized clear block functions +;* Copyright (c) 2002 Michael Niedermayer +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2009 Fiona Glaser +;* +;* AVX version by Jokyo Images +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +;---------------------------------------- +; void ff_clear_block(int16_t *blocks); +;---------------------------------------- +; %1 = number of xmm registers used +; %2 = number of inline store loops +%macro CLEAR_BLOCK 2 +cglobal clear_block, 1, 1, %1, blocks + ZERO m0, m0, m0 +%assign %%i 0 +%rep %2 + mova [blocksq+mmsize*(0+%%i)], m0 + mova [blocksq+mmsize*(1+%%i)], m0 + mova [blocksq+mmsize*(2+%%i)], m0 + mova [blocksq+mmsize*(3+%%i)], m0 +%assign %%i %%i+4 +%endrep + RET +%endmacro + +INIT_MMX mmx +%define ZERO pxor +CLEAR_BLOCK 0, 4 +INIT_XMM sse +%define ZERO xorps +CLEAR_BLOCK 1, 2 +INIT_YMM avx +CLEAR_BLOCK 1, 1 + +;----------------------------------------- +; void ff_clear_blocks(int16_t *blocks); +;----------------------------------------- +; %1 = number of xmm registers used +%macro CLEAR_BLOCKS 1 +cglobal clear_blocks, 1, 2, %1, blocks, len + add blocksq, 768 + mov lenq, -768 + ZERO m0, m0, m0 +.loop: + mova [blocksq+lenq+mmsize*0], m0 + mova [blocksq+lenq+mmsize*1], m0 + mova [blocksq+lenq+mmsize*2], m0 + mova [blocksq+lenq+mmsize*3], m0 + mova [blocksq+lenq+mmsize*4], m0 + mova [blocksq+lenq+mmsize*5], m0 + mova [blocksq+lenq+mmsize*6], m0 + mova [blocksq+lenq+mmsize*7], m0 + add lenq, mmsize*8 + js .loop + RET +%endmacro + +INIT_MMX mmx +%define ZERO pxor +CLEAR_BLOCKS 0 +INIT_XMM sse +%define ZERO xorps +CLEAR_BLOCKS 1 +INIT_YMM avx +CLEAR_BLOCKS 1 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/blockdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/blockdsp_init.c new file mode 100644 index 00000000..8b01a447 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/blockdsp_init.c @@ -0,0 +1,60 @@ +/* + * 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 + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/internal.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/blockdsp.h" +#include "libavcodec/version.h" + +void ff_clear_block_mmx(int16_t *block); +void ff_clear_block_sse(int16_t *block); +void ff_clear_block_avx(int16_t *block); +void ff_clear_blocks_mmx(int16_t *blocks); +void ff_clear_blocks_sse(int16_t *blocks); +void ff_clear_blocks_avx(int16_t *blocks); + +av_cold void ff_blockdsp_init_x86(BlockDSPContext *c, + AVCodecContext *avctx) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->clear_block = ff_clear_block_mmx; + c->clear_blocks = ff_clear_blocks_mmx; + } + + /* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */ + if (CONFIG_XVMC && avctx->hwaccel && avctx->hwaccel->decode_mb) + return; + + if (EXTERNAL_SSE(cpu_flags)) { + c->clear_block = ff_clear_block_sse; + c->clear_blocks = ff_clear_blocks_sse; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + c->clear_block = ff_clear_block_avx; + c->clear_blocks = ff_clear_blocks_avx; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/bswapdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/bswapdsp.asm new file mode 100644 index 00000000..31c6c48a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/bswapdsp.asm @@ -0,0 +1,159 @@ +;****************************************************************************** +;* optimized bswap buffer functions +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2003-2013 Michael Niedermayer +;* Copyright (c) 2013 Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +pb_bswap32: db 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 + +cextern pb_80 + +SECTION .text + +; %1 = aligned/unaligned +%macro BSWAP_LOOPS 1 + mov r3d, r2d + sar r2d, 3 + jz .left4_%1 +%if cpuflag(avx2) + sar r2d, 1 + jz .left8_%1 +%endif +.loop8_%1: + mov%1 m0, [r1 + 0] + mov%1 m1, [r1 + mmsize] +%if cpuflag(ssse3)||cpuflag(avx2) + pshufb m0, m2 + pshufb m1, m2 + mov%1 [r0 + 0], m0 + mov%1 [r0 + mmsize], m1 +%else + pshuflw m0, m0, 10110001b + pshuflw m1, m1, 10110001b + pshufhw m0, m0, 10110001b + pshufhw m1, m1, 10110001b + mova m2, m0 + mova m3, m1 + psllw m0, 8 + psllw m1, 8 + psrlw m2, 8 + psrlw m3, 8 + por m2, m0 + por m3, m1 + mov%1 [r0 + 0], m2 + mov%1 [r0 + 16], m3 +%endif + add r0, mmsize*2 + add r1, mmsize*2 + dec r2d + jnz .loop8_%1 +%if cpuflag(avx2) +.left8_%1: + mov r2d, r3d + test r3d, 8 + jz .left4_%1 + mov%1 m0, [r1] + pshufb m0, m2 + mov%1 [r0 + 0], m0 + add r1, mmsize + add r0, mmsize +%endif +.left4_%1: + mov r2d, r3d + test r3d, 4 + jz .left + mov%1 xm0, [r1] +%if cpuflag(ssse3) + pshufb xm0, xm2 + mov%1 [r0], xm0 +%else + pshuflw m0, m0, 10110001b + pshufhw m0, m0, 10110001b + mova m2, m0 + psllw m0, 8 + psrlw m2, 8 + por m2, m0 + mov%1 [r0], m2 +%endif + add r1, 16 + add r0, 16 +%endmacro + +; void ff_bswap_buf(uint32_t *dst, const uint32_t *src, int w); +%macro BSWAP32_BUF 0 +%if cpuflag(ssse3)||cpuflag(avx2) +cglobal bswap32_buf, 3,4,3 + mov r3, r1 + VBROADCASTI128 m2, [pb_bswap32] +%else +cglobal bswap32_buf, 3,4,5 + mov r3, r1 +%endif + or r3, r0 + test r3, mmsize - 1 + jz .start_align + BSWAP_LOOPS u + jmp .left +.start_align: + BSWAP_LOOPS a +.left: +%if cpuflag(ssse3) + test r2d, 2 + jz .left1 + movq xm0, [r1] + pshufb xm0, xm2 + movq [r0], xm0 + add r1, 8 + add r0, 8 +.left1: + test r2d, 1 + jz .end + mov r2d, [r1] + bswap r2d + mov [r0], r2d +%else + and r2d, 3 + jz .end +.loop2: + mov r3d, [r1] + bswap r3d + mov [r0], r3d + add r1, 4 + add r0, 4 + dec r2d + jnz .loop2 +%endif +.end: + RET +%endmacro + +INIT_XMM sse2 +BSWAP32_BUF + +INIT_XMM ssse3 +BSWAP32_BUF + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +BSWAP32_BUF +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/bswapdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/bswapdsp_init.c new file mode 100644 index 00000000..877bab1a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/bswapdsp_init.c @@ -0,0 +1,40 @@ +/* + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/bswapdsp.h" + +void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w); +void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w); +void ff_bswap32_buf_avx2(uint32_t *dst, const uint32_t *src, int w); + +av_cold void ff_bswapdsp_init_x86(BswapDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) + c->bswap_buf = ff_bswap32_buf_sse2; + if (EXTERNAL_SSSE3(cpu_flags)) + c->bswap_buf = ff_bswap32_buf_ssse3; + if (EXTERNAL_AVX2_FAST(cpu_flags)) + c->bswap_buf = ff_bswap32_buf_avx2; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cabac.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cabac.h new file mode 100644 index 00000000..53d74c54 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cabac.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2003 Michael Niedermayer + * + * 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 + */ + +#ifndef AVCODEC_X86_CABAC_H +#define AVCODEC_X86_CABAC_H + +#include + +#include "libavcodec/cabac.h" +#include "libavutil/attributes.h" +#include "libavutil/macros.h" +#include "libavutil/x86/asm.h" +#include "config.h" + +#if (defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\ + || ( !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)\ + || (defined(__INTEL_COMPILER) && defined(_MSC_VER)) +# define BROKEN_COMPILER 1 +#else +# define BROKEN_COMPILER 0 +#endif + +#if HAVE_INLINE_ASM + +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + +#if UNCHECKED_BITSTREAM_READER +#define END_CHECK(end) "" +#else +#define END_CHECK(end) \ + "cmp "end" , %%"FF_REG_c" \n\t"\ + "jge 1f \n\t" +#endif + +#ifdef BROKEN_RELOCATIONS +#define TABLES_ARG , "r"(tables) + +#if HAVE_FAST_CMOV +#define BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \ + "cmp "low" , "tmp" \n\t"\ + "cmova %%ecx , "range" \n\t"\ + "sbb %%rcx , %%rcx \n\t"\ + "and %%ecx , "tmp" \n\t"\ + "xor %%rcx , "retq" \n\t"\ + "sub "tmp" , "low" \n\t" +#else /* HAVE_FAST_CMOV */ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \ +/* P4 Prescott has crappy cmov,sbb,64-bit shift so avoid them */ \ + "sub "low" , "tmp" \n\t"\ + "sar $31 , "tmp" \n\t"\ + "sub %%ecx , "range" \n\t"\ + "and "tmp" , "range" \n\t"\ + "add %%ecx , "range" \n\t"\ + "shl $17 , %%ecx \n\t"\ + "and "tmp" , %%ecx \n\t"\ + "sub %%ecx , "low" \n\t"\ + "xor "tmp" , "ret" \n\t"\ + "movslq "ret" , "retq" \n\t" +#endif /* HAVE_FAST_CMOV */ + +#define BRANCHLESS_GET_CABAC(ret, retq, statep, low, lowword, range, rangeq, tmp, tmpbyte, byte, end, norm_off, lps_off, mlps_off, tables) \ + "movzbl "statep" , "ret" \n\t"\ + "mov "range" , "tmp" \n\t"\ + "and $0xC0 , "range" \n\t"\ + "lea ("ret", "range", 2), %%ecx \n\t"\ + "movzbl "lps_off"("tables", %%rcx), "range" \n\t"\ + "sub "range" , "tmp" \n\t"\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \ + "movzbl "norm_off"("tables", "rangeq"), %%ecx \n\t"\ + "shl %%cl , "range" \n\t"\ + "movzbl "mlps_off"+128("tables", "retq"), "tmp" \n\t"\ + "shl %%cl , "low" \n\t"\ + "mov "tmpbyte" , "statep" \n\t"\ + "test "lowword" , "lowword" \n\t"\ + "jnz 2f \n\t"\ + "mov "byte" , %%"FF_REG_c" \n\t"\ + END_CHECK(end)\ + "add"FF_OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ + "movzwl (%%"FF_REG_c") , "tmp" \n\t"\ + "lea -1("low") , %%ecx \n\t"\ + "xor "low" , %%ecx \n\t"\ + "shr $15 , %%ecx \n\t"\ + "bswap "tmp" \n\t"\ + "shr $15 , "tmp" \n\t"\ + "movzbl "norm_off"("tables", %%rcx), %%ecx \n\t"\ + "sub $0xFFFF , "tmp" \n\t"\ + "neg %%ecx \n\t"\ + "add $7 , %%ecx \n\t"\ + "shl %%cl , "tmp" \n\t"\ + "add "tmp" , "low" \n\t"\ + "2: \n\t" + +#else /* BROKEN_RELOCATIONS */ +#define TABLES_ARG NAMED_CONSTRAINTS_ARRAY_ADD(ff_h264_cabac_tables) +#define RIP_ARG + +#if HAVE_FAST_CMOV +#define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + "cmp "low" , "tmp" \n\t"\ + "cmova %%ecx , "range" \n\t"\ + "sbb %%ecx , %%ecx \n\t"\ + "and %%ecx , "tmp" \n\t"\ + "xor %%ecx , "ret" \n\t"\ + "sub "tmp" , "low" \n\t" +#else /* HAVE_FAST_CMOV */ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + "sub "low" , "tmp" \n\t"\ + "sar $31 , "tmp" \n\t" /*lps_mask*/\ + "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ + "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ + "add %%ecx , "range" \n\t" /*new range*/\ + "shl $17 , %%ecx \n\t"\ + "and "tmp" , %%ecx \n\t"\ + "sub %%ecx , "low" \n\t"\ + "xor "tmp" , "ret" \n\t" +#endif /* HAVE_FAST_CMOV */ + +#define BRANCHLESS_GET_CABAC(ret, retq, statep, low, lowword, range, rangeq, tmp, tmpbyte, byte, end, norm_off, lps_off, mlps_off, tables) \ + "movzbl "statep" , "ret" \n\t"\ + "mov "range" , "tmp" \n\t"\ + "and $0xC0 , "range" \n\t"\ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"lps_off"("ret", "range", 2), "range" \n\t"\ + "sub "range" , "tmp" \n\t"\ + BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp) \ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"norm_off"("range"), %%ecx \n\t"\ + "shl %%cl , "range" \n\t"\ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"mlps_off"+128("ret"), "tmp" \n\t"\ + "shl %%cl , "low" \n\t"\ + "mov "tmpbyte" , "statep" \n\t"\ + "test "lowword" , "lowword" \n\t"\ + " jnz 2f \n\t"\ + "mov "byte" , %%"FF_REG_c" \n\t"\ + END_CHECK(end)\ + "add"FF_OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ + "movzwl (%%"FF_REG_c") , "tmp" \n\t"\ + "lea -1("low") , %%ecx \n\t"\ + "xor "low" , %%ecx \n\t"\ + "shr $15 , %%ecx \n\t"\ + "bswap "tmp" \n\t"\ + "shr $15 , "tmp" \n\t"\ + "movzbl "MANGLE(ff_h264_cabac_tables)"+"norm_off"(%%ecx), %%ecx \n\t"\ + "sub $0xFFFF , "tmp" \n\t"\ + "neg %%ecx \n\t"\ + "add $7 , %%ecx \n\t"\ + "shl %%cl , "tmp" \n\t"\ + "add "tmp" , "low" \n\t"\ + "2: \n\t" + +#endif /* BROKEN_RELOCATIONS */ + +#if HAVE_7REGS && !BROKEN_COMPILER +#define get_cabac_inline get_cabac_inline_x86 +static av_always_inline int get_cabac_inline_x86(CABACContext *c, + uint8_t *const state) +{ + int bit, tmp; +#ifdef BROKEN_RELOCATIONS + void *tables; + + __asm__ volatile( + "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" + : "=&r"(tables) + : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) + ); +#endif + + __asm__ volatile( + BRANCHLESS_GET_CABAC("%0", "%q0", "(%4)", "%1", "%w1", + "%2", "%q2", "%3", "%b3", + "%c6(%5)", "%c7(%5)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%8") + : "=&r"(bit), "=&r"(c->low), "=&r"(c->range), "=&q"(tmp) + : "r"(state), "r"(c), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)) + TABLES_ARG + ,"1"(c->low), "2"(c->range) + : "%"FF_REG_c, "memory" + ); + return bit & 1; +} +#endif /* HAVE_7REGS && !BROKEN_COMPILER */ + +#if !BROKEN_COMPILER +#define get_cabac_bypass_sign get_cabac_bypass_sign_x86 +static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) +{ + x86_reg tmp; + __asm__ volatile( + "movl %c6(%2), %k1 \n\t" + "movl %c3(%2), %%eax \n\t" + "shl $17, %k1 \n\t" + "add %%eax, %%eax \n\t" + "sub %k1, %%eax \n\t" + "cdq \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" + "xor %%edx, %%ecx \n\t" + "sub %%edx, %%ecx \n\t" + "test %%ax, %%ax \n\t" + "jnz 1f \n\t" + "mov %c4(%2), %1 \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%1), %%edx \n\t" + "bswap %%edx \n\t" + "shrl $15, %%edx \n\t" +#if UNCHECKED_BITSTREAM_READER + "add $2, %1 \n\t" + "addl %%edx, %%eax \n\t" + "mov %1, %c4(%2) \n\t" +#else + "addl %%edx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"FF_OPSIZE" $2, %c4(%2) \n\t" +#endif + "1: \n\t" + "movl %%eax, %c3(%2) \n\t" + + : "+c"(val), "=&r"(tmp) + : "r"(c), + "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(offsetof(CABACContext, range)) + : "%eax", "%edx", "memory" + ); + return val; +} + +#define get_cabac_bypass get_cabac_bypass_x86 +static av_always_inline int get_cabac_bypass_x86(CABACContext *c) +{ + x86_reg tmp; + int res; + __asm__ volatile( + "movl %c6(%2), %k1 \n\t" + "movl %c3(%2), %%eax \n\t" + "shl $17, %k1 \n\t" + "add %%eax, %%eax \n\t" + "sub %k1, %%eax \n\t" + "cdq \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" + "inc %%edx \n\t" + "test %%ax, %%ax \n\t" + "jnz 1f \n\t" + "mov %c4(%2), %1 \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%1), %%ecx \n\t" + "bswap %%ecx \n\t" + "shrl $15, %%ecx \n\t" + "addl %%ecx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"FF_OPSIZE" $2, %c4(%2) \n\t" + "1: \n\t" + "movl %%eax, %c3(%2) \n\t" + + : "=&d"(res), "=&r"(tmp) + : "r"(c), + "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(offsetof(CABACContext, range)) + : "%eax", "%ecx", "memory" + ); + return res; +} +#endif /* !BROKEN_COMPILER */ + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVCODEC_X86_CABAC_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cavsdsp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cavsdsp.c new file mode 100644 index 00000000..f974f93f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cavsdsp.c @@ -0,0 +1,464 @@ +/* + * Chinese AVS video (AVS1-P2, JiZhun profile) decoder. + * Copyright (c) 2006 Stefan Gehrer + * + * MMX-optimized DSP functions, based on H.264 optimizations by + * Michael Niedermayer and Loren Merritt + * + * 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 "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/cavsdsp.h" +#include "libavcodec/idctdsp.h" +#include "constants.h" +#include "fpel.h" +#include "idctdsp.h" +#include "config.h" + + +#if HAVE_MMX_EXTERNAL + +void ff_cavs_idct8_mmx(int16_t *out, const int16_t *in); + +static void cavs_idct8_add_mmx(uint8_t *dst, int16_t *block, ptrdiff_t stride) +{ + LOCAL_ALIGNED(16, int16_t, b2, [64]); + ff_cavs_idct8_mmx(b2, block); + ff_add_pixels_clamped_mmx(b2, dst, stride); +} + +void ff_cavs_idct8_sse2(int16_t *out, const int16_t *in); + +static void cavs_idct8_add_sse2(uint8_t *dst, int16_t *block, ptrdiff_t stride) +{ + LOCAL_ALIGNED(16, int16_t, b2, [64]); + ff_cavs_idct8_sse2(b2, block); + ff_add_pixels_clamped_sse2(b2, dst, stride); +} + +#endif /* HAVE_MMX_EXTERNAL */ + +#if (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) + +/***************************************************************************** + * + * motion compensation + * + ****************************************************************************/ + +/* vertical filter [-1 -2 96 42 -7 0] */ +#define QPEL_CAVSV1(A,B,C,D,E,F,OP,ADD, MUL1, MUL2) \ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "pmullw "MANGLE(MUL1)", %%mm6\n\t"\ + "movq "#D", %%mm7 \n\t"\ + "pmullw "MANGLE(MUL2)", %%mm7\n\t"\ + "psllw $3, "#E" \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "psraw $3, "#E" \n\t"\ + "paddw %%mm7, %%mm6 \n\t"\ + "paddw "#E", %%mm6 \n\t"\ + "paddw "#B", "#B" \n\t"\ + "pxor %%mm7, %%mm7 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psraw $1, "#B" \n\t"\ + "psubw "#A", %%mm6 \n\t"\ + "paddw "MANGLE(ADD)", %%mm6 \n\t"\ + "psraw $7, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d) \ + "add %3, %1 \n\t" + +/* vertical filter [ 0 -1 5 5 -1 0] */ +#define QPEL_CAVSV2(A,B,C,D,E,F,OP,ADD, MUL1, MUL2) \ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "paddw "#D", %%mm6 \n\t"\ + "pmullw "MANGLE(MUL1)", %%mm6\n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "paddw "MANGLE(ADD)", %%mm6 \n\t"\ + "psraw $3, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d) \ + "add %3, %1 \n\t" + +/* vertical filter [ 0 -7 42 96 -2 -1] */ +#define QPEL_CAVSV3(A,B,C,D,E,F,OP,ADD, MUL1, MUL2) \ + "movd (%0), "#F" \n\t"\ + "movq "#C", %%mm6 \n\t"\ + "pmullw "MANGLE(MUL2)", %%mm6\n\t"\ + "movq "#D", %%mm7 \n\t"\ + "pmullw "MANGLE(MUL1)", %%mm7\n\t"\ + "psllw $3, "#B" \n\t"\ + "psubw "#B", %%mm6 \n\t"\ + "psraw $3, "#B" \n\t"\ + "paddw %%mm7, %%mm6 \n\t"\ + "paddw "#B", %%mm6 \n\t"\ + "paddw "#E", "#E" \n\t"\ + "pxor %%mm7, %%mm7 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, "#F" \n\t"\ + "psubw "#E", %%mm6 \n\t"\ + "psraw $1, "#E" \n\t"\ + "psubw "#F", %%mm6 \n\t"\ + "paddw "MANGLE(ADD)", %%mm6 \n\t"\ + "psraw $7, %%mm6 \n\t"\ + "packuswb %%mm6, %%mm6 \n\t"\ + OP(%%mm6, (%1), A, d) \ + "add %3, %1 \n\t" + + +#define QPEL_CAVSVNUM(VOP,OP,ADD,MUL1,MUL2)\ + int w= 2;\ + src -= 2*srcStride;\ + \ + while(w--){\ + __asm__ volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movd (%0), %%mm0 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm1 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm3 \n\t"\ + "add %2, %0 \n\t"\ + "movd (%0), %%mm4 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpcklbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, ADD, MUL1, MUL2)\ + VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, ADD, MUL1, MUL2)\ + VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, ADD, MUL1, MUL2)\ + VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, ADD, MUL1, MUL2)\ + VOP(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP, ADD, MUL1, MUL2)\ + VOP(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP, ADD, MUL1, MUL2)\ + VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, ADD, MUL1, MUL2)\ + VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, ADD, MUL1, MUL2)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((x86_reg)srcStride), "r"((x86_reg)dstStride)\ + NAMED_CONSTRAINTS_ADD(ADD,MUL1,MUL2)\ + : "memory"\ + );\ + if(h==16){\ + __asm__ volatile(\ + VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, ADD, MUL1, MUL2)\ + VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, ADD, MUL1, MUL2)\ + VOP(%%mm4, %%mm5, %%mm0, %%mm1, %%mm2, %%mm3, OP, ADD, MUL1, MUL2)\ + VOP(%%mm5, %%mm0, %%mm1, %%mm2, %%mm3, %%mm4, OP, ADD, MUL1, MUL2)\ + VOP(%%mm0, %%mm1, %%mm2, %%mm3, %%mm4, %%mm5, OP, ADD, MUL1, MUL2)\ + VOP(%%mm1, %%mm2, %%mm3, %%mm4, %%mm5, %%mm0, OP, ADD, MUL1, MUL2)\ + VOP(%%mm2, %%mm3, %%mm4, %%mm5, %%mm0, %%mm1, OP, ADD, MUL1, MUL2)\ + VOP(%%mm3, %%mm4, %%mm5, %%mm0, %%mm1, %%mm2, OP, ADD, MUL1, MUL2)\ + \ + : "+a"(src), "+c"(dst)\ + : "S"((x86_reg)srcStride), "r"((x86_reg)dstStride)\ + NAMED_CONSTRAINTS_ADD(ADD,MUL1,MUL2)\ + : "memory"\ + );\ + }\ + src += 4-(h+5)*srcStride;\ + dst += 4-h*dstStride;\ + } + +#define QPEL_CAVS(OPNAME, OP, MMX)\ +static void OPNAME ## cavs_qpel8_h_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{\ + int h=8;\ + __asm__ volatile(\ + "pxor %%mm7, %%mm7 \n\t"\ + "movq "MANGLE(ff_pw_5)", %%mm6\n\t"\ + "1: \n\t"\ + "movq (%0), %%mm0 \n\t"\ + "movq 1(%0), %%mm2 \n\t"\ + "movq %%mm0, %%mm1 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpckhbw %%mm7, %%mm1 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "paddw %%mm2, %%mm0 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "pmullw %%mm6, %%mm0 \n\t"\ + "pmullw %%mm6, %%mm1 \n\t"\ + "movq -1(%0), %%mm2 \n\t"\ + "movq 2(%0), %%mm4 \n\t"\ + "movq %%mm2, %%mm3 \n\t"\ + "movq %%mm4, %%mm5 \n\t"\ + "punpcklbw %%mm7, %%mm2 \n\t"\ + "punpckhbw %%mm7, %%mm3 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "punpckhbw %%mm7, %%mm5 \n\t"\ + "paddw %%mm4, %%mm2 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psubw %%mm2, %%mm0 \n\t"\ + "psubw %%mm5, %%mm1 \n\t"\ + "movq "MANGLE(ff_pw_4)", %%mm5\n\t"\ + "paddw %%mm5, %%mm0 \n\t"\ + "paddw %%mm5, %%mm1 \n\t"\ + "psraw $3, %%mm0 \n\t"\ + "psraw $3, %%mm1 \n\t"\ + "packuswb %%mm1, %%mm0 \n\t"\ + OP(%%mm0, (%1),%%mm5, q) \ + "add %3, %0 \n\t"\ + "add %4, %1 \n\t"\ + "decl %2 \n\t"\ + " jnz 1b \n\t"\ + : "+a"(src), "+c"(dst), "+m"(h)\ + : "d"((x86_reg)srcStride), "S"((x86_reg)dstStride)\ + NAMED_CONSTRAINTS_ADD(ff_pw_4,ff_pw_5)\ + : "memory"\ + );\ +}\ +\ +static inline void OPNAME ## cavs_qpel8or16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ + QPEL_CAVSVNUM(QPEL_CAVSV1,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ +}\ +\ +static inline void OPNAME ## cavs_qpel8or16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ + QPEL_CAVSVNUM(QPEL_CAVSV2,OP,ff_pw_4,ff_pw_5,ff_pw_42) \ +}\ +\ +static inline void OPNAME ## cavs_qpel8or16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride, int h)\ +{ \ + QPEL_CAVSVNUM(QPEL_CAVSV3,OP,ff_pw_64,ff_pw_96,ff_pw_42) \ +}\ +\ +static void OPNAME ## cavs_qpel8_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## cavs_qpel16_v1_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## cavs_qpel8or16_v1_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## cavs_qpel8_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## cavs_qpel16_v2_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## cavs_qpel8or16_v2_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## cavs_qpel8_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static void OPNAME ## cavs_qpel16_v3_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst , src , dstStride, srcStride, 16);\ + OPNAME ## cavs_qpel8or16_v3_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static void OPNAME ## cavs_qpel16_h_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t dstStride, ptrdiff_t srcStride)\ +{ \ + OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + OPNAME ## cavs_qpel8_h_ ## MMX(dst , src , dstStride, srcStride);\ + OPNAME ## cavs_qpel8_h_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ + +#define CAVS_MC(OPNAME, SIZE, MMX) \ +static void OPNAME ## cavs_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _h_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _v1_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _v2_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## cavs_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + OPNAME ## cavs_qpel ## SIZE ## _v3_ ## MMX(dst, src, stride, stride);\ +}\ + +#define PUT_OP(a,b,temp, size) "mov" #size " " #a ", " #b " \n\t" +#define AVG_3DNOW_OP(a,b,temp, size) \ +"mov" #size " " #b ", " #temp " \n\t"\ +"pavgusb " #temp ", " #a " \n\t"\ +"mov" #size " " #a ", " #b " \n\t" +#define AVG_MMXEXT_OP(a, b, temp, size) \ +"mov" #size " " #b ", " #temp " \n\t"\ +"pavgb " #temp ", " #a " \n\t"\ +"mov" #size " " #a ", " #b " \n\t" + +#endif /* (HAVE_MMXEXT_INLINE || HAVE_AMD3DNOW_INLINE) */ + +#if HAVE_MMX_EXTERNAL +static void put_cavs_qpel8_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels8_mmx(dst, src, stride, 8); +} + +static void avg_cavs_qpel8_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels8_mmx(dst, src, stride, 8); +} + +static void avg_cavs_qpel8_mc00_mmxext(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels8_mmxext(dst, src, stride, 8); +} + +static void put_cavs_qpel16_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_mmx(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_mmx(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_mmx(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_mmxext(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_mmxext(dst, src, stride, 16); +} + +static void put_cavs_qpel16_mc00_sse2(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_sse2(dst, src, stride, 16); +} + +static void avg_cavs_qpel16_mc00_sse2(uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_sse2(dst, src, stride, 16); +} +#endif + +static av_cold void cavsdsp_init_mmx(CAVSDSPContext *c, + AVCodecContext *avctx) +{ +#if HAVE_MMX_EXTERNAL + c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_mmx; + c->put_cavs_qpel_pixels_tab[1][0] = put_cavs_qpel8_mc00_mmx; + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmx; + c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmx; + + c->cavs_idct8_add = cavs_idct8_add_mmx; + c->idct_perm = FF_IDCT_PERM_TRANSPOSE; +#endif /* HAVE_MMX_EXTERNAL */ +} + +#define DSPFUNC(PFX, IDX, NUM, EXT) \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 2] = PFX ## _cavs_qpel ## NUM ## _mc20_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 4] = PFX ## _cavs_qpel ## NUM ## _mc01_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][ 8] = PFX ## _cavs_qpel ## NUM ## _mc02_ ## EXT; \ + c->PFX ## _cavs_qpel_pixels_tab[IDX][12] = PFX ## _cavs_qpel ## NUM ## _mc03_ ## EXT; \ + +#if HAVE_MMXEXT_INLINE +QPEL_CAVS(put_, PUT_OP, mmxext) +QPEL_CAVS(avg_, AVG_MMXEXT_OP, mmxext) + +CAVS_MC(put_, 8, mmxext) +CAVS_MC(put_, 16, mmxext) +CAVS_MC(avg_, 8, mmxext) +CAVS_MC(avg_, 16, mmxext) +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_AMD3DNOW_INLINE +QPEL_CAVS(put_, PUT_OP, 3dnow) +QPEL_CAVS(avg_, AVG_3DNOW_OP, 3dnow) + +CAVS_MC(put_, 8, 3dnow) +CAVS_MC(put_, 16,3dnow) +CAVS_MC(avg_, 8, 3dnow) +CAVS_MC(avg_, 16,3dnow) + +static av_cold void cavsdsp_init_3dnow(CAVSDSPContext *c, + AVCodecContext *avctx) +{ + DSPFUNC(put, 0, 16, 3dnow); + DSPFUNC(put, 1, 8, 3dnow); + DSPFUNC(avg, 0, 16, 3dnow); + DSPFUNC(avg, 1, 8, 3dnow); +} +#endif /* HAVE_AMD3DNOW_INLINE */ + +av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + + if (X86_MMX(cpu_flags)) + cavsdsp_init_mmx(c, avctx); + +#if HAVE_AMD3DNOW_INLINE + if (INLINE_AMD3DNOW(cpu_flags)) + cavsdsp_init_3dnow(c, avctx); +#endif /* HAVE_AMD3DNOW_INLINE */ +#if HAVE_MMXEXT_INLINE + if (INLINE_MMXEXT(cpu_flags)) { + DSPFUNC(put, 0, 16, mmxext); + DSPFUNC(put, 1, 8, mmxext); + DSPFUNC(avg, 0, 16, mmxext); + DSPFUNC(avg, 1, 8, mmxext); + } +#endif +#if HAVE_MMX_EXTERNAL + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmxext; + c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmxext; + } +#endif +#if HAVE_SSE2_EXTERNAL + if (EXTERNAL_SSE2(cpu_flags)) { + c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_sse2; + c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_sse2; + + c->cavs_idct8_add = cavs_idct8_add_sse2; + c->idct_perm = FF_IDCT_PERM_TRANSPOSE; + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cavsidct.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cavsidct.asm new file mode 100644 index 00000000..6c768c26 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cavsidct.asm @@ -0,0 +1,211 @@ +; Chinese AVS video (AVS1-P2, JiZhun profile) decoder +; Copyright (c) 2006 Stefan Gehrer +; +; MMX-optimized DSP functions, based on H.264 optimizations by +; Michael Niedermayer and Loren Merritt +; Conversion from gcc syntax to x264asm syntax with modifications +; by Ronald S. Bultje +; +; 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 "libavutil/x86/x86util.asm" + +cextern pw_4 +cextern pw_64 + +SECTION .text + +%macro CAVS_IDCT8_1D 2-3 1 ; source, round, init_load +%if %3 == 1 + mova m4, [%1+7*16] ; m4 = src7 + mova m5, [%1+1*16] ; m5 = src1 + mova m2, [%1+5*16] ; m2 = src5 + mova m7, [%1+3*16] ; m7 = src3 +%else + SWAP 1, 7 + SWAP 4, 6 +%endif + mova m0, m4 + mova m3, m5 + mova m6, m2 + mova m1, m7 + + paddw m4, m4 ; m4 = 2*src7 + paddw m3, m3 ; m3 = 2*src1 + paddw m6, m6 ; m6 = 2*src5 + paddw m1, m1 ; m1 = 2*src3 + paddw m0, m4 ; m0 = 3*src7 + paddw m5, m3 ; m5 = 3*src1 + paddw m2, m6 ; m2 = 3*src5 + paddw m7, m1 ; m7 = 3*src3 + psubw m5, m4 ; m5 = 3*src1 - 2*src7 = a0 + paddw m7, m6 ; m7 = 3*src3 - 2*src5 = a1 + psubw m1, m2 ; m1 = 2*src3 - 3*src5 = a2 + paddw m3, m0 ; m3 = 2*src1 - 3*src7 = a3 + + mova m4, m5 + mova m6, m7 + mova m0, m3 + mova m2, m1 + SUMSUB_BA w, 7, 5 ; m7 = a0 + a1, m5 = a0 - a1 + paddw m7, m3 ; m7 = a0 + a1 + a3 + paddw m5, m1 ; m5 = a0 - a1 + a2 + paddw m7, m7 + paddw m5, m5 + paddw m7, m6 ; m7 = b4 + paddw m5, m4 ; m5 = b5 + + SUMSUB_BA w, 1, 3 ; m1 = a3 + a2, m3 = a3 - a2 + psubw m4, m1 ; m4 = a0 - a2 - a3 + mova m1, m4 ; m1 = a0 - a2 - a3 + psubw m3, m6 ; m3 = a3 - a2 - a1 + paddw m1, m1 + paddw m3, m3 + psubw m1, m2 ; m1 = b7 + paddw m3, m0 ; m3 = b6 + + mova m2, [%1+2*16] ; m2 = src2 + mova m6, [%1+6*16] ; m6 = src6 + mova m4, m2 + mova m0, m6 + psllw m4, 2 ; m4 = 4*src2 + psllw m6, 2 ; m6 = 4*src6 + paddw m2, m4 ; m2 = 5*src2 + paddw m0, m6 ; m0 = 5*src6 + paddw m2, m2 + paddw m0, m0 + psubw m4, m0 ; m4 = 4*src2 - 10*src6 = a7 + paddw m6, m2 ; m6 = 4*src6 + 10*src2 = a6 + + mova m2, [%1+0*16] ; m2 = src0 + mova m0, [%1+4*16] ; m0 = src4 + SUMSUB_BA w, 0, 2 ; m0 = src0 + src4, m2 = src0 - src4 + psllw m0, 3 + psllw m2, 3 + paddw m0, %2 ; add rounding bias + paddw m2, %2 ; add rounding bias + + SUMSUB_BA w, 6, 0 ; m6 = a4 + a6, m0 = a4 - a6 + SUMSUB_BA w, 4, 2 ; m4 = a5 + a7, m2 = a5 - a7 + SUMSUB_BA w, 7, 6 ; m7 = dst0, m6 = dst7 + SUMSUB_BA w, 5, 4 ; m5 = dst1, m4 = dst6 + SUMSUB_BA w, 3, 2 ; m3 = dst2, m2 = dst5 + SUMSUB_BA w, 1, 0 ; m1 = dst3, m0 = dst4 +%endmacro + +INIT_MMX mmx +cglobal cavs_idct8, 2, 4, 8, 8 * 16, out, in, cnt, tmp + mov cntd, 2 + mov tmpq, rsp + +.loop_1: + CAVS_IDCT8_1D inq, [pw_4] + psraw m7, 3 + psraw m6, 3 + psraw m5, 3 + psraw m4, 3 + psraw m3, 3 + psraw m2, 3 + psraw m1, 3 + psraw m0, 3 + mova [tmpq], m7 + TRANSPOSE4x4W 0, 2, 4, 6, 7 + mova [tmpq+1*8], m0 + mova [tmpq+3*8], m2 + mova [tmpq+5*8], m4 + mova [tmpq+7*8], m6 + mova m7, [tmpq] + TRANSPOSE4x4W 7, 5, 3, 1, 0 + mova [tmpq+0*8], m7 + mova [tmpq+2*8], m5 + mova [tmpq+4*8], m3 + mova [tmpq+6*8], m1 + + add inq, mmsize + add tmpq, 64 + dec cntd + jg .loop_1 + + mov cntd, 2 + mov tmpq, rsp +.loop_2: + CAVS_IDCT8_1D tmpq, [pw_64] + psraw m7, 7 + psraw m6, 7 + psraw m5, 7 + psraw m4, 7 + psraw m3, 7 + psraw m2, 7 + psraw m1, 7 + psraw m0, 7 + + mova [outq+0*16], m7 + mova [outq+1*16], m5 + mova [outq+2*16], m3 + mova [outq+3*16], m1 + mova [outq+4*16], m0 + mova [outq+5*16], m2 + mova [outq+6*16], m4 + mova [outq+7*16], m6 + + add outq, mmsize + add tmpq, mmsize + dec cntd + jg .loop_2 + + RET + +INIT_XMM sse2 +cglobal cavs_idct8, 2, 2, 8 + ARCH_X86_64, 0 - 8 * 16, out, in + CAVS_IDCT8_1D inq, [pw_4] + psraw m7, 3 + psraw m6, 3 + psraw m5, 3 + psraw m4, 3 + psraw m3, 3 + psraw m2, 3 + psraw m1, 3 + psraw m0, 3 +%if ARCH_X86_64 + TRANSPOSE8x8W 7, 5, 3, 1, 0, 2, 4, 6, 8 + mova [rsp+4*16], m0 +%else + mova [rsp+0*16], m4 + TRANSPOSE8x8W 7, 5, 3, 1, 0, 2, 4, 6, [rsp+0*16], [rsp+4*16], 1 +%endif + mova [rsp+0*16], m7 + mova [rsp+2*16], m3 + mova [rsp+6*16], m4 + CAVS_IDCT8_1D rsp, [pw_64], 0 + psraw m7, 7 + psraw m6, 7 + psraw m5, 7 + psraw m4, 7 + psraw m3, 7 + psraw m2, 7 + psraw m1, 7 + psraw m0, 7 + + mova [outq+0*16], m7 + mova [outq+1*16], m5 + mova [outq+2*16], m3 + mova [outq+3*16], m1 + mova [outq+4*16], m0 + mova [outq+5*16], m2 + mova [outq+6*16], m4 + mova [outq+7*16], m6 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/celt_pvq_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/celt_pvq_init.c new file mode 100644 index 00000000..13724c35 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/celt_pvq_init.c @@ -0,0 +1,43 @@ +/* + * Opus encoder assembly optimizations + * Copyright (C) 2017 Ivan Kalvachev + * + * 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.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/opus_pvq.h" + +extern float ff_pvq_search_approx_sse2(float *X, int *y, int K, int N); +extern float ff_pvq_search_approx_sse4(float *X, int *y, int K, int N); +extern float ff_pvq_search_exact_avx (float *X, int *y, int K, int N); + +av_cold void ff_celt_pvq_init_x86(CeltPVQ *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) + s->pvq_search = ff_pvq_search_approx_sse2; + + if (EXTERNAL_SSE4(cpu_flags)) + s->pvq_search = ff_pvq_search_approx_sse4; + + if (EXTERNAL_AVX_FAST(cpu_flags)) + s->pvq_search = ff_pvq_search_exact_avx; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/celt_pvq_search.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/celt_pvq_search.asm new file mode 100644 index 00000000..5c1e6d61 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/celt_pvq_search.asm @@ -0,0 +1,385 @@ +;****************************************************************************** +;* SIMD optimized Opus encoder DSP function +;* +;* Copyright (C) 2017 Ivan Kalvachev +;* +;* 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.asm" +%include "libavutil/x86/x86util.asm" + +%ifdef __NASM_VER__ +%use "smartalign" +ALIGNMODE p6 +%endif + +SECTION_RODATA 64 + +const_float_abs_mask: times 8 dd 0x7fffffff +const_align_abs_edge: times 8 dd 0 + +const_float_0_5: times 8 dd 0.5 +const_float_1: times 8 dd 1.0 +const_float_sign_mask: times 8 dd 0x80000000 + +const_int32_offsets: + %rep 8 + dd $-const_int32_offsets + %endrep +SECTION .text + +; +; Setup High Register to be used +; for holding memory constants +; +; %1 - the register to be used, assmues it is >= mm8 +; %2 - name of the constant. +; +; Subsequent opcodes are going to use the constant in the form +; "addps m0, mm_const_name" and it would be turned into: +; "addps m0, [const_name]" on 32 bit arch or +; "addps m0, m8" on 64 bit arch +%macro SET_HI_REG_MM_CONSTANT 3 ; movop, reg, const_name +%if num_mmregs > 8 + %define mm_%3 %2 + %{1} %2, [%3] ; movaps m8, [const_name] +%else + %define mm_%3 [%3] +%endif +%endmacro + +; +; Set Position Independent Code +; Base address of a constant +; %1 - the register to be used, if PIC is set +; %2 - name of the constant. +; +; Subsequent opcode are going to use the base address in the form +; "movaps m0, [pic_base_constant_name+r4]" and it would be turned into +; "movaps m0, [r5 + r4]" if PIC is enabled +; "movaps m0, [constant_name + r4]" if texrel are used +%macro SET_PIC_BASE 3; reg, const_label +%ifdef PIC + %{1} %2, [%3] ; lea r5, [rip+const] + %define pic_base_%3 %2 +%else + %define pic_base_%3 %3 +%endif +%endmacro + +%macro PULSES_SEARCH 1 +; m6 Syy_norm +; m7 Sxy_norm + addps m6, mm_const_float_0_5 ; Syy_norm += 1.0/2 + pxor m1, m1 ; max_idx + xorps m3, m3 ; p_max + xor r4d, r4d +align 16 +%%distortion_search: + movd xm2, dword r4d ; movd zero extends +%ifidn %1,add + movaps m4, [tmpY + r4] ; y[i] + movaps m5, [tmpX + r4] ; X[i] + + %if USE_APPROXIMATION == 1 + xorps m0, m0 + cmpps m0, m0, m5, 4 ; m0 = (X[i] != 0.0) + %endif + + addps m4, m6 ; m4 = Syy_new = y[i] + Syy_norm + addps m5, m7 ; m5 = Sxy_new = X[i] + Sxy_norm + + %if USE_APPROXIMATION == 1 + andps m5, m0 ; if(X[i] == 0) Sxy_new = 0; Prevent aproximation error from setting pulses in array padding. + %endif + +%else + movaps m5, [tmpY + r4] ; m5 = y[i] + + xorps m0, m0 ; m0 = 0; + cmpps m0, m0, m5, 1 ; m0 = (0 p_max) + maxps m3, m5 ; m3=max(p_max,p) + ; maxps here is faster than blendvps, despite blend having lower latency. + + pand m2, m0 ; This version seems faster than sse41 pblendvb + pmaxsw m1, m2 ; SSE2 signed word, so it would work for N < 32768/4 + + add r4d, mmsize + cmp r4d, Nd + jb %%distortion_search + + por m1, mm_const_int32_offsets ; max_idx offsets per individual lane (skipped in the inner loop) + movdqa m4, m1 ; needed for the aligned y[max_idx]+=1; processing + +%if mmsize >= 32 +; Merge parallel maximums round 8 (4 vs 4) + + vextractf128 xm5, ym3, 1 ; xmm5 = ymm3[1x128] = ymm3[255..128b] + cmpps xm0, xm3, xm5, 1 ; m0 = (m3 < m5) = ( p[0x128] < p[1x128] ) + + vextracti128 xm2, ym1, 1 ; xmm2 = ymm1[1x128] = ymm1[255..128b] + BLENDVPS xm3, xm5, xm0 ; max_idx = m0 ? max_idx[1x128] : max_idx[0x128] + PBLENDVB xm1, xm2, xm0 ; p = m0 ? p[1x128] : p[0x128] +%endif + +; Merge parallel maximums round 4 (2 vs 2) + ; m3=p[3210] + movhlps xm5, xm3 ; m5=p[xx32] + cmpps xm0, xm3, xm5, 1 ; m0 = (m3 < m5) = ( p[1,0] < p[3,2] ) + + pshufd xm2, xm1, q3232 + BLENDVPS xm3, xm5, xm0 ; max_idx = m0 ? max_idx[3,2] : max_idx[1,0] + PBLENDVB xm1, xm2, xm0 ; p = m0 ? p[3,2] : p[1,0] + +; Merge parallel maximums final round (1 vs 1) + shufps xm0, xm3, xm3, q1111 ; m0 = m3[1] = p[1] + cmpss xm0, xm3, 5 ; m0 = !(m0 >= m3) = !( p[1] >= p[0] ) + + pshufd xm2, xm1, q1111 + PBLENDVB xm1, xm2, xm0 + + movd dword r4d, xm1 ; zero extends to the rest of r4q + + VBROADCASTSS m3, [tmpX + r4] + %{1}ps m7, m3 ; Sxy += X[max_idx] + + VBROADCASTSS m5, [tmpY + r4] + %{1}ps m6, m5 ; Syy += Y[max_idx] + + ; We have to update a single element in Y[i] + ; However writing 4 bytes and then doing 16 byte load in the inner loop + ; could cause a stall due to breaking write forwarding. + VPBROADCASTD m1, xm1 + pcmpeqd m1, m1, m4 ; exactly 1 element matches max_idx and this finds it + + and r4d, ~(mmsize-1) ; align address down, so the value pointed by max_idx is inside a mmsize load + movaps m5, [tmpY + r4] ; m5 = Y[y3...ym...y0] + andps m1, mm_const_float_1 ; m1 = [ 0...1.0...0] + %{1}ps m5, m1 ; m5 = Y[y3...ym...y0] +/- [0...1.0...0] + movaps [tmpY + r4], m5 ; Y[max_idx] +-= 1.0; +%endmacro + +; +; We need one more register for +; PIC relative addressing. Use this +; to count it in cglobal +; +%ifdef PIC + %define num_pic_regs 1 +%else + %define num_pic_regs 0 +%endif + +; +; Pyramid Vector Quantization Search implementation +; +; float * inX - Unaligned (SIMD) access, it will be overread, +; but extra data is masked away. +; int32 * outY - Should be aligned and padded buffer. +; It is used as temp buffer. +; uint32 K - Number of pulses to have after quantizations. +; uint32 N - Number of vector elements. Must be 0 < N < 256 +; +%macro PVQ_FAST_SEARCH 1 +cglobal pvq_search%1, 4, 5+num_pic_regs, 11, 256*4, inX, outY, K, N +%define tmpX rsp +%define tmpY outYq + + movaps m0, [const_float_abs_mask] + shl Nd, 2 ; N *= sizeof(float); also 32 bit operation zeroes the high 32 bits in 64 bit mode. + mov r4d, Nd + + neg r4d + and r4d, mmsize-1 + + SET_PIC_BASE lea, r5, const_align_abs_edge ; rip+const + movups m2, [pic_base_const_align_abs_edge + r4 - mmsize] + + add Nd, r4d ; N = align(N, mmsize) + + lea r4d, [Nd - mmsize] ; N is rounded up (aligned up) to mmsize, so r4 can't become negative here, unless N=0. + movups m1, [inXq + r4] + andps m1, m2 + movaps [tmpX + r4], m1 ; Sx = abs( X[N-1] ) + +align 16 +%%loop_abs_sum: + sub r4d, mmsize + jc %%end_loop_abs_sum + + movups m2, [inXq + r4] + andps m2, m0 + + movaps [tmpX + r4], m2 ; tmpX[i]=abs(X[i]) + addps m1, m2 ; Sx += abs(X[i]) + jmp %%loop_abs_sum + +align 16 +%%end_loop_abs_sum: + + HSUMPS m1, m2 ; m1 = Sx + + xorps m0, m0 + comiss xm0, xm1 ; + jz %%zero_input ; if (Sx==0) goto zero_input + + cvtsi2ss xm0, dword Kd ; m0 = K +%if USE_APPROXIMATION == 1 + rcpss xm1, xm1 ; m1 = approx(1/Sx) + mulss xm0, xm1 ; m0 = K*(1/Sx) +%else + divss xm0, xm1 ; b = K/Sx + ; b = K/max_x +%endif + + VBROADCASTSS m0, xm0 + + lea r4d, [Nd - mmsize] + pxor m5, m5 ; Sy ( Sum of abs( y[i]) ) + xorps m6, m6 ; Syy ( Sum of y[i]*y[i] ) + xorps m7, m7 ; Sxy ( Sum of X[i]*y[i] ) +align 16 +%%loop_guess: + movaps m1, [tmpX + r4] ; m1 = X[i] + mulps m2, m0, m1 ; m2 = res*X[i] + cvtps2dq m2, m2 ; yt = (int)lrintf( res*X[i] ) + paddd m5, m2 ; Sy += yt + cvtdq2ps m2, m2 ; yt = (float)yt + mulps m1, m2 ; m1 = X[i]*yt + movaps [tmpY + r4], m2 ; y[i] = m2 + addps m7, m1 ; Sxy += m1; + mulps m2, m2 ; m2 = yt*yt + addps m6, m2 ; Syy += m2 + + sub r4d, mmsize + jnc %%loop_guess + + HSUMPS m6, m1 ; Syy_norm + HADDD m5, m4 ; pulses + + movd dword r4d, xm5 ; zero extends to the rest of r4q + + sub Kd, r4d ; K -= pulses , also 32 bit operation zeroes high 32 bit in 64 bit mode. + jz %%finish ; K - pulses == 0 + + SET_HI_REG_MM_CONSTANT movaps, m8, const_float_0_5 + SET_HI_REG_MM_CONSTANT movaps, m9, const_float_1 + SET_HI_REG_MM_CONSTANT movdqa, m10, const_int32_offsets + ; Use Syy/2 in distortion parameter calculations. + ; Saves pre and post-caclulation to correct Y[] values. + ; Same precision, since float mantisa is normalized. + ; The SQRT approximation does differ. + HSUMPS m7, m0 ; Sxy_norm + mulps m6, mm_const_float_0_5 + + jc %%remove_pulses_loop ; K - pulses < 0 + +align 16 ; K - pulses > 0 +%%add_pulses_loop: + + PULSES_SEARCH add ; m6 Syy_norm ; m7 Sxy_norm + + sub Kd, 1 + jnz %%add_pulses_loop + + addps m6, m6 ; Syy*=2 + + jmp %%finish + +align 16 +%%remove_pulses_loop: + + PULSES_SEARCH sub ; m6 Syy_norm ; m7 Sxy_norm + + add Kd, 1 + jnz %%remove_pulses_loop + + addps m6, m6 ; Syy*=2 + +align 16 +%%finish: + lea r4d, [Nd - mmsize] + movaps m2, [const_float_sign_mask] + +align 16 +%%restore_sign_loop: + movaps m0, [tmpY + r4] ; m0 = Y[i] + movups m1, [inXq + r4] ; m1 = X[i] + andps m1, m2 ; m1 = sign(X[i]) + orps m0, m1 ; m0 = Y[i]*sign + cvtps2dq m3, m0 ; m3 = (int)m0 + movaps [outYq + r4], m3 + + sub r4d, mmsize + jnc %%restore_sign_loop +%%return: + +%if ARCH_X86_64 == 0 ; sbrdsp + movss r0m, xm6 ; return (float)Syy_norm + fld dword r0m +%else + movaps m0, m6 ; return (float)Syy_norm +%endif + + RET + +align 16 +%%zero_input: + lea r4d, [Nd - mmsize] + xorps m0, m0 +%%zero_loop: + movaps [outYq + r4], m0 + sub r4d, mmsize + jnc %%zero_loop + + movaps m6, [const_float_1] + jmp %%return +%endmacro + +; if 1, use a float op that give half precision but execute for around 3 cycles. +; On Skylake & Ryzen the division is much faster (around 11c/3), +; that makes the full precision code about 2% slower. +; Opus also does use rsqrt approximation in their intrinsics code. +%define USE_APPROXIMATION 1 + +INIT_XMM sse2 +PVQ_FAST_SEARCH _approx + +INIT_XMM sse4 +PVQ_FAST_SEARCH _approx + +%define USE_APPROXIMATION 0 + +INIT_XMM avx +PVQ_FAST_SEARCH _exact diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhddsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhddsp.asm new file mode 100644 index 00000000..87c2df63 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhddsp.asm @@ -0,0 +1,697 @@ +;****************************************************************************** +;* x86-optimized functions for the CFHD decoder +;* Copyright (c) 2020 Paul B Mahol +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +factor_p1_n1: dw 1, -1, 1, -1, 1, -1, 1, -1, +factor_n1_p1: dw -1, 1, -1, 1, -1, 1, -1, 1, +factor_p11_n4: dw 11, -4, 11, -4, 11, -4, 11, -4, +factor_p5_p4: dw 5, 4, 5, 4, 5, 4, 5, 4, +pd_4: times 4 dd 4 +pw_1: times 8 dw 1 +pw_0: times 8 dw 0 +pw_1023: times 8 dw 1023 +pw_4095: times 8 dw 4095 + +SECTION .text + +%macro CFHD_HORIZ_FILTER 1 +%if %1 == 1023 +cglobal cfhd_horiz_filter_clip10, 5, 6, 8 + 4 * ARCH_X86_64, output, low, high, width, x, temp + shl widthd, 1 +%define ostrideq widthq +%define lwidthq widthq +%define hwidthq widthq +%elif %1 == 4095 +cglobal cfhd_horiz_filter_clip12, 5, 6, 8 + 4 * ARCH_X86_64, output, low, high, width, x, temp + shl widthd, 1 +%define ostrideq widthq +%define lwidthq widthq +%define hwidthq widthq +%else +%if ARCH_X86_64 +cglobal cfhd_horiz_filter, 8, 11, 12, output, ostride, low, lwidth, high, hwidth, width, height, x, y, temp + shl ostrided, 1 + shl lwidthd, 1 + shl hwidthd, 1 + shl widthd, 1 + + mov yd, heightd + neg yq +%else +cglobal cfhd_horiz_filter, 7, 7, 8, output, x, low, y, high, temp, width, height + shl xd, 1 + shl yd, 1 + shl tempd, 1 + shl widthd, 1 + + mov xmp, xq + mov ymp, yq + mov tempmp, tempq + + mov yd, r7m + neg yq + +%define ostrideq xm +%define lwidthq ym +%define hwidthq tempm +%endif +%endif + +%if ARCH_X86_64 + mova m8, [factor_p1_n1] + mova m9, [factor_n1_p1] + mova m10, [pw_1] + mova m11, [pd_4] +%endif + +%if %1 == 0 +.looph: +%endif + movsx xq, word [lowq] + imul xq, 11 + + movsx tempq, word [lowq + 2] + imul tempq, -4 + add tempq, xq + + movsx xq, word [lowq + 4] + add tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq] + add tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq], tempw + + movsx xq, word [lowq] + imul xq, 5 + + movsx tempq, word [lowq + 2] + imul tempq, 4 + add tempq, xq + + movsx xq, word [lowq + 4] + sub tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq] + sub tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq + 2], tempw + + mov xq, 0 + +.loop: + movu m4, [lowq + xq] + movu m1, [lowq + xq + 4] + + mova m5, m4 + punpcklwd m4, m1 + punpckhwd m5, m1 + + mova m6, m4 + mova m7, m5 + +%if ARCH_X86_64 + pmaddwd m4, m8 + pmaddwd m5, m8 + pmaddwd m6, m9 + pmaddwd m7, m9 + + paddd m4, m11 + paddd m5, m11 + paddd m6, m11 + paddd m7, m11 +%else + pmaddwd m4, [factor_p1_n1] + pmaddwd m5, [factor_p1_n1] + pmaddwd m6, [factor_n1_p1] + pmaddwd m7, [factor_n1_p1] + + paddd m4, [pd_4] + paddd m5, [pd_4] + paddd m6, [pd_4] + paddd m7, [pd_4] +%endif + + psrad m4, 3 + psrad m5, 3 + psrad m6, 3 + psrad m7, 3 + + movu m2, [lowq + xq + 2] + movu m3, [highq + xq + 2] + + mova m0, m2 + punpcklwd m2, m3 + punpckhwd m0, m3 + + mova m1, m2 + mova m3, m0 + +%if ARCH_X86_64 + pmaddwd m2, m10 + pmaddwd m0, m10 + pmaddwd m1, m8 + pmaddwd m3, m8 +%else + pmaddwd m2, [pw_1] + pmaddwd m0, [pw_1] + pmaddwd m1, [factor_p1_n1] + pmaddwd m3, [factor_p1_n1] +%endif + + paddd m2, m4 + paddd m0, m5 + paddd m1, m6 + paddd m3, m7 + + psrad m2, 1 + psrad m0, 1 + psrad m1, 1 + psrad m3, 1 + + packssdw m2, m0 + packssdw m1, m3 + + mova m0, m2 + punpcklwd m2, m1 + punpckhwd m0, m1 + +%if %1 + CLIPW m2, [pw_0], [pw_%1] + CLIPW m0, [pw_0], [pw_%1] +%endif + + movu [outputq + xq * 2 + 4], m2 + movu [outputq + xq * 2 + mmsize + 4], m0 + + add xq, mmsize + cmp xq, widthq + jl .loop + + add lowq, widthq + add highq, widthq + add outputq, widthq + add outputq, widthq + + movsx xq, word [lowq - 2] + imul xq, 5 + + movsx tempq, word [lowq - 4] + imul tempq, 4 + add tempq, xq + + movsx xq, word [lowq - 6] + sub tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq - 2] + add tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq - 4], tempw + + movsx xq, word [lowq - 2] + imul xq, 11 + + movsx tempq, word [lowq - 4] + imul tempq, -4 + add tempq, xq + + movsx xq, word [lowq - 6] + add tempq, xq + add tempq, 4 + sar tempq, 3 + + movsx xq, word [highq - 2] + sub tempq, xq + sar tempq, 1 + +%if %1 + movd xm0, tempd + CLIPW m0, [pw_0], [pw_%1] + pextrw tempd, xm0, 0 +%endif + mov word [outputq - 2], tempw + +%if %1 == 0 + sub lowq, widthq + sub highq, widthq + sub outputq, widthq + sub outputq, widthq + + add lowq, lwidthq + add highq, hwidthq + add outputq, ostrideq + add outputq, ostrideq + add yq, 1 + jl .looph +%endif + + RET +%endmacro + +INIT_XMM sse2 +CFHD_HORIZ_FILTER 0 + +INIT_XMM sse2 +CFHD_HORIZ_FILTER 1023 + +INIT_XMM sse2 +CFHD_HORIZ_FILTER 4095 + +INIT_XMM sse2 +%if ARCH_X86_64 +cglobal cfhd_vert_filter, 8, 11, 14, output, ostride, low, lwidth, high, hwidth, width, height, x, y, pos + shl ostrided, 1 + shl lwidthd, 1 + shl hwidthd, 1 + shl widthd, 1 + + dec heightd + + mova m8, [factor_p1_n1] + mova m9, [factor_n1_p1] + mova m10, [pw_1] + mova m11, [pd_4] + mova m12, [factor_p11_n4] + mova m13, [factor_p5_p4] +%else +cglobal cfhd_vert_filter, 7, 7, 8, output, x, low, y, high, pos, width, height + shl xd, 1 + shl yd, 1 + shl posd, 1 + shl widthd, 1 + + mov xmp, xq + mov ymp, yq + mov posmp, posq + + mov xq, r7m + dec xq + mov widthmp, xq + +%define ostrideq xm +%define lwidthq ym +%define hwidthq posm +%define heightq widthm + +%endif + + xor xq, xq +.loopw: + xor yq, yq + + mov posq, xq + movu m0, [lowq + posq] + add posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m12 + pmaddwd m2, m12 +%else + pmaddwd m0, [factor_p11_n4] + pmaddwd m2, [factor_p11_n4] +%endif + + pxor m4, m4 + add posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + + paddd m0, [pd_4] + paddd m2, [pd_4] + + psrad m0, 3 + psrad m2, 3 + + mov posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + movu [outputq + posq], m0 + + movu m0, [lowq + posq] + add posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m13 + pmaddwd m2, m13 +%else + pmaddwd m0, [factor_p5_p4] + pmaddwd m2, [factor_p5_p4] +%endif + + pxor m4, m4 + add posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + + paddd m0, [pd_4] + paddd m2, [pd_4] + + psrad m0, 3 + psrad m2, 3 + + mov posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + add posq, ostrideq + movu [outputq + posq], m0 + + add yq, 1 +.looph: + mov posq, lwidthq + imul posq, yq + sub posq, lwidthq + add posq, xq + + movu m4, [lowq + posq] + + add posq, lwidthq + add posq, lwidthq + movu m1, [lowq + posq] + + mova m5, m4 + punpcklwd m4, m1 + punpckhwd m5, m1 + + mova m6, m4 + mova m7, m5 + +%if ARCH_X86_64 + pmaddwd m4, m8 + pmaddwd m5, m8 + pmaddwd m6, m9 + pmaddwd m7, m9 + + paddd m4, m11 + paddd m5, m11 + paddd m6, m11 + paddd m7, m11 +%else + pmaddwd m4, [factor_p1_n1] + pmaddwd m5, [factor_p1_n1] + pmaddwd m6, [factor_n1_p1] + pmaddwd m7, [factor_n1_p1] + + paddd m4, [pd_4] + paddd m5, [pd_4] + paddd m6, [pd_4] + paddd m7, [pd_4] +%endif + + psrad m4, 3 + psrad m5, 3 + psrad m6, 3 + psrad m7, 3 + + sub posq, lwidthq + movu m0, [lowq + posq] + + mov posq, hwidthq + imul posq, yq + add posq, xq + movu m1, [highq + posq] + + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + + mova m1, m0 + mova m3, m2 + +%if ARCH_X86_64 + pmaddwd m0, m10 + pmaddwd m2, m10 + pmaddwd m1, m8 + pmaddwd m3, m8 +%else + pmaddwd m0, [pw_1] + pmaddwd m2, [pw_1] + pmaddwd m1, [factor_p1_n1] + pmaddwd m3, [factor_p1_n1] +%endif + + paddd m0, m4 + paddd m2, m5 + paddd m1, m6 + paddd m3, m7 + + psrad m0, 1 + psrad m2, 1 + psrad m1, 1 + psrad m3, 1 + + packssdw m0, m2 + packssdw m1, m3 + + mov posq, ostrideq + imul posq, 2 + imul posq, yq + add posq, xq + + movu [outputq + posq], m0 + add posq, ostrideq + movu [outputq + posq], m1 + + add yq, 1 + cmp yq, heightq + jl .looph + + mov posq, lwidthq + imul posq, yq + add posq, xq + movu m0, [lowq + posq] + sub posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m13 + pmaddwd m2, m13 +%else + pmaddwd m0, [factor_p5_p4] + pmaddwd m2, [factor_p5_p4] +%endif + + pxor m4, m4 + sub posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + +%if ARCH_X86_64 + paddd m0, m11 + paddd m2, m11 +%else + paddd m0, [pd_4] + paddd m2, [pd_4] +%endif + + psrad m0, 3 + psrad m2, 3 + + mov posq, hwidthq + imul posq, yq + add posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + mov posq, ostrideq + imul posq, 2 + imul posq, yq + add posq, xq + movu [outputq + posq], m0 + + mov posq, lwidthq + imul posq, yq + add posq, xq + movu m0, [lowq + posq] + sub posq, lwidthq + movu m1, [lowq + posq] + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + +%if ARCH_X86_64 + pmaddwd m0, m12 + pmaddwd m2, m12 +%else + pmaddwd m0, [factor_p11_n4] + pmaddwd m2, [factor_p11_n4] +%endif + + pxor m4, m4 + sub posq, lwidthq + movu m1, [lowq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + paddd m0, m4 + paddd m2, m3 + +%if ARCH_X86_64 + paddd m0, m11 + paddd m2, m11 +%else + paddd m0, [pd_4] + paddd m2, [pd_4] +%endif + + psrad m0, 3 + psrad m2, 3 + + mov posq, hwidthq + imul posq, yq + add posq, xq + pxor m4, m4 + movu m1, [highq + posq] + mova m3, m4 + punpcklwd m4, m1 + punpckhwd m3, m1 + + psrad m4, 16 + psrad m3, 16 + + psubd m0, m4 + psubd m2, m3 + + psrad m0, 1 + psrad m2, 1 + + packssdw m0, m2 + + mov posq, ostrideq + imul posq, 2 + imul posq, yq + add posq, ostrideq + add posq, xq + movu [outputq + posq], m0 + + add xq, mmsize + cmp xq, widthq + jl .loopw + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhddsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhddsp_init.c new file mode 100644 index 00000000..ab7ff830 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhddsp_init.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Paul B Mahol + * + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/cfhddsp.h" + +void ff_cfhd_horiz_filter_sse2(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height); +void ff_cfhd_vert_filter_sse2(int16_t *output, ptrdiff_t out_stride, + const int16_t *low, ptrdiff_t low_stride, + const int16_t *high, ptrdiff_t high_stride, + int width, int height); +void ff_cfhd_horiz_filter_clip10_sse2(int16_t *output, const int16_t *low, const int16_t *high, int width, int bpc); +void ff_cfhd_horiz_filter_clip12_sse2(int16_t *output, const int16_t *low, const int16_t *high, int width, int bpc); + +av_cold void ff_cfhddsp_init_x86(CFHDDSPContext *c, int depth, int bayer) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->horiz_filter = ff_cfhd_horiz_filter_sse2; + c->vert_filter = ff_cfhd_vert_filter_sse2; + if (depth == 10 && !bayer) + c->horiz_filter_clip = ff_cfhd_horiz_filter_clip10_sse2; + if (depth == 12 && !bayer) + c->horiz_filter_clip = ff_cfhd_horiz_filter_clip12_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhdencdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhdencdsp.asm new file mode 100644 index 00000000..4aaeb569 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhdencdsp.asm @@ -0,0 +1,432 @@ +;****************************************************************************** +;* x86-optimized functions for the CFHD encoder +;* Copyright (c) 2021 Paul B Mahol +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pw_p1_n1: dw 1, -1, 1, -1, 1, -1, 1, -1 +pw_n1_p1: dw -1, 1, -1, 1, -1, 1, -1, 1 +pw_p5_n11: dw 5, -11, 5, -11, 5, -11, 5, -11 +pw_n5_p11: dw -5, 11, -5, 11, -5, 11, -5, 11 +pw_p11_n5: dw 11, -5, 11, -5, 11, -5, 11, -5 +pw_n11_p5: dw -11, 5, -11, 5, -11, 5, -11, 5 +pd_4: times 4 dd 4 +pw_n4: times 8 dw -4 +cextern pw_m1 +cextern pw_1 +cextern pw_4 + +SECTION .text + +%if ARCH_X86_64 +INIT_XMM sse2 +cglobal cfhdenc_horiz_filter, 8, 10, 11, input, low, high, istride, lwidth, hwidth, width, y, x, temp + shl istrideq, 1 + shl lwidthq, 1 + shl hwidthq, 1 + mova m7, [pd_4] + mova m8, [pw_1] + mova m9, [pw_m1] + mova m10,[pw_p1_n1] + movsxdifnidn yq, yd + movsxdifnidn widthq, widthd + neg yq +.looph: + movsx xq, word [inputq] + + movsx tempq, word [inputq + 2] + add tempq, xq + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [lowq], tempw + + movsx xq, word [inputq] + imul xq, 5 + movsx tempq, word [inputq + 2] + imul tempq, -11 + add tempq, xq + + movsx xq, word [inputq + 4] + imul xq, 4 + add tempq, xq + + movsx xq, word [inputq + 6] + imul xq, 4 + add tempq, xq + + movsx xq, word [inputq + 8] + imul xq, -1 + add tempq, xq + + movsx xq, word [inputq + 10] + imul xq, -1 + add tempq, xq + + add tempq, 4 + sar tempq, 3 + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [highq], tempw + + mov xq, 2 + +.loopw: + movu m0, [inputq + xq * 2] + movu m1, [inputq + xq * 2 + mmsize] + + pmaddwd m0, m8 + pmaddwd m1, m8 + + packssdw m0, m1 + movu [lowq+xq], m0 + + movu m2, [inputq + xq * 2 - 4] + movu m3, [inputq + xq * 2 - 4 + mmsize] + + pmaddwd m2, m9 + pmaddwd m3, m9 + + movu m0, [inputq + xq * 2 + 4] + movu m1, [inputq + xq * 2 + 4 + mmsize] + + pmaddwd m0, m8 + pmaddwd m1, m8 + + paddd m0, m2 + paddd m1, m3 + + paddd m0, m7 + paddd m1, m7 + + psrad m0, 3 + psrad m1, 3 + + movu m5, [inputq + xq * 2 + 0] + movu m6, [inputq + xq * 2 + mmsize] + + pmaddwd m5, m10 + pmaddwd m6, m10 + + paddd m0, m5 + paddd m1, m6 + + packssdw m0, m1 + movu [highq+xq], m0 + + add xq, mmsize + cmp xq, widthq + jl .loopw + + add lowq, widthq + add highq, widthq + lea inputq, [inputq + widthq * 2] + + movsx xq, word [inputq - 4] + movsx tempq, word [inputq - 2] + add tempq, xq + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [lowq-2], tempw + + movsx tempq, word [inputq - 4] + imul tempq, 11 + movsx xq, word [inputq - 2] + imul xq, -5 + add tempq, xq + + movsx xq, word [inputq - 6] + imul xq, -4 + add tempq, xq + + movsx xq, word [inputq - 8] + imul xq, -4 + add tempq, xq + + movsx xq, word [inputq - 10] + add tempq, xq + + movsx xq, word [inputq - 12] + add tempq, xq + + add tempq, 4 + sar tempq, 3 + + movd xm0, tempd + packssdw m0, m0 + movd tempd, m0 + mov word [highq-2], tempw + + sub inputq, widthq + sub inputq, widthq + sub highq, widthq + sub lowq, widthq + + add lowq, lwidthq + add highq, hwidthq + add inputq, istrideq + add yq, 1 + jl .looph + + RET +%endif + +%if ARCH_X86_64 +INIT_XMM sse2 +cglobal cfhdenc_vert_filter, 8, 11, 14, input, low, high, istride, lwidth, hwidth, width, height, x, y, pos + shl istrideq, 1 + + shl widthd, 1 + sub heightd, 2 + + xor xq, xq + + mova m7, [pd_4] + mova m8, [pw_1] + mova m9, [pw_m1] + mova m10,[pw_p1_n1] + mova m11,[pw_n1_p1] + mova m12,[pw_4] + mova m13,[pw_n4] +.loopw: + mov yq, 2 + + mov posq, xq + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + + paddsw m0, m1 + + movu [lowq + xq], m0 + + mov posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + add posq, istrideq + movu m2, [inputq + posq] + add posq, istrideq + movu m3, [inputq + posq] + add posq, istrideq + movu m4, [inputq + posq] + add posq, istrideq + movu m5, [inputq + posq] + + mova m6, m0 + punpcklwd m0, m1 + punpckhwd m1, m6 + + mova m6, m2 + punpcklwd m2, m3 + punpckhwd m3, m6 + + mova m6, m4 + punpcklwd m4, m5 + punpckhwd m5, m6 + + pmaddwd m0, [pw_p5_n11] + pmaddwd m1, [pw_n11_p5] + pmaddwd m2, m12 + pmaddwd m3, m12 + pmaddwd m4, m9 + pmaddwd m5, m9 + + paddd m0, m2 + paddd m1, m3 + paddd m0, m4 + paddd m1, m5 + + paddd m0, m7 + paddd m1, m7 + + psrad m0, 3 + psrad m1, 3 + packssdw m0, m1 + + movu [highq + xq], m0 + +.looph: + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + + add posq, istrideq + movu m1, [inputq + posq] + + paddsw m0, m1 + + mov posq, lwidthq + imul posq, yq + add posq, xq + + movu [lowq + posq], m0 + + add yq, -2 + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + add posq, istrideq + movu m2, [inputq + posq] + add posq, istrideq + movu m3, [inputq + posq] + add posq, istrideq + movu m4, [inputq + posq] + add posq, istrideq + movu m5, [inputq + posq] + + add yq, 2 + + mova m6, m0 + punpcklwd m0, m1 + punpckhwd m1, m6 + + mova m6, m2 + punpcklwd m2, m3 + punpckhwd m3, m6 + + mova m6, m4 + punpcklwd m4, m5 + punpckhwd m5, m6 + + pmaddwd m0, m9 + pmaddwd m1, m9 + pmaddwd m2, m10 + pmaddwd m3, m11 + pmaddwd m4, m8 + pmaddwd m5, m8 + + paddd m0, m4 + paddd m1, m5 + + paddd m0, m7 + paddd m1, m7 + + psrad m0, 3 + psrad m1, 3 + paddd m0, m2 + paddd m1, m3 + packssdw m0, m1 + + mov posq, hwidthq + imul posq, yq + add posq, xq + + movu [highq + posq], m0 + + add yq, 2 + cmp yq, heightq + jl .looph + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + + paddsw m0, m1 + + mov posq, lwidthq + imul posq, yq + add posq, xq + + movu [lowq + posq], m0 + + sub yq, 4 + + mov posq, istrideq + imul posq, yq + add posq, xq + + movu m0, [inputq + posq] + add posq, istrideq + movu m1, [inputq + posq] + add posq, istrideq + movu m2, [inputq + posq] + add posq, istrideq + movu m3, [inputq + posq] + add posq, istrideq + movu m4, [inputq + posq] + add posq, istrideq + movu m5, [inputq + posq] + + add yq, 4 + + mova m6, m0 + punpcklwd m0, m1 + punpckhwd m1, m6 + + mova m6, m2 + punpcklwd m2, m3 + punpckhwd m3, m6 + + mova m6, m4 + punpcklwd m4, m5 + punpckhwd m5, m6 + + pmaddwd m0, m8 + pmaddwd m1, m8 + pmaddwd m2, m13 + pmaddwd m3, m13 + pmaddwd m4, [pw_p11_n5] + pmaddwd m5, [pw_n5_p11] + + paddd m4, m2 + paddd m5, m3 + + paddd m4, m0 + paddd m5, m1 + + paddd m4, m7 + paddd m5, m7 + + psrad m4, 3 + psrad m5, 3 + packssdw m4, m5 + + mov posq, hwidthq + imul posq, yq + add posq, xq + + movu [highq + posq], m4 + + add xq, mmsize + cmp xq, widthq + jl .loopw + RET +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhdencdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhdencdsp_init.c new file mode 100644 index 00000000..28f1dd50 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/cfhdencdsp_init.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Paul B Mahol + * + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/cfhdencdsp.h" + +void ff_cfhdenc_horiz_filter_sse2(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height); +void ff_cfhdenc_vert_filter_sse2(int16_t *input, int16_t *low, int16_t *high, + ptrdiff_t in_stride, ptrdiff_t low_stride, + ptrdiff_t high_stride, + int width, int height); + +av_cold void ff_cfhdencdsp_init_x86(CFHDEncDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_64 + if (EXTERNAL_SSE2(cpu_flags)) { + c->horiz_filter = ff_cfhdenc_horiz_filter_sse2; + c->vert_filter = ff_cfhdenc_vert_filter_sse2; + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/constants.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/constants.c new file mode 100644 index 00000000..bc7f2b17 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/constants.c @@ -0,0 +1,93 @@ +/* + * MMX/SSE/AVX constants used across x86 dsp optimizations. + * + * 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 "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" // for xmm_reg +#include "constants.h" + +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_1) = { 0x0001000100010001ULL, 0x0001000100010001ULL, + 0x0001000100010001ULL, 0x0001000100010001ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_2) = { 0x0002000200020002ULL, 0x0002000200020002ULL, + 0x0002000200020002ULL, 0x0002000200020002ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_3) = { 0x0003000300030003ULL, 0x0003000300030003ULL }; +DECLARE_ASM_ALIGNED(32, const ymm_reg, ff_pw_4) = { 0x0004000400040004ULL, 0x0004000400040004ULL, + 0x0004000400040004ULL, 0x0004000400040004ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_5) = { 0x0005000500050005ULL, 0x0005000500050005ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_8) = { 0x0008000800080008ULL, 0x0008000800080008ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_9) = { 0x0009000900090009ULL, 0x0009000900090009ULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pw_15) = 0x000F000F000F000FULL; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_16) = { 0x0010001000100010ULL, 0x0010001000100010ULL }; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_18) = { 0x0012001200120012ULL, 0x0012001200120012ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_20) = { 0x0014001400140014ULL, 0x0014001400140014ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_32) = { 0x0020002000200020ULL, 0x0020002000200020ULL }; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_42) = 0x002A002A002A002AULL; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_53) = 0x0035003500350035ULL; +DECLARE_ASM_ALIGNED(16, const xmm_reg, ff_pw_64) = { 0x0040004000400040ULL, 0x0040004000400040ULL }; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_96) = 0x0060006000600060ULL; +DECLARE_ASM_ALIGNED(8, const uint64_t, ff_pw_128) = 0x0080008000800080ULL; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_255) = { 0x00ff00ff00ff00ffULL, 0x00ff00ff00ff00ffULL, + 0x00ff00ff00ff00ffULL, 0x00ff00ff00ff00ffULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_256) = { 0x0100010001000100ULL, 0x0100010001000100ULL, + 0x0100010001000100ULL, 0x0100010001000100ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_512) = { 0x0200020002000200ULL, 0x0200020002000200ULL, + 0x0200020002000200ULL, 0x0200020002000200ULL }; +DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1019) = { 0x03FB03FB03FB03FBULL, 0x03FB03FB03FB03FBULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_1023) = { 0x03ff03ff03ff03ffULL, 0x03ff03ff03ff03ffULL, + 0x03ff03ff03ff03ffULL, 0x03ff03ff03ff03ffULL}; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_1024) = { 0x0400040004000400ULL, 0x0400040004000400ULL, + 0x0400040004000400ULL, 0x0400040004000400ULL}; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_2048) = { 0x0800080008000800ULL, 0x0800080008000800ULL, + 0x0800080008000800ULL, 0x0800080008000800ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_4095) = { 0x0fff0fff0fff0fffULL, 0x0fff0fff0fff0fffULL, + 0x0fff0fff0fff0fffULL, 0x0fff0fff0fff0fffULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_4096) = { 0x1000100010001000ULL, 0x1000100010001000ULL, + 0x1000100010001000ULL, 0x1000100010001000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_8192) = { 0x2000200020002000ULL, 0x2000200020002000ULL, + 0x2000200020002000ULL, 0x2000200020002000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pw_m1) = { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL }; + +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_0) = { 0x0000000000000000ULL, 0x0000000000000000ULL, + 0x0000000000000000ULL, 0x0000000000000000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_1) = { 0x0101010101010101ULL, 0x0101010101010101ULL, + 0x0101010101010101ULL, 0x0101010101010101ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_2) = { 0x0202020202020202ULL, 0x0202020202020202ULL, + 0x0202020202020202ULL, 0x0202020202020202ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_3) = { 0x0303030303030303ULL, 0x0303030303030303ULL, + 0x0303030303030303ULL, 0x0303030303030303ULL }; +DECLARE_ALIGNED(32, const xmm_reg, ff_pb_15) = { 0x0F0F0F0F0F0F0F0FULL, 0x0F0F0F0F0F0F0F0FULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_80) = { 0x8080808080808080ULL, 0x8080808080808080ULL, + 0x8080808080808080ULL, 0x8080808080808080ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pb_FE) = { 0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL, + 0xFEFEFEFEFEFEFEFEULL, 0xFEFEFEFEFEFEFEFEULL }; +DECLARE_ALIGNED(8, const uint64_t, ff_pb_FC) = 0xFCFCFCFCFCFCFCFCULL; + +DECLARE_ALIGNED(16, const xmm_reg, ff_ps_neg) = { 0x8000000080000000ULL, 0x8000000080000000ULL }; + +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_1) = { 0x0000000100000001ULL, 0x0000000100000001ULL, + 0x0000000100000001ULL, 0x0000000100000001ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_16) = { 0x0000001000000010ULL, 0x0000001000000010ULL, + 0x0000001000000010ULL, 0x0000001000000010ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_32) = { 0x0000002000000020ULL, 0x0000002000000020ULL, + 0x0000002000000020ULL, 0x0000002000000020ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_8192) = { 0x0000200000002000ULL, 0x0000200000002000ULL, + 0x0000200000002000ULL, 0x0000200000002000ULL }; +DECLARE_ALIGNED(32, const ymm_reg, ff_pd_65535)= { 0x0000ffff0000ffffULL, 0x0000ffff0000ffffULL, + 0x0000ffff0000ffffULL, 0x0000ffff0000ffffULL }; diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/constants.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/constants.h new file mode 100644 index 00000000..85da38b7 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/constants.h @@ -0,0 +1,72 @@ +/* + * MMX/SSE constants used across x86 dsp optimizations. + * + * 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 + */ + +#ifndef AVCODEC_X86_CONSTANTS_H +#define AVCODEC_X86_CONSTANTS_H + +#include + +#include "libavutil/x86/asm.h" + +extern const ymm_reg ff_pw_1; +extern const ymm_reg ff_pw_2; +extern const xmm_reg ff_pw_3; +extern const ymm_reg ff_pw_4; +extern const xmm_reg ff_pw_5; +extern const xmm_reg ff_pw_8; +extern const xmm_reg ff_pw_9; +extern const uint64_t ff_pw_15; +extern const xmm_reg ff_pw_16; +extern const xmm_reg ff_pw_18; +extern const xmm_reg ff_pw_20; +extern const xmm_reg ff_pw_32; +extern const uint64_t ff_pw_42; +extern const uint64_t ff_pw_53; +extern const xmm_reg ff_pw_64; +extern const uint64_t ff_pw_96; +extern const uint64_t ff_pw_128; +extern const ymm_reg ff_pw_255; +extern const ymm_reg ff_pw_256; +extern const ymm_reg ff_pw_512; +extern const ymm_reg ff_pw_1023; +extern const ymm_reg ff_pw_1024; +extern const ymm_reg ff_pw_2048; +extern const ymm_reg ff_pw_4095; +extern const ymm_reg ff_pw_4096; +extern const ymm_reg ff_pw_8192; +extern const ymm_reg ff_pw_m1; + +extern const ymm_reg ff_pb_0; +extern const ymm_reg ff_pb_1; +extern const ymm_reg ff_pb_2; +extern const ymm_reg ff_pb_3; +extern const ymm_reg ff_pb_80; +extern const ymm_reg ff_pb_FE; +extern const uint64_t ff_pb_FC; + +extern const xmm_reg ff_ps_neg; + +extern const ymm_reg ff_pd_1; +extern const ymm_reg ff_pd_16; +extern const ymm_reg ff_pd_32; +extern const ymm_reg ff_pd_8192; +extern const ymm_reg ff_pd_65535; + +#endif /* AVCODEC_X86_CONSTANTS_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dcadsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dcadsp.asm new file mode 100644 index 00000000..055361a7 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dcadsp.asm @@ -0,0 +1,301 @@ +;****************************************************************************** +;* SIMD-optimized functions for the DCA decoder +;* Copyright (C) 2016 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%define sizeof_float 4 +%define FMA3_OFFSET (8 * cpuflag(fma3)) + +%macro LFE_FIR0_FLOAT 0 +cglobal lfe_fir0_float, 4, 6, 12 + cpuflag(fma3)*4, samples, lfe, coeff, nblocks, cnt1, cnt2 + shr nblocksd, 1 + sub lfeq, 7*sizeof_float + mov cnt1d, 32*sizeof_float + mov cnt2d, 32*sizeof_float-8-FMA3_OFFSET + lea coeffq, [coeffq+cnt1q*8] + add samplesq, cnt1q + neg cnt1q + +.loop: +%if cpuflag(avx) + cvtdq2ps m4, [lfeq+16] + cvtdq2ps m5, [lfeq ] + shufps m7, m4, m4, q0123 + shufps m6, m5, m5, q0123 +%elif cpuflag(sse2) + movu m4, [lfeq+16] + movu m5, [lfeq ] + cvtdq2ps m4, m4 + cvtdq2ps m5, m5 + pshufd m7, m4, q0123 + pshufd m6, m5, q0123 +%else + cvtpi2ps m4, [lfeq+16] + cvtpi2ps m0, [lfeq+24] + cvtpi2ps m5, [lfeq ] + cvtpi2ps m1, [lfeq+8 ] + shufps m4, m0, q1010 + shufps m5, m1, q1010 + shufps m7, m4, m4, q0123 + shufps m6, m5, m5, q0123 +%endif + +.inner_loop: +%if ARCH_X86_64 + movaps m8, [coeffq+cnt1q*8 ] + movaps m9, [coeffq+cnt1q*8+16] + movaps m10, [coeffq+cnt1q*8+32] + movaps m11, [coeffq+cnt1q*8+48] +%if cpuflag(fma3) + movaps m12, [coeffq+cnt1q*8+64] + movaps m13, [coeffq+cnt1q*8+80] + movaps m14, [coeffq+cnt1q*8+96] + movaps m15, [coeffq+cnt1q*8+112] + mulps m0, m7, m8 + mulps m1, m7, m10 + mulps m2, m7, m12 + mulps m3, m7, m14 + fmaddps m0, m6, m9, m0 + fmaddps m1, m6, m11, m1 + fmaddps m2, m6, m13, m2 + fmaddps m3, m6, m15, m3 + + haddps m0, m1 + haddps m2, m3 + haddps m0, m2 + movaps [samplesq+cnt1q], m0 +%else + mulps m0, m7, m8 + mulps m1, m6, m9 + mulps m2, m7, m10 + mulps m3, m6, m11 + addps m0, m1 + addps m2, m3 + + unpckhps m3, m0, m2 + unpcklps m0, m2 + addps m3, m0 + movhlps m2, m3 + addps m2, m3 + movlps [samplesq+cnt1q], m2 +%endif +%else ; ARCH_X86_32 +%if cpuflag(fma3) + mulps m0, m7, [coeffq+cnt1q*8 ] + mulps m1, m7, [coeffq+cnt1q*8+32 ] + mulps m2, m7, [coeffq+cnt1q*8+64 ] + mulps m3, m7, [coeffq+cnt1q*8+96 ] + fmaddps m0, m6, [coeffq+cnt1q*8+16 ], m0 + fmaddps m1, m6, [coeffq+cnt1q*8+48 ], m1 + fmaddps m2, m6, [coeffq+cnt1q*8+80 ], m2 + fmaddps m3, m6, [coeffq+cnt1q*8+112], m3 + + haddps m0, m1 + haddps m2, m3 + haddps m0, m2 + movaps [samplesq+cnt1q], m0 +%else + mulps m0, m7, [coeffq+cnt1q*8 ] + mulps m1, m6, [coeffq+cnt1q*8+16] + mulps m2, m7, [coeffq+cnt1q*8+32] + mulps m3, m6, [coeffq+cnt1q*8+48] + addps m0, m1 + addps m2, m3 + + unpckhps m3, m0, m2 + unpcklps m0, m2 + addps m3, m0 + movhlps m2, m3 + addps m2, m3 + movlps [samplesq+cnt1q], m2 +%endif +%endif; ARCH + +%if ARCH_X86_64 +%if cpuflag(fma3) + mulps m8, m5 + mulps m10, m5 + mulps m12, m5 + mulps m14, m5 + fmaddps m8, m4, m9, m8 + fmaddps m10, m4, m11, m10 + fmaddps m12, m4, m13, m12 + fmaddps m14, m4, m15, m14 + + haddps m10, m8 + haddps m14, m12 + haddps m14, m10 + movaps [samplesq+cnt2q], m14 +%else + mulps m8, m5 + mulps m9, m4 + mulps m10, m5 + mulps m11, m4 + addps m8, m9 + addps m10, m11 + + unpckhps m11, m10, m8 + unpcklps m10, m8 + addps m11, m10 + movhlps m8, m11 + addps m8, m11 + movlps [samplesq+cnt2q], m8 +%endif +%else ; ARCH_X86_32 +%if cpuflag(fma3) + mulps m0, m5, [coeffq+cnt1q*8 ] + mulps m1, m5, [coeffq+cnt1q*8+32 ] + mulps m2, m5, [coeffq+cnt1q*8+64 ] + mulps m3, m5, [coeffq+cnt1q*8+96 ] + fmaddps m0, m4, [coeffq+cnt1q*8+16 ], m0 + fmaddps m1, m4, [coeffq+cnt1q*8+48 ], m1 + fmaddps m2, m4, [coeffq+cnt1q*8+80 ], m2 + fmaddps m3, m4, [coeffq+cnt1q*8+112], m3 + + haddps m1, m0 + haddps m3, m2 + haddps m3, m1 + movaps [samplesq+cnt2q], m3 +%else + mulps m0, m5, [coeffq+cnt1q*8 ] + mulps m1, m4, [coeffq+cnt1q*8+16] + mulps m2, m5, [coeffq+cnt1q*8+32] + mulps m3, m4, [coeffq+cnt1q*8+48] + addps m0, m1 + addps m2, m3 + + unpckhps m3, m2, m0 + unpcklps m2, m0 + addps m3, m2 + movhlps m0, m3 + addps m0, m3 + movlps [samplesq+cnt2q], m0 +%endif +%endif; ARCH + + sub cnt2d, 8 + FMA3_OFFSET + add cnt1q, 8 + FMA3_OFFSET + jl .inner_loop + + add lfeq, 4 + add samplesq, 64*sizeof_float + mov cnt1q, -32*sizeof_float + mov cnt2d, 32*sizeof_float-8-FMA3_OFFSET + sub nblocksd, 1 + jg .loop + RET +%endmacro + +%if ARCH_X86_32 +INIT_XMM sse +LFE_FIR0_FLOAT +%endif +INIT_XMM sse2 +LFE_FIR0_FLOAT +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +LFE_FIR0_FLOAT +%endif +%if HAVE_FMA3_EXTERNAL +INIT_XMM fma3 +LFE_FIR0_FLOAT +%endif + +%macro LFE_FIR1_FLOAT 0 +cglobal lfe_fir1_float, 4, 6, 10, samples, lfe, coeff, nblocks, cnt1, cnt2 + shr nblocksd, 2 + sub lfeq, 3*sizeof_float + mov cnt1d, 64*sizeof_float + mov cnt2d, 64*sizeof_float-16 + lea coeffq, [coeffq+cnt1q*4] + add samplesq, cnt1q + neg cnt1q + +.loop: +%if cpuflag(avx) + cvtdq2ps m4, [lfeq] + shufps m5, m4, m4, q0123 +%elif cpuflag(sse2) + movu m4, [lfeq] + cvtdq2ps m4, m4 + pshufd m5, m4, q0123 +%endif + +.inner_loop: + movaps m6, [coeffq+cnt1q*4 ] + movaps m7, [coeffq+cnt1q*4+16] + mulps m0, m5, m6 + mulps m1, m5, m7 +%if ARCH_X86_64 + movaps m8, [coeffq+cnt1q*4+32] + movaps m9, [coeffq+cnt1q*4+48] + mulps m2, m5, m8 + mulps m3, m5, m9 +%else + mulps m2, m5, [coeffq+cnt1q*4+32] + mulps m3, m5, [coeffq+cnt1q*4+48] +%endif + + haddps m0, m1 + haddps m2, m3 + haddps m0, m2 + movaps [samplesq+cnt1q], m0 + + mulps m6, m4 + mulps m7, m4 +%if ARCH_X86_64 + mulps m8, m4 + mulps m9, m4 + + haddps m6, m7 + haddps m8, m9 + haddps m6, m8 +%else + mulps m2, m4, [coeffq+cnt1q*4+32] + mulps m3, m4, [coeffq+cnt1q*4+48] + + haddps m6, m7 + haddps m2, m3 + haddps m6, m2 +%endif + movaps [samplesq+cnt2q], m6 + + sub cnt2d, 16 + add cnt1q, 16 + jl .inner_loop + + add lfeq, sizeof_float + add samplesq, 128*sizeof_float + mov cnt1q, -64*sizeof_float + mov cnt2d, 64*sizeof_float-16 + sub nblocksd, 1 + jg .loop + RET +%endmacro + +INIT_XMM sse3 +LFE_FIR1_FLOAT +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +LFE_FIR1_FLOAT +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dcadsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dcadsp_init.c new file mode 100644 index 00000000..fc10fb8b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dcadsp_init.c @@ -0,0 +1,52 @@ +/* + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dcadsp.h" + +#define LFE_FIR_FLOAT_FUNC(opt) \ +void ff_lfe_fir0_float_##opt(float *pcm_samples, int32_t *lfe_samples, \ + const float *filter_coeff, ptrdiff_t npcmblocks); \ +void ff_lfe_fir1_float_##opt(float *pcm_samples, int32_t *lfe_samples, \ + const float *filter_coeff, ptrdiff_t npcmblocks); + +LFE_FIR_FLOAT_FUNC(sse) +LFE_FIR_FLOAT_FUNC(sse2) +LFE_FIR_FLOAT_FUNC(sse3) +LFE_FIR_FLOAT_FUNC(avx) +LFE_FIR_FLOAT_FUNC(fma3) + +av_cold void ff_dcadsp_init_x86(DCADSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (ARCH_X86_32 && EXTERNAL_SSE(cpu_flags)) + s->lfe_fir_float[0] = ff_lfe_fir0_float_sse; + if (EXTERNAL_SSE2(cpu_flags)) + s->lfe_fir_float[0] = ff_lfe_fir0_float_sse2; + if (EXTERNAL_SSE3(cpu_flags)) + s->lfe_fir_float[1] = ff_lfe_fir1_float_sse3; + if (EXTERNAL_AVX(cpu_flags)) { + s->lfe_fir_float[0] = ff_lfe_fir0_float_avx; + s->lfe_fir_float[1] = ff_lfe_fir1_float_avx; + } + if (EXTERNAL_FMA3(cpu_flags)) + s->lfe_fir_float[0] = ff_lfe_fir0_float_fma3; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dct32.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dct32.asm new file mode 100644 index 00000000..21e2f21c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dct32.asm @@ -0,0 +1,491 @@ +;****************************************************************************** +;* 32 point SSE-optimized DCT transform +;* Copyright (c) 2010 Vitor Sessak +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +ps_p1p1m1m1: dd 0, 0, 0x80000000, 0x80000000, 0, 0, 0x80000000, 0x80000000 + +ps_cos_vec: dd 0.500603, 0.505471, 0.515447, 0.531043 + dd 0.553104, 0.582935, 0.622504, 0.674808 + dd -10.190008, -3.407609, -2.057781, -1.484165 + dd -1.169440, -0.972568, -0.839350, -0.744536 + dd 0.502419, 0.522499, 0.566944, 0.646822 + dd 0.788155, 1.060678, 1.722447, 5.101149 + dd 0.509796, 0.601345, 0.899976, 2.562916 + dd 0.509796, 0.601345, 0.899976, 2.562916 + dd 1.000000, 1.000000, 1.306563, 0.541196 + dd 1.000000, 1.000000, 1.306563, 0.541196 + dd 1.000000, 0.707107, 1.000000, -0.707107 + dd 1.000000, 0.707107, 1.000000, -0.707107 + dd 0.707107, 0.707107, 0.707107, 0.707107 + +%macro BUTTERFLY 4 + subps %4, %1, %2 + addps %2, %2, %1 + mulps %1, %4, %3 +%endmacro + +%macro BUTTERFLY0 5 +%if cpuflag(sse2) && notcpuflag(avx) + pshufd %4, %1, %5 + xorps %1, %2 + addps %1, %4 + mulps %1, %3 +%else + shufps %4, %1, %1, %5 + xorps %1, %1, %2 + addps %4, %4, %1 + mulps %1, %4, %3 +%endif +%endmacro + +%macro BUTTERFLY2 4 + BUTTERFLY0 %1, %2, %3, %4, 0x1b +%endmacro + +%macro BUTTERFLY3 4 + BUTTERFLY0 %1, %2, %3, %4, 0xb1 +%endmacro + +%macro BUTTERFLY3V 5 + movaps m%5, m%1 + addps m%1, m%2 + subps m%5, m%2 + SWAP %2, %5 + mulps m%2, [ps_cos_vec+192] + movaps m%5, m%3 + addps m%3, m%4 + subps m%4, m%5 + mulps m%4, [ps_cos_vec+192] +%endmacro + +%macro PASS6_AND_PERMUTE 0 + mov tmpd, [outq+4] + movss m7, [outq+72] + addss m7, [outq+76] + movss m3, [outq+56] + addss m3, [outq+60] + addss m4, m3 + movss m2, [outq+52] + addss m2, m3 + movss m3, [outq+104] + addss m3, [outq+108] + addss m1, m3 + addss m5, m4 + movss [outq+ 16], m1 + movss m1, [outq+100] + addss m1, m3 + movss m3, [outq+40] + movss [outq+ 48], m1 + addss m3, [outq+44] + movss m1, [outq+100] + addss m4, m3 + addss m3, m2 + addss m1, [outq+108] + movss [outq+ 40], m3 + addss m2, [outq+36] + movss m3, [outq+8] + movss [outq+ 56], m2 + addss m3, [outq+12] + movss [outq+ 32], m3 + movss m3, [outq+80] + movss [outq+ 8], m5 + movss [outq+ 80], m1 + movss m2, [outq+52] + movss m5, [outq+120] + addss m5, [outq+124] + movss m1, [outq+64] + addss m2, [outq+60] + addss m0, m5 + addss m5, [outq+116] + mov [outq+64], tmpd + addss m6, m0 + addss m1, m6 + mov tmpd, [outq+12] + mov [outq+ 96], tmpd + movss [outq+ 4], m1 + movss m1, [outq+24] + movss [outq+ 24], m4 + movss m4, [outq+88] + addss m4, [outq+92] + addss m3, m4 + addss m4, [outq+84] + mov tmpd, [outq+108] + addss m1, [outq+28] + addss m0, m1 + addss m1, m5 + addss m6, m3 + addss m3, m0 + addss m0, m7 + addss m5, [outq+20] + addss m7, m1 + movss [outq+ 12], m6 + mov [outq+112], tmpd + movss m6, [outq+28] + movss [outq+ 28], m0 + movss m0, [outq+36] + movss [outq+ 36], m7 + addss m1, m4 + movss m7, [outq+116] + addss m0, m2 + addss m7, [outq+124] + movss [outq+ 72], m0 + movss m0, [outq+44] + addss m2, m0 + movss [outq+ 44], m1 + movss [outq+ 88], m2 + addss m0, [outq+60] + mov tmpd, [outq+60] + mov [outq+120], tmpd + movss [outq+104], m0 + addss m4, m5 + addss m5, [outq+68] + movss [outq+52], m4 + movss [outq+60], m5 + movss m4, [outq+68] + movss m5, [outq+20] + movss [outq+ 20], m3 + addss m5, m7 + addss m7, m6 + addss m4, m5 + movss m2, [outq+84] + addss m2, [outq+92] + addss m5, m2 + movss [outq+ 68], m4 + addss m2, m7 + movss m4, [outq+76] + movss [outq+ 84], m2 + movss [outq+ 76], m5 + addss m7, m4 + addss m6, [outq+124] + addss m4, m6 + addss m6, [outq+92] + movss [outq+100], m4 + movss [outq+108], m6 + movss m6, [outq+92] + movss [outq+92], m7 + addss m6, [outq+124] + movss [outq+116], m6 +%endmacro + +INIT_YMM avx +SECTION .text +%if HAVE_AVX_EXTERNAL +; void ff_dct32_float_avx(FFTSample *out, const FFTSample *in) +cglobal dct32_float, 2,3,8, out, in, tmp + ; pass 1 + vmovaps m4, [inq+0] + vinsertf128 m5, m5, [inq+96], 1 + vinsertf128 m5, m5, [inq+112], 0 + vshufps m5, m5, m5, 0x1b + BUTTERFLY m4, m5, [ps_cos_vec], m6 + + vmovaps m2, [inq+64] + vinsertf128 m6, m6, [inq+32], 1 + vinsertf128 m6, m6, [inq+48], 0 + vshufps m6, m6, m6, 0x1b + BUTTERFLY m2, m6, [ps_cos_vec+32], m0 + + ; pass 2 + + BUTTERFLY m5, m6, [ps_cos_vec+64], m0 + BUTTERFLY m4, m2, [ps_cos_vec+64], m7 + + + ; pass 3 + vperm2f128 m3, m6, m4, 0x31 + vperm2f128 m1, m6, m4, 0x20 + vshufps m3, m3, m3, 0x1b + + BUTTERFLY m1, m3, [ps_cos_vec+96], m6 + + + vperm2f128 m4, m5, m2, 0x20 + vperm2f128 m5, m5, m2, 0x31 + vshufps m5, m5, m5, 0x1b + + BUTTERFLY m4, m5, [ps_cos_vec+96], m6 + + ; pass 4 + vmovaps m6, [ps_p1p1m1m1+0] + vmovaps m2, [ps_cos_vec+128] + + BUTTERFLY2 m5, m6, m2, m7 + BUTTERFLY2 m4, m6, m2, m7 + BUTTERFLY2 m1, m6, m2, m7 + BUTTERFLY2 m3, m6, m2, m7 + + + ; pass 5 + vshufps m6, m6, m6, 0xcc + vmovaps m2, [ps_cos_vec+160] + + BUTTERFLY3 m5, m6, m2, m7 + BUTTERFLY3 m4, m6, m2, m7 + BUTTERFLY3 m1, m6, m2, m7 + BUTTERFLY3 m3, m6, m2, m7 + + vperm2f128 m6, m3, m3, 0x31 + vmovaps [outq], m3 + + vextractf128 [outq+64], m5, 1 + vextractf128 [outq+32], m5, 0 + + vextractf128 [outq+80], m4, 1 + vextractf128 [outq+48], m4, 0 + + vperm2f128 m0, m1, m1, 0x31 + vmovaps [outq+96], m1 + + vzeroupper + + ; pass 6, no SIMD... +INIT_XMM + PASS6_AND_PERMUTE + RET +%endif + +%if ARCH_X86_64 +%define SPILL SWAP +%define UNSPILL SWAP + +%macro PASS5 0 + nop ; FIXME code alignment + SWAP 5, 8 + SWAP 4, 12 + SWAP 6, 14 + SWAP 7, 13 + SWAP 0, 15 + PERMUTE 9,10, 10,12, 11,14, 12,9, 13,11, 14,13 + TRANSPOSE4x4PS 8, 9, 10, 11, 0 + BUTTERFLY3V 8, 9, 10, 11, 0 + addps m10, m11 + TRANSPOSE4x4PS 12, 13, 14, 15, 0 + BUTTERFLY3V 12, 13, 14, 15, 0 + addps m14, m15 + addps m12, m14 + addps m14, m13 + addps m13, m15 +%endmacro + +%macro PASS6 0 + SWAP 9, 12 + SWAP 11, 14 + movss [outq+0x00], m8 + pshuflw m0, m8, 0xe + movss [outq+0x10], m9 + pshuflw m1, m9, 0xe + movss [outq+0x20], m10 + pshuflw m2, m10, 0xe + movss [outq+0x30], m11 + pshuflw m3, m11, 0xe + movss [outq+0x40], m12 + pshuflw m4, m12, 0xe + movss [outq+0x50], m13 + pshuflw m5, m13, 0xe + movss [outq+0x60], m14 + pshuflw m6, m14, 0xe + movaps [outq+0x70], m15 + pshuflw m7, m15, 0xe + addss m0, m1 + addss m1, m2 + movss [outq+0x08], m0 + addss m2, m3 + movss [outq+0x18], m1 + addss m3, m4 + movss [outq+0x28], m2 + addss m4, m5 + movss [outq+0x38], m3 + addss m5, m6 + movss [outq+0x48], m4 + addss m6, m7 + movss [outq+0x58], m5 + movss [outq+0x68], m6 + movss [outq+0x78], m7 + + PERMUTE 1,8, 3,9, 5,10, 7,11, 9,12, 11,13, 13,14, 8,1, 10,3, 12,5, 14,7 + movhlps m0, m1 + pshufd m1, m1, 3 + SWAP 0, 2, 4, 6, 8, 10, 12, 14 + SWAP 1, 3, 5, 7, 9, 11, 13, 15 +%rep 7 + movhlps m0, m1 + pshufd m1, m1, 3 + addss m15, m1 + SWAP 0, 2, 4, 6, 8, 10, 12, 14 + SWAP 1, 3, 5, 7, 9, 11, 13, 15 +%endrep +%assign i 4 +%rep 15 + addss m0, m1 + movss [outq+i], m0 + SWAP 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + %assign i i+8 +%endrep +%endmacro + +%else ; ARCH_X86_32 +%macro SPILL 2 ; xmm#, mempos + movaps [outq+(%2-8)*16], m%1 +%endmacro +%macro UNSPILL 2 + movaps m%1, [outq+(%2-8)*16] +%endmacro + +%define PASS6 PASS6_AND_PERMUTE +%macro PASS5 0 + movaps m2, [ps_cos_vec+160] + shufps m3, m3, 0xcc + + BUTTERFLY3 m5, m3, m2, m1 + SPILL 5, 8 + + UNSPILL 1, 9 + BUTTERFLY3 m1, m3, m2, m5 + SPILL 1, 14 + + BUTTERFLY3 m4, m3, m2, m5 + SPILL 4, 12 + + BUTTERFLY3 m7, m3, m2, m5 + SPILL 7, 13 + + UNSPILL 5, 10 + BUTTERFLY3 m5, m3, m2, m7 + SPILL 5, 10 + + UNSPILL 4, 11 + BUTTERFLY3 m4, m3, m2, m7 + SPILL 4, 11 + + BUTTERFLY3 m6, m3, m2, m7 + SPILL 6, 9 + + BUTTERFLY3 m0, m3, m2, m7 + SPILL 0, 15 +%endmacro +%endif + + +; void ff_dct32_float_sse(FFTSample *out, const FFTSample *in) +%macro DCT32_FUNC 0 +cglobal dct32_float, 2, 3, 16, out, in, tmp + ; pass 1 + + movaps m0, [inq+0] + LOAD_INV m1, [inq+112] + BUTTERFLY m0, m1, [ps_cos_vec], m3 + + movaps m7, [inq+64] + LOAD_INV m4, [inq+48] + BUTTERFLY m7, m4, [ps_cos_vec+32], m3 + + ; pass 2 + movaps m2, [ps_cos_vec+64] + BUTTERFLY m1, m4, m2, m3 + SPILL 1, 11 + SPILL 4, 8 + + ; pass 1 + movaps m1, [inq+16] + LOAD_INV m6, [inq+96] + BUTTERFLY m1, m6, [ps_cos_vec+16], m3 + + movaps m4, [inq+80] + LOAD_INV m5, [inq+32] + BUTTERFLY m4, m5, [ps_cos_vec+48], m3 + + ; pass 2 + BUTTERFLY m0, m7, m2, m3 + + movaps m2, [ps_cos_vec+80] + BUTTERFLY m6, m5, m2, m3 + + BUTTERFLY m1, m4, m2, m3 + + ; pass 3 + movaps m2, [ps_cos_vec+96] + shufps m1, m1, 0x1b + BUTTERFLY m0, m1, m2, m3 + SPILL 0, 15 + SPILL 1, 14 + + UNSPILL 0, 8 + shufps m5, m5, 0x1b + BUTTERFLY m0, m5, m2, m3 + + UNSPILL 1, 11 + shufps m6, m6, 0x1b + BUTTERFLY m1, m6, m2, m3 + SPILL 1, 11 + + shufps m4, m4, 0x1b + BUTTERFLY m7, m4, m2, m3 + + ; pass 4 + movaps m3, [ps_p1p1m1m1+0] + movaps m2, [ps_cos_vec+128] + + BUTTERFLY2 m5, m3, m2, m1 + + BUTTERFLY2 m0, m3, m2, m1 + SPILL 0, 9 + + BUTTERFLY2 m6, m3, m2, m1 + SPILL 6, 10 + + UNSPILL 0, 11 + BUTTERFLY2 m0, m3, m2, m1 + SPILL 0, 11 + + BUTTERFLY2 m4, m3, m2, m1 + + BUTTERFLY2 m7, m3, m2, m1 + + UNSPILL 6, 14 + BUTTERFLY2 m6, m3, m2, m1 + + UNSPILL 0, 15 + BUTTERFLY2 m0, m3, m2, m1 + + PASS5 + PASS6 + RET +%endmacro + +%macro LOAD_INV 2 +%if cpuflag(sse2) + pshufd %1, %2, 0x1b +%elif cpuflag(sse) + movaps %1, %2 + shufps %1, %1, 0x1b +%endif +%endmacro + +%if ARCH_X86_32 +INIT_XMM sse +DCT32_FUNC +%endif + +INIT_XMM sse2 +DCT32_FUNC diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dct_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dct_init.c new file mode 100644 index 00000000..c31ef922 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dct_init.c @@ -0,0 +1,41 @@ +/* + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dct.h" + +void ff_dct32_float_sse(FFTSample *out, const FFTSample *in); +void ff_dct32_float_sse2(FFTSample *out, const FFTSample *in); +void ff_dct32_float_avx(FFTSample *out, const FFTSample *in); + +av_cold void ff_dct_init_x86(DCTContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) + s->dct32 = ff_dct32_float_sse; +#endif + if (EXTERNAL_SSE2(cpu_flags)) + s->dct32 = ff_dct32_float_sse2; + if (EXTERNAL_AVX_FAST(cpu_flags)) + s->dct32 = ff_dct32_float_avx; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dirac_dwt.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dirac_dwt.asm new file mode 100644 index 00000000..22a5c2bb --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dirac_dwt.asm @@ -0,0 +1,307 @@ +;****************************************************************************** +;* x86 optimized discrete wavelet trasnform +;* Copyright (c) 2010 David Conrad +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA +pw_1991: times 4 dw 9,-1 + +cextern pw_1 +cextern pw_2 +cextern pw_8 +cextern pw_16 + +SECTION .text + +; %1 -= (%2 + %3 + 2)>>2 %4 is pw_2 +%macro COMPOSE_53iL0 4 + paddw %2, %3 + paddw %2, %4 + psraw %2, 2 + psubw %1, %2 +%endm + +; m1 = %1 + (-m0 + 9*m1 + 9*%2 -%3 + 8)>>4 +; if %4 is supplied, %1 is loaded unaligned from there +; m2: clobbered m3: pw_8 m4: pw_1991 +%macro COMPOSE_DD97iH0 3-4 + paddw m0, %3 + paddw m1, %2 + psubw m0, m3 + mova m2, m1 + punpcklwd m1, m0 + punpckhwd m2, m0 + pmaddwd m1, m4 + pmaddwd m2, m4 +%if %0 > 3 + movu %1, %4 +%endif + psrad m1, 4 + psrad m2, 4 + packssdw m1, m2 + paddw m1, %1 +%endm + +%macro COMPOSE_VERTICAL 1 +; void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; int width) +cglobal vertical_compose53iL0_%1, 4,4,1, b0, b1, b2, width + mova m2, [pw_2] +%if ARCH_X86_64 + mov widthd, widthd +%endif +.loop: + sub widthq, mmsize/2 + mova m1, [b0q+2*widthq] + mova m0, [b1q+2*widthq] + COMPOSE_53iL0 m0, m1, [b2q+2*widthq], m2 + mova [b1q+2*widthq], m0 + jg .loop + REP_RET + +; void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; int width) +cglobal vertical_compose_dirac53iH0_%1, 4,4,1, b0, b1, b2, width + mova m1, [pw_1] +%if ARCH_X86_64 + mov widthd, widthd +%endif +.loop: + sub widthq, mmsize/2 + mova m0, [b0q+2*widthq] + paddw m0, [b2q+2*widthq] + paddw m0, m1 + psraw m0, 1 + paddw m0, [b1q+2*widthq] + mova [b1q+2*widthq], m0 + jg .loop + REP_RET + +; void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; IDWTELEM *b3, IDWTELEM *b4, int width) +cglobal vertical_compose_dd97iH0_%1, 6,6,5, b0, b1, b2, b3, b4, width + mova m3, [pw_8] + mova m4, [pw_1991] +%if ARCH_X86_64 + mov widthd, widthd +%endif +.loop: + sub widthq, mmsize/2 + mova m0, [b0q+2*widthq] + mova m1, [b1q+2*widthq] + COMPOSE_DD97iH0 [b2q+2*widthq], [b3q+2*widthq], [b4q+2*widthq] + mova [b2q+2*widthq], m1 + jg .loop + REP_RET + +; void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, +; IDWTELEM *b3, IDWTELEM *b4, int width) +cglobal vertical_compose_dd137iL0_%1, 6,6,6, b0, b1, b2, b3, b4, width + mova m3, [pw_16] + mova m4, [pw_1991] +%if ARCH_X86_64 + mov widthd, widthd +%endif +.loop: + sub widthq, mmsize/2 + mova m0, [b0q+2*widthq] + mova m1, [b1q+2*widthq] + mova m5, [b2q+2*widthq] + paddw m0, [b4q+2*widthq] + paddw m1, [b3q+2*widthq] + psubw m0, m3 + mova m2, m1 + punpcklwd m1, m0 + punpckhwd m2, m0 + pmaddwd m1, m4 + pmaddwd m2, m4 + psrad m1, 5 + psrad m2, 5 + packssdw m1, m2 + psubw m5, m1 + mova [b2q+2*widthq], m5 + jg .loop + REP_RET + +; void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width) +cglobal vertical_compose_haar_%1, 3,4,3, b0, b1, width + mova m3, [pw_1] +%if ARCH_X86_64 + mov widthd, widthd +%endif +.loop: + sub widthq, mmsize/2 + mova m1, [b1q+2*widthq] + mova m0, [b0q+2*widthq] + mova m2, m1 + paddw m1, m3 + psraw m1, 1 + psubw m0, m1 + mova [b0q+2*widthq], m0 + paddw m2, m0 + mova [b1q+2*widthq], m2 + jg .loop + REP_RET +%endmacro + +; extend the left and right edges of the tmp array by %1 and %2 respectively +%macro EDGE_EXTENSION 3 + mov %3, [tmpq] +%assign %%i 1 +%rep %1 + mov [tmpq-2*%%i], %3 + %assign %%i %%i+1 +%endrep + mov %3, [tmpq+2*w2q-2] +%assign %%i 0 +%rep %2 + mov [tmpq+2*w2q+2*%%i], %3 + %assign %%i %%i+1 +%endrep +%endmacro + + +%macro HAAR_HORIZONTAL 2 +; void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *tmp, int width) +cglobal horizontal_compose_haar%2i_%1, 3,6,4, b, tmp, w, x, w2, b_w2 + mov w2d, wd + xor xq, xq + shr w2d, 1 + lea b_w2q, [bq+wq] + mova m3, [pw_1] +.lowpass_loop: + movu m1, [b_w2q + 2*xq] + mova m0, [bq + 2*xq] + paddw m1, m3 + psraw m1, 1 + psubw m0, m1 + mova [tmpq + 2*xq], m0 + add xq, mmsize/2 + cmp xq, w2q + jl .lowpass_loop + + xor xq, xq + and w2q, ~(mmsize/2 - 1) + cmp w2q, mmsize/2 + jl .end + +.highpass_loop: + movu m1, [b_w2q + 2*xq] + mova m0, [tmpq + 2*xq] + paddw m1, m0 + + ; shift and interleave +%if %2 == 1 + paddw m0, m3 + paddw m1, m3 + psraw m0, 1 + psraw m1, 1 +%endif + mova m2, m0 + punpcklwd m0, m1 + punpckhwd m2, m1 + mova [bq+4*xq], m0 + mova [bq+4*xq+mmsize], m2 + + add xq, mmsize/2 + cmp xq, w2q + jl .highpass_loop +.end: + REP_RET +%endmacro + + +INIT_XMM +; void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int width) +cglobal horizontal_compose_dd97i_ssse3, 3,6,8, b, tmp, w, x, w2, b_w2 + mov w2d, wd + xor xd, xd + shr w2d, 1 + lea b_w2q, [bq+wq] + movu m4, [bq+wq] + mova m7, [pw_2] + pslldq m4, 14 +.lowpass_loop: + movu m1, [b_w2q + 2*xq] + mova m0, [bq + 2*xq] + mova m2, m1 + palignr m1, m4, 14 + mova m4, m2 + COMPOSE_53iL0 m0, m1, m2, m7 + mova [tmpq + 2*xq], m0 + add xd, mmsize/2 + cmp xd, w2d + jl .lowpass_loop + + EDGE_EXTENSION 1, 2, xw + ; leave the last up to 7 (sse) or 3 (mmx) values for C + xor xd, xd + and w2d, ~(mmsize/2 - 1) + cmp w2d, mmsize/2 + jl .end + + mova m7, [tmpq-mmsize] + mova m0, [tmpq] + mova m5, [pw_1] + mova m3, [pw_8] + mova m4, [pw_1991] +.highpass_loop: + mova m6, m0 + palignr m0, m7, 14 + mova m7, [tmpq + 2*xq + 16] + mova m1, m7 + mova m2, m7 + palignr m1, m6, 2 + palignr m2, m6, 4 + COMPOSE_DD97iH0 m0, m6, m2, [b_w2q + 2*xq] + mova m0, m7 + mova m7, m6 + + ; shift and interleave + paddw m6, m5 + paddw m1, m5 + psraw m6, 1 + psraw m1, 1 + mova m2, m6 + punpcklwd m6, m1 + punpckhwd m2, m1 + mova [bq+4*xq], m6 + mova [bq+4*xq+mmsize], m2 + + add xd, mmsize/2 + cmp xd, w2d + jl .highpass_loop +.end: + REP_RET + + +%if ARCH_X86_64 == 0 +INIT_MMX +COMPOSE_VERTICAL mmx +HAAR_HORIZONTAL mmx, 0 +HAAR_HORIZONTAL mmx, 1 +%endif + +;;INIT_XMM +INIT_XMM +COMPOSE_VERTICAL sse2 +HAAR_HORIZONTAL sse2, 0 +HAAR_HORIZONTAL sse2, 1 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dirac_dwt_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dirac_dwt_init.c new file mode 100644 index 00000000..49a6380a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dirac_dwt_init.c @@ -0,0 +1,229 @@ +/* + * x86 optimized discrete wavelet transform + * Copyright (c) 2002-2004 Michael Niedermayer + * Copyright (c) 2010 David Conrad + * + * 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 "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dirac_dwt.h" + +#define COMPOSE_VERTICAL(ext, align) \ +void ff_vertical_compose53iL0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int width); \ +void ff_vertical_compose_dirac53iH0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int width); \ +void ff_vertical_compose_dd137iL0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int16_t *b3, int16_t *b4, int width); \ +void ff_vertical_compose_dd97iH0##ext(int16_t *b0, int16_t *b1, int16_t *b2, int16_t *b3, int16_t *b4, int width); \ +void ff_vertical_compose_haar##ext(int16_t *b0, int16_t *b1, int width); \ +void ff_horizontal_compose_haar0i##ext(int16_t *b, int16_t *tmp, int w);\ +void ff_horizontal_compose_haar1i##ext(int16_t *b, int16_t *tmp, int w);\ +\ +static void vertical_compose53iL0##ext(uint8_t *_b0, uint8_t *_b1, uint8_t *_b2, int width) \ +{ \ + int i, width_align = width&~(align-1); \ + int16_t *b0 = (int16_t *)_b0; \ + int16_t *b1 = (int16_t *)_b1; \ + int16_t *b2 = (int16_t *)_b2; \ +\ + for(i=width_align; i>1;\ + int x= w2 - (w2&(align-1));\ + int16_t *b = (int16_t *)_b; \ + int16_t *tmp = (int16_t *)_tmp; \ +\ + ff_horizontal_compose_haar0i##ext(b, tmp, w);\ +\ + for (; x < w2; x++) {\ + b[2*x ] = tmp[x];\ + b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);\ + }\ +}\ +static void horizontal_compose_haar1i##ext(uint8_t *_b, uint8_t *_tmp, int w)\ +{\ + int w2= w>>1;\ + int x= w2 - (w2&(align-1));\ + int16_t *b = (int16_t *)_b; \ + int16_t *tmp = (int16_t *)_tmp; \ +\ + ff_horizontal_compose_haar1i##ext(b, tmp, w);\ +\ + for (; x < w2; x++) {\ + b[2*x ] = (tmp[x] + 1)>>1;\ + b[2*x+1] = (COMPOSE_HAARiH0(b[x+w2], tmp[x]) + 1)>>1;\ + }\ +}\ +\ + +#if HAVE_X86ASM +#if !ARCH_X86_64 +COMPOSE_VERTICAL(_mmx, 4) +#endif +COMPOSE_VERTICAL(_sse2, 8) + + +void ff_horizontal_compose_dd97i_ssse3(int16_t *_b, int16_t *_tmp, int w); + +static void horizontal_compose_dd97i_ssse3(uint8_t *_b, uint8_t *_tmp, int w) +{ + int w2= w>>1; + int x= w2 - (w2&7); + int16_t *b = (int16_t *)_b; + int16_t *tmp = (int16_t *)_tmp; + + ff_horizontal_compose_dd97i_ssse3(b, tmp, w); + + for (; x < w2; x++) { + b[2*x ] = (tmp[x] + 1)>>1; + b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1; + } +} +#endif + +void ff_spatial_idwt_init_x86(DWTContext *d, enum dwt_type type) +{ +#if HAVE_X86ASM + int mm_flags = av_get_cpu_flags(); + +#if !ARCH_X86_64 + if (!(mm_flags & AV_CPU_FLAG_MMX)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx; + break; + case DWT_DIRAC_LEGALL5_3: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx; + d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_mmx; + break; + case DWT_DIRAC_DD13_7: + d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_mmx; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx; + break; + case DWT_DIRAC_HAAR0: + d->vertical_compose = (void*)vertical_compose_haar_mmx; + d->horizontal_compose = horizontal_compose_haar0i_mmx; + break; + case DWT_DIRAC_HAAR1: + d->vertical_compose = (void*)vertical_compose_haar_mmx; + d->horizontal_compose = horizontal_compose_haar1i_mmx; + break; + } +#endif + + if (!(mm_flags & AV_CPU_FLAG_SSE2)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2; + break; + case DWT_DIRAC_LEGALL5_3: + d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2; + d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_sse2; + break; + case DWT_DIRAC_DD13_7: + d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_sse2; + d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2; + break; + case DWT_DIRAC_HAAR0: + d->vertical_compose = (void*)vertical_compose_haar_sse2; + d->horizontal_compose = horizontal_compose_haar0i_sse2; + break; + case DWT_DIRAC_HAAR1: + d->vertical_compose = (void*)vertical_compose_haar_sse2; + d->horizontal_compose = horizontal_compose_haar1i_sse2; + break; + } + + if (!(mm_flags & AV_CPU_FLAG_SSSE3)) + return; + + switch (type) { + case DWT_DIRAC_DD9_7: + d->horizontal_compose = horizontal_compose_dd97i_ssse3; + break; + } +#endif // HAVE_X86ASM +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/diracdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/diracdsp.asm new file mode 100644 index 00000000..17145baf --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/diracdsp.asm @@ -0,0 +1,348 @@ +;****************************************************************************** +;* Copyright (c) 2010 David Conrad +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA +pw_7: times 8 dw 7 +convert_to_unsigned_10bit: times 4 dd 0x200 +clip_10bit: times 8 dw 0x3ff + +cextern pw_3 +cextern pw_16 +cextern pw_32 +cextern pb_80 + +SECTION .text + +%macro UNPACK_ADD 6 + mov%5 %1, %3 + mov%6 m5, %4 + mova m4, %1 + mova %2, m5 + punpcklbw %1, m7 + punpcklbw m5, m7 + punpckhbw m4, m7 + punpckhbw %2, m7 + paddw %1, m5 + paddw %2, m4 +%endmacro + +%macro HPEL_FILTER 1 +; dirac_hpel_filter_v_sse2(uint8_t *dst, uint8_t *src, int stride, int width); +cglobal dirac_hpel_filter_v_%1, 4,6,8, dst, src, stride, width, src0, stridex3 + mov src0q, srcq + lea stridex3q, [3*strideq] + sub src0q, stridex3q + pxor m7, m7 +.loop: + ; 7*(src[0] + src[1]) + UNPACK_ADD m0, m1, [srcq], [srcq + strideq], a,a + pmullw m0, [pw_7] + pmullw m1, [pw_7] + + ; 3*( ... + src[-2] + src[3]) + UNPACK_ADD m2, m3, [src0q + strideq], [srcq + stridex3q], a,a + paddw m0, m2 + paddw m1, m3 + pmullw m0, [pw_3] + pmullw m1, [pw_3] + + ; ... - 7*(src[-1] + src[2]) + UNPACK_ADD m2, m3, [src0q + strideq*2], [srcq + strideq*2], a,a + pmullw m2, [pw_7] + pmullw m3, [pw_7] + psubw m0, m2 + psubw m1, m3 + + ; ... - (src[-3] + src[4]) + UNPACK_ADD m2, m3, [src0q], [srcq + strideq*4], a,a + psubw m0, m2 + psubw m1, m3 + + paddw m0, [pw_16] + paddw m1, [pw_16] + psraw m0, 5 + psraw m1, 5 + packuswb m0, m1 + mova [dstq], m0 + add dstq, mmsize + add srcq, mmsize + add src0q, mmsize + sub widthd, mmsize + jg .loop + RET + +; dirac_hpel_filter_h_sse2(uint8_t *dst, uint8_t *src, int width); +cglobal dirac_hpel_filter_h_%1, 3,3,8, dst, src, width + dec widthd + pxor m7, m7 + and widthd, ~(mmsize-1) +.loop: + ; 7*(src[0] + src[1]) + UNPACK_ADD m0, m1, [srcq + widthq], [srcq + widthq + 1], u,u + pmullw m0, [pw_7] + pmullw m1, [pw_7] + + ; 3*( ... + src[-2] + src[3]) + UNPACK_ADD m2, m3, [srcq + widthq - 2], [srcq + widthq + 3], u,u + paddw m0, m2 + paddw m1, m3 + pmullw m0, [pw_3] + pmullw m1, [pw_3] + + ; ... - 7*(src[-1] + src[2]) + UNPACK_ADD m2, m3, [srcq + widthq - 1], [srcq + widthq + 2], u,u + pmullw m2, [pw_7] + pmullw m3, [pw_7] + psubw m0, m2 + psubw m1, m3 + + ; ... - (src[-3] + src[4]) + UNPACK_ADD m2, m3, [srcq + widthq - 3], [srcq + widthq + 4], u,u + psubw m0, m2 + psubw m1, m3 + + paddw m0, [pw_16] + paddw m1, [pw_16] + psraw m0, 5 + psraw m1, 5 + packuswb m0, m1 + mova [dstq + widthq], m0 + sub widthd, mmsize + jge .loop + RET +%endmacro + +%macro PUT_RECT 1 +; void put_rect_clamped(uint8_t *dst, int dst_stride, int16_t *src, int src_stride, int width, int height) +cglobal put_signed_rect_clamped_%1, 5,9,3, dst, dst_stride, src, src_stride, w, dst2, src2 + mova m0, [pb_80] + add wd, (mmsize-1) + and wd, ~(mmsize-1) + +%if ARCH_X86_64 + movsxd dst_strideq, dst_strided + movsxd src_strideq, src_strided + mov r7d, r5m + mov r8d, wd + %define wspill r8d + %define hd r7d +%else + mov r4m, wd + %define wspill r4m + %define hd r5mp +%endif + +.loopy: + lea src2q, [srcq+src_strideq] + lea dst2q, [dstq+dst_strideq] +.loopx: + sub wd, mmsize + mova m1, [srcq +2*wq] + mova m2, [src2q+2*wq] + packsswb m1, [srcq +2*wq+mmsize] + packsswb m2, [src2q+2*wq+mmsize] + paddb m1, m0 + paddb m2, m0 + mova [dstq +wq], m1 + mova [dst2q+wq], m2 + jg .loopx + + lea srcq, [srcq+src_strideq*2] + lea dstq, [dstq+dst_strideq*2] + sub hd, 2 + mov wd, wspill + jg .loopy + RET +%endm + +%macro ADD_RECT 1 +; void add_rect_clamped(uint8_t *dst, uint16_t *src, int stride, int16_t *idwt, int idwt_stride, int width, int height) +cglobal add_rect_clamped_%1, 7,9,3, dst, src, stride, idwt, idwt_stride, w, h + mova m0, [pw_32] + add wd, (mmsize-1) + and wd, ~(mmsize-1) + +%if ARCH_X86_64 + movsxd strideq, strided + movsxd idwt_strideq, idwt_strided + mov r8d, wd + %define wspill r8d +%else + mov r5m, wd + %define wspill r5m +%endif + +.loop: + sub wd, mmsize + movu m1, [srcq +2*wq] ; FIXME: ensure alignment + paddw m1, m0 + psraw m1, 6 + movu m2, [srcq +2*wq+mmsize] ; FIXME: ensure alignment + paddw m2, m0 + psraw m2, 6 + paddw m1, [idwtq+2*wq] + paddw m2, [idwtq+2*wq+mmsize] + packuswb m1, m2 + mova [dstq +wq], m1 + jg .loop + + lea srcq, [srcq + 2*strideq] + add dstq, strideq + lea idwtq, [idwtq+ 2*idwt_strideq] + sub hd, 1 + mov wd, wspill + jg .loop + RET +%endm + +%macro ADD_OBMC 2 +; void add_obmc(uint16_t *dst, uint8_t *src, int stride, uint8_t *obmc_weight, int yblen) +cglobal add_dirac_obmc%1_%2, 6,6,5, dst, src, stride, obmc, yblen + pxor m4, m4 +.loop: +%assign i 0 +%rep %1 / mmsize + mova m0, [srcq+i] + mova m1, m0 + punpcklbw m0, m4 + punpckhbw m1, m4 + mova m2, [obmcq+i] + mova m3, m2 + punpcklbw m2, m4 + punpckhbw m3, m4 + pmullw m0, m2 + pmullw m1, m3 + movu m2, [dstq+2*i] + movu m3, [dstq+2*i+mmsize] + paddw m0, m2 + paddw m1, m3 + movu [dstq+2*i], m0 + movu [dstq+2*i+mmsize], m1 +%assign i i+mmsize +%endrep + lea srcq, [srcq+strideq] + lea dstq, [dstq+2*strideq] + add obmcq, 32 + sub yblend, 1 + jg .loop + RET +%endm + +INIT_MMX +%if ARCH_X86_64 == 0 +PUT_RECT mmx +ADD_RECT mmx + +HPEL_FILTER mmx +ADD_OBMC 32, mmx +ADD_OBMC 16, mmx +%endif +ADD_OBMC 8, mmx + +INIT_XMM +PUT_RECT sse2 +ADD_RECT sse2 + +HPEL_FILTER sse2 +ADD_OBMC 32, sse2 +ADD_OBMC 16, sse2 + +INIT_XMM sse4 + +; void dequant_subband_32(uint8_t *src, uint8_t *dst, ptrdiff_t stride, const int qf, const int qs, int tot_v, int tot_h) +cglobal dequant_subband_32, 7, 7, 4, src, dst, stride, qf, qs, tot_v, tot_h + movd m2, qfd + movd m3, qsd + SPLATD m2 + SPLATD m3 + mov r4d, tot_hd + mov r3, dstq + + .loop_v: + mov tot_hq, r4 + mov dstq, r3 + + .loop_h: + movu m0, [srcq] + + pabsd m1, m0 + pmulld m1, m2 + paddd m1, m3 + psrld m1, 2 + psignd m1, m0 + + movu [dstq], m1 + + add srcq, mmsize + add dstq, mmsize + sub tot_hq, 4 + jg .loop_h + lea srcq, [srcq + 4*tot_hq] + + add r3, strideq + dec tot_vd + jg .loop_v + + RET + +INIT_XMM sse4 +; void put_signed_rect_clamped_10(uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int width, int height) +%if ARCH_X86_64 +cglobal put_signed_rect_clamped_10, 6, 8, 5, dst, dst_stride, src, src_stride, w, h, t1, t2 +%else +cglobal put_signed_rect_clamped_10, 5, 7, 5, dst, dst_stride, src, src_stride, w, t1, t2 + %define hd r5mp +%endif + shl wd, 2 + add srcq, wq + neg wq + mov t2q, dstq + mov t1q, wq + pxor m2, m2 + mova m3, [clip_10bit] + mova m4, [convert_to_unsigned_10bit] + + .loop_h: + mov dstq, t2q + mov wq, t1q + + .loop_w: + movu m0, [srcq+wq+0*mmsize] + movu m1, [srcq+wq+1*mmsize] + + paddd m0, m4 + paddd m1, m4 + packusdw m0, m0, m1 + CLIPW m0, m2, m3 ; packusdw saturates so it's fine + + movu [dstq], m0 + + add dstq, 1*mmsize + add wq, 2*mmsize + jl .loop_w + + add srcq, src_strideq + add t2q, dst_strideq + sub hd, 1 + jg .loop_h + + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/diracdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/diracdsp_init.c new file mode 100644 index 00000000..8baacf31 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/diracdsp_init.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2010 David Conrad + * + * 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 "libavutil/x86/cpu.h" +#include "libavcodec/diracdsp.h" +#include "fpel.h" + +void ff_add_rect_clamped_mmx(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); +void ff_add_rect_clamped_sse2(uint8_t *, const uint16_t *, int, const int16_t *, int, int, int); + +void ff_add_dirac_obmc8_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc16_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc32_mmx(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + +void ff_add_dirac_obmc16_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); +void ff_add_dirac_obmc32_sse2(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen); + +void ff_put_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_mmx(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_sse2(uint8_t *dst, int dst_stride, const int16_t *src, int src_stride, int width, int height); +void ff_put_signed_rect_clamped_10_sse4(uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int width, int height); + +void ff_dequant_subband_32_sse4(uint8_t *src, uint8_t *dst, ptrdiff_t stride, const int qf, const int qs, int tot_v, int tot_h); + +#if HAVE_X86ASM + +#define HPEL_FILTER(MMSIZE, EXT) \ + void ff_dirac_hpel_filter_v_ ## EXT(uint8_t *, const uint8_t *, int, int); \ + void ff_dirac_hpel_filter_h_ ## EXT(uint8_t *, const uint8_t *, int); \ + \ + static void dirac_hpel_filter_ ## EXT(uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, \ + const uint8_t *src, int stride, int width, int height) \ + { \ + while( height-- ) \ + { \ + ff_dirac_hpel_filter_v_ ## EXT(dstv-MMSIZE, src-MMSIZE, stride, width+MMSIZE+5); \ + ff_dirac_hpel_filter_h_ ## EXT(dsth, src, width); \ + ff_dirac_hpel_filter_h_ ## EXT(dstc, dstv, width); \ + \ + dsth += stride; \ + dstv += stride; \ + dstc += stride; \ + src += stride; \ + } \ + } + +#define PIXFUNC(PFX, IDX, EXT) \ + /*MMXDISABLEDc->PFX ## _dirac_pixels_tab[0][IDX] = PFX ## _dirac_pixels8_ ## EXT;*/ \ + c->PFX ## _dirac_pixels_tab[1][IDX] = PFX ## _dirac_pixels16_ ## EXT; \ + c->PFX ## _dirac_pixels_tab[2][IDX] = PFX ## _dirac_pixels32_ ## EXT + +#define DIRAC_PIXOP(OPNAME, EXT)\ +static void OPNAME ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], \ + int stride, int h) \ +{\ + if (h&3)\ + ff_ ## OPNAME ## _dirac_pixels16_c(dst, src, stride, h);\ + else\ + ff_ ## OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\ +}\ +static void OPNAME ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], \ + int stride, int h) \ +{\ + if (h&3) {\ + ff_ ## OPNAME ## _dirac_pixels32_c(dst, src, stride, h);\ + } else {\ + ff_ ## OPNAME ## _pixels16_ ## EXT(dst , src[0] , stride, h);\ + ff_ ## OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\ + }\ +} + +DIRAC_PIXOP(put, mmx) +DIRAC_PIXOP(avg, mmx) +DIRAC_PIXOP(avg, mmxext) + +DIRAC_PIXOP(put, sse2) +DIRAC_PIXOP(avg, sse2) + +#if !ARCH_X86_64 +HPEL_FILTER(8, mmx) +#endif +HPEL_FILTER(16, sse2) + +#endif // HAVE_X86ASM + +void ff_diracdsp_init_x86(DiracDSPContext* c) +{ +#if HAVE_X86ASM + int mm_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(mm_flags)) { + c->add_dirac_obmc[0] = ff_add_dirac_obmc8_mmx; +#if !ARCH_X86_64 + c->add_dirac_obmc[1] = ff_add_dirac_obmc16_mmx; + c->add_dirac_obmc[2] = ff_add_dirac_obmc32_mmx; + c->dirac_hpel_filter = dirac_hpel_filter_mmx; + c->add_rect_clamped = ff_add_rect_clamped_mmx; + c->put_signed_rect_clamped[0] = (void *)ff_put_signed_rect_clamped_mmx; +#endif + PIXFUNC(put, 0, mmx); + PIXFUNC(avg, 0, mmx); + } + + if (EXTERNAL_MMXEXT(mm_flags)) { + PIXFUNC(avg, 0, mmxext); + } + + if (EXTERNAL_SSE2(mm_flags)) { + c->dirac_hpel_filter = dirac_hpel_filter_sse2; + c->add_rect_clamped = ff_add_rect_clamped_sse2; + c->put_signed_rect_clamped[0] = (void *)ff_put_signed_rect_clamped_sse2; + + c->add_dirac_obmc[1] = ff_add_dirac_obmc16_sse2; + c->add_dirac_obmc[2] = ff_add_dirac_obmc32_sse2; + + c->put_dirac_pixels_tab[1][0] = put_dirac_pixels16_sse2; + c->avg_dirac_pixels_tab[1][0] = avg_dirac_pixels16_sse2; + c->put_dirac_pixels_tab[2][0] = put_dirac_pixels32_sse2; + c->avg_dirac_pixels_tab[2][0] = avg_dirac_pixels32_sse2; + } + + if (EXTERNAL_SSE4(mm_flags)) { + c->dequant_subband[1] = ff_dequant_subband_32_sse4; + c->put_signed_rect_clamped[1] = ff_put_signed_rect_clamped_10_sse4; + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dnxhdenc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dnxhdenc.asm new file mode 100644 index 00000000..b4f75955 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dnxhdenc.asm @@ -0,0 +1,49 @@ +;************************************************************************ +;* VC3/DNxHD SIMD functions +;* Copyright (c) 2007 Baptiste Coudurier +;* Copyright (c) 2014 Tiancheng "Timothy" Gu +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +; void get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, +; ptrdiff_t line_size) +INIT_XMM sse2 +cglobal get_pixels_8x4_sym, 3,3,5, block, pixels, linesize + pxor m4, m4 + movq m0, [pixelsq] + add pixelsq, linesizeq + movq m1, [pixelsq] + movq m2, [pixelsq+linesizeq] + movq m3, [pixelsq+linesizeq*2] + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpcklbw m3, m4 + mova [blockq ], m0 + mova [blockq+16 ], m1 + mova [blockq+32 ], m2 + mova [blockq+48 ], m3 + mova [blockq+64 ], m3 + mova [blockq+80 ], m2 + mova [blockq+96 ], m1 + mova [blockq+112], m0 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dnxhdenc_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dnxhdenc_init.c new file mode 100644 index 00000000..fd6f1500 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/dnxhdenc_init.c @@ -0,0 +1,37 @@ +/* + * VC3/DNxHD SIMD functions + * Copyright (c) 2007 Baptiste Coudurier + * + * VC-3 encoder funded by the British Broadcasting Corporation + * + * 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 "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dnxhdenc.h" + +void ff_get_pixels_8x4_sym_sse2(int16_t *block, const uint8_t *pixels, + ptrdiff_t line_size); + +av_cold void ff_dnxhdenc_init_x86(DNXHDEncContext *ctx) +{ + if (EXTERNAL_SSE2(av_get_cpu_flags())) { + if (ctx->cid_table->bit_depth == 8) + ctx->get_pixels_8x4_sym = ff_get_pixels_8x4_sym_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/exrdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/exrdsp.asm new file mode 100644 index 00000000..3bf240c8 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/exrdsp.asm @@ -0,0 +1,118 @@ +;****************************************************************************** +;* X86 Optimized functions for Open Exr Decoder +;* Copyright (c) 2006 Industrial Light & Magic, a division of Lucas Digital Ltd. LLC +;* +;* reorder_pixels, predictor based on patch by John Loy +;* port to ASM by Jokyo Images support by CNC - French National Center for Cinema +;* +;* predictor AVX/AVX2 by Henrik Gramner +;* +;* 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 "libavutil/x86/x86util.asm" + +cextern pb_15 +cextern pb_80 + +SECTION .text + +;------------------------------------------------------------------------------ +; void ff_reorder_pixels(uint8_t *dst, const uint8_t *src, ptrdiff_t size); +;------------------------------------------------------------------------------ + +%macro REORDER_PIXELS 0 +cglobal reorder_pixels, 3,4,3, dst, src1, size, src2 + lea src2q, [src1q+sizeq] ; src2 = src + 2 * half_size + add dstq, sizeq ; dst offset by size + shr sizeq, 1 ; half_size + add src1q, sizeq ; offset src by half_size + neg sizeq ; size = offset for dst, src1, src2 +.loop: + + mova m0, [src1q+sizeq] ; load first part + movu m1, [src2q+sizeq] ; load second part + SBUTTERFLY bw, 0, 1, 2 ; interleaved + mova [dstq+2*sizeq ], xm0 ; copy to dst + mova [dstq+2*sizeq+16], xm1 +%if cpuflag(avx2) + vperm2i128 m0, m0, m1, q0301 + mova [dstq+2*sizeq+32], m0 +%endif + add sizeq, mmsize + jl .loop + RET +%endmacro + +INIT_XMM sse2 +REORDER_PIXELS + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +REORDER_PIXELS +%endif + + +;------------------------------------------------------------------------------ +; void ff_predictor(uint8_t *src, ptrdiff_t size); +;------------------------------------------------------------------------------ + +%macro PREDICTOR 0 +cglobal predictor, 2,2,5, src, size + mova m0, [pb_80] + mova xm1, [pb_15] + mova xm2, xm0 + add srcq, sizeq + neg sizeq +.loop: + pxor m3, m0, [srcq + sizeq] + pslldq m4, m3, 1 + paddb m3, m4 + pslldq m4, m3, 2 + paddb m3, m4 + pslldq m4, m3, 4 + paddb m3, m4 + pslldq m4, m3, 8 +%if mmsize == 32 + paddb m3, m4 + paddb xm2, xm3 + vextracti128 xm4, m3, 1 + mova [srcq + sizeq], xm2 + pshufb xm2, xm1 + paddb xm2, xm4 + mova [srcq + sizeq + 16], xm2 +%else + paddb m2, m3 + paddb m2, m4 + mova [srcq + sizeq], m2 +%endif + pshufb xm2, xm1 + add sizeq, mmsize + jl .loop + RET +%endmacro + +INIT_XMM ssse3 +PREDICTOR + +INIT_XMM avx +PREDICTOR + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +PREDICTOR +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/exrdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/exrdsp_init.c new file mode 100644 index 00000000..63b3480d --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/exrdsp_init.c @@ -0,0 +1,52 @@ +/* + * OpenEXR (.exr) image decoder + * + * 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 "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/exrdsp.h" + +void ff_reorder_pixels_sse2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); + +void ff_reorder_pixels_avx2(uint8_t *dst, const uint8_t *src, ptrdiff_t size); + +void ff_predictor_ssse3(uint8_t *src, ptrdiff_t size); + +void ff_predictor_avx(uint8_t *src, ptrdiff_t size); + +void ff_predictor_avx2(uint8_t *src, ptrdiff_t size); + +av_cold void ff_exrdsp_init_x86(ExrDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->reorder_pixels = ff_reorder_pixels_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + dsp->predictor = ff_predictor_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + dsp->predictor = ff_predictor_avx; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + dsp->reorder_pixels = ff_reorder_pixels_avx2; + dsp->predictor = ff_predictor_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdct.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdct.c new file mode 100644 index 00000000..d77f60c8 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdct.c @@ -0,0 +1,595 @@ +/* + * SIMD-optimized forward DCT + * The gcc porting is Copyright (c) 2001 Fabrice Bellard. + * cleanup/optimizations are Copyright (c) 2002-2004 Michael Niedermayer + * SSE2 optimization is Copyright (c) 2004 Denes Balatoni. + * + * from fdctam32.c - AP922 MMX(3D-Now) forward-DCT + * + * Intel Application Note AP-922 - fast, precise implementation of DCT + * http://developer.intel.com/vtune/cbts/appnotes.htm + * + * Also of inspiration: + * a page about fdct at http://www.geocities.com/ssavekar/dct.htm + * Skal's fdct at http://skal.planet-d.net/coding/dct.html + * + * 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 "libavutil/common.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "fdct.h" + +#if HAVE_MMX_INLINE + +////////////////////////////////////////////////////////////////////// +// +// constants for the forward DCT +// ----------------------------- +// +// Be sure to check that your compiler is aligning all constants to QWORD +// (8-byte) memory boundaries! Otherwise the unaligned memory access will +// severely stall MMX execution. +// +////////////////////////////////////////////////////////////////////// + +#define BITS_FRW_ACC 3 //; 2 or 3 for accuracy +#define SHIFT_FRW_COL BITS_FRW_ACC +#define SHIFT_FRW_ROW (BITS_FRW_ACC + 17 - 3) +#define RND_FRW_ROW (1 << (SHIFT_FRW_ROW-1)) +//#define RND_FRW_COL (1 << (SHIFT_FRW_COL-1)) + +#define X8(x) x,x,x,x,x,x,x,x + +//concatenated table, for forward DCT transformation +DECLARE_ALIGNED(16, static const int16_t, fdct_tg_all_16)[24] = { + X8(13036), // tg * (2<<16) + 0.5 + X8(27146), // tg * (2<<16) + 0.5 + X8(-21746) // tg * (2<<16) + 0.5 +}; + +DECLARE_ALIGNED(16, static const int16_t, ocos_4_16)[8] = { + X8(23170) //cos * (2<<15) + 0.5 +}; + +DECLARE_ALIGNED(16, static const int16_t, fdct_one_corr)[8] = { X8(1) }; + +DECLARE_ALIGNED(8, static const int32_t, fdct_r_row)[2] = {RND_FRW_ROW, RND_FRW_ROW }; + +static const struct +{ + DECLARE_ALIGNED(16, const int32_t, fdct_r_row_sse2)[4]; +} fdct_r_row_sse2 = +{{ + RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW +}}; +//DECLARE_ALIGNED(16, static const long, fdct_r_row_sse2)[4] = {RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW, RND_FRW_ROW}; + +DECLARE_ALIGNED(8, static const int16_t, tab_frw_01234567)[] = { // forward_dct coeff table + 16384, 16384, 22725, 19266, + 16384, 16384, 12873, 4520, + 21407, 8867, 19266, -4520, + -8867, -21407, -22725, -12873, + 16384, -16384, 12873, -22725, + -16384, 16384, 4520, 19266, + 8867, -21407, 4520, -12873, + 21407, -8867, 19266, -22725, + + 22725, 22725, 31521, 26722, + 22725, 22725, 17855, 6270, + 29692, 12299, 26722, -6270, + -12299, -29692, -31521, -17855, + 22725, -22725, 17855, -31521, + -22725, 22725, 6270, 26722, + 12299, -29692, 6270, -17855, + 29692, -12299, 26722, -31521, + + 21407, 21407, 29692, 25172, + 21407, 21407, 16819, 5906, + 27969, 11585, 25172, -5906, + -11585, -27969, -29692, -16819, + 21407, -21407, 16819, -29692, + -21407, 21407, 5906, 25172, + 11585, -27969, 5906, -16819, + 27969, -11585, 25172, -29692, + + 19266, 19266, 26722, 22654, + 19266, 19266, 15137, 5315, + 25172, 10426, 22654, -5315, + -10426, -25172, -26722, -15137, + 19266, -19266, 15137, -26722, + -19266, 19266, 5315, 22654, + 10426, -25172, 5315, -15137, + 25172, -10426, 22654, -26722, + + 16384, 16384, 22725, 19266, + 16384, 16384, 12873, 4520, + 21407, 8867, 19266, -4520, + -8867, -21407, -22725, -12873, + 16384, -16384, 12873, -22725, + -16384, 16384, 4520, 19266, + 8867, -21407, 4520, -12873, + 21407, -8867, 19266, -22725, + + 19266, 19266, 26722, 22654, + 19266, 19266, 15137, 5315, + 25172, 10426, 22654, -5315, + -10426, -25172, -26722, -15137, + 19266, -19266, 15137, -26722, + -19266, 19266, 5315, 22654, + 10426, -25172, 5315, -15137, + 25172, -10426, 22654, -26722, + + 21407, 21407, 29692, 25172, + 21407, 21407, 16819, 5906, + 27969, 11585, 25172, -5906, + -11585, -27969, -29692, -16819, + 21407, -21407, 16819, -29692, + -21407, 21407, 5906, 25172, + 11585, -27969, 5906, -16819, + 27969, -11585, 25172, -29692, + + 22725, 22725, 31521, 26722, + 22725, 22725, 17855, 6270, + 29692, 12299, 26722, -6270, + -12299, -29692, -31521, -17855, + 22725, -22725, 17855, -31521, + -22725, 22725, 6270, 26722, + 12299, -29692, 6270, -17855, + 29692, -12299, 26722, -31521, +}; + +static const struct +{ + DECLARE_ALIGNED(16, const int16_t, tab_frw_01234567_sse2)[256]; +} tab_frw_01234567_sse2 = +{{ +//DECLARE_ALIGNED(16, static const int16_t, tab_frw_01234567_sse2)[] = { // forward_dct coeff table +#define TABLE_SSE2 C4, C4, C1, C3, -C6, -C2, -C1, -C5, \ + C4, C4, C5, C7, C2, C6, C3, -C7, \ + -C4, C4, C7, C3, C6, -C2, C7, -C5, \ + C4, -C4, C5, -C1, C2, -C6, C3, -C1, +// c1..c7 * cos(pi/4) * 2^15 +#define C1 22725 +#define C2 21407 +#define C3 19266 +#define C4 16384 +#define C5 12873 +#define C6 8867 +#define C7 4520 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 31521 +#define C2 29692 +#define C3 26722 +#define C4 22725 +#define C5 17855 +#define C6 12299 +#define C7 6270 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 29692 +#define C2 27969 +#define C3 25172 +#define C4 21407 +#define C5 16819 +#define C6 11585 +#define C7 5906 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 26722 +#define C2 25172 +#define C3 22654 +#define C4 19266 +#define C5 15137 +#define C6 10426 +#define C7 5315 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 22725 +#define C2 21407 +#define C3 19266 +#define C4 16384 +#define C5 12873 +#define C6 8867 +#define C7 4520 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 26722 +#define C2 25172 +#define C3 22654 +#define C4 19266 +#define C5 15137 +#define C6 10426 +#define C7 5315 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 29692 +#define C2 27969 +#define C3 25172 +#define C4 21407 +#define C5 16819 +#define C6 11585 +#define C7 5906 +TABLE_SSE2 + +#undef C1 +#undef C2 +#undef C3 +#undef C4 +#undef C5 +#undef C6 +#undef C7 +#define C1 31521 +#define C2 29692 +#define C3 26722 +#define C4 22725 +#define C5 17855 +#define C6 12299 +#define C7 6270 +TABLE_SSE2 +}}; + +#define S(s) AV_TOSTRING(s) //AV_STRINGIFY is too long + +#define FDCT_COL(cpu, mm, mov)\ +static av_always_inline void fdct_col_##cpu(const int16_t *in, int16_t *out, int offset)\ +{\ + __asm__ volatile (\ + #mov" 16(%0), %%"#mm"0 \n\t" \ + #mov" 96(%0), %%"#mm"1 \n\t" \ + #mov" %%"#mm"0, %%"#mm"2 \n\t" \ + #mov" 32(%0), %%"#mm"3 \n\t" \ + "paddsw %%"#mm"1, %%"#mm"0 \n\t" \ + #mov" 80(%0), %%"#mm"4 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"0 \n\t" \ + #mov" (%0), %%"#mm"5 \n\t" \ + "paddsw %%"#mm"3, %%"#mm"4 \n\t" \ + "paddsw 112(%0), %%"#mm"5 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"4 \n\t" \ + #mov" %%"#mm"0, %%"#mm"6 \n\t" \ + "psubsw %%"#mm"1, %%"#mm"2 \n\t" \ + #mov" 16(%1), %%"#mm"1 \n\t" \ + "psubsw %%"#mm"4, %%"#mm"0 \n\t" \ + #mov" 48(%0), %%"#mm"7 \n\t" \ + "pmulhw %%"#mm"0, %%"#mm"1 \n\t" \ + "paddsw 64(%0), %%"#mm"7 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"5 \n\t" \ + "paddsw %%"#mm"4, %%"#mm"6 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"7 \n\t" \ + #mov" %%"#mm"5, %%"#mm"4 \n\t" \ + "psubsw %%"#mm"7, %%"#mm"5 \n\t" \ + "paddsw %%"#mm"5, %%"#mm"1 \n\t" \ + "paddsw %%"#mm"7, %%"#mm"4 \n\t" \ + "por (%2), %%"#mm"1 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)"+1, %%"#mm"2 \n\t" \ + "pmulhw 16(%1), %%"#mm"5 \n\t" \ + #mov" %%"#mm"4, %%"#mm"7 \n\t" \ + "psubsw 80(%0), %%"#mm"3 \n\t" \ + "psubsw %%"#mm"6, %%"#mm"4 \n\t" \ + #mov" %%"#mm"1, 32(%3) \n\t" \ + "paddsw %%"#mm"6, %%"#mm"7 \n\t" \ + #mov" 48(%0), %%"#mm"1 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)"+1, %%"#mm"3 \n\t" \ + "psubsw 64(%0), %%"#mm"1 \n\t" \ + #mov" %%"#mm"2, %%"#mm"6 \n\t" \ + #mov" %%"#mm"4, 64(%3) \n\t" \ + "paddsw %%"#mm"3, %%"#mm"2 \n\t" \ + "pmulhw (%4), %%"#mm"2 \n\t" \ + "psubsw %%"#mm"3, %%"#mm"6 \n\t" \ + "pmulhw (%4), %%"#mm"6 \n\t" \ + "psubsw %%"#mm"0, %%"#mm"5 \n\t" \ + "por (%2), %%"#mm"5 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"1 \n\t" \ + "por (%2), %%"#mm"2 \n\t" \ + #mov" %%"#mm"1, %%"#mm"4 \n\t" \ + #mov" (%0), %%"#mm"3 \n\t" \ + "paddsw %%"#mm"6, %%"#mm"1 \n\t" \ + "psubsw 112(%0), %%"#mm"3 \n\t" \ + "psubsw %%"#mm"6, %%"#mm"4 \n\t" \ + #mov" (%1), %%"#mm"0 \n\t" \ + "psllw $"S(SHIFT_FRW_COL)", %%"#mm"3 \n\t" \ + #mov" 32(%1), %%"#mm"6 \n\t" \ + "pmulhw %%"#mm"1, %%"#mm"0 \n\t" \ + #mov" %%"#mm"7, (%3) \n\t" \ + "pmulhw %%"#mm"4, %%"#mm"6 \n\t" \ + #mov" %%"#mm"5, 96(%3) \n\t" \ + #mov" %%"#mm"3, %%"#mm"7 \n\t" \ + #mov" 32(%1), %%"#mm"5 \n\t" \ + "psubsw %%"#mm"2, %%"#mm"7 \n\t" \ + "paddsw %%"#mm"2, %%"#mm"3 \n\t" \ + "pmulhw %%"#mm"7, %%"#mm"5 \n\t" \ + "paddsw %%"#mm"3, %%"#mm"0 \n\t" \ + "paddsw %%"#mm"4, %%"#mm"6 \n\t" \ + "pmulhw (%1), %%"#mm"3 \n\t" \ + "por (%2), %%"#mm"0 \n\t" \ + "paddsw %%"#mm"7, %%"#mm"5 \n\t" \ + "psubsw %%"#mm"6, %%"#mm"7 \n\t" \ + #mov" %%"#mm"0, 16(%3) \n\t" \ + "paddsw %%"#mm"4, %%"#mm"5 \n\t" \ + #mov" %%"#mm"7, 48(%3) \n\t" \ + "psubsw %%"#mm"1, %%"#mm"3 \n\t" \ + #mov" %%"#mm"5, 80(%3) \n\t" \ + #mov" %%"#mm"3, 112(%3) \n\t" \ + : \ + : "r" (in + offset), "r" (fdct_tg_all_16), "r" (fdct_one_corr), \ + "r" (out + offset), "r" (ocos_4_16)); \ +} + +FDCT_COL(mmx, mm, movq) +FDCT_COL(sse2, xmm, movdqa) + +static av_always_inline void fdct_row_sse2(const int16_t *in, int16_t *out) +{ + __asm__ volatile( +#define FDCT_ROW_SSE2_H1(i,t) \ + "movq " #i "(%0), %%xmm2 \n\t" \ + "movq " #i "+8(%0), %%xmm0 \n\t" \ + "movdqa " #t "+32(%1), %%xmm3 \n\t" \ + "movdqa " #t "+48(%1), %%xmm7 \n\t" \ + "movdqa " #t "(%1), %%xmm4 \n\t" \ + "movdqa " #t "+16(%1), %%xmm5 \n\t" + +#define FDCT_ROW_SSE2_H2(i,t) \ + "movq " #i "(%0), %%xmm2 \n\t" \ + "movq " #i "+8(%0), %%xmm0 \n\t" \ + "movdqa " #t "+32(%1), %%xmm3 \n\t" \ + "movdqa " #t "+48(%1), %%xmm7 \n\t" + +#define FDCT_ROW_SSE2(i) \ + "movq %%xmm2, %%xmm1 \n\t" \ + "pshuflw $27, %%xmm0, %%xmm0 \n\t" \ + "paddsw %%xmm0, %%xmm1 \n\t" \ + "psubsw %%xmm0, %%xmm2 \n\t" \ + "punpckldq %%xmm2, %%xmm1 \n\t" \ + "pshufd $78, %%xmm1, %%xmm2 \n\t" \ + "pmaddwd %%xmm2, %%xmm3 \n\t" \ + "pmaddwd %%xmm1, %%xmm7 \n\t" \ + "pmaddwd %%xmm5, %%xmm2 \n\t" \ + "pmaddwd %%xmm4, %%xmm1 \n\t" \ + "paddd %%xmm7, %%xmm3 \n\t" \ + "paddd %%xmm2, %%xmm1 \n\t" \ + "paddd %%xmm6, %%xmm3 \n\t" \ + "paddd %%xmm6, %%xmm1 \n\t" \ + "psrad %3, %%xmm3 \n\t" \ + "psrad %3, %%xmm1 \n\t" \ + "packssdw %%xmm3, %%xmm1 \n\t" \ + "movdqa %%xmm1, " #i "(%4) \n\t" + + "movdqa (%2), %%xmm6 \n\t" + FDCT_ROW_SSE2_H1(0,0) + FDCT_ROW_SSE2(0) + FDCT_ROW_SSE2_H2(64,0) + FDCT_ROW_SSE2(64) + + FDCT_ROW_SSE2_H1(16,64) + FDCT_ROW_SSE2(16) + FDCT_ROW_SSE2_H2(112,64) + FDCT_ROW_SSE2(112) + + FDCT_ROW_SSE2_H1(32,128) + FDCT_ROW_SSE2(32) + FDCT_ROW_SSE2_H2(96,128) + FDCT_ROW_SSE2(96) + + FDCT_ROW_SSE2_H1(48,192) + FDCT_ROW_SSE2(48) + FDCT_ROW_SSE2_H2(80,192) + FDCT_ROW_SSE2(80) + : + : "r" (in), "r" (tab_frw_01234567_sse2.tab_frw_01234567_sse2), + "r" (fdct_r_row_sse2.fdct_r_row_sse2), "i" (SHIFT_FRW_ROW), "r" (out) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); +} + +static av_always_inline void fdct_row_mmxext(const int16_t *in, int16_t *out, + const int16_t *table) +{ + __asm__ volatile ( + "pshufw $0x1B, 8(%0), %%mm5 \n\t" + "movq (%0), %%mm0 \n\t" + "movq %%mm0, %%mm1 \n\t" + "paddsw %%mm5, %%mm0 \n\t" + "psubsw %%mm5, %%mm1 \n\t" + "movq %%mm0, %%mm2 \n\t" + "punpckldq %%mm1, %%mm0 \n\t" + "punpckhdq %%mm1, %%mm2 \n\t" + "movq (%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm5 \n\t" + "movq 32(%1), %%mm6 \n\t" + "movq 40(%1), %%mm7 \n\t" + "pmaddwd %%mm0, %%mm1 \n\t" + "pmaddwd %%mm2, %%mm3 \n\t" + "pmaddwd %%mm0, %%mm4 \n\t" + "pmaddwd %%mm2, %%mm5 \n\t" + "pmaddwd %%mm0, %%mm6 \n\t" + "pmaddwd %%mm2, %%mm7 \n\t" + "pmaddwd 48(%1), %%mm0 \n\t" + "pmaddwd 56(%1), %%mm2 \n\t" + "paddd %%mm1, %%mm3 \n\t" + "paddd %%mm4, %%mm5 \n\t" + "paddd %%mm6, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "movq (%2), %%mm0 \n\t" + "paddd %%mm0, %%mm3 \n\t" + "paddd %%mm0, %%mm5 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm3 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm5 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm7 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm2 \n\t" + "packssdw %%mm5, %%mm3 \n\t" + "packssdw %%mm2, %%mm7 \n\t" + "movq %%mm3, (%3) \n\t" + "movq %%mm7, 8(%3) \n\t" + : + : "r" (in), "r" (table), "r" (fdct_r_row), "r" (out)); +} + +static av_always_inline void fdct_row_mmx(const int16_t *in, int16_t *out, const int16_t *table) +{ + //FIXME reorder (I do not have an old MMX-only CPU here to benchmark ...) + __asm__ volatile( + "movd 12(%0), %%mm1 \n\t" + "punpcklwd 8(%0), %%mm1 \n\t" + "movq %%mm1, %%mm2 \n\t" + "psrlq $0x20, %%mm1 \n\t" + "movq 0(%0), %%mm0 \n\t" + "punpcklwd %%mm2, %%mm1 \n\t" + "movq %%mm0, %%mm5 \n\t" + "paddsw %%mm1, %%mm0 \n\t" + "psubsw %%mm1, %%mm5 \n\t" + "movq %%mm0, %%mm2 \n\t" + "punpckldq %%mm5, %%mm0 \n\t" + "punpckhdq %%mm5, %%mm2 \n\t" + "movq 0(%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm5 \n\t" + "movq 32(%1), %%mm6 \n\t" + "movq 40(%1), %%mm7 \n\t" + "pmaddwd %%mm0, %%mm1 \n\t" + "pmaddwd %%mm2, %%mm3 \n\t" + "pmaddwd %%mm0, %%mm4 \n\t" + "pmaddwd %%mm2, %%mm5 \n\t" + "pmaddwd %%mm0, %%mm6 \n\t" + "pmaddwd %%mm2, %%mm7 \n\t" + "pmaddwd 48(%1), %%mm0 \n\t" + "pmaddwd 56(%1), %%mm2 \n\t" + "paddd %%mm1, %%mm3 \n\t" + "paddd %%mm4, %%mm5 \n\t" + "paddd %%mm6, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "movq (%2), %%mm0 \n\t" + "paddd %%mm0, %%mm3 \n\t" + "paddd %%mm0, %%mm5 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "paddd %%mm0, %%mm2 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm3 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm5 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm7 \n\t" + "psrad $"S(SHIFT_FRW_ROW)", %%mm2 \n\t" + "packssdw %%mm5, %%mm3 \n\t" + "packssdw %%mm2, %%mm7 \n\t" + "movq %%mm3, 0(%3) \n\t" + "movq %%mm7, 8(%3) \n\t" + : + : "r" (in), "r" (table), "r" (fdct_r_row), "r" (out)); +} + +void ff_fdct_mmx(int16_t *block) +{ + DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; + int16_t * block1= (int16_t*)align_tmp; + const int16_t *table= tab_frw_01234567; + int i; + + fdct_col_mmx(block, block1, 0); + fdct_col_mmx(block, block1, 4); + + for(i=8;i>0;i--) { + fdct_row_mmx(block1, block, table); + block1 += 8; + table += 32; + block += 8; + } +} + +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_MMXEXT_INLINE + +void ff_fdct_mmxext(int16_t *block) +{ + DECLARE_ALIGNED(8, int64_t, align_tmp)[16]; + int16_t *block1= (int16_t*)align_tmp; + const int16_t *table= tab_frw_01234567; + int i; + + fdct_col_mmx(block, block1, 0); + fdct_col_mmx(block, block1, 4); + + for(i=8;i>0;i--) { + fdct_row_mmxext(block1, block, table); + block1 += 8; + table += 32; + block += 8; + } +} + +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_SSE2_INLINE + +void ff_fdct_sse2(int16_t *block) +{ + DECLARE_ALIGNED(16, int64_t, align_tmp)[16]; + int16_t * const block1= (int16_t*)align_tmp; + + fdct_col_sse2(block, block1, 0); + fdct_row_sse2(block1, block); +} + +#endif /* HAVE_SSE2_INLINE */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdct.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdct.h new file mode 100644 index 00000000..648cdc53 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdct.h @@ -0,0 +1,28 @@ +/* + * 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 + */ + +#ifndef AVCODEC_X86_FDCT_H +#define AVCODEC_X86_FDCT_H + +#include + +void ff_fdct_mmx(int16_t *block); +void ff_fdct_mmxext(int16_t *block); +void ff_fdct_sse2(int16_t *block); + +#endif /* AVCODEC_X86_FDCT_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdctdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdctdsp_init.c new file mode 100644 index 00000000..0cb5fd62 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fdctdsp_init.c @@ -0,0 +1,44 @@ +/* + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/fdctdsp.h" +#include "fdct.h" + +av_cold void ff_fdctdsp_init_x86(FDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + const int dct_algo = avctx->dct_algo; + + if (!high_bit_depth) { + if ((dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX)) { + if (INLINE_MMX(cpu_flags)) + c->fdct = ff_fdct_mmx; + + if (INLINE_MMXEXT(cpu_flags)) + c->fdct = ff_fdct_mmxext; + + if (INLINE_SSE2(cpu_flags)) + c->fdct = ff_fdct_sse2; + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft.asm new file mode 100644 index 00000000..a671e8f4 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft.asm @@ -0,0 +1,1085 @@ +;****************************************************************************** +;* FFT transform with SSE/3DNow optimizations +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2011 Vitor Sessak +;* +;* This algorithm (though not any of the implementation details) is +;* based on libdjbfft by D. J. Bernstein. +;* +;* 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 +;****************************************************************************** + +; These functions are not individually interchangeable with the C versions. +; While C takes arrays of FFTComplex, SSE/3DNow leave intermediate results +; in blocks as conventient to the vector size. +; i.e. {4x real, 4x imaginary, 4x real, ...} (or 2x respectively) + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 +%define pointer resq +%else +%define pointer resd +%endif + +struc FFTContext + .nbits: resd 1 + .reverse: resd 1 + .revtab: pointer 1 + .tmpbuf: pointer 1 + .mdctsize: resd 1 + .mdctbits: resd 1 + .tcos: pointer 1 + .tsin: pointer 1 + .fftperm: pointer 1 + .fftcalc: pointer 1 + .imdctcalc:pointer 1 + .imdcthalf:pointer 1 +endstruc + +SECTION_RODATA 32 + +%define M_SQRT1_2 0.70710678118654752440 +%define M_COS_PI_1_8 0.923879532511287 +%define M_COS_PI_3_8 0.38268343236509 + +ps_cos16_1: dd 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8, 1.0, M_COS_PI_1_8, M_SQRT1_2, M_COS_PI_3_8 +ps_cos16_2: dd 0, M_COS_PI_3_8, M_SQRT1_2, M_COS_PI_1_8, 0, -M_COS_PI_3_8, -M_SQRT1_2, -M_COS_PI_1_8 + +ps_root2: times 8 dd M_SQRT1_2 +ps_root2mppm: dd -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2 +ps_p1p1m1p1: dd 0, 0, 1<<31, 0, 0, 0, 1<<31, 0 + +perm1: dd 0x00, 0x02, 0x03, 0x01, 0x03, 0x00, 0x02, 0x01 +perm2: dd 0x00, 0x01, 0x02, 0x03, 0x01, 0x00, 0x02, 0x03 +ps_p1p1m1p1root2: dd 1.0, 1.0, -1.0, 1.0, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, M_SQRT1_2 +ps_m1m1p1m1p1m1m1m1: dd 1<<31, 1<<31, 0, 1<<31, 0, 1<<31, 1<<31, 1<<31 +ps_m1p1: dd 1<<31, 0 + +cextern ps_neg + +%assign i 16 +%rep 14 +cextern cos_ %+ i +%assign i i<<1 +%endrep + +%if ARCH_X86_64 + %define pointer dq +%else + %define pointer dd +%endif + +%macro IF0 1+ +%endmacro +%macro IF1 1+ + %1 +%endmacro + +SECTION .text + +%macro T2_3DNOW 4 ; z0, z1, mem0, mem1 + mova %1, %3 + mova %2, %1 + pfadd %1, %4 + pfsub %2, %4 +%endmacro + +%macro T4_3DNOW 6 ; z0, z1, z2, z3, tmp0, tmp1 + mova %5, %3 + pfsub %3, %4 + pfadd %5, %4 ; {t6,t5} + pxor %3, [ps_m1p1] ; {t8,t7} + mova %6, %1 + movd [r0+12], %3 + punpckhdq %3, [r0+8] + pfadd %1, %5 ; {r0,i0} + pfsub %6, %5 ; {r2,i2} + mova %4, %2 + pfadd %2, %3 ; {r1,i1} + pfsub %4, %3 ; {r3,i3} + SWAP %3, %6 +%endmacro + +; in: %1 = {r0,i0,r2,i2,r4,i4,r6,i6} +; %2 = {r1,i1,r3,i3,r5,i5,r7,i7} +; %3, %4, %5 tmp +; out: %1 = {r0,r1,r2,r3,i0,i1,i2,i3} +; %2 = {r4,r5,r6,r7,i4,i5,i6,i7} +%macro T8_AVX 5 + vsubps %5, %1, %2 ; v = %1 - %2 + vaddps %3, %1, %2 ; w = %1 + %2 + vmulps %2, %5, [ps_p1p1m1p1root2] ; v *= vals1 + vpermilps %2, %2, [perm1] + vblendps %1, %2, %3, 0x33 ; q = {w1,w2,v4,v2,w5,w6,v7,v6} + vshufps %5, %3, %2, 0x4e ; r = {w3,w4,v1,v3,w7,w8,v8,v5} + vsubps %4, %5, %1 ; s = r - q + vaddps %1, %5, %1 ; u = r + q + vpermilps %1, %1, [perm2] ; k = {u1,u2,u3,u4,u6,u5,u7,u8} + vshufps %5, %4, %1, 0xbb + vshufps %3, %4, %1, 0xee + vperm2f128 %3, %3, %5, 0x13 + vxorps %4, %4, [ps_m1m1p1m1p1m1m1m1] ; s *= {1,1,-1,-1,1,-1,-1,-1} + vshufps %2, %1, %4, 0xdd + vshufps %1, %1, %4, 0x88 + vperm2f128 %4, %2, %1, 0x02 ; v = {k1,k3,s1,s3,k2,k4,s2,s4} + vperm2f128 %1, %1, %2, 0x13 ; w = {k6,k8,s6,s8,k5,k7,s5,s7} + vsubps %5, %1, %3 + vblendps %1, %5, %1, 0x55 ; w -= {0,s7,0,k7,0,s8,0,k8} + vsubps %2, %4, %1 ; %2 = v - w + vaddps %1, %4, %1 ; %1 = v + w +%endmacro + +; In SSE mode do one fft4 transforms +; in: %1={r0,i0,r2,i2} %2={r1,i1,r3,i3} +; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} +; +; In AVX mode do two fft4 transforms +; in: %1={r0,i0,r2,i2,r4,i4,r6,i6} %2={r1,i1,r3,i3,r5,i5,r7,i7} +; out: %1={r0,r1,r2,r3,r4,r5,r6,r7} %2={i0,i1,i2,i3,i4,i5,i6,i7} +%macro T4_SSE 3 + subps %3, %1, %2 ; {t3,t4,-t8,t7} + addps %1, %1, %2 ; {t1,t2,t6,t5} + xorps %3, %3, [ps_p1p1m1p1] + shufps %2, %1, %3, 0xbe ; {t6,t5,t7,t8} + shufps %1, %1, %3, 0x44 ; {t1,t2,t3,t4} + subps %3, %1, %2 ; {r2,i2,r3,i3} + addps %1, %1, %2 ; {r0,i0,r1,i1} + shufps %2, %1, %3, 0xdd ; {i0,i1,i2,i3} + shufps %1, %1, %3, 0x88 ; {r0,r1,r2,r3} +%endmacro + +; In SSE mode do one FFT8 +; in: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} %3={r4,i4,r6,i6} %4={r5,i5,r7,i7} +; out: %1={r0,r1,r2,r3} %2={i0,i1,i2,i3} %1={r4,r5,r6,r7} %2={i4,i5,i6,i7} +; +; In AVX mode do two FFT8 +; in: %1={r0,i0,r2,i2,r8, i8, r10,i10} %2={r1,i1,r3,i3,r9, i9, r11,i11} +; %3={r4,i4,r6,i6,r12,i12,r14,i14} %4={r5,i5,r7,i7,r13,i13,r15,i15} +; out: %1={r0,r1,r2,r3,r8, r9, r10,r11} %2={i0,i1,i2,i3,i8, i9, i10,i11} +; %3={r4,r5,r6,r7,r12,r13,r14,r15} %4={i4,i5,i6,i7,i12,i13,i14,i15} +%macro T8_SSE 6 + addps %6, %3, %4 ; {t1,t2,t3,t4} + subps %3, %3, %4 ; {r5,i5,r7,i7} + shufps %4, %3, %3, 0xb1 ; {i5,r5,i7,r7} + mulps %3, %3, [ps_root2mppm] ; {-r5,i5,r7,-i7} + mulps %4, %4, [ps_root2] + addps %3, %3, %4 ; {t8,t7,ta,t9} + shufps %4, %6, %3, 0x9c ; {t1,t4,t7,ta} + shufps %6, %6, %3, 0x36 ; {t3,t2,t9,t8} + subps %3, %6, %4 ; {t6,t5,tc,tb} + addps %6, %6, %4 ; {t1,t2,t9,ta} + shufps %5, %6, %3, 0x8d ; {t2,ta,t6,tc} + shufps %6, %6, %3, 0xd8 ; {t1,t9,t5,tb} + subps %3, %1, %6 ; {r4,r5,r6,r7} + addps %1, %1, %6 ; {r0,r1,r2,r3} + subps %4, %2, %5 ; {i4,i5,i6,i7} + addps %2, %2, %5 ; {i0,i1,i2,i3} +%endmacro + +%macro INTERL 5 +%if cpuflag(avx) + vunpckhps %3, %2, %1 + vunpcklps %2, %2, %1 + vextractf128 %4(%5), %2, 0 + vextractf128 %4 %+ H(%5), %3, 0 + vextractf128 %4(%5 + 1), %2, 1 + vextractf128 %4 %+ H(%5 + 1), %3, 1 +%elif cpuflag(sse) || cpuflag(3dnow) + mova %3, %2 + unpcklps %2, %1 + unpckhps %3, %1 + mova %4(%5), %2 + mova %4(%5+1), %3 +%endif +%endmacro + +; scheduled for cpu-bound sizes +%macro PASS_SMALL 3 ; (to load m4-m7), wre, wim +IF%1 mova m4, Z(4) +IF%1 mova m5, Z(5) + mova m0, %2 ; wre + mova m1, %3 ; wim + mulps m2, m4, m0 ; r2*wre +IF%1 mova m6, Z2(6) + mulps m3, m5, m1 ; i2*wim +IF%1 mova m7, Z2(7) + mulps m4, m4, m1 ; r2*wim + mulps m5, m5, m0 ; i2*wre + addps m2, m2, m3 ; r2*wre + i2*wim + mulps m3, m1, m7 ; i3*wim + subps m5, m5, m4 ; i2*wre - r2*wim + mulps m1, m1, m6 ; r3*wim + mulps m4, m0, m6 ; r3*wre + mulps m0, m0, m7 ; i3*wre + subps m4, m4, m3 ; r3*wre - i3*wim + mova m3, Z(0) + addps m0, m0, m1 ; i3*wre + r3*wim + subps m1, m4, m2 ; t3 + addps m4, m4, m2 ; t5 + subps m3, m3, m4 ; r2 + addps m4, m4, Z(0) ; r0 + mova m6, Z(2) + mova Z(4), m3 + mova Z(0), m4 + subps m3, m5, m0 ; t4 + subps m4, m6, m3 ; r3 + addps m3, m3, m6 ; r1 + mova Z2(6), m4 + mova Z(2), m3 + mova m2, Z(3) + addps m3, m5, m0 ; t6 + subps m2, m2, m1 ; i3 + mova m7, Z(1) + addps m1, m1, Z(3) ; i1 + mova Z2(7), m2 + mova Z(3), m1 + subps m4, m7, m3 ; i2 + addps m3, m3, m7 ; i0 + mova Z(5), m4 + mova Z(1), m3 +%endmacro + +; scheduled to avoid store->load aliasing +%macro PASS_BIG 1 ; (!interleave) + mova m4, Z(4) ; r2 + mova m5, Z(5) ; i2 + mova m0, [wq] ; wre + mova m1, [wq+o1q] ; wim + mulps m2, m4, m0 ; r2*wre + mova m6, Z2(6) ; r3 + mulps m3, m5, m1 ; i2*wim + mova m7, Z2(7) ; i3 + mulps m4, m4, m1 ; r2*wim + mulps m5, m5, m0 ; i2*wre + addps m2, m2, m3 ; r2*wre + i2*wim + mulps m3, m1, m7 ; i3*wim + mulps m1, m1, m6 ; r3*wim + subps m5, m5, m4 ; i2*wre - r2*wim + mulps m4, m0, m6 ; r3*wre + mulps m0, m0, m7 ; i3*wre + subps m4, m4, m3 ; r3*wre - i3*wim + mova m3, Z(0) + addps m0, m0, m1 ; i3*wre + r3*wim + subps m1, m4, m2 ; t3 + addps m4, m4, m2 ; t5 + subps m3, m3, m4 ; r2 + addps m4, m4, Z(0) ; r0 + mova m6, Z(2) + mova Z(4), m3 + mova Z(0), m4 + subps m3, m5, m0 ; t4 + subps m4, m6, m3 ; r3 + addps m3, m3, m6 ; r1 +IF%1 mova Z2(6), m4 +IF%1 mova Z(2), m3 + mova m2, Z(3) + addps m5, m5, m0 ; t6 + subps m2, m2, m1 ; i3 + mova m7, Z(1) + addps m1, m1, Z(3) ; i1 +IF%1 mova Z2(7), m2 +IF%1 mova Z(3), m1 + subps m6, m7, m5 ; i2 + addps m5, m5, m7 ; i0 +IF%1 mova Z(5), m6 +IF%1 mova Z(1), m5 +%if %1==0 + INTERL m1, m3, m7, Z, 2 + INTERL m2, m4, m0, Z2, 6 + + mova m1, Z(0) + mova m2, Z(4) + + INTERL m5, m1, m3, Z, 0 + INTERL m6, m2, m7, Z, 4 +%endif +%endmacro + +%macro PUNPCK 3 + mova %3, %1 + punpckldq %1, %2 + punpckhdq %3, %2 +%endmacro + +%define Z(x) [r0+mmsize*x] +%define Z2(x) [r0+mmsize*x] +%define ZH(x) [r0+mmsize*x+mmsize/2] + +INIT_YMM avx + +%if HAVE_AVX_EXTERNAL +align 16 +fft8_avx: + mova m0, Z(0) + mova m1, Z(1) + T8_AVX m0, m1, m2, m3, m4 + mova Z(0), m0 + mova Z(1), m1 + ret + + +align 16 +fft16_avx: + mova m2, Z(2) + mova m3, Z(3) + T4_SSE m2, m3, m7 + + mova m0, Z(0) + mova m1, Z(1) + T8_AVX m0, m1, m4, m5, m7 + + mova m4, [ps_cos16_1] + mova m5, [ps_cos16_2] + vmulps m6, m2, m4 + vmulps m7, m3, m5 + vaddps m7, m7, m6 + vmulps m2, m2, m5 + vmulps m3, m3, m4 + vsubps m3, m3, m2 + vblendps m2, m7, m3, 0xf0 + vperm2f128 m3, m7, m3, 0x21 + vaddps m4, m2, m3 + vsubps m2, m3, m2 + vperm2f128 m2, m2, m2, 0x01 + vsubps m3, m1, m2 + vaddps m1, m1, m2 + vsubps m5, m0, m4 + vaddps m0, m0, m4 + vextractf128 Z(0), m0, 0 + vextractf128 ZH(0), m1, 0 + vextractf128 Z(1), m0, 1 + vextractf128 ZH(1), m1, 1 + vextractf128 Z(2), m5, 0 + vextractf128 ZH(2), m3, 0 + vextractf128 Z(3), m5, 1 + vextractf128 ZH(3), m3, 1 + ret + +align 16 +fft32_avx: + call fft16_avx + + mova m0, Z(4) + mova m1, Z(5) + + T4_SSE m0, m1, m4 + + mova m2, Z(6) + mova m3, Z(7) + + T8_SSE m0, m1, m2, m3, m4, m6 + ; m0={r0,r1,r2,r3,r8, r9, r10,r11} m1={i0,i1,i2,i3,i8, i9, i10,i11} + ; m2={r4,r5,r6,r7,r12,r13,r14,r15} m3={i4,i5,i6,i7,i12,i13,i14,i15} + + vperm2f128 m4, m0, m2, 0x20 + vperm2f128 m5, m1, m3, 0x20 + vperm2f128 m6, m0, m2, 0x31 + vperm2f128 m7, m1, m3, 0x31 + + PASS_SMALL 0, [cos_32], [cos_32+32] + + ret + +fft32_interleave_avx: + call fft32_avx + mov r2d, 32 +.deint_loop: + mova m2, Z(0) + mova m3, Z(1) + vunpcklps m0, m2, m3 + vunpckhps m1, m2, m3 + vextractf128 Z(0), m0, 0 + vextractf128 ZH(0), m1, 0 + vextractf128 Z(1), m0, 1 + vextractf128 ZH(1), m1, 1 + add r0, mmsize*2 + sub r2d, mmsize/4 + jg .deint_loop + ret + +%endif + +INIT_XMM sse + +align 16 +fft4_avx: +fft4_sse: + mova m0, Z(0) + mova m1, Z(1) + T4_SSE m0, m1, m2 + mova Z(0), m0 + mova Z(1), m1 + ret + +align 16 +fft8_sse: + mova m0, Z(0) + mova m1, Z(1) + T4_SSE m0, m1, m2 + mova m2, Z(2) + mova m3, Z(3) + T8_SSE m0, m1, m2, m3, m4, m5 + mova Z(0), m0 + mova Z(1), m1 + mova Z(2), m2 + mova Z(3), m3 + ret + +align 16 +fft16_sse: + mova m0, Z(0) + mova m1, Z(1) + T4_SSE m0, m1, m2 + mova m2, Z(2) + mova m3, Z(3) + T8_SSE m0, m1, m2, m3, m4, m5 + mova m4, Z(4) + mova m5, Z(5) + mova Z(0), m0 + mova Z(1), m1 + mova Z(2), m2 + mova Z(3), m3 + T4_SSE m4, m5, m6 + mova m6, Z2(6) + mova m7, Z2(7) + T4_SSE m6, m7, m0 + PASS_SMALL 0, [cos_16], [cos_16+16] + ret + + +%macro FFT48_3DNOW 0 +align 16 +fft4 %+ SUFFIX: + T2_3DNOW m0, m1, Z(0), Z(1) + mova m2, Z(2) + mova m3, Z(3) + T4_3DNOW m0, m1, m2, m3, m4, m5 + PUNPCK m0, m1, m4 + PUNPCK m2, m3, m5 + mova Z(0), m0 + mova Z(1), m4 + mova Z(2), m2 + mova Z(3), m5 + ret + +align 16 +fft8 %+ SUFFIX: + T2_3DNOW m0, m1, Z(0), Z(1) + mova m2, Z(2) + mova m3, Z(3) + T4_3DNOW m0, m1, m2, m3, m4, m5 + mova Z(0), m0 + mova Z(2), m2 + T2_3DNOW m4, m5, Z(4), Z(5) + T2_3DNOW m6, m7, Z2(6), Z2(7) + PSWAPD m0, m5 + PSWAPD m2, m7 + pxor m0, [ps_m1p1] + pxor m2, [ps_m1p1] + pfsub m5, m0 + pfadd m7, m2 + pfmul m5, [ps_root2] + pfmul m7, [ps_root2] + T4_3DNOW m1, m3, m5, m7, m0, m2 + mova Z(5), m5 + mova Z2(7), m7 + mova m0, Z(0) + mova m2, Z(2) + T4_3DNOW m0, m2, m4, m6, m5, m7 + PUNPCK m0, m1, m5 + PUNPCK m2, m3, m7 + mova Z(0), m0 + mova Z(1), m5 + mova Z(2), m2 + mova Z(3), m7 + PUNPCK m4, Z(5), m5 + PUNPCK m6, Z2(7), m7 + mova Z(4), m4 + mova Z(5), m5 + mova Z2(6), m6 + mova Z2(7), m7 + ret +%endmacro + +%if ARCH_X86_32 +INIT_MMX 3dnowext +FFT48_3DNOW + +INIT_MMX 3dnow +FFT48_3DNOW +%endif + +%define Z(x) [zcq + o1q*(x&6) + mmsize*(x&1)] +%define Z2(x) [zcq + o3q + mmsize*(x&1)] +%define ZH(x) [zcq + o1q*(x&6) + mmsize*(x&1) + mmsize/2] +%define Z2H(x) [zcq + o3q + mmsize*(x&1) + mmsize/2] + +%macro DECL_PASS 2+ ; name, payload +align 16 +%1: +DEFINE_ARGS zc, w, n, o1, o3 + lea o3q, [nq*3] + lea o1q, [nq*8] + shl o3q, 4 +.loop: + %2 + add zcq, mmsize*2 + add wq, mmsize + sub nd, mmsize/8 + jg .loop + rep ret +%endmacro + +%macro FFT_DISPATCH 2; clobbers 5 GPRs, 8 XMMs + lea r2, [dispatch_tab%1] + mov r2, [r2 + (%2q-2)*gprsize] +%ifdef PIC + lea r3, [$$] + add r2, r3 +%endif + call r2 +%endmacro ; FFT_DISPATCH + +INIT_YMM avx + +%if HAVE_AVX_EXTERNAL +DECL_PASS pass_avx, PASS_BIG 1 +DECL_PASS pass_interleave_avx, PASS_BIG 0 + +cglobal fft_calc, 2,5,8 + mov r3d, [r0 + FFTContext.nbits] + mov r0, r1 + mov r1, r3 + FFT_DISPATCH _interleave %+ SUFFIX, r1 + REP_RET + +%endif + +INIT_XMM sse + +DECL_PASS pass_sse, PASS_BIG 1 +DECL_PASS pass_interleave_sse, PASS_BIG 0 + +%macro FFT_CALC_FUNC 0 +cglobal fft_calc, 2,5,8 + mov r3d, [r0 + FFTContext.nbits] + PUSH r1 + PUSH r3 + mov r0, r1 + mov r1, r3 + FFT_DISPATCH _interleave %+ SUFFIX, r1 + POP rcx + POP r4 + cmp rcx, 3+(mmsize/16) + jg .end + mov r2, -1 + add rcx, 3 + shl r2, cl + sub r4, r2 +.loop: +%if mmsize == 8 + PSWAPD m0, [r4 + r2 + 4] + mova [r4 + r2 + 4], m0 +%else + movaps xmm0, [r4 + r2] + movaps xmm1, xmm0 + unpcklps xmm0, [r4 + r2 + 16] + unpckhps xmm1, [r4 + r2 + 16] + movaps [r4 + r2], xmm0 + movaps [r4 + r2 + 16], xmm1 +%endif + add r2, mmsize*2 + jl .loop +.end: +%if cpuflag(3dnow) + femms + RET +%else + REP_RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX 3dnow +FFT_CALC_FUNC +INIT_MMX 3dnowext +FFT_CALC_FUNC +%endif +INIT_XMM sse +FFT_CALC_FUNC + +cglobal fft_permute, 2,7,1 + mov r4, [r0 + FFTContext.revtab] + mov r5, [r0 + FFTContext.tmpbuf] + mov ecx, [r0 + FFTContext.nbits] + mov r2, 1 + shl r2, cl + xor r0, r0 +%if ARCH_X86_32 + mov r1, r1m +%endif +.loop: + movaps xmm0, [r1 + 8*r0] + movzx r6, word [r4 + 2*r0] + movzx r3, word [r4 + 2*r0 + 2] + movlps [r5 + 8*r6], xmm0 + movhps [r5 + 8*r3], xmm0 + add r0, 2 + cmp r0, r2 + jl .loop + shl r2, 3 + add r1, r2 + add r5, r2 + neg r2 +; nbits >= 2 (FFT4) and sizeof(FFTComplex)=8 => at least 32B +.loopcopy: + movaps xmm0, [r5 + r2] + movaps xmm1, [r5 + r2 + 16] + movaps [r1 + r2], xmm0 + movaps [r1 + r2 + 16], xmm1 + add r2, 32 + jl .loopcopy + REP_RET + +%macro IMDCT_CALC_FUNC 0 +cglobal imdct_calc, 3,5,3 + mov r3d, [r0 + FFTContext.mdctsize] + mov r4, [r0 + FFTContext.imdcthalf] + add r1, r3 + PUSH r3 + PUSH r1 +%if ARCH_X86_32 + push r2 + push r1 + push r0 +%else + sub rsp, 8+32*WIN64 ; allocate win64 shadow space +%endif + call r4 +%if ARCH_X86_32 + add esp, 12 +%else + add rsp, 8+32*WIN64 +%endif + POP r1 + POP r3 + lea r0, [r1 + 2*r3] + mov r2, r3 + sub r3, mmsize + neg r2 + mova m2, [ps_neg] +.loop: +%if mmsize == 8 + PSWAPD m0, [r1 + r3] + PSWAPD m1, [r0 + r2] + pxor m0, m2 +%else + mova m0, [r1 + r3] + mova m1, [r0 + r2] + shufps m0, m0, 0x1b + shufps m1, m1, 0x1b + xorps m0, m2 +%endif + mova [r0 + r3], m1 + mova [r1 + r2], m0 + sub r3, mmsize + add r2, mmsize + jl .loop +%if cpuflag(3dnow) + femms + RET +%else + REP_RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX 3dnow +IMDCT_CALC_FUNC +INIT_MMX 3dnowext +IMDCT_CALC_FUNC +%endif + +INIT_XMM sse +IMDCT_CALC_FUNC + +%if ARCH_X86_32 +INIT_MMX 3dnow +%define mulps pfmul +%define addps pfadd +%define subps pfsub +%define unpcklps punpckldq +%define unpckhps punpckhdq +DECL_PASS pass_3dnow, PASS_SMALL 1, [wq], [wq+o1q] +DECL_PASS pass_interleave_3dnow, PASS_BIG 0 +%define pass_3dnowext pass_3dnow +%define pass_interleave_3dnowext pass_interleave_3dnow +%endif + +%ifdef PIC +%define SECTION_REL - $$ +%else +%define SECTION_REL +%endif + +%macro DECL_FFT 1-2 ; nbits, suffix +%ifidn %0, 1 +%xdefine fullsuffix SUFFIX +%else +%xdefine fullsuffix %2 %+ SUFFIX +%endif +%xdefine list_of_fft fft4 %+ SUFFIX SECTION_REL, fft8 %+ SUFFIX SECTION_REL +%if %1>=5 +%xdefine list_of_fft list_of_fft, fft16 %+ SUFFIX SECTION_REL +%endif +%if %1>=6 +%xdefine list_of_fft list_of_fft, fft32 %+ fullsuffix SECTION_REL +%endif + +%assign n 1<<%1 +%rep 18-%1 +%assign n2 n/2 +%assign n4 n/4 +%xdefine list_of_fft list_of_fft, fft %+ n %+ fullsuffix SECTION_REL + +align 16 +fft %+ n %+ fullsuffix: + call fft %+ n2 %+ SUFFIX + add r0, n*4 - (n&(-2<<%1)) + call fft %+ n4 %+ SUFFIX + add r0, n*2 - (n2&(-2<<%1)) + call fft %+ n4 %+ SUFFIX + sub r0, n*6 + (n2&(-2<<%1)) + lea r1, [cos_ %+ n] + mov r2d, n4/2 + jmp pass %+ fullsuffix + +%assign n n*2 +%endrep +%undef n + +align 8 +dispatch_tab %+ fullsuffix: pointer list_of_fft +%endmacro ; DECL_FFT + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +DECL_FFT 6 +DECL_FFT 6, _interleave +%endif +INIT_XMM sse +DECL_FFT 5 +DECL_FFT 5, _interleave +%if ARCH_X86_32 +INIT_MMX 3dnow +DECL_FFT 4 +DECL_FFT 4, _interleave +INIT_MMX 3dnowext +DECL_FFT 4 +DECL_FFT 4, _interleave +%endif + +INIT_XMM sse +%undef mulps +%undef addps +%undef subps +%undef unpcklps +%undef unpckhps + +%macro PREROTATER 5 ;-2*k, 2*k, input+n4, tcos+n8, tsin+n8 +%if mmsize == 8 ; j*2+2-n4, n4-2-j*2, input+n4, tcos+n8, tsin+n8 + PSWAPD m0, [%3+%2*4] + movq m2, [%3+%1*4-8] + movq m3, m0 + punpckldq m0, m2 + punpckhdq m2, m3 + movd m1, [%4+%1*2-4] ; tcos[j] + movd m3, [%4+%2*2] ; tcos[n4-j-1] + punpckldq m1, [%5+%1*2-4] ; tsin[j] + punpckldq m3, [%5+%2*2] ; tsin[n4-j-1] + + mova m4, m0 + PSWAPD m5, m1 + pfmul m0, m1 + pfmul m4, m5 + mova m6, m2 + PSWAPD m5, m3 + pfmul m2, m3 + pfmul m6, m5 +%if cpuflag(3dnowext) + pfpnacc m0, m4 + pfpnacc m2, m6 +%else + SBUTTERFLY dq, 0, 4, 1 + SBUTTERFLY dq, 2, 6, 3 + pxor m4, m7 + pxor m6, m7 + pfadd m0, m4 + pfadd m2, m6 +%endif +%else + movaps xmm0, [%3+%2*4] + movaps xmm1, [%3+%1*4-0x10] + movaps xmm2, xmm0 + shufps xmm0, xmm1, 0x88 + shufps xmm1, xmm2, 0x77 + movlps xmm4, [%4+%2*2] + movlps xmm5, [%5+%2*2+0x0] + movhps xmm4, [%4+%1*2-0x8] + movhps xmm5, [%5+%1*2-0x8] + movaps xmm2, xmm0 + movaps xmm3, xmm1 + mulps xmm0, xmm5 + mulps xmm1, xmm4 + mulps xmm2, xmm4 + mulps xmm3, xmm5 + subps xmm1, xmm0 + addps xmm2, xmm3 + movaps xmm0, xmm1 + unpcklps xmm1, xmm2 + unpckhps xmm0, xmm2 +%endif +%endmacro + +%macro CMUL 6 ;j, xmm0, xmm1, 3, 4, 5 +%if cpuflag(sse) + mulps m6, %3, [%5+%1] + mulps m7, %2, [%5+%1] + mulps %2, %2, [%6+%1] + mulps %3, %3, [%6+%1] + subps %2, %2, m6 + addps %3, %3, m7 +%elif cpuflag(3dnow) + mova m6, [%1+%2*2] + mova %3, [%1+%2*2+8] + mova %4, m6 + mova m7, %3 + pfmul m6, [%5+%2] + pfmul %3, [%6+%2] + pfmul %4, [%6+%2] + pfmul m7, [%5+%2] + pfsub %3, m6 + pfadd %4, m7 +%endif +%endmacro + +%macro POSROTATESHUF 5 ;j, k, z+n8, tcos+n8, tsin+n8 +.post: +%if cpuflag(avx) + vmovaps ymm1, [%3+%1*2] + vmovaps ymm0, [%3+%1*2+0x20] + vmovaps ymm3, [%3+%2*2] + vmovaps ymm2, [%3+%2*2+0x20] + + CMUL %1, ymm0, ymm1, %3, %4, %5 + CMUL %2, ymm2, ymm3, %3, %4, %5 + vshufps ymm1, ymm1, ymm1, 0x1b + vshufps ymm3, ymm3, ymm3, 0x1b + vperm2f128 ymm1, ymm1, ymm1, 0x01 + vperm2f128 ymm3, ymm3, ymm3, 0x01 + vunpcklps ymm6, ymm2, ymm1 + vunpckhps ymm4, ymm2, ymm1 + vunpcklps ymm7, ymm0, ymm3 + vunpckhps ymm5, ymm0, ymm3 + + vextractf128 [%3+%1*2], ymm7, 0 + vextractf128 [%3+%1*2+0x10], ymm5, 0 + vextractf128 [%3+%1*2+0x20], ymm7, 1 + vextractf128 [%3+%1*2+0x30], ymm5, 1 + + vextractf128 [%3+%2*2], ymm6, 0 + vextractf128 [%3+%2*2+0x10], ymm4, 0 + vextractf128 [%3+%2*2+0x20], ymm6, 1 + vextractf128 [%3+%2*2+0x30], ymm4, 1 + sub %2, 0x20 + add %1, 0x20 + jl .post +%elif cpuflag(sse) + movaps xmm1, [%3+%1*2] + movaps xmm0, [%3+%1*2+0x10] + CMUL %1, xmm0, xmm1, %3, %4, %5 + movaps xmm5, [%3+%2*2] + movaps xmm4, [%3+%2*2+0x10] + CMUL %2, xmm4, xmm5, %3, %4, %5 + shufps xmm1, xmm1, 0x1b + shufps xmm5, xmm5, 0x1b + movaps xmm6, xmm4 + unpckhps xmm4, xmm1 + unpcklps xmm6, xmm1 + movaps xmm2, xmm0 + unpcklps xmm0, xmm5 + unpckhps xmm2, xmm5 + movaps [%3+%2*2], xmm6 + movaps [%3+%2*2+0x10], xmm4 + movaps [%3+%1*2], xmm0 + movaps [%3+%1*2+0x10], xmm2 + sub %2, 0x10 + add %1, 0x10 + jl .post +%elif cpuflag(3dnow) + CMUL %3, %1, m0, m1, %4, %5 + CMUL %3, %2, m2, m3, %4, %5 + movd [%3+%1*2+ 0], m0 + movd [%3+%2*2+12], m1 + movd [%3+%2*2+ 0], m2 + movd [%3+%1*2+12], m3 + psrlq m0, 32 + psrlq m1, 32 + psrlq m2, 32 + psrlq m3, 32 + movd [%3+%1*2+ 8], m0 + movd [%3+%2*2+ 4], m1 + movd [%3+%2*2+ 8], m2 + movd [%3+%1*2+ 4], m3 + sub %2, 8 + add %1, 8 + jl .post +%endif +%endmacro + +%macro DECL_IMDCT 0 +cglobal imdct_half, 3,12,8; FFTContext *s, FFTSample *output, const FFTSample *input +%if ARCH_X86_64 +%define rrevtab r7 +%define rtcos r8 +%define rtsin r9 +%else +%define rrevtab r6 +%define rtsin r6 +%define rtcos r5 +%endif + mov r3d, [r0+FFTContext.mdctsize] + add r2, r3 + shr r3, 1 + mov rtcos, [r0+FFTContext.tcos] + mov rtsin, [r0+FFTContext.tsin] + add rtcos, r3 + add rtsin, r3 +%if ARCH_X86_64 == 0 + push rtcos + push rtsin +%endif + shr r3, 1 + mov rrevtab, [r0+FFTContext.revtab] + add rrevtab, r3 +%if ARCH_X86_64 == 0 + push rrevtab +%endif + +%if mmsize == 8 + sub r3, 2 +%else + sub r3, 4 +%endif +%if ARCH_X86_64 || mmsize == 8 + xor r4, r4 + sub r4, r3 +%endif +%if notcpuflag(3dnowext) && mmsize == 8 + movd m7, [ps_neg] +%endif +.pre: +%if ARCH_X86_64 == 0 +;unspill +%if mmsize != 8 + xor r4, r4 + sub r4, r3 +%endif + mov rtcos, [esp+8] + mov rtsin, [esp+4] +%endif + + PREROTATER r4, r3, r2, rtcos, rtsin +%if mmsize == 8 + mov r6, [esp] ; rrevtab = ptr+n8 + movzx r5, word [rrevtab+r4-2] ; rrevtab[j] + movzx r6, word [rrevtab+r3] ; rrevtab[n4-j-1] + mova [r1+r5*8], m0 + mova [r1+r6*8], m2 + add r4, 2 + sub r3, 2 +%else +%if ARCH_X86_64 + movzx r5, word [rrevtab+r4-4] + movzx r6, word [rrevtab+r4-2] + movzx r10, word [rrevtab+r3] + movzx r11, word [rrevtab+r3+2] + movlps [r1+r5 *8], xmm0 + movhps [r1+r6 *8], xmm0 + movlps [r1+r10*8], xmm1 + movhps [r1+r11*8], xmm1 + add r4, 4 +%else + mov r6, [esp] + movzx r5, word [r6+r4-4] + movzx r4, word [r6+r4-2] + movlps [r1+r5*8], xmm0 + movhps [r1+r4*8], xmm0 + movzx r5, word [r6+r3] + movzx r4, word [r6+r3+2] + movlps [r1+r5*8], xmm1 + movhps [r1+r4*8], xmm1 +%endif + sub r3, 4 +%endif + jns .pre + + mov r5, r0 + mov r6, r1 + mov r0, r1 + mov r1d, [r5+FFTContext.nbits] + + FFT_DISPATCH SUFFIX, r1 + + mov r0d, [r5+FFTContext.mdctsize] + add r6, r0 + shr r0, 1 +%if ARCH_X86_64 == 0 +%define rtcos r2 +%define rtsin r3 + mov rtcos, [esp+8] + mov rtsin, [esp+4] +%endif + neg r0 + mov r1, -mmsize + sub r1, r0 + POSROTATESHUF r0, r1, r6, rtcos, rtsin +%if ARCH_X86_64 == 0 + add esp, 12 +%endif +%if mmsize == 8 + femms +%endif + RET +%endmacro + +DECL_IMDCT + +%if ARCH_X86_32 +INIT_MMX 3dnow +DECL_IMDCT + +INIT_MMX 3dnowext +DECL_IMDCT +%endif + +INIT_YMM avx + +%if HAVE_AVX_EXTERNAL +DECL_IMDCT +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft.h new file mode 100644 index 00000000..398091eb --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft.h @@ -0,0 +1,38 @@ +/* + * 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 + */ + +#ifndef AVCODEC_X86_FFT_H +#define AVCODEC_X86_FFT_H + +#include "libavcodec/fft.h" + +void ff_fft_permute_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_avx(FFTContext *s, FFTComplex *z); +void ff_fft_calc_sse(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dnow(FFTContext *s, FFTComplex *z); +void ff_fft_calc_3dnowext(FFTContext *s, FFTComplex *z); + +void ff_imdct_calc_3dnow(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dnow(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_3dnowext(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_3dnowext(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_calc_sse(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_sse(FFTContext *s, FFTSample *output, const FFTSample *input); +void ff_imdct_half_avx(FFTContext *s, FFTSample *output, const FFTSample *input); + +#endif /* AVCODEC_X86_FFT_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft_init.c new file mode 100644 index 00000000..928f1dcd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fft_init.c @@ -0,0 +1,61 @@ +/* + * 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.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" + +#include "fft.h" + +av_cold void ff_fft_init_x86(FFTContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (s->nbits > 16) + return; + +#if ARCH_X86_32 + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_3dnow; + s->imdct_half = ff_imdct_half_3dnow; + s->fft_calc = ff_fft_calc_3dnow; + } + + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_3dnowext; + s->imdct_half = ff_imdct_half_3dnowext; + s->fft_calc = ff_fft_calc_3dnowext; + } +#endif /* ARCH_X86_32 */ + + if (EXTERNAL_SSE(cpu_flags)) { + s->imdct_calc = ff_imdct_calc_sse; + s->imdct_half = ff_imdct_half_sse; + s->fft_permute = ff_fft_permute_sse; + s->fft_calc = ff_fft_calc_sse; + s->fft_permutation = FF_FFT_PERM_SWAP_LSBS; + } + + if (EXTERNAL_AVX_FAST(cpu_flags) && s->nbits >= 5) { + s->imdct_half = ff_imdct_half_avx; + s->fft_calc = ff_fft_calc_avx; + s->fft_permutation = FF_FFT_PERM_AVX; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flac_dsp_gpl.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flac_dsp_gpl.asm new file mode 100644 index 00000000..e2851581 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flac_dsp_gpl.asm @@ -0,0 +1,101 @@ +;****************************************************************************** +;* FLAC DSP functions +;* +;* Copyright (c) 2014 James Darnley +;* +;* This file is part of FFmpeg. +;* +;* FFmpeg 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. +;* +;* 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 General Public License for more details. +;* +;* You should have received a copy of the GNU 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 "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_XMM sse4 +%if ARCH_X86_64 + cglobal flac_enc_lpc_16, 5, 7, 8, 0, res, smp, len, order, coefs + DECLARE_REG_TMP 5, 6 + %define length r2d + + movsxd orderq, orderd +%else + cglobal flac_enc_lpc_16, 5, 6, 8, 0, res, smp, len, order, coefs + DECLARE_REG_TMP 2, 5 + %define length r2mp +%endif + +; Here we assume that the maximum order value is 32. This means that we only +; need to copy a maximum of 32 samples. Therefore we let the preprocessor +; unroll this loop and copy all 32. +%assign iter 0 +%rep 32/(mmsize/4) + movu m0, [smpq+iter] + movu [resq+iter], m0 + %assign iter iter+mmsize +%endrep + +lea resq, [resq+orderq*4] +lea smpq, [smpq+orderq*4] +lea coefsq, [coefsq+orderq*4] +sub length, orderd +movd m3, r5m +neg orderq + +%define posj t0q +%define negj t1q + +.looplen: + pxor m0, m0 + pxor m4, m4 + pxor m6, m6 + mov posj, orderq + xor negj, negj + + .looporder: + movd m2, [coefsq+posj*4] ; c = coefs[j] + SPLATD m2 + movu m1, [smpq+negj*4-4] ; s = smp[i-j-1] + movu m5, [smpq+negj*4-4+mmsize] + movu m7, [smpq+negj*4-4+mmsize*2] + pmulld m1, m2 + pmulld m5, m2 + pmulld m7, m2 + paddd m0, m1 ; p += c * s + paddd m4, m5 + paddd m6, m7 + + dec negj + inc posj + jnz .looporder + + psrad m0, m3 ; p >>= shift + psrad m4, m3 + psrad m6, m3 + movu m1, [smpq] + movu m5, [smpq+mmsize] + movu m7, [smpq+mmsize*2] + psubd m1, m0 ; smp[i] - p + psubd m5, m4 + psubd m7, m6 + movu [resq], m1 ; res[i] = smp[i] - (p >> shift) + movu [resq+mmsize], m5 + movu [resq+mmsize*2], m7 + + add resq, 3*mmsize + add smpq, 3*mmsize + sub length, (3*mmsize)/4 +jg .looplen +RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flacdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flacdsp.asm new file mode 100644 index 00000000..71386115 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flacdsp.asm @@ -0,0 +1,313 @@ +;****************************************************************************** +;* FLAC DSP SIMD optimizations +;* +;* Copyright (C) 2014 Loren Merritt +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro PMACSDQL 5 +%if cpuflag(xop) + pmacsdql %1, %2, %3, %1 +%else + pmuldq %2, %3 + paddq %1, %2 +%endif +%endmacro + +%macro LPC_32 1 +INIT_XMM %1 +cglobal flac_lpc_32, 5,6,5, decoded, coeffs, pred_order, qlevel, len, j + sub lend, pred_orderd + jle .ret + lea decodedq, [decodedq+pred_orderq*4-8] + lea coeffsq, [coeffsq+pred_orderq*4] + neg pred_orderq + movd m4, qlevelm +ALIGN 16 +.loop_sample: + movd m0, [decodedq+pred_orderq*4+8] + add decodedq, 8 + movd m1, [coeffsq+pred_orderq*4] + pxor m2, m2 + pxor m3, m3 + lea jq, [pred_orderq+1] + test jq, jq + jz .end_order +.loop_order: + PMACSDQL m2, m0, m1, m2, m0 + movd m0, [decodedq+jq*4] + PMACSDQL m3, m1, m0, m3, m1 + movd m1, [coeffsq+jq*4] + inc jq + jl .loop_order +.end_order: + PMACSDQL m2, m0, m1, m2, m0 + psrlq m2, m4 + movd m0, [decodedq] + paddd m0, m2 + movd [decodedq], m0 + sub lend, 2 + jl .ret + PMACSDQL m3, m1, m0, m3, m1 + psrlq m3, m4 + movd m1, [decodedq+4] + paddd m1, m3 + movd [decodedq+4], m1 + jg .loop_sample +.ret: + REP_RET +%endmacro + +%if HAVE_XOP_EXTERNAL +LPC_32 xop +%endif +LPC_32 sse4 + +;---------------------------------------------------------------------------------- +;void ff_flac_decorrelate_[lrm]s_16_sse2(uint8_t **out, int32_t **in, int channels, +; int len, int shift); +;---------------------------------------------------------------------------------- +%macro FLAC_DECORRELATE_16 3-4 +cglobal flac_decorrelate_%1_16, 2, 4, 4, out, in0, in1, len +%if ARCH_X86_32 + mov lend, lenm +%endif + movd m3, r4m + shl lend, 2 + mov in1q, [in0q + gprsize] + mov in0q, [in0q] + mov outq, [outq] + add in1q, lenq + add in0q, lenq + add outq, lenq + neg lenq + +align 16 +.loop: + mova m0, [in0q + lenq] + mova m1, [in1q + lenq] +%ifidn %1, ms + psrad m2, m1, 1 + psubd m0, m2 +%endif +%ifnidn %1, indep2 + p%4d m2, m0, m1 +%endif + packssdw m%2, m%2 + packssdw m%3, m%3 + punpcklwd m%2, m%3 + psllw m%2, m3 + mova [outq + lenq], m%2 + add lenq, 16 + jl .loop + REP_RET +%endmacro + +INIT_XMM sse2 +FLAC_DECORRELATE_16 ls, 0, 2, sub +FLAC_DECORRELATE_16 rs, 2, 1, add +FLAC_DECORRELATE_16 ms, 2, 0, add + +;---------------------------------------------------------------------------------- +;void ff_flac_decorrelate_[lrm]s_32_sse2(uint8_t **out, int32_t **in, int channels, +; int len, int shift); +;---------------------------------------------------------------------------------- +%macro FLAC_DECORRELATE_32 5 +cglobal flac_decorrelate_%1_32, 2, 4, 4, out, in0, in1, len +%if ARCH_X86_32 + mov lend, lenm +%endif + movd m3, r4m + mov in1q, [in0q + gprsize] + mov in0q, [in0q] + mov outq, [outq] + sub in1q, in0q + +align 16 +.loop: + mova m0, [in0q] + mova m1, [in0q + in1q] +%ifidn %1, ms + psrad m2, m1, 1 + psubd m0, m2 +%endif + p%5d m2, m0, m1 + pslld m%2, m3 + pslld m%3, m3 + + SBUTTERFLY dq, %2, %3, %4 + + mova [outq ], m%2 + mova [outq + mmsize], m%3 + + add in0q, mmsize + add outq, mmsize*2 + sub lend, mmsize/4 + jg .loop + REP_RET +%endmacro + +INIT_XMM sse2 +FLAC_DECORRELATE_32 ls, 0, 2, 1, sub +FLAC_DECORRELATE_32 rs, 2, 1, 0, add +FLAC_DECORRELATE_32 ms, 2, 0, 1, add + +;----------------------------------------------------------------------------------------- +;void ff_flac_decorrelate_indep__(uint8_t **out, int32_t **in, int channels, +; int len, int shift); +;----------------------------------------------------------------------------------------- +;%1 = bps +;%2 = channels +;%3 = last xmm reg used +;%4 = word/dword (shift instruction) +%macro FLAC_DECORRELATE_INDEP 4 +%define REPCOUNT %2/(32/%1) ; 16bits = channels / 2; 32bits = channels +cglobal flac_decorrelate_indep%2_%1, 2, %2+2, %3+1, out, in0, in1, len, in2, in3, in4, in5, in6, in7 +%if ARCH_X86_32 +%if %2 == 6 + DEFINE_ARGS out, in0, in1, in2, in3, in4, in5 + %define lend dword r3m +%else + mov lend, lenm +%endif +%endif + movd m%3, r4m + +%assign %%i 1 +%rep %2-1 + mov in %+ %%i %+ q, [in0q+%%i*gprsize] +%assign %%i %%i+1 +%endrep + + mov in0q, [in0q] + mov outq, [outq] + +%assign %%i 1 +%rep %2-1 + sub in %+ %%i %+ q, in0q +%assign %%i %%i+1 +%endrep + +align 16 +.loop: + mova m0, [in0q] + +%assign %%i 1 +%rep REPCOUNT-1 + mova m %+ %%i, [in0q + in %+ %%i %+ q] +%assign %%i %%i+1 +%endrep + +%if %1 == 32 + +%if %2 == 8 + TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8 +%elif %2 == 6 + SBUTTERFLY dq, 0, 1, 6 + SBUTTERFLY dq, 2, 3, 6 + SBUTTERFLY dq, 4, 5, 6 + + punpcklqdq m6, m0, m2 + punpckhqdq m2, m4 + shufps m4, m0, 0xe4 + punpcklqdq m0, m1, m3 + punpckhqdq m3, m5 + shufps m5, m1, 0xe4 + SWAP 0,6,1,4,5,3 +%elif %2 == 4 + TRANSPOSE4x4D 0, 1, 2, 3, 4 +%else ; %2 == 2 + SBUTTERFLY dq, 0, 1, 2 +%endif + +%else ; %1 == 16 + +%if %2 == 8 + packssdw m0, [in0q + in4q] + packssdw m1, [in0q + in5q] + packssdw m2, [in0q + in6q] + packssdw m3, [in0q + in7q] + TRANSPOSE2x4x4W 0, 1, 2, 3, 4 +%elif %2 == 6 + packssdw m0, [in0q + in3q] + packssdw m1, [in0q + in4q] + packssdw m2, [in0q + in5q] + pshufd m3, m0, q1032 + punpcklwd m0, m1 + punpckhwd m1, m2 + punpcklwd m2, m3 + + shufps m3, m0, m2, q2020 + shufps m0, m1, q2031 + shufps m2, m1, q3131 + shufps m1, m2, m3, q3120 + shufps m3, m0, q0220 + shufps m0, m2, q3113 + SWAP 2, 0, 3 +%else ; %2 == 4 + packssdw m0, [in0q + in2q] + packssdw m1, [in0q + in3q] + SBUTTERFLY wd, 0, 1, 2 + SBUTTERFLY dq, 0, 1, 2 +%endif + +%endif + +%assign %%i 0 +%rep REPCOUNT + psll%4 m %+ %%i, m%3 +%assign %%i %%i+1 +%endrep + +%assign %%i 0 +%rep REPCOUNT + mova [outq + %%i*mmsize], m %+ %%i +%assign %%i %%i+1 +%endrep + + add in0q, mmsize + add outq, mmsize*REPCOUNT + sub lend, mmsize/4 + jg .loop + REP_RET +%endmacro + +INIT_XMM sse2 +FLAC_DECORRELATE_16 indep2, 0, 1 ; Reuse stereo 16bits macro +FLAC_DECORRELATE_INDEP 32, 2, 3, d +FLAC_DECORRELATE_INDEP 16, 4, 3, w +FLAC_DECORRELATE_INDEP 32, 4, 5, d +FLAC_DECORRELATE_INDEP 16, 6, 4, w +FLAC_DECORRELATE_INDEP 32, 6, 7, d +%if ARCH_X86_64 +FLAC_DECORRELATE_INDEP 16, 8, 5, w +FLAC_DECORRELATE_INDEP 32, 8, 9, d +%endif + +INIT_XMM avx +FLAC_DECORRELATE_INDEP 32, 4, 5, d +FLAC_DECORRELATE_INDEP 32, 6, 7, d +%if ARCH_X86_64 +FLAC_DECORRELATE_INDEP 16, 8, 5, w +FLAC_DECORRELATE_INDEP 32, 8, 9, d +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flacdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flacdsp_init.c new file mode 100644 index 00000000..1971f81b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/flacdsp_init.c @@ -0,0 +1,115 @@ +/* + * 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 "libavcodec/flacdsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_flac_lpc_32_sse4(int32_t *samples, const int coeffs[32], int order, + int qlevel, int len); +void ff_flac_lpc_32_xop(int32_t *samples, const int coeffs[32], int order, + int qlevel, int len); + +void ff_flac_enc_lpc_16_sse4(int32_t *, const int32_t *, int, int, const int32_t *,int); + +#define DECORRELATE_FUNCS(fmt, opt) \ +void ff_flac_decorrelate_ls_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_rs_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_ms_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep2_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep4_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep6_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift); \ +void ff_flac_decorrelate_indep8_##fmt##_##opt(uint8_t **out, int32_t **in, int channels, \ + int len, int shift) + +DECORRELATE_FUNCS(16, sse2); +DECORRELATE_FUNCS(16, avx); +DECORRELATE_FUNCS(32, sse2); +DECORRELATE_FUNCS(32, avx); + +av_cold void ff_flacdsp_init_x86(FLACDSPContext *c, enum AVSampleFormat fmt, int channels, + int bps) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#if CONFIG_FLAC_DECODER + if (EXTERNAL_SSE2(cpu_flags)) { + if (fmt == AV_SAMPLE_FMT_S16) { + if (channels == 2) + c->decorrelate[0] = ff_flac_decorrelate_indep2_16_sse2; + else if (channels == 4) + c->decorrelate[0] = ff_flac_decorrelate_indep4_16_sse2; + else if (channels == 6) + c->decorrelate[0] = ff_flac_decorrelate_indep6_16_sse2; + else if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_16_sse2; + c->decorrelate[1] = ff_flac_decorrelate_ls_16_sse2; + c->decorrelate[2] = ff_flac_decorrelate_rs_16_sse2; + c->decorrelate[3] = ff_flac_decorrelate_ms_16_sse2; + } else if (fmt == AV_SAMPLE_FMT_S32) { + if (channels == 2) + c->decorrelate[0] = ff_flac_decorrelate_indep2_32_sse2; + else if (channels == 4) + c->decorrelate[0] = ff_flac_decorrelate_indep4_32_sse2; + else if (channels == 6) + c->decorrelate[0] = ff_flac_decorrelate_indep6_32_sse2; + else if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_32_sse2; + c->decorrelate[1] = ff_flac_decorrelate_ls_32_sse2; + c->decorrelate[2] = ff_flac_decorrelate_rs_32_sse2; + c->decorrelate[3] = ff_flac_decorrelate_ms_32_sse2; + } + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->lpc32 = ff_flac_lpc_32_sse4; + } + if (EXTERNAL_AVX(cpu_flags)) { + if (fmt == AV_SAMPLE_FMT_S16) { + if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_16_avx; + } else if (fmt == AV_SAMPLE_FMT_S32) { + if (channels == 4) + c->decorrelate[0] = ff_flac_decorrelate_indep4_32_avx; + else if (channels == 6) + c->decorrelate[0] = ff_flac_decorrelate_indep6_32_avx; + else if (ARCH_X86_64 && channels == 8) + c->decorrelate[0] = ff_flac_decorrelate_indep8_32_avx; + } + } + if (EXTERNAL_XOP(cpu_flags)) { + c->lpc32 = ff_flac_lpc_32_xop; + } +#endif + +#if CONFIG_FLAC_ENCODER + if (EXTERNAL_SSE4(cpu_flags)) { + if (CONFIG_GPL) + c->lpc16_encode = ff_flac_enc_lpc_16_sse4; + } +#endif +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fmtconvert.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fmtconvert.asm new file mode 100644 index 00000000..8f62a0a0 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fmtconvert.asm @@ -0,0 +1,124 @@ +;****************************************************************************** +;* x86 optimized Format Conversion Utils +;* Copyright (c) 2008 Loren Merritt +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +;------------------------------------------------------------------------------ +; void ff_int32_to_float_fmul_scalar(float *dst, const int32_t *src, float mul, +; int len); +;------------------------------------------------------------------------------ +%macro INT32_TO_FLOAT_FMUL_SCALAR 1 +%if UNIX64 +cglobal int32_to_float_fmul_scalar, 3, 3, %1, dst, src, len +%else +cglobal int32_to_float_fmul_scalar, 4, 4, %1, dst, src, mul, len +%endif +%if WIN64 + SWAP 0, 2 +%elif ARCH_X86_32 + movss m0, mulm +%endif + SPLATD m0 + shl lend, 2 + add srcq, lenq + add dstq, lenq + neg lenq +.loop: +%if cpuflag(sse2) + cvtdq2ps m1, [srcq+lenq ] + cvtdq2ps m2, [srcq+lenq+16] +%else + cvtpi2ps m1, [srcq+lenq ] + cvtpi2ps m3, [srcq+lenq+ 8] + cvtpi2ps m2, [srcq+lenq+16] + cvtpi2ps m4, [srcq+lenq+24] + movlhps m1, m3 + movlhps m2, m4 +%endif + mulps m1, m0 + mulps m2, m0 + mova [dstq+lenq ], m1 + mova [dstq+lenq+16], m2 + add lenq, 32 + jl .loop +%if notcpuflag(sse2) + ;; cvtpi2ps switches to MMX even if the source is a memory location + ;; possible an error in documentation since every tested CPU disagrees with + ;; that. Use emms anyway since the vast majority of machines will use the + ;; SSE2 variant + emms +%endif + RET +%endmacro + +INIT_XMM sse +INT32_TO_FLOAT_FMUL_SCALAR 5 +INIT_XMM sse2 +INT32_TO_FLOAT_FMUL_SCALAR 3 + +;------------------------------------------------------------------------------ +; void ff_int32_to_float_fmul_array8(FmtConvertContext *c, float *dst, const int32_t *src, +; const float *mul, int len); +;------------------------------------------------------------------------------ +%macro INT32_TO_FLOAT_FMUL_ARRAY8 0 +cglobal int32_to_float_fmul_array8, 5, 5, 5, c, dst, src, mul, len + shl lend, 2 + add srcq, lenq + add dstq, lenq + neg lenq +.loop: + movss m0, [mulq] + SPLATD m0 +%if cpuflag(sse2) + cvtdq2ps m1, [srcq+lenq ] + cvtdq2ps m2, [srcq+lenq+16] +%else + cvtpi2ps m1, [srcq+lenq ] + cvtpi2ps m3, [srcq+lenq+ 8] + cvtpi2ps m2, [srcq+lenq+16] + cvtpi2ps m4, [srcq+lenq+24] + movlhps m1, m3 + movlhps m2, m4 +%endif + mulps m1, m0 + mulps m2, m0 + mova [dstq+lenq ], m1 + mova [dstq+lenq+16], m2 + add mulq, 4 + add lenq, 32 + jl .loop +%if notcpuflag(sse2) + ;; cvtpi2ps switches to MMX even if the source is a memory location + ;; possible an error in documentation since every tested CPU disagrees with + ;; that. Use emms anyway since the vast majority of machines will use the + ;; SSE2 variant + emms +%endif + RET +%endmacro + +INIT_XMM sse +INT32_TO_FLOAT_FMUL_ARRAY8 +INIT_XMM sse2 +INT32_TO_FLOAT_FMUL_ARRAY8 + diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fmtconvert_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fmtconvert_init.c new file mode 100644 index 00000000..df097054 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fmtconvert_init.c @@ -0,0 +1,55 @@ +/* + * Format Conversion Utils + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/fmtconvert.h" + +#if HAVE_X86ASM + +void ff_int32_to_float_fmul_scalar_sse (float *dst, const int32_t *src, float mul, int len); +void ff_int32_to_float_fmul_scalar_sse2(float *dst, const int32_t *src, float mul, int len); +void ff_int32_to_float_fmul_array8_sse (FmtConvertContext *c, float *dst, const int32_t *src, + const float *mul, int len); +void ff_int32_to_float_fmul_array8_sse2(FmtConvertContext *c, float *dst, const int32_t *src, + const float *mul, int len); + +#endif /* HAVE_X86ASM */ + +av_cold void ff_fmt_convert_init_x86(FmtConvertContext *c, AVCodecContext *avctx) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse; + c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2; + c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_sse2; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fpel.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fpel.asm new file mode 100644 index 00000000..961a1587 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fpel.asm @@ -0,0 +1,106 @@ +;****************************************************************************** +;* SIMD-optimized fullpel functions +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2003-2013 Michael Niedermayer +;* Copyright (c) 2013 Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro PAVGB_MMX 4 + LOAD %3, %1 + por %3, %2 + pxor %2, %1 + pand %2, %4 + psrlq %2, 1 + psubb %3, %2 + SWAP %2, %3 +%endmacro + +; void ff_put/avg_pixels(uint8_t *block, const uint8_t *pixels, +; ptrdiff_t line_size, int h) +%macro OP_PIXELS 2 +%if %2 == mmsize/2 +%define LOAD movh +%define SAVE movh +%define LEN mmsize +%else +%define LOAD movu +%define SAVE mova +%define LEN %2 +%endif +cglobal %1_pixels%2, 4,5,4 + lea r4, [r2*3] +%ifidn %1, avg +%if notcpuflag(mmxext) + pcmpeqd m6, m6 + paddb m6, m6 +%endif +%endif +.loop: +%assign %%i 0 +%rep LEN/mmsize + LOAD m0, [r1 + %%i] + LOAD m1, [r1+r2 + %%i] + LOAD m2, [r1+r2*2 + %%i] + LOAD m3, [r1+r4 + %%i] +%ifidn %1, avg +%if notcpuflag(mmxext) + PAVGB_MMX [r0 + %%i], m0, m4, m6 + PAVGB_MMX [r0+r2 + %%i], m1, m5, m6 + PAVGB_MMX [r0+r2*2 + %%i], m2, m4, m6 + PAVGB_MMX [r0+r4 + %%i], m3, m5, m6 +%else + pavgb m0, [r0 + %%i] + pavgb m1, [r0+r2 + %%i] + pavgb m2, [r0+r2*2 + %%i] + pavgb m3, [r0+r4 + %%i] +%endif +%endif + SAVE [r0 + %%i], m0 + SAVE [r0+r2 + %%i], m1 + SAVE [r0+r2*2 + %%i], m2 + SAVE [r0+r4 + %%i], m3 +%assign %%i %%i+mmsize +%endrep + sub r3d, 4 + lea r1, [r1+r2*4] + lea r0, [r0+r2*4] + jne .loop + RET +%endmacro + +INIT_MMX mmx +OP_PIXELS put, 4 +OP_PIXELS avg, 4 +OP_PIXELS put, 8 +OP_PIXELS avg, 8 +OP_PIXELS put, 16 +OP_PIXELS avg, 16 + +INIT_MMX mmxext +OP_PIXELS avg, 4 +OP_PIXELS avg, 8 +OP_PIXELS avg, 16 + +INIT_XMM sse2 +OP_PIXELS put, 16 +OP_PIXELS avg, 16 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fpel.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fpel.h new file mode 100644 index 00000000..4e83cf71 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/fpel.h @@ -0,0 +1,49 @@ +/* + * 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 + */ + +#ifndef AVCODEC_X86_FPEL_H +#define AVCODEC_X86_FPEL_H + +#include +#include + +void ff_avg_pixels4_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels4_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels4_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + + +#endif /* AVCODEC_X86_FPEL_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/g722dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/g722dsp.asm new file mode 100644 index 00000000..a5294222 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/g722dsp.asm @@ -0,0 +1,54 @@ +;****************************************************************************** +;* SIMD optimized DSP functions for G722 coding +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pw_qmf_coeffs: dw 3, -210, -11, -805, -11, 951, 53, 3876 +pw_qmf_coeffs2: dw 12, 3876, -156, 951, 32, -805, 362, -210 +pw_qmf_coeffs3: dw 362, 0 , 32, 0, -156, 0, 12, 0 +pw_qmf_coeffs4: dw 53, 0, -11, 0, -11, 0, 3, 0 + +SECTION .text + +INIT_XMM sse2 +cglobal g722_apply_qmf, 2, 2, 5, prev, out + movu m0, [prevq+mmsize*0] + movu m1, [prevq+mmsize*1] + movu m2, [prevq+mmsize*2] + punpcklwd m3, m0, m1 + punpckhwd m0, m1 + punpcklwd m4, m2, m2 + punpckhwd m2, m2 + pmaddwd m3, [pw_qmf_coeffs ] + pmaddwd m0, [pw_qmf_coeffs2] + pmaddwd m4, [pw_qmf_coeffs3] + pmaddwd m2, [pw_qmf_coeffs4] + paddd m0, m3 + paddd m2, m4 + paddd m0, m2 + pshufd m2, m0, q0032 + paddd m0, m2 + pshufd m0, m0, q0001 + movq [outq], m0 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/g722dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/g722dsp_init.c new file mode 100644 index 00000000..61469519 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/g722dsp_init.c @@ -0,0 +1,35 @@ +/* + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/g722dsp.h" + +void ff_g722_apply_qmf_sse2(const int16_t *prev_samples, int xout[2]); + +av_cold void ff_g722dsp_init_x86(G722DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) + dsp->apply_qmf = ff_g722_apply_qmf_sse2; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h263_loopfilter.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h263_loopfilter.asm new file mode 100644 index 00000000..77c8cf15 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h263_loopfilter.asm @@ -0,0 +1,189 @@ +;****************************************************************************** +;* MMX-optimized H.263 loop filter +;* Copyright (c) 2003-2013 Michael Niedermayer +;* Copyright (c) 2013 Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +cextern pb_FC +cextern h263_loop_filter_strength + +SECTION .text + +%macro H263_LOOP_FILTER 5 + pxor m7, m7 + mova m0, [%1] + mova m1, [%1] + mova m2, [%4] + mova m3, [%4] + punpcklbw m0, m7 + punpckhbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + psubw m0, m2 + psubw m1, m3 + mova m2, [%2] + mova m3, [%2] + mova m4, [%3] + mova m5, [%3] + punpcklbw m2, m7 + punpckhbw m3, m7 + punpcklbw m4, m7 + punpckhbw m5, m7 + psubw m4, m2 + psubw m5, m3 + psllw m4, 2 + psllw m5, 2 + paddw m4, m0 + paddw m5, m1 + pxor m6, m6 + pcmpgtw m6, m4 + pcmpgtw m7, m5 + pxor m4, m6 + pxor m5, m7 + psubw m4, m6 + psubw m5, m7 + psrlw m4, 3 + psrlw m5, 3 + packuswb m4, m5 + packsswb m6, m7 + pxor m7, m7 + movd m2, %5 + punpcklbw m2, m2 + punpcklbw m2, m2 + punpcklbw m2, m2 + psubusb m2, m4 + mova m3, m2 + psubusb m3, m4 + psubb m2, m3 + mova m3, [%2] + mova m4, [%3] + pxor m3, m6 + pxor m4, m6 + paddusb m3, m2 + psubusb m4, m2 + pxor m3, m6 + pxor m4, m6 + paddusb m2, m2 + packsswb m0, m1 + pcmpgtb m7, m0 + pxor m0, m7 + psubb m0, m7 + mova m1, m0 + psubusb m0, m2 + psubb m1, m0 + pand m1, [pb_FC] + psrlw m1, 2 + pxor m1, m7 + psubb m1, m7 + mova m5, [%1] + mova m6, [%4] + psubb m5, m1 + paddb m6, m1 +%endmacro + +INIT_MMX mmx +; void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale) +cglobal h263_v_loop_filter, 3,5 + movsxdifnidn r1, r1d + movsxdifnidn r2, r2d + + lea r4, [h263_loop_filter_strength] + movzx r3d, BYTE [r4+r2] + movsx r2, r3b + shl r2, 1 + + mov r3, r0 + sub r3, r1 + mov r4, r3 + sub r4, r1 + H263_LOOP_FILTER r4, r3, r0, r0+r1, r2d + + mova [r3], m3 + mova [r0], m4 + mova [r4], m5 + mova [r0+r1], m6 + RET + +%macro TRANSPOSE4X4 2 + movd m0, [%1] + movd m1, [%1+r1] + movd m2, [%1+r1*2] + movd m3, [%1+r3] + punpcklbw m0, m1 + punpcklbw m2, m3 + mova m1, m0 + punpcklwd m0, m2 + punpckhwd m1, m2 + movd [%2+ 0], m0 + punpckhdq m0, m0 + movd [%2+ 8], m0 + movd [%2+16], m1 + punpckhdq m1, m1 + movd [%2+24], m1 +%endmacro + + +; void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale) +INIT_MMX mmx +cglobal h263_h_loop_filter, 3,5,0,32 + movsxdifnidn r1, r1d + movsxdifnidn r2, r2d + + lea r4, [h263_loop_filter_strength] + movzx r3d, BYTE [r4+r2] + movsx r2, r3b + shl r2, 1 + + sub r0, 2 + lea r3, [r1*3] + + TRANSPOSE4X4 r0, rsp + lea r4, [r0+r1*4] + TRANSPOSE4X4 r4, rsp+4 + + H263_LOOP_FILTER rsp, rsp+8, rsp+16, rsp+24, r2d + + mova m1, m5 + mova m0, m4 + punpcklbw m5, m3 + punpcklbw m4, m6 + punpckhbw m1, m3 + punpckhbw m0, m6 + mova m3, m5 + mova m6, m1 + punpcklwd m5, m4 + punpcklwd m1, m0 + punpckhwd m3, m4 + punpckhwd m6, m0 + movd [r0], m5 + punpckhdq m5, m5 + movd [r0+r1*1], m5 + movd [r0+r1*2], m3 + punpckhdq m3, m3 + movd [r0+r3], m3 + movd [r4], m1 + punpckhdq m1, m1 + movd [r4+r1*1], m1 + movd [r4+r1*2], m6 + punpckhdq m6, m6 + movd [r4+r3], m6 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h263dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h263dsp_init.c new file mode 100644 index 00000000..ab810632 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h263dsp_init.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2013 Diego Biurrun + * + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h263dsp.h" + +void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale); +void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale); + +av_cold void ff_h263dsp_init_x86(H263DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx; + c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_cabac.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_cabac.c new file mode 100644 index 00000000..2edc6d7e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_cabac.c @@ -0,0 +1,208 @@ +/* + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder + * Copyright (c) 2003 Michael Niedermayer + * + * 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 + */ + +/** + * @file + * H.264 / AVC / MPEG-4 part10 codec. + * non-SIMD x86-specific optimizations for H.264 + * @author Michael Niedermayer + */ + +#include + +#include "libavcodec/cabac.h" +#include "cabac.h" + +#if HAVE_INLINE_ASM + +#if ARCH_X86_64 +#define REG64 "r" +#else +#define REG64 "m" +#endif + +//FIXME use some macros to avoid duplicating get_cabac (cannot be done yet +//as that would make optimization work hard) +#if HAVE_7REGS && !BROKEN_COMPILER +#define decode_significance decode_significance_x86 +static int decode_significance_x86(CABACContext *c, int max_coeff, + uint8_t *significant_coeff_ctx_base, + int *index, x86_reg last_off){ + void *end= significant_coeff_ctx_base + max_coeff - 1; + int minusstart= -(intptr_t)significant_coeff_ctx_base; + int minusindex= 4-(intptr_t)index; + int bit; + x86_reg coeff_count; + +#ifdef BROKEN_RELOCATIONS + void *tables; + + __asm__ volatile( + "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" + : "=&r"(tables) + : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) + ); +#endif + + __asm__ volatile( + "3: \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c11(%6)", "%c12(%6)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%13") + + "test $1, %4 \n\t" + " jz 4f \n\t" + "add %10, %1 \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%1)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c11(%6)", "%c12(%6)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%13") + + "sub %10, %1 \n\t" + "mov %2, %0 \n\t" + "movl %7, %%ecx \n\t" + "add %1, %%"FF_REG_c" \n\t" + "movl %%ecx, (%0) \n\t" + + "test $1, %4 \n\t" + " jnz 5f \n\t" + + "add"FF_OPSIZE" $4, %2 \n\t" + + "4: \n\t" + "add $1, %1 \n\t" + "cmp %8, %1 \n\t" + " jb 3b \n\t" + "mov %2, %0 \n\t" + "movl %7, %%ecx \n\t" + "add %1, %%"FF_REG_c" \n\t" + "movl %%ecx, (%0) \n\t" + "5: \n\t" + "add %9, %k0 \n\t" + "shr $2, %k0 \n\t" + : "=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), + "+&r"(c->low), "=&r"(bit), "+&r"(c->range) + : "r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)) + TABLES_ARG + : "%"FF_REG_c, "memory" + ); + return coeff_count; +} + +#define decode_significance_8x8 decode_significance_8x8_x86 +static int decode_significance_8x8_x86(CABACContext *c, + uint8_t *significant_coeff_ctx_base, + int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){ + int minusindex= 4-(intptr_t)index; + int bit; + x86_reg coeff_count; + x86_reg last=0; + x86_reg state; + +#ifdef BROKEN_RELOCATIONS + void *tables; + + __asm__ volatile( + "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t" + : "=&r"(tables) + : NAMED_CONSTRAINTS_ARRAY(ff_h264_cabac_tables) + ); +#endif + + __asm__ volatile( + "mov %1, %6 \n\t" + "3: \n\t" + + "mov %10, %0 \n\t" + "movzb (%0, %6), %6 \n\t" + "add %9, %6 \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c12(%7)", "%c13(%7)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%15") + + "mov %1, %6 \n\t" + "test $1, %4 \n\t" + " jz 4f \n\t" + +#ifdef BROKEN_RELOCATIONS + "movzb %c14(%15, %q6), %6\n\t" +#else + "movzb "MANGLE(ff_h264_cabac_tables)"+%c14(%6), %6\n\t" +#endif + "add %11, %6 \n\t" + + BRANCHLESS_GET_CABAC("%4", "%q4", "(%6)", "%3", "%w3", + "%5", "%q5", "%k0", "%b0", + "%c12(%7)", "%c13(%7)", + AV_STRINGIFY(H264_NORM_SHIFT_OFFSET), + AV_STRINGIFY(H264_LPS_RANGE_OFFSET), + AV_STRINGIFY(H264_MLPS_STATE_OFFSET), + "%15") + + "mov %2, %0 \n\t" + "mov %1, %6 \n\t" + "mov %k6, (%0) \n\t" + + "test $1, %4 \n\t" + " jnz 5f \n\t" + + "add"FF_OPSIZE" $4, %2 \n\t" + + "4: \n\t" + "add $1, %6 \n\t" + "mov %6, %1 \n\t" + "cmp $63, %6 \n\t" + " jb 3b \n\t" + "mov %2, %0 \n\t" + "mov %k6, (%0) \n\t" + "5: \n\t" + "addl %8, %k0 \n\t" + "shr $2, %k0 \n\t" + : "=&q"(coeff_count), "+"REG64(last), "+"REG64(index), "+&r"(c->low), + "=&r"(bit), "+&r"(c->range), "=&r"(state) + : "r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), + REG64(sig_off), REG64(last_coeff_ctx_base), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, bytestream_end)), + "i"(H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET) TABLES_ARG + : "%"FF_REG_c, "memory" + ); + return coeff_count; +} +#endif /* HAVE_7REGS && BROKEN_COMPILER */ + +#endif /* HAVE_INLINE_ASM */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_chromamc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_chromamc.asm new file mode 100644 index 00000000..b5a78b53 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_chromamc.asm @@ -0,0 +1,663 @@ +;****************************************************************************** +;* MMX/SSSE3-optimized functions for H.264 chroma MC +;* Copyright (c) 2005 Zoltan Hidvegi , +;* 2005-2008 Loren Merritt +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +rnd_rv40_2d_tbl: times 4 dw 0 + times 4 dw 16 + times 4 dw 32 + times 4 dw 16 + times 4 dw 32 + times 4 dw 28 + times 4 dw 32 + times 4 dw 28 + times 4 dw 0 + times 4 dw 32 + times 4 dw 16 + times 4 dw 32 + times 4 dw 32 + times 4 dw 28 + times 4 dw 32 + times 4 dw 28 +rnd_rv40_1d_tbl: times 4 dw 0 + times 4 dw 2 + times 4 dw 4 + times 4 dw 2 + times 4 dw 4 + times 4 dw 3 + times 4 dw 4 + times 4 dw 3 + times 4 dw 0 + times 4 dw 4 + times 4 dw 2 + times 4 dw 4 + times 4 dw 4 + times 4 dw 3 + times 4 dw 4 + times 4 dw 3 + +cextern pw_3 +cextern pw_4 +cextern pw_8 +pw_28: times 8 dw 28 +cextern pw_32 +cextern pw_64 + +SECTION .text + +%macro mv0_pixels_mc8 0 + lea r4, [r2*2 ] +.next4rows: + movq mm0, [r1 ] + movq mm1, [r1+r2] + add r1, r4 + CHROMAMC_AVG mm0, [r0 ] + CHROMAMC_AVG mm1, [r0+r2] + movq [r0 ], mm0 + movq [r0+r2], mm1 + add r0, r4 + movq mm0, [r1 ] + movq mm1, [r1+r2] + add r1, r4 + CHROMAMC_AVG mm0, [r0 ] + CHROMAMC_AVG mm1, [r0+r2] + movq [r0 ], mm0 + movq [r0+r2], mm1 + add r0, r4 + sub r3d, 4 + jne .next4rows +%endmacro + +%macro chroma_mc8_mmx_func 2-3 +%ifidn %2, rv40 +%ifdef PIC +%define rnd_1d_rv40 r8 +%define rnd_2d_rv40 r8 +%define extra_regs 2 +%else ; no-PIC +%define rnd_1d_rv40 rnd_rv40_1d_tbl +%define rnd_2d_rv40 rnd_rv40_2d_tbl +%define extra_regs 1 +%endif ; PIC +%else +%define extra_regs 0 +%endif ; rv40 +; void ff_put/avg_h264_chroma_mc8_*(uint8_t *dst /* align 8 */, +; uint8_t *src /* align 1 */, +; ptrdiff_t stride, int h, int mx, int my) +cglobal %1_%2_chroma_mc8%3, 6, 7 + extra_regs, 0 + mov r6d, r5d + or r6d, r4d + jne .at_least_one_non_zero + ; mx == 0 AND my == 0 - no filter needed + mv0_pixels_mc8 + REP_RET + +.at_least_one_non_zero: +%ifidn %2, rv40 +%if ARCH_X86_64 + mov r7, r5 + and r7, 6 ; &~1 for mx/my=[0,7] + lea r7, [r7*4+r4] + sar r7d, 1 +%define rnd_bias r7 +%define dest_reg r0 +%else ; x86-32 + mov r0, r5 + and r0, 6 ; &~1 for mx/my=[0,7] + lea r0, [r0*4+r4] + sar r0d, 1 +%define rnd_bias r0 +%define dest_reg r5 +%endif +%else ; vc1, h264 +%define rnd_bias 0 +%define dest_reg r0 +%endif + + test r5d, r5d + mov r6, 1 + je .my_is_zero + test r4d, r4d + mov r6, r2 ; dxy = x ? 1 : stride + jne .both_non_zero +.my_is_zero: + ; mx == 0 XOR my == 0 - 1 dimensional filter only + or r4d, r5d ; x + y + +%ifidn %2, rv40 +%ifdef PIC + lea r8, [rnd_rv40_1d_tbl] +%endif +%if ARCH_X86_64 == 0 + mov r5, r0m +%endif +%endif + + movd m5, r4d + movq m4, [pw_8] + movq m6, [rnd_1d_%2+rnd_bias*8] ; mm6 = rnd >> 3 + punpcklwd m5, m5 + punpckldq m5, m5 ; mm5 = B = x + pxor m7, m7 + psubw m4, m5 ; mm4 = A = 8-x + +.next1drow: + movq m0, [r1 ] ; mm0 = src[0..7] + movq m2, [r1+r6] ; mm1 = src[1..8] + + movq m1, m0 + movq m3, m2 + punpcklbw m0, m7 + punpckhbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + pmullw m0, m4 ; [mm0,mm1] = A * src[0..7] + pmullw m1, m4 + pmullw m2, m5 ; [mm2,mm3] = B * src[1..8] + pmullw m3, m5 + + paddw m0, m6 + paddw m1, m6 + paddw m0, m2 + paddw m1, m3 + psrlw m0, 3 + psrlw m1, 3 + packuswb m0, m1 + CHROMAMC_AVG m0, [dest_reg] + movq [dest_reg], m0 ; dst[0..7] = (A * src[0..7] + B * src[1..8] + (rnd >> 3)) >> 3 + + add dest_reg, r2 + add r1, r2 + dec r3d + jne .next1drow + REP_RET + +.both_non_zero: ; general case, bilinear + movd m4, r4d ; x + movd m6, r5d ; y +%ifidn %2, rv40 +%ifdef PIC + lea r8, [rnd_rv40_2d_tbl] +%endif +%if ARCH_X86_64 == 0 + mov r5, r0m +%endif +%endif + mov r6, rsp ; backup stack pointer + and rsp, ~(mmsize-1) ; align stack + sub rsp, 16 ; AA and DD + + punpcklwd m4, m4 + punpcklwd m6, m6 + punpckldq m4, m4 ; mm4 = x words + punpckldq m6, m6 ; mm6 = y words + movq m5, m4 + pmullw m4, m6 ; mm4 = x * y + psllw m5, 3 + psllw m6, 3 + movq m7, m5 + paddw m7, m6 + movq [rsp+8], m4 ; DD = x * y + psubw m5, m4 ; mm5 = B = 8x - xy + psubw m6, m4 ; mm6 = C = 8y - xy + paddw m4, [pw_64] + psubw m4, m7 ; mm4 = A = xy - (8x+8y) + 64 + pxor m7, m7 + movq [rsp ], m4 + + movq m0, [r1 ] ; mm0 = src[0..7] + movq m1, [r1+1] ; mm1 = src[1..8] +.next2drow: + add r1, r2 + + movq m2, m0 + movq m3, m1 + punpckhbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + pmullw m0, [rsp] + pmullw m2, [rsp] + pmullw m1, m5 + pmullw m3, m5 + paddw m2, m1 ; mm2 = A * src[0..3] + B * src[1..4] + paddw m3, m0 ; mm3 = A * src[4..7] + B * src[5..8] + + movq m0, [r1] + movq m1, m0 + punpcklbw m0, m7 + punpckhbw m1, m7 + pmullw m0, m6 + pmullw m1, m6 + paddw m2, m0 + paddw m3, m1 ; [mm2,mm3] += C * src[0..7] + + movq m1, [r1+1] + movq m0, m1 + movq m4, m1 + punpcklbw m0, m7 + punpckhbw m4, m7 + pmullw m0, [rsp+8] + pmullw m4, [rsp+8] + paddw m2, m0 + paddw m3, m4 ; [mm2,mm3] += D * src[1..8] + movq m0, [r1] + + paddw m2, [rnd_2d_%2+rnd_bias*8] + paddw m3, [rnd_2d_%2+rnd_bias*8] + psrlw m2, 6 + psrlw m3, 6 + packuswb m2, m3 + CHROMAMC_AVG m2, [dest_reg] + movq [dest_reg], m2 ; dst[0..7] = ([mm2,mm3] + rnd) >> 6 + + add dest_reg, r2 + dec r3d + jne .next2drow + mov rsp, r6 ; restore stack pointer + RET +%endmacro + +%macro chroma_mc4_mmx_func 2 +%define extra_regs 0 +%ifidn %2, rv40 +%ifdef PIC +%define extra_regs 1 +%endif ; PIC +%endif ; rv40 +cglobal %1_%2_chroma_mc4, 6, 6 + extra_regs, 0 + pxor m7, m7 + movd m2, r4d ; x + movd m3, r5d ; y + movq m4, [pw_8] + movq m5, [pw_8] + punpcklwd m2, m2 + punpcklwd m3, m3 + punpcklwd m2, m2 + punpcklwd m3, m3 + psubw m4, m2 + psubw m5, m3 + +%ifidn %2, rv40 +%ifdef PIC + lea r6, [rnd_rv40_2d_tbl] +%define rnd_2d_rv40 r6 +%else +%define rnd_2d_rv40 rnd_rv40_2d_tbl +%endif + and r5, 6 ; &~1 for mx/my=[0,7] + lea r5, [r5*4+r4] + sar r5d, 1 +%define rnd_bias r5 +%else ; vc1, h264 +%define rnd_bias 0 +%endif + + movd m0, [r1 ] + movd m6, [r1+1] + add r1, r2 + punpcklbw m0, m7 + punpcklbw m6, m7 + pmullw m0, m4 + pmullw m6, m2 + paddw m6, m0 + +.next2rows: + movd m0, [r1 ] + movd m1, [r1+1] + add r1, r2 + punpcklbw m0, m7 + punpcklbw m1, m7 + pmullw m0, m4 + pmullw m1, m2 + paddw m1, m0 + movq m0, m1 + + pmullw m6, m5 + pmullw m1, m3 + paddw m6, [rnd_2d_%2+rnd_bias*8] + paddw m1, m6 + psrlw m1, 6 + packuswb m1, m1 + CHROMAMC_AVG4 m1, m6, [r0] + movd [r0], m1 + add r0, r2 + + movd m6, [r1 ] + movd m1, [r1+1] + add r1, r2 + punpcklbw m6, m7 + punpcklbw m1, m7 + pmullw m6, m4 + pmullw m1, m2 + paddw m1, m6 + movq m6, m1 + pmullw m0, m5 + pmullw m1, m3 + paddw m0, [rnd_2d_%2+rnd_bias*8] + paddw m1, m0 + psrlw m1, 6 + packuswb m1, m1 + CHROMAMC_AVG4 m1, m0, [r0] + movd [r0], m1 + add r0, r2 + sub r3d, 2 + jnz .next2rows + REP_RET +%endmacro + +%macro chroma_mc2_mmx_func 2 +cglobal %1_%2_chroma_mc2, 6, 7, 0 + mov r6d, r4d + shl r4d, 16 + sub r4d, r6d + add r4d, 8 + imul r5d, r4d ; x*y<<16 | y*(8-x) + shl r4d, 3 + sub r4d, r5d ; x*(8-y)<<16 | (8-x)*(8-y) + + movd m5, r4d + movd m6, r5d + punpckldq m5, m5 ; mm5 = {A,B,A,B} + punpckldq m6, m6 ; mm6 = {C,D,C,D} + pxor m7, m7 + movd m2, [r1] + punpcklbw m2, m7 + pshufw m2, m2, 0x94 ; mm0 = src[0,1,1,2] + +.nextrow: + add r1, r2 + movq m1, m2 + pmaddwd m1, m5 ; mm1 = A * src[0,1] + B * src[1,2] + movd m0, [r1] + punpcklbw m0, m7 + pshufw m0, m0, 0x94 ; mm0 = src[0,1,1,2] + movq m2, m0 + pmaddwd m0, m6 + paddw m1, [rnd_2d_%2] + paddw m1, m0 ; mm1 += C * src[0,1] + D * src[1,2] + psrlw m1, 6 + packssdw m1, m7 + packuswb m1, m7 + CHROMAMC_AVG4 m1, m3, [r0] + movd r5d, m1 + mov [r0], r5w + add r0, r2 + sub r3d, 1 + jnz .nextrow + REP_RET +%endmacro + +%define rnd_1d_h264 pw_4 +%define rnd_2d_h264 pw_32 +%define rnd_1d_vc1 pw_3 +%define rnd_2d_vc1 pw_28 + +%macro NOTHING 2-3 +%endmacro +%macro DIRECT_AVG 2 + PAVGB %1, %2 +%endmacro +%macro COPY_AVG 3 + movd %2, %3 + PAVGB %1, %2 +%endmacro + +INIT_MMX mmx +%define CHROMAMC_AVG NOTHING +%define CHROMAMC_AVG4 NOTHING +chroma_mc8_mmx_func put, h264, _rnd +chroma_mc8_mmx_func put, vc1, _nornd +chroma_mc8_mmx_func put, rv40 +chroma_mc4_mmx_func put, h264 +chroma_mc4_mmx_func put, rv40 + +INIT_MMX mmxext +chroma_mc2_mmx_func put, h264 + +%define CHROMAMC_AVG DIRECT_AVG +%define CHROMAMC_AVG4 COPY_AVG +chroma_mc8_mmx_func avg, h264, _rnd +chroma_mc8_mmx_func avg, vc1, _nornd +chroma_mc8_mmx_func avg, rv40 +chroma_mc4_mmx_func avg, h264 +chroma_mc4_mmx_func avg, rv40 +chroma_mc2_mmx_func avg, h264 + +INIT_MMX 3dnow +chroma_mc8_mmx_func avg, h264, _rnd +chroma_mc8_mmx_func avg, vc1, _nornd +chroma_mc8_mmx_func avg, rv40 +chroma_mc4_mmx_func avg, h264 +chroma_mc4_mmx_func avg, rv40 + +%macro chroma_mc8_ssse3_func 2-3 +cglobal %1_%2_chroma_mc8%3, 6, 7, 8 + mov r6d, r5d + or r6d, r4d + jne .at_least_one_non_zero + ; mx == 0 AND my == 0 - no filter needed + mv0_pixels_mc8 + REP_RET + +.at_least_one_non_zero: + test r5d, r5d + je .my_is_zero + test r4d, r4d + je .mx_is_zero + + ; general case, bilinear + mov r6d, r4d + shl r4d, 8 + sub r4, r6 + mov r6, 8 + add r4, 8 ; x*288+8 = x<<8 | (8-x) + sub r6d, r5d + imul r6, r4 ; (8-y)*(x*255+8) = (8-y)*x<<8 | (8-y)*(8-x) + imul r4d, r5d ; y *(x*255+8) = y *x<<8 | y *(8-x) + + movd m7, r6d + movd m6, r4d + movdqa m5, [rnd_2d_%2] + movq m0, [r1 ] + movq m1, [r1+1] + pshuflw m7, m7, 0 + pshuflw m6, m6, 0 + punpcklbw m0, m1 + movlhps m7, m7 + movlhps m6, m6 + +.next2rows: + movq m1, [r1+r2*1 ] + movq m2, [r1+r2*1+1] + movq m3, [r1+r2*2 ] + movq m4, [r1+r2*2+1] + lea r1, [r1+r2*2] + punpcklbw m1, m2 + movdqa m2, m1 + punpcklbw m3, m4 + movdqa m4, m3 + pmaddubsw m0, m7 + pmaddubsw m1, m6 + pmaddubsw m2, m7 + pmaddubsw m3, m6 + paddw m0, m5 + paddw m2, m5 + paddw m1, m0 + paddw m3, m2 + psrlw m1, 6 + movdqa m0, m4 + psrlw m3, 6 +%ifidn %1, avg + movq m2, [r0 ] + movhps m2, [r0+r2] +%endif + packuswb m1, m3 + CHROMAMC_AVG m1, m2 + movq [r0 ], m1 + movhps [r0+r2], m1 + sub r3d, 2 + lea r0, [r0+r2*2] + jg .next2rows + REP_RET + +.my_is_zero: + mov r5d, r4d + shl r4d, 8 + add r4, 8 + sub r4, r5 ; 255*x+8 = x<<8 | (8-x) + movd m7, r4d + movdqa m6, [rnd_1d_%2] + pshuflw m7, m7, 0 + movlhps m7, m7 + +.next2xrows: + movq m0, [r1 ] + movq m1, [r1 +1] + movq m2, [r1+r2 ] + movq m3, [r1+r2+1] + punpcklbw m0, m1 + punpcklbw m2, m3 + pmaddubsw m0, m7 + pmaddubsw m2, m7 +%ifidn %1, avg + movq m4, [r0 ] + movhps m4, [r0+r2] +%endif + paddw m0, m6 + paddw m2, m6 + psrlw m0, 3 + psrlw m2, 3 + packuswb m0, m2 + CHROMAMC_AVG m0, m4 + movq [r0 ], m0 + movhps [r0+r2], m0 + sub r3d, 2 + lea r0, [r0+r2*2] + lea r1, [r1+r2*2] + jg .next2xrows + REP_RET + +.mx_is_zero: + mov r4d, r5d + shl r5d, 8 + add r5, 8 + sub r5, r4 ; 255*y+8 = y<<8 | (8-y) + movd m7, r5d + movdqa m6, [rnd_1d_%2] + pshuflw m7, m7, 0 + movlhps m7, m7 + +.next2yrows: + movq m0, [r1 ] + movq m1, [r1+r2 ] + movdqa m2, m1 + movq m3, [r1+r2*2] + lea r1, [r1+r2*2] + punpcklbw m0, m1 + punpcklbw m2, m3 + pmaddubsw m0, m7 + pmaddubsw m2, m7 +%ifidn %1, avg + movq m4, [r0 ] + movhps m4, [r0+r2] +%endif + paddw m0, m6 + paddw m2, m6 + psrlw m0, 3 + psrlw m2, 3 + packuswb m0, m2 + CHROMAMC_AVG m0, m4 + movq [r0 ], m0 + movhps [r0+r2], m0 + sub r3d, 2 + lea r0, [r0+r2*2] + jg .next2yrows + REP_RET +%endmacro + +%macro chroma_mc4_ssse3_func 2 +cglobal %1_%2_chroma_mc4, 6, 7, 0 + mov r6, r4 + shl r4d, 8 + sub r4d, r6d + mov r6, 8 + add r4d, 8 ; x*288+8 + sub r6d, r5d + imul r6d, r4d ; (8-y)*(x*255+8) = (8-y)*x<<8 | (8-y)*(8-x) + imul r4d, r5d ; y *(x*255+8) = y *x<<8 | y *(8-x) + + movd m7, r6d + movd m6, r4d + movq m5, [pw_32] + movd m0, [r1 ] + pshufw m7, m7, 0 + punpcklbw m0, [r1+1] + pshufw m6, m6, 0 + +.next2rows: + movd m1, [r1+r2*1 ] + movd m3, [r1+r2*2 ] + punpcklbw m1, [r1+r2*1+1] + punpcklbw m3, [r1+r2*2+1] + lea r1, [r1+r2*2] + movq m2, m1 + movq m4, m3 + pmaddubsw m0, m7 + pmaddubsw m1, m6 + pmaddubsw m2, m7 + pmaddubsw m3, m6 + paddw m0, m5 + paddw m2, m5 + paddw m1, m0 + paddw m3, m2 + psrlw m1, 6 + movq m0, m4 + psrlw m3, 6 + packuswb m1, m1 + packuswb m3, m3 + CHROMAMC_AVG m1, [r0 ] + CHROMAMC_AVG m3, [r0+r2] + movd [r0 ], m1 + movd [r0+r2], m3 + sub r3d, 2 + lea r0, [r0+r2*2] + jg .next2rows + REP_RET +%endmacro + +%define CHROMAMC_AVG NOTHING +INIT_XMM ssse3 +chroma_mc8_ssse3_func put, h264, _rnd +chroma_mc8_ssse3_func put, vc1, _nornd +INIT_MMX ssse3 +chroma_mc4_ssse3_func put, h264 + +%define CHROMAMC_AVG DIRECT_AVG +INIT_XMM ssse3 +chroma_mc8_ssse3_func avg, h264, _rnd +chroma_mc8_ssse3_func avg, vc1, _nornd +INIT_MMX ssse3 +chroma_mc4_ssse3_func avg, h264 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_chromamc_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_chromamc_10bit.asm new file mode 100644 index 00000000..34bc4196 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_chromamc_10bit.asm @@ -0,0 +1,269 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 chroma MC code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pw_4 +cextern pw_8 +cextern pw_32 +cextern pw_64 + +SECTION .text + + +%macro MV0_PIXELS_MC8 0 + lea r4, [r2*3 ] + lea r5, [r2*4 ] +.next4rows: + movu m0, [r1 ] + movu m1, [r1+r2 ] + CHROMAMC_AVG m0, [r0 ] + CHROMAMC_AVG m1, [r0+r2 ] + mova [r0 ], m0 + mova [r0+r2 ], m1 + movu m0, [r1+r2*2] + movu m1, [r1+r4 ] + CHROMAMC_AVG m0, [r0+r2*2] + CHROMAMC_AVG m1, [r0+r4 ] + mova [r0+r2*2], m0 + mova [r0+r4 ], m1 + add r1, r5 + add r0, r5 + sub r3d, 4 + jne .next4rows +%endmacro + +;----------------------------------------------------------------------------- +; void ff_put/avg_h264_chroma_mc8(pixel *dst, pixel *src, ptrdiff_t stride, +; int h, int mx, int my) +;----------------------------------------------------------------------------- +%macro CHROMA_MC8 1 +cglobal %1_h264_chroma_mc8_10, 6,7,8 + mov r6d, r5d + or r6d, r4d + jne .at_least_one_non_zero + ; mx == 0 AND my == 0 - no filter needed + MV0_PIXELS_MC8 + REP_RET + +.at_least_one_non_zero: + mov r6d, 2 + test r5d, r5d + je .x_interpolation + mov r6, r2 ; dxy = x ? 1 : stride + test r4d, r4d + jne .xy_interpolation +.x_interpolation: + ; mx == 0 XOR my == 0 - 1 dimensional filter only + or r4d, r5d ; x + y + movd m5, r4d + mova m4, [pw_8] + mova m6, [pw_4] ; mm6 = rnd >> 3 + SPLATW m5, m5 ; mm5 = B = x + psubw m4, m5 ; mm4 = A = 8-x + +.next1drow: + movu m0, [r1 ] ; mm0 = src[0..7] + movu m2, [r1+r6] ; mm2 = src[1..8] + + pmullw m0, m4 ; mm0 = A * src[0..7] + pmullw m2, m5 ; mm2 = B * src[1..8] + + paddw m0, m6 + paddw m0, m2 + psrlw m0, 3 + CHROMAMC_AVG m0, [r0] + mova [r0], m0 ; dst[0..7] = (A * src[0..7] + B * src[1..8] + (rnd >> 3)) >> 3 + + add r0, r2 + add r1, r2 + dec r3d + jne .next1drow + REP_RET + +.xy_interpolation: ; general case, bilinear + movd m4, r4m ; x + movd m6, r5m ; y + + SPLATW m4, m4 ; mm4 = x words + SPLATW m6, m6 ; mm6 = y words + psllw m5, m4, 3 ; mm5 = 8x + pmullw m4, m6 ; mm4 = x * y + psllw m6, 3 ; mm6 = 8y + paddw m1, m5, m6 ; mm7 = 8x+8y + mova m7, m4 ; DD = x * y + psubw m5, m4 ; mm5 = B = 8x - xy + psubw m6, m4 ; mm6 = C = 8y - xy + paddw m4, [pw_64] + psubw m4, m1 ; mm4 = A = xy - (8x+8y) + 64 + + movu m0, [r1 ] ; mm0 = src[0..7] + movu m1, [r1+2] ; mm1 = src[1..8] +.next2drow: + add r1, r2 + + pmullw m2, m0, m4 + pmullw m1, m5 + paddw m2, m1 ; mm2 = A * src[0..7] + B * src[1..8] + + movu m0, [r1] + movu m1, [r1+2] + pmullw m3, m0, m6 + paddw m2, m3 ; mm2 += C * src[0..7+strde] + pmullw m3, m1, m7 + paddw m2, m3 ; mm2 += D * src[1..8+strde] + + paddw m2, [pw_32] + psrlw m2, 6 + CHROMAMC_AVG m2, [r0] + mova [r0], m2 ; dst[0..7] = (mm2 + 32) >> 6 + + add r0, r2 + dec r3d + jne .next2drow + REP_RET +%endmacro + +;----------------------------------------------------------------------------- +; void ff_put/avg_h264_chroma_mc4(pixel *dst, pixel *src, ptrdiff_t stride, +; int h, int mx, int my) +;----------------------------------------------------------------------------- +;TODO: xmm mc4 +%macro MC4_OP 2 + movq %1, [r1 ] + movq m1, [r1+2] + add r1, r2 + pmullw %1, m4 + pmullw m1, m2 + paddw m1, %1 + mova %1, m1 + + pmullw %2, m5 + pmullw m1, m3 + paddw %2, [pw_32] + paddw m1, %2 + psrlw m1, 6 + CHROMAMC_AVG m1, %2, [r0] + movq [r0], m1 + add r0, r2 +%endmacro + +%macro CHROMA_MC4 1 +cglobal %1_h264_chroma_mc4_10, 6,6,7 + movd m2, r4m ; x + movd m3, r5m ; y + mova m4, [pw_8] + mova m5, m4 + SPLATW m2, m2 + SPLATW m3, m3 + psubw m4, m2 + psubw m5, m3 + + movq m0, [r1 ] + movq m6, [r1+2] + add r1, r2 + pmullw m0, m4 + pmullw m6, m2 + paddw m6, m0 + +.next2rows: + MC4_OP m0, m6 + MC4_OP m6, m0 + sub r3d, 2 + jnz .next2rows + REP_RET +%endmacro + +;----------------------------------------------------------------------------- +; void ff_put/avg_h264_chroma_mc2(pixel *dst, pixel *src, ptrdiff_t stride, +; int h, int mx, int my) +;----------------------------------------------------------------------------- +%macro CHROMA_MC2 1 +cglobal %1_h264_chroma_mc2_10, 6,7 + mov r6d, r4d + shl r4d, 16 + sub r4d, r6d + add r4d, 8 + imul r5d, r4d ; x*y<<16 | y*(8-x) + shl r4d, 3 + sub r4d, r5d ; x*(8-y)<<16 | (8-x)*(8-y) + + movd m5, r4d + movd m6, r5d + punpckldq m5, m5 ; mm5 = {A,B,A,B} + punpckldq m6, m6 ; mm6 = {C,D,C,D} + pxor m7, m7 + pshufw m2, [r1], 0x94 ; mm0 = src[0,1,1,2] + +.nextrow: + add r1, r2 + movq m1, m2 + pmaddwd m1, m5 ; mm1 = A * src[0,1] + B * src[1,2] + pshufw m0, [r1], 0x94 ; mm0 = src[0,1,1,2] + movq m2, m0 + pmaddwd m0, m6 + paddw m1, [pw_32] + paddw m1, m0 ; mm1 += C * src[0,1] + D * src[1,2] + psrlw m1, 6 + packssdw m1, m7 + CHROMAMC_AVG m1, m3, [r0] + movd [r0], m1 + add r0, r2 + dec r3d + jnz .nextrow + REP_RET +%endmacro + +%macro NOTHING 2-3 +%endmacro +%macro AVG 2-3 +%if %0==3 + movq %2, %3 +%endif + pavgw %1, %2 +%endmacro + +%define CHROMAMC_AVG NOTHING +INIT_XMM sse2 +CHROMA_MC8 put +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +CHROMA_MC8 put +%endif +INIT_MMX mmxext +CHROMA_MC4 put +CHROMA_MC2 put + +%define CHROMAMC_AVG AVG +INIT_XMM sse2 +CHROMA_MC8 avg +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +CHROMA_MC8 avg +%endif +INIT_MMX mmxext +CHROMA_MC4 avg +CHROMA_MC2 avg diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_deblock.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_deblock.asm new file mode 100644 index 00000000..a2e745cd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_deblock.asm @@ -0,0 +1,1420 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized H.264 deblocking code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Loren Merritt +;* Fiona Glaser +;* Oskar Arvidsson +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pb_A1: times 16 db 0xA1 +pb_3_1: times 4 db 3, 1 + +SECTION .text + +cextern pb_0 +cextern pb_1 +cextern pb_3 + +%define PASS8ROWS(base, base3, stride, stride3, offset) \ + PASS8ROWS(base+offset, base3+offset, stride, stride3) + +; in: 8 rows of 4 bytes in %4..%11 +; out: 4 rows of 8 bytes in m0..m3 +%macro TRANSPOSE4x8_LOAD 11 + movh m0, %4 + movh m2, %5 + movh m1, %6 + movh m3, %7 + punpckl%1 m0, m2 + punpckl%1 m1, m3 + mova m2, m0 + punpckl%2 m0, m1 + punpckh%2 m2, m1 + + movh m4, %8 + movh m6, %9 + movh m5, %10 + movh m7, %11 + punpckl%1 m4, m6 + punpckl%1 m5, m7 + mova m6, m4 + punpckl%2 m4, m5 + punpckh%2 m6, m5 + + punpckh%3 m1, m0, m4 + punpckh%3 m3, m2, m6 + punpckl%3 m0, m4 + punpckl%3 m2, m6 +%endmacro + +; in: 4 rows of 8 bytes in m0..m3 +; out: 8 rows of 4 bytes in %1..%8 +%macro TRANSPOSE8x4B_STORE 8 + punpckhdq m4, m0, m0 + punpckhdq m5, m1, m1 + punpckhdq m6, m2, m2 + + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklwd m1, m0, m2 + punpckhwd m0, m2 + movh %1, m1 + punpckhdq m1, m1 + movh %2, m1 + movh %3, m0 + punpckhdq m0, m0 + movh %4, m0 + + punpckhdq m3, m3 + punpcklbw m4, m5 + punpcklbw m6, m3 + punpcklwd m5, m4, m6 + punpckhwd m4, m6 + movh %5, m5 + punpckhdq m5, m5 + movh %6, m5 + movh %7, m4 + punpckhdq m4, m4 + movh %8, m4 +%endmacro + +%macro TRANSPOSE4x8B_LOAD 8 + TRANSPOSE4x8_LOAD bw, wd, dq, %1, %2, %3, %4, %5, %6, %7, %8 +%endmacro + +%macro SBUTTERFLY3 4 + punpckh%1 %4, %2, %3 + punpckl%1 %2, %3 +%endmacro + +; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8 +; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16] +%macro TRANSPOSE6x8_MEM 9 + RESET_MM_PERMUTATION + movq m0, %1 + movq m1, %2 + movq m2, %3 + movq m3, %4 + movq m4, %5 + movq m5, %6 + movq m6, %7 + SBUTTERFLY bw, 0, 1, 7 + SBUTTERFLY bw, 2, 3, 7 + SBUTTERFLY bw, 4, 5, 7 + movq [%9+0x10], m3 + SBUTTERFLY3 bw, m6, %8, m7 + SBUTTERFLY wd, 0, 2, 3 + SBUTTERFLY wd, 4, 6, 3 + punpckhdq m0, m4 + movq [%9+0x00], m0 + SBUTTERFLY3 wd, m1, [%9+0x10], m3 + SBUTTERFLY wd, 5, 7, 0 + SBUTTERFLY dq, 1, 5, 0 + SBUTTERFLY dq, 2, 6, 0 + punpckldq m3, m7 + movq [%9+0x10], m2 + movq [%9+0x20], m6 + movq [%9+0x30], m1 + movq [%9+0x40], m5 + movq [%9+0x50], m3 + RESET_MM_PERMUTATION +%endmacro + +; in: 8 rows of 8 in %1..%8 +; out: 8 rows of 8 in %9..%16 +%macro TRANSPOSE8x8_MEM 16 + RESET_MM_PERMUTATION + movq m0, %1 + movq m1, %2 + movq m2, %3 + movq m3, %4 + movq m4, %5 + movq m5, %6 + movq m6, %7 + SBUTTERFLY bw, 0, 1, 7 + SBUTTERFLY bw, 2, 3, 7 + SBUTTERFLY bw, 4, 5, 7 + SBUTTERFLY3 bw, m6, %8, m7 + movq %9, m5 + SBUTTERFLY wd, 0, 2, 5 + SBUTTERFLY wd, 4, 6, 5 + SBUTTERFLY wd, 1, 3, 5 + movq %11, m6 + movq m6, %9 + SBUTTERFLY wd, 6, 7, 5 + SBUTTERFLY dq, 0, 4, 5 + SBUTTERFLY dq, 1, 6, 5 + movq %9, m0 + movq %10, m4 + movq %13, m1 + movq %14, m6 + SBUTTERFLY3 dq, m2, %11, m0 + SBUTTERFLY dq, 3, 7, 4 + movq %11, m2 + movq %12, m0 + movq %15, m3 + movq %16, m7 + RESET_MM_PERMUTATION +%endmacro + +; out: %4 = |%1-%2|>%3 +; clobbers: %5 +%macro DIFF_GT 5 +%if avx_enabled == 0 + mova %5, %2 + mova %4, %1 + psubusb %5, %1 + psubusb %4, %2 +%else + psubusb %5, %2, %1 + psubusb %4, %1, %2 +%endif + por %4, %5 + psubusb %4, %3 +%endmacro + +; out: %4 = |%1-%2|>%3 +; clobbers: %5 +%macro DIFF_GT2 5 +%if ARCH_X86_64 + psubusb %5, %2, %1 + psubusb %4, %1, %2 +%else + mova %5, %2 + mova %4, %1 + psubusb %5, %1 + psubusb %4, %2 +%endif + psubusb %5, %3 + psubusb %4, %3 + pcmpeqb %4, %5 +%endmacro + +; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1 +; out: m5=beta-1, m7=mask, %3=alpha-1 +; clobbers: m4,m6 +%macro LOAD_MASK 2-3 + movd m4, %1 + movd m5, %2 + SPLATW m4, m4 + SPLATW m5, m5 + packuswb m4, m4 ; 16x alpha-1 + packuswb m5, m5 ; 16x beta-1 +%if %0>2 + mova %3, m4 +%endif + DIFF_GT m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1 + DIFF_GT m0, m1, m5, m4, m6 ; |p1-p0| > beta-1 + por m7, m4 + DIFF_GT m3, m2, m5, m4, m6 ; |q1-q0| > beta-1 + por m7, m4 + pxor m6, m6 + pcmpeqb m7, m6 +%endmacro + +; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask) +; out: m1=p0' m2=q0' +; clobbers: m0,3-6 +%macro DEBLOCK_P0_Q0 0 + pcmpeqb m4, m4 + pxor m5, m1, m2 ; p0^q0 + pxor m3, m4 + pand m5, [pb_1] ; (p0^q0)&1 + pavgb m3, m0 ; (p1 - q1 + 256)>>1 + pxor m4, m1 + pavgb m3, [pb_3] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2 + pavgb m4, m2 ; (q0 - p0 + 256)>>1 + pavgb m3, m5 + mova m6, [pb_A1] + paddusb m3, m4 ; d+128+33 + psubusb m6, m3 + psubusb m3, [pb_A1] + pminub m6, m7 + pminub m3, m7 + psubusb m1, m6 + psubusb m2, m3 + paddusb m1, m3 + paddusb m2, m6 +%endmacro + +; in: m1=p0 m2=q0 +; %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp +; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 ) +; clobbers: q2, tmp, tc0 +%macro LUMA_Q1 6 + pavgb %6, m1, m2 + pavgb %2, %6 ; avg(p2,avg(p0,q0)) + pxor %6, %3 + pand %6, [pb_1] ; (p2^avg(p0,q0))&1 + psubusb %2, %6 ; (p2+((p0+q0+1)>>1))>>1 + psubusb %6, %1, %5 + paddusb %5, %1 + pmaxub %2, %6 + pminub %2, %5 + mova %4, %2 +%endmacro + +%if ARCH_X86_64 +;----------------------------------------------------------------------------- +; void ff_deblock_v_luma(uint8_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +%macro DEBLOCK_LUMA 0 +cglobal deblock_v_luma_8, 5,5,10, pix_, stride_, alpha_, beta_, base3_ + movd m8, [r4] ; tc0 + lea r4, [stride_q*3] + dec alpha_d ; alpha-1 + neg r4 + dec beta_d ; beta-1 + add base3_q, pix_q ; pix-3*stride + + mova m0, [base3_q + stride_q] ; p1 + mova m1, [base3_q + 2*stride_q] ; p0 + mova m2, [pix_q] ; q0 + mova m3, [pix_q + stride_q] ; q1 + LOAD_MASK r2d, r3d + + punpcklbw m8, m8 + punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0] + pcmpeqb m9, m9 + pcmpeqb m9, m8 + pandn m9, m7 + pand m8, m9 + + movdqa m3, [base3_q] ; p2 + DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1 + pand m6, m9 + psubb m7, m8, m6 + pand m6, m8 + LUMA_Q1 m0, m3, [base3_q], [base3_q + stride_q], m6, m4 + + movdqa m4, [pix_q + 2*stride_q] ; q2 + DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1 + pand m6, m9 + pand m8, m6 + psubb m7, m6 + mova m3, [pix_q + stride_q] + LUMA_Q1 m3, m4, [pix_q + 2*stride_q], [pix_q + stride_q], m8, m6 + + DEBLOCK_P0_Q0 + mova [base3_q + 2*stride_q], m1 + mova [pix_q], m2 + RET + +;----------------------------------------------------------------------------- +; void ff_deblock_h_luma(uint8_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +INIT_MMX cpuname +cglobal deblock_h_luma_8, 5,9,0,0x60+16*WIN64 + movsxd r7, r1d + lea r8, [r7+r7*2] + lea r6, [r0-4] + lea r5, [r0-4+r8] +%if WIN64 + %define pix_tmp rsp+0x30 ; shadow space + r4 +%else + %define pix_tmp rsp +%endif + + ; transpose 6x16 -> tmp space + TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r7, r8), pix_tmp + lea r6, [r6+r7*8] + lea r5, [r5+r7*8] + TRANSPOSE6x8_MEM PASS8ROWS(r6, r5, r7, r8), pix_tmp+8 + + ; vertical filter + ; alpha, beta, tc0 are still in r2d, r3d, r4 + ; don't backup r6, r5, r7, r8 because deblock_v_luma_sse2 doesn't use them + lea r0, [pix_tmp+0x30] + mov r1d, 0x10 +%if WIN64 + mov [rsp+0x20], r4 +%endif + call deblock_v_luma_8 + + ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter) + add r6, 2 + add r5, 2 + movq m0, [pix_tmp+0x18] + movq m1, [pix_tmp+0x28] + movq m2, [pix_tmp+0x38] + movq m3, [pix_tmp+0x48] + TRANSPOSE8x4B_STORE PASS8ROWS(r6, r5, r7, r8) + + shl r7, 3 + sub r6, r7 + sub r5, r7 + shr r7, 3 + movq m0, [pix_tmp+0x10] + movq m1, [pix_tmp+0x20] + movq m2, [pix_tmp+0x30] + movq m3, [pix_tmp+0x40] + TRANSPOSE8x4B_STORE PASS8ROWS(r6, r5, r7, r8) + + RET +%endmacro + +%macro DEBLOCK_H_LUMA_MBAFF 0 + +cglobal deblock_h_luma_mbaff_8, 5, 9, 10, 8*16, pix_, stride_, alpha_, beta_, tc0_, base3_, stride3_ + movsxd stride_q, stride_d + dec alpha_d + dec beta_d + mov base3_q, pix_q + lea stride3_q, [3*stride_q] + add base3_q, stride3_q + + movq m0, [pix_q - 4] + movq m1, [pix_q + stride_q - 4] + movq m2, [pix_q + 2*stride_q - 4] + movq m3, [base3_q - 4] + movq m4, [base3_q + stride_q - 4] + movq m5, [base3_q + 2*stride_q - 4] + movq m6, [base3_q + stride3_q - 4] + movq m7, [base3_q + 4*stride_q - 4] + + TRANSPOSE_8X8B 0,1,2,3,4,5,6,7 + + %assign i 0 + %rep 8 + movq [rsp + 16*i], m %+ i + %assign i i+1 + %endrep + + ; p2 = m1 [rsp + 16] + ; p1 = m2 [rsp + 32] + ; p0 = m3 [rsp + 48] + ; q0 = m4 [rsp + 64] + ; q1 = m5 [rsp + 80] + ; q2 = m6 [rsp + 96] + + SWAP 0, 2 + SWAP 1, 3 + SWAP 2, 4 + SWAP 3, 5 + + LOAD_MASK alpha_d, beta_d + movd m8, [tc0_q] + punpcklbw m8, m8 + pcmpeqb m9, m9 + pcmpeqb m9, m8 + pandn m9, m7 + pand m8, m9 + + movdqa m3, [rsp + 16] ; p2 + DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1 + pand m6, m9 + psubb m7, m8, m6 + pand m6, m8 + LUMA_Q1 m0, m3, [rsp + 16], [rsp + 32], m6, m4 + + movdqa m4, [rsp + 96] ; q2 + DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1 + pand m6, m9 + pand m8, m6 + psubb m7, m6 + mova m3, [rsp + 80] + LUMA_Q1 m3, m4, [rsp + 96], [rsp + 80], m8, m6 + + DEBLOCK_P0_Q0 + SWAP 1, 3 + SWAP 2, 4 + movq m0, [rsp] + movq m1, [rsp + 16] + movq m2, [rsp + 32] + movq m5, [rsp + 80] + movq m6, [rsp + 96] + movq m7, [rsp + 112] + + TRANSPOSE_8X8B 0,1,2,3,4,5,6,7 + movq [pix_q - 4], m0 + movq [pix_q + stride_q - 4], m1 + movq [pix_q + 2*stride_q - 4], m2 + movq [base3_q - 4], m3 + movq [base3_q + stride_q - 4], m4 + movq [base3_q + 2*stride_q - 4], m5 + movq [base3_q + stride3_q - 4], m6 + movq [base3_q + 4*stride_q - 4], m7 + +RET + +%endmacro + +INIT_XMM sse2 +DEBLOCK_H_LUMA_MBAFF +DEBLOCK_LUMA + +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_H_LUMA_MBAFF +DEBLOCK_LUMA +%endif + +%else + +%macro DEBLOCK_LUMA 2 +;----------------------------------------------------------------------------- +; void ff_deblock_v8_luma(uint8_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_%1_luma_8, 5,5,8,2*%2 + lea r4, [r1*3] + dec r2 ; alpha-1 + neg r4 + dec r3 ; beta-1 + add r4, r0 ; pix-3*stride + + mova m0, [r4+r1] ; p1 + mova m1, [r4+2*r1] ; p0 + mova m2, [r0] ; q0 + mova m3, [r0+r1] ; q1 + LOAD_MASK r2, r3 + + mov r3, r4mp + pcmpeqb m3, m3 + movd m4, [r3] ; tc0 + punpcklbw m4, m4 + punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0] + mova [esp+%2], m4 ; tc + pcmpgtb m4, m3 + mova m3, [r4] ; p2 + pand m4, m7 + mova [esp], m4 ; mask + + DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1 + pand m6, m4 + pand m4, [esp+%2] ; tc + psubb m7, m4, m6 + pand m6, m4 + LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4 + + mova m4, [r0+2*r1] ; q2 + DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1 + pand m6, [esp] ; mask + mova m5, [esp+%2] ; tc + psubb m7, m6 + pand m5, m6 + mova m3, [r0+r1] + LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6 + + DEBLOCK_P0_Q0 + mova [r4+2*r1], m1 + mova [r0], m2 + RET + +;----------------------------------------------------------------------------- +; void ff_deblock_h_luma(uint8_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +INIT_MMX cpuname +cglobal deblock_h_luma_8, 0,5,8,0x60+12 + mov r0, r0mp + mov r3, r1m + lea r4, [r3*3] + sub r0, 4 + lea r1, [r0+r4] +%define pix_tmp esp+12 + + ; transpose 6x16 -> tmp space + TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp + lea r0, [r0+r3*8] + lea r1, [r1+r3*8] + TRANSPOSE6x8_MEM PASS8ROWS(r0, r1, r3, r4), pix_tmp+8 + + ; vertical filter + lea r0, [pix_tmp+0x30] + PUSH dword r4m + PUSH dword r3m + PUSH dword r2m + PUSH dword 16 + PUSH dword r0 + call deblock_%1_luma_8 +%ifidn %1, v8 + add dword [esp ], 8 ; pix_tmp+0x38 + add dword [esp+16], 2 ; tc0+2 + call deblock_%1_luma_8 +%endif + ADD esp, 20 + + ; transpose 16x4 -> original space (only the middle 4 rows were changed by the filter) + mov r0, r0mp + sub r0, 2 + + movq m0, [pix_tmp+0x10] + movq m1, [pix_tmp+0x20] + lea r1, [r0+r4] + movq m2, [pix_tmp+0x30] + movq m3, [pix_tmp+0x40] + TRANSPOSE8x4B_STORE PASS8ROWS(r0, r1, r3, r4) + + lea r0, [r0+r3*8] + lea r1, [r1+r3*8] + movq m0, [pix_tmp+0x18] + movq m1, [pix_tmp+0x28] + movq m2, [pix_tmp+0x38] + movq m3, [pix_tmp+0x48] + TRANSPOSE8x4B_STORE PASS8ROWS(r0, r1, r3, r4) + + RET +%endmacro ; DEBLOCK_LUMA + +INIT_MMX mmxext +DEBLOCK_LUMA v8, 8 +INIT_XMM sse2 +DEBLOCK_LUMA v, 16 +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_LUMA v, 16 +%endif + +%endif ; ARCH + + + +%macro LUMA_INTRA_P012 4 ; p0..p3 in memory +%if ARCH_X86_64 + pavgb t0, p2, p1 + pavgb t1, p0, q0 +%else + mova t0, p2 + mova t1, p0 + pavgb t0, p1 + pavgb t1, q0 +%endif + pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2 + mova t5, t1 +%if ARCH_X86_64 + paddb t2, p2, p1 + paddb t3, p0, q0 +%else + mova t2, p2 + mova t3, p0 + paddb t2, p1 + paddb t3, q0 +%endif + paddb t2, t3 + mova t3, t2 + mova t4, t2 + psrlw t2, 1 + pavgb t2, mpb_0 + pxor t2, t0 + pand t2, mpb_1 + psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4; + +%if ARCH_X86_64 + pavgb t1, p2, q1 + psubb t2, p2, q1 +%else + mova t1, p2 + mova t2, p2 + pavgb t1, q1 + psubb t2, q1 +%endif + paddb t3, t3 + psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1 + pand t2, mpb_1 + psubb t1, t2 + pavgb t1, p1 + pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2 + psrlw t3, 2 + pavgb t3, mpb_0 + pxor t3, t1 + pand t3, mpb_1 + psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8 + + pxor t3, p0, q1 + pavgb t2, p0, q1 + pand t3, mpb_1 + psubb t2, t3 + pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4 + + pxor t1, t2 + pxor t2, p0 + pand t1, mask1p + pand t2, mask0 + pxor t1, t2 + pxor t1, p0 + mova %1, t1 ; store p0 + + mova t1, %4 ; p3 + paddb t2, t1, p2 + pavgb t1, p2 + pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4 + paddb t2, t2 + paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0 + psrlw t2, 2 + pavgb t2, mpb_0 + pxor t2, t1 + pand t2, mpb_1 + psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8 + + pxor t0, p1 + pxor t1, p2 + pand t0, mask1p + pand t1, mask1p + pxor t0, p1 + pxor t1, p2 + mova %2, t0 ; store p1 + mova %3, t1 ; store p2 +%endmacro + +%macro LUMA_INTRA_SWAP_PQ 0 + %define q1 m0 + %define q0 m1 + %define p0 m2 + %define p1 m3 + %define p2 q2 + %define mask1p mask1q +%endmacro + +%macro DEBLOCK_LUMA_INTRA 1 + %define p1 m0 + %define p0 m1 + %define q0 m2 + %define q1 m3 + %define t0 m4 + %define t1 m5 + %define t2 m6 + %define t3 m7 +%if ARCH_X86_64 + %define p2 m8 + %define q2 m9 + %define t4 m10 + %define t5 m11 + %define mask0 m12 + %define mask1p m13 +%if WIN64 + %define mask1q [rsp] +%else + %define mask1q [rsp-24] +%endif + %define mpb_0 m14 + %define mpb_1 m15 +%else + %define spill(x) [esp+16*x] + %define p2 [r4+r1] + %define q2 [r0+2*r1] + %define t4 spill(0) + %define t5 spill(1) + %define mask0 spill(2) + %define mask1p spill(3) + %define mask1q spill(4) + %define mpb_0 [pb_0] + %define mpb_1 [pb_1] +%endif + +;----------------------------------------------------------------------------- +; void ff_deblock_v_luma_intra(uint8_t *pix, int stride, int alpha, int beta) +;----------------------------------------------------------------------------- +%if WIN64 +cglobal deblock_%1_luma_intra_8, 4,6,16,0x10 +%else +cglobal deblock_%1_luma_intra_8, 4,6,16,ARCH_X86_64*0x50-0x50 +%endif + lea r4, [r1*4] + lea r5, [r1*3] ; 3*stride + dec r2d ; alpha-1 + jl .end + neg r4 + dec r3d ; beta-1 + jl .end + add r4, r0 ; pix-4*stride + mova p1, [r4+2*r1] + mova p0, [r4+r5] + mova q0, [r0] + mova q1, [r0+r1] +%if ARCH_X86_64 + pxor mpb_0, mpb_0 + mova mpb_1, [pb_1] + LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0 + SWAP 7, 12 ; m12=mask0 + pavgb t5, mpb_0 + pavgb t5, mpb_1 ; alpha/4+1 + movdqa p2, [r4+r1] + movdqa q2, [r0+2*r1] + DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1 + DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1 + DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1 + pand t0, mask0 + pand t4, t0 + pand t2, t0 + mova mask1q, t4 + mova mask1p, t2 +%else + LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0 + mova m4, t5 + mova mask0, m7 + pavgb m4, [pb_0] + pavgb m4, [pb_1] ; alpha/4+1 + DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1 + pand m6, mask0 + DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1 + pand m4, m6 + mova mask1p, m4 + DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1 + pand m4, m6 + mova mask1q, m4 +%endif + LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4] + LUMA_INTRA_SWAP_PQ + LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5] +.end: + RET + +INIT_MMX cpuname +%if ARCH_X86_64 +;----------------------------------------------------------------------------- +; void ff_deblock_h_luma_intra(uint8_t *pix, int stride, int alpha, int beta) +;----------------------------------------------------------------------------- +cglobal deblock_h_luma_intra_8, 4,9,0,0x80 + movsxd r7, r1d + lea r8, [r7*3] + lea r6, [r0-4] + lea r5, [r0-4+r8] +%if WIN64 + %define pix_tmp rsp+0x20 ; shadow space +%else + %define pix_tmp rsp +%endif + + ; transpose 8x16 -> tmp space + TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r7, r8), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30) + lea r6, [r6+r7*8] + lea r5, [r5+r7*8] + TRANSPOSE8x8_MEM PASS8ROWS(r6, r5, r7, r8), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30) + + lea r0, [pix_tmp+0x40] + mov r1, 0x10 + call deblock_v_luma_intra_8 + + ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8) + lea r5, [r6+r8] + TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r7, r8) + shl r7, 3 + sub r6, r7 + sub r5, r7 + shr r7, 3 + TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r7, r8) + RET +%else +cglobal deblock_h_luma_intra_8, 2,4,8,0x80 + lea r3, [r1*3] + sub r0, 4 + lea r2, [r0+r3] + %define pix_tmp rsp + + ; transpose 8x16 -> tmp space + TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30) + lea r0, [r0+r1*8] + lea r2, [r2+r1*8] + TRANSPOSE8x8_MEM PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30) + + lea r0, [pix_tmp+0x40] + PUSH dword r3m + PUSH dword r2m + PUSH dword 16 + PUSH r0 + call deblock_%1_luma_intra_8 +%ifidn %1, v8 + add dword [rsp], 8 ; pix_tmp+8 + call deblock_%1_luma_intra_8 +%endif + ADD esp, 16 + + mov r1, r1m + mov r0, r0mp + lea r3, [r1*3] + sub r0, 4 + lea r2, [r0+r3] + ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8) + TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3) + lea r0, [r0+r1*8] + lea r2, [r2+r1*8] + TRANSPOSE8x8_MEM PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3) + RET +%endif ; ARCH_X86_64 +%endmacro ; DEBLOCK_LUMA_INTRA + +INIT_XMM sse2 +DEBLOCK_LUMA_INTRA v +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_LUMA_INTRA v +%endif +%if ARCH_X86_64 == 0 +INIT_MMX mmxext +DEBLOCK_LUMA_INTRA v8 +%endif + +INIT_MMX mmxext + +%macro CHROMA_V_START 0 + dec r2d ; alpha-1 + dec r3d ; beta-1 + mov t5, r0 + sub t5, r1 + sub t5, r1 +%endmacro + +%macro CHROMA_H_START 0 + dec r2d + dec r3d + sub r0, 2 + lea t6, [r1*3] + mov t5, r0 + add r0, t6 +%endmacro + +%define t5 r5 +%define t6 r6 + +;----------------------------------------------------------------------------- +; void ff_deblock_v_chroma(uint8_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_v_chroma_8, 5,6 + CHROMA_V_START + movq m0, [t5] + movq m1, [t5+r1] + movq m2, [r0] + movq m3, [r0+r1] + call ff_chroma_inter_body_mmxext + movq [t5+r1], m1 + movq [r0], m2 + RET + +;----------------------------------------------------------------------------- +; void ff_deblock_h_chroma(uint8_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_h_chroma_8, 5,7 +%if ARCH_X86_64 + ; This could use the red zone on 64 bit unix to avoid the stack pointer + ; readjustment, but valgrind assumes the red zone is clobbered on + ; function calls and returns. + sub rsp, 16 + %define buf0 [rsp] + %define buf1 [rsp+8] +%else + %define buf0 r0m + %define buf1 r2m +%endif + CHROMA_H_START + TRANSPOSE4x8_LOAD bw, wd, dq, PASS8ROWS(t5, r0, r1, t6) + movq buf0, m0 + movq buf1, m3 + LOAD_MASK r2d, r3d + movd m6, [r4] ; tc0 + punpcklbw m6, m6 + pand m7, m6 + DEBLOCK_P0_Q0 + movq m0, buf0 + movq m3, buf1 + TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6) +%if ARCH_X86_64 + add rsp, 16 +%endif + RET + +ALIGN 16 +ff_chroma_inter_body_mmxext: + LOAD_MASK r2d, r3d + movd m6, [r4] ; tc0 + punpcklbw m6, m6 + pand m7, m6 + DEBLOCK_P0_Q0 + ret + +%define t5 r4 +%define t6 r5 + +cglobal deblock_h_chroma422_8, 5, 6 + SUB rsp, (1+ARCH_X86_64*2)*mmsize + %if ARCH_X86_64 + %define buf0 [rsp+16] + %define buf1 [rsp+8] + %else + %define buf0 r0m + %define buf1 r2m + %endif + + movd m6, [r4] + punpcklbw m6, m6 + movq [rsp], m6 + CHROMA_H_START + + TRANSPOSE4x8B_LOAD PASS8ROWS(t5, r0, r1, t6) + movq buf0, m0 + movq buf1, m3 + LOAD_MASK r2d, r3d + movd m6, [rsp] + punpcklwd m6, m6 + pand m7, m6 + DEBLOCK_P0_Q0 + movq m0, buf0 + movq m3, buf1 + TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6) + + lea r0, [r0+r1*8] + lea t5, [t5+r1*8] + + TRANSPOSE4x8B_LOAD PASS8ROWS(t5, r0, r1, t6) + movq buf0, m0 + movq buf1, m3 + LOAD_MASK r2d, r3d + movd m6, [rsp+4] + punpcklwd m6, m6 + pand m7, m6 + DEBLOCK_P0_Q0 + movq m0, buf0 + movq m3, buf1 + TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6) + ADD rsp, (1+ARCH_X86_64*2)*mmsize +RET + +; in: %1=p0 %2=p1 %3=q1 +; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2 +%macro CHROMA_INTRA_P0 3 + movq m4, %1 + pxor m4, %3 + pand m4, [pb_1] ; m4 = (p0^q1)&1 + pavgb %1, %3 + psubusb %1, m4 + pavgb %1, %2 ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1)) +%endmacro + +;------------------------------------------------------------------------------ +; void ff_deblock_v_chroma_intra(uint8_t *pix, int stride, int alpha, int beta) +;------------------------------------------------------------------------------ +cglobal deblock_v_chroma_intra_8, 4,5 + CHROMA_V_START + movq m0, [t5] + movq m1, [t5+r1] + movq m2, [r0] + movq m3, [r0+r1] + call ff_chroma_intra_body_mmxext + movq [t5+r1], m1 + movq [r0], m2 + RET + +;------------------------------------------------------------------------------ +; void ff_deblock_h_chroma_intra(uint8_t *pix, int stride, int alpha, int beta) +;------------------------------------------------------------------------------ +cglobal deblock_h_chroma_intra_8, 4,6 + CHROMA_H_START + TRANSPOSE4x8_LOAD bw, wd, dq, PASS8ROWS(t5, r0, r1, t6) + call ff_chroma_intra_body_mmxext + TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6) + RET + +cglobal deblock_h_chroma422_intra_8, 4, 6 + CHROMA_H_START + TRANSPOSE4x8_LOAD bw, wd, dq, PASS8ROWS(t5, r0, r1, t6) + call ff_chroma_intra_body_mmxext + TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6) + + lea r0, [r0+r1*8] + lea t5, [t5+r1*8] + + TRANSPOSE4x8_LOAD bw, wd, dq, PASS8ROWS(t5, r0, r1, t6) + call ff_chroma_intra_body_mmxext + TRANSPOSE8x4B_STORE PASS8ROWS(t5, r0, r1, t6) +RET + +ALIGN 16 +ff_chroma_intra_body_mmxext: + LOAD_MASK r2d, r3d + movq m5, m1 + movq m6, m2 + CHROMA_INTRA_P0 m1, m0, m3 + CHROMA_INTRA_P0 m2, m3, m0 + psubb m1, m5 + psubb m2, m6 + pand m1, m7 + pand m2, m7 + paddb m1, m5 + paddb m2, m6 + ret + +%macro LOAD_8_ROWS 8 + movd m0, %1 + movd m1, %2 + movd m2, %3 + movd m3, %4 + movd m4, %5 + movd m5, %6 + movd m6, %7 + movd m7, %8 +%endmacro + +%macro STORE_8_ROWS 8 + movd %1, m0 + movd %2, m1 + movd %3, m2 + movd %4, m3 + movd %5, m4 + movd %6, m5 + movd %7, m6 + movd %8, m7 +%endmacro + +%macro TRANSPOSE_8x4B_XMM 0 + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 + punpcklwd m0, m2 + punpcklwd m4, m6 + punpckhdq m2, m0, m4 + punpckldq m0, m4 + MOVHL m1, m0 + MOVHL m3, m2 +%endmacro + +%macro TRANSPOSE_4x8B_XMM 0 + punpcklbw m0, m1 + punpcklbw m2, m3 + punpckhwd m4, m0, m2 + punpcklwd m0, m2 + MOVHL m6, m4 + MOVHL m2, m0 + pshufd m1, m0, 1 + pshufd m3, m2, 1 + pshufd m5, m4, 1 + pshufd m7, m6, 1 +%endmacro + +%macro CHROMA_INTER_BODY_XMM 1 + LOAD_MASK alpha_d, beta_d + movd m6, [tc0_q] + %rep %1 + punpcklbw m6, m6 + %endrep + pand m7, m6 + DEBLOCK_P0_Q0 +%endmacro + +%macro CHROMA_INTRA_BODY_XMM 0 + LOAD_MASK alpha_d, beta_d + mova m5, m1 + mova m6, m2 + pxor m4, m1, m3 + pand m4, [pb_1] + pavgb m1, m3 + psubusb m1, m4 + pavgb m1, m0 + pxor m4, m2, m0 + pand m4, [pb_1] + pavgb m2, m0 + psubusb m2, m4 + pavgb m2, m3 + psubb m1, m5 + psubb m2, m6 + pand m1, m7 + pand m2, m7 + paddb m1, m5 + paddb m2, m6 +%endmacro + +%macro CHROMA_V_START_XMM 1 + movsxdifnidn stride_q, stride_d + dec alpha_d + dec beta_d + mov %1, pix_q + sub %1, stride_q + sub %1, stride_q +%endmacro + +%macro CHROMA_H_START_XMM 2 + movsxdifnidn stride_q, stride_d + dec alpha_d + dec beta_d + lea %2, [3*stride_q] + mov %1, pix_q + add %1, %2 +%endmacro + +%macro DEBLOCK_CHROMA_XMM 1 + +INIT_XMM %1 + +cglobal deblock_v_chroma_8, 5, 6, 8, pix_, stride_, alpha_, beta_, tc0_ + CHROMA_V_START_XMM r5 + movq m0, [r5] + movq m1, [r5 + stride_q] + movq m2, [pix_q] + movq m3, [pix_q + stride_q] + CHROMA_INTER_BODY_XMM 1 + movq [r5 + stride_q], m1 + movq [pix_q], m2 +RET + +cglobal deblock_h_chroma_8, 5, 7, 8, 0-16, pix_, stride_, alpha_, beta_, tc0_ + CHROMA_H_START_XMM r5, r6 + LOAD_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) + TRANSPOSE_8x4B_XMM + movq [rsp], m0 + movq [rsp + 8], m3 + CHROMA_INTER_BODY_XMM 1 + movq m0, [rsp] + movq m3, [rsp + 8] + TRANSPOSE_4x8B_XMM + STORE_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) +RET + +cglobal deblock_h_chroma422_8, 5, 7, 8, 0-16, pix_, stride_, alpha_, beta_, tc0_ + CHROMA_H_START_XMM r5, r6 + LOAD_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) + TRANSPOSE_8x4B_XMM + movq [rsp], m0 + movq [rsp + 8], m3 + CHROMA_INTER_BODY_XMM 2 + movq m0, [rsp] + movq m3, [rsp + 8] + TRANSPOSE_4x8B_XMM + STORE_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) + + lea pix_q, [pix_q + 8*stride_q] + lea r5, [r5 + 8*stride_q] + add tc0_q, 2 + + LOAD_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) + TRANSPOSE_8x4B_XMM + movq [rsp], m0 + movq [rsp + 8], m3 + CHROMA_INTER_BODY_XMM 2 + movq m0, [rsp] + movq m3, [rsp + 8] + TRANSPOSE_4x8B_XMM + STORE_8_ROWS PASS8ROWS(pix_q - 2, r5 - 2, stride_q, r6) +RET + +cglobal deblock_v_chroma_intra_8, 4, 5, 8, pix_, stride_, alpha_, beta_ + CHROMA_V_START_XMM r4 + movq m0, [r4] + movq m1, [r4 + stride_q] + movq m2, [pix_q] + movq m3, [pix_q + stride_q] + CHROMA_INTRA_BODY_XMM + movq [r4 + stride_q], m1 + movq [pix_q], m2 +RET + +cglobal deblock_h_chroma_intra_8, 4, 6, 8, pix_, stride_, alpha_, beta_ + CHROMA_H_START_XMM r4, r5 + LOAD_8_ROWS PASS8ROWS(pix_q - 2, r4 - 2, stride_q, r5) + TRANSPOSE_8x4B_XMM + CHROMA_INTRA_BODY_XMM + TRANSPOSE_4x8B_XMM + STORE_8_ROWS PASS8ROWS(pix_q - 2, r4 - 2, stride_q, r5) +RET + +cglobal deblock_h_chroma422_intra_8, 4, 6, 8, pix_, stride_, alpha_, beta_ + CHROMA_H_START_XMM r4, r5 + LOAD_8_ROWS PASS8ROWS(pix_q - 2, r4 - 2, stride_q, r5) + TRANSPOSE_8x4B_XMM + CHROMA_INTRA_BODY_XMM + TRANSPOSE_4x8B_XMM + STORE_8_ROWS PASS8ROWS(pix_q - 2, r4 - 2, stride_q, r5) + + lea pix_q, [pix_q + 8*stride_q] + lea r4, [r4 + 8*stride_q] + + LOAD_8_ROWS PASS8ROWS(pix_q - 2, r4 - 2, stride_q, r5) + TRANSPOSE_8x4B_XMM + CHROMA_INTRA_BODY_XMM + TRANSPOSE_4x8B_XMM + STORE_8_ROWS PASS8ROWS(pix_q - 2, r4 - 2, stride_q, r5) +RET + +%endmacro ; DEBLOCK_CHROMA_XMM + +DEBLOCK_CHROMA_XMM sse2 +DEBLOCK_CHROMA_XMM avx + +;----------------------------------------------------------------------------- +; void ff_h264_loop_filter_strength(int16_t bs[2][4][4], uint8_t nnz[40], +; int8_t ref[2][40], int16_t mv[2][40][2], +; int bidir, int edges, int step, +; int mask_mv0, int mask_mv1, int field); +; +; bidir is 0 or 1 +; edges is 1 or 4 +; step is 1 or 2 +; mask_mv0 is 0 or 3 +; mask_mv1 is 0 or 1 +; field is 0 or 1 +;----------------------------------------------------------------------------- +%macro loop_filter_strength_iteration 7 ; edges, step, mask_mv, + ; dir, d_idx, mask_dir, bidir +%define edgesd %1 +%define stepd %2 +%define mask_mvd %3 +%define dir %4 +%define d_idx %5 +%define mask_dir %6 +%define bidir %7 + xor b_idxd, b_idxd ; for (b_idx = 0; b_idx < edges; b_idx += step) +%%.b_idx_loop: +%if mask_dir == 0 + pxor m0, m0 +%endif + test b_idxd, dword mask_mvd + jnz %%.skip_loop_iter ; if (!(b_idx & mask_mv)) +%if bidir == 1 + movd m2, [refq+b_idxq+d_idx+12] ; { ref0[bn] } + punpckldq m2, [refq+b_idxq+d_idx+52] ; { ref0[bn], ref1[bn] } + pshufw m0, [refq+b_idxq+12], 0x44 ; { ref0[b], ref0[b] } + pshufw m1, [refq+b_idxq+52], 0x44 ; { ref1[b], ref1[b] } + pshufw m3, m2, 0x4E ; { ref1[bn], ref0[bn] } + psubb m0, m2 ; { ref0[b] != ref0[bn], + ; ref0[b] != ref1[bn] } + psubb m1, m3 ; { ref1[b] != ref1[bn], + ; ref1[b] != ref0[bn] } + + por m0, m1 + mova m1, [mvq+b_idxq*4+(d_idx+12)*4] + mova m2, [mvq+b_idxq*4+(d_idx+12)*4+mmsize] + mova m3, m1 + mova m4, m2 + psubw m1, [mvq+b_idxq*4+12*4] + psubw m2, [mvq+b_idxq*4+12*4+mmsize] + psubw m3, [mvq+b_idxq*4+52*4] + psubw m4, [mvq+b_idxq*4+52*4+mmsize] + packsswb m1, m2 + packsswb m3, m4 + paddb m1, m6 + paddb m3, m6 + psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit + psubusb m3, m5 + packsswb m1, m3 + + por m0, m1 + mova m1, [mvq+b_idxq*4+(d_idx+52)*4] + mova m2, [mvq+b_idxq*4+(d_idx+52)*4+mmsize] + mova m3, m1 + mova m4, m2 + psubw m1, [mvq+b_idxq*4+12*4] + psubw m2, [mvq+b_idxq*4+12*4+mmsize] + psubw m3, [mvq+b_idxq*4+52*4] + psubw m4, [mvq+b_idxq*4+52*4+mmsize] + packsswb m1, m2 + packsswb m3, m4 + paddb m1, m6 + paddb m3, m6 + psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit + psubusb m3, m5 + packsswb m1, m3 + + pshufw m1, m1, 0x4E + por m0, m1 + pshufw m1, m0, 0x4E + pminub m0, m1 +%else ; bidir == 0 + movd m0, [refq+b_idxq+12] + psubb m0, [refq+b_idxq+d_idx+12] ; ref[b] != ref[bn] + + mova m1, [mvq+b_idxq*4+12*4] + mova m2, [mvq+b_idxq*4+12*4+mmsize] + psubw m1, [mvq+b_idxq*4+(d_idx+12)*4] + psubw m2, [mvq+b_idxq*4+(d_idx+12)*4+mmsize] + packsswb m1, m2 + paddb m1, m6 + psubusb m1, m5 ; abs(mv[b] - mv[bn]) >= limit + packsswb m1, m1 + por m0, m1 +%endif ; bidir == 1/0 + +%%.skip_loop_iter: + movd m1, [nnzq+b_idxq+12] + por m1, [nnzq+b_idxq+d_idx+12] ; nnz[b] || nnz[bn] + + pminub m1, m7 + pminub m0, m7 + psllw m1, 1 + pxor m2, m2 + pmaxub m1, m0 + punpcklbw m1, m2 + movq [bsq+b_idxq+32*dir], m1 + + add b_idxd, dword stepd + cmp b_idxd, dword edgesd + jl %%.b_idx_loop +%endmacro + +INIT_MMX mmxext +cglobal h264_loop_filter_strength, 9, 9, 0, bs, nnz, ref, mv, bidir, edges, \ + step, mask_mv0, mask_mv1, field +%define b_idxq bidirq +%define b_idxd bidird + cmp dword fieldm, 0 + mova m7, [pb_1] + mova m5, [pb_3] + je .nofield + mova m5, [pb_3_1] +.nofield: + mova m6, m5 + paddb m5, m5 + + shl dword stepd, 3 + shl dword edgesd, 3 +%if ARCH_X86_32 +%define mask_mv0d mask_mv0m +%define mask_mv1d mask_mv1m +%endif + shl dword mask_mv1d, 3 + shl dword mask_mv0d, 3 + + cmp dword bidird, 0 + jne .bidir + loop_filter_strength_iteration edgesd, stepd, mask_mv1d, 1, -8, 0, 0 + loop_filter_strength_iteration 32, 8, mask_mv0d, 0, -1, -1, 0 + + mova m0, [bsq+mmsize*0] + mova m1, [bsq+mmsize*1] + mova m2, [bsq+mmsize*2] + mova m3, [bsq+mmsize*3] + TRANSPOSE4x4W 0, 1, 2, 3, 4 + mova [bsq+mmsize*0], m0 + mova [bsq+mmsize*1], m1 + mova [bsq+mmsize*2], m2 + mova [bsq+mmsize*3], m3 + RET + +.bidir: + loop_filter_strength_iteration edgesd, stepd, mask_mv1d, 1, -8, 0, 1 + loop_filter_strength_iteration 32, 8, mask_mv0d, 0, -1, -1, 1 + + mova m0, [bsq+mmsize*0] + mova m1, [bsq+mmsize*1] + mova m2, [bsq+mmsize*2] + mova m3, [bsq+mmsize*3] + TRANSPOSE4x4W 0, 1, 2, 3, 4 + mova [bsq+mmsize*0], m0 + mova [bsq+mmsize*1], m1 + mova [bsq+mmsize*2], m2 + mova [bsq+mmsize*3], m3 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_deblock_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_deblock_10bit.asm new file mode 100644 index 00000000..1af3257a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_deblock_10bit.asm @@ -0,0 +1,1080 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 deblocking code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Oskar Arvidsson +;* Loren Merritt +;* Fiona Glaser +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +cextern pw_2 +cextern pw_3 +cextern pw_4 +cextern pw_1023 +%define pw_pixel_max pw_1023 + +; out: %4 = |%1-%2|-%3 +; clobbers: %5 +%macro ABS_SUB 5 + psubusw %5, %2, %1 + psubusw %4, %1, %2 + por %4, %5 + psubw %4, %3 +%endmacro + +; out: %4 = |%1-%2|<%3 +%macro DIFF_LT 5 + psubusw %4, %2, %1 + psubusw %5, %1, %2 + por %5, %4 ; |%1-%2| + pxor %4, %4 + psubw %5, %3 ; |%1-%2|-%3 + pcmpgtw %4, %5 ; 0 > |%1-%2|-%3 +%endmacro + +%macro LOAD_AB 4 + movd %1, %3 + movd %2, %4 + SPLATW %1, %1 + SPLATW %2, %2 +%endmacro + +; in: %2=tc reg +; out: %1=splatted tc +%macro LOAD_TC 2 + movd %1, [%2] + punpcklbw %1, %1 +%if mmsize == 8 + pshufw %1, %1, 0 +%else + pshuflw %1, %1, 01010000b + pshufd %1, %1, 01010000b +%endif + psraw %1, 6 +%endmacro + +; in: %1=p1, %2=p0, %3=q0, %4=q1 +; %5=alpha, %6=beta, %7-%9=tmp +; out: %7=mask +%macro LOAD_MASK 9 + ABS_SUB %2, %3, %5, %8, %7 ; |p0-q0| - alpha + ABS_SUB %1, %2, %6, %9, %7 ; |p1-p0| - beta + pand %8, %9 + ABS_SUB %3, %4, %6, %9, %7 ; |q1-q0| - beta + pxor %7, %7 + pand %8, %9 + pcmpgtw %7, %8 +%endmacro + +; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp +; out: %1=p0', m2=q0' +%macro DEBLOCK_P0_Q0 7 + psubw %3, %4 + pxor %7, %7 + paddw %3, [pw_4] + psubw %7, %5 + psubw %6, %2, %1 + psllw %6, 2 + paddw %3, %6 + psraw %3, 3 + mova %6, [pw_pixel_max] + CLIPW %3, %7, %5 + pxor %7, %7 + paddw %1, %3 + psubw %2, %3 + CLIPW %1, %7, %6 + CLIPW %2, %7, %6 +%endmacro + +; in: %1=x2, %2=x1, %3=p0, %4=q0 %5=mask&tc, %6=tmp +%macro LUMA_Q1 6 + pavgw %6, %3, %4 ; (p0+q0+1)>>1 + paddw %1, %6 + pxor %6, %6 + psraw %1, 1 + psubw %6, %5 + psubw %1, %2 + CLIPW %1, %6, %5 + paddw %1, %2 +%endmacro + +%macro LUMA_DEBLOCK_ONE 3 + DIFF_LT m5, %1, bm, m4, m6 + pxor m6, m6 + mova %3, m4 + pcmpgtw m6, tcm + pand m4, tcm + pandn m6, m7 + pand m4, m6 + LUMA_Q1 m5, %2, m1, m2, m4, m6 +%endmacro + +%macro LUMA_H_STORE 2 +%if mmsize == 8 + movq [r0-4], m0 + movq [r0+r1-4], m1 + movq [r0+r1*2-4], m2 + movq [r0+%2-4], m3 +%else + movq [r0-4], m0 + movhps [r0+r1-4], m0 + movq [r0+r1*2-4], m1 + movhps [%1-4], m1 + movq [%1+r1-4], m2 + movhps [%1+r1*2-4], m2 + movq [%1+%2-4], m3 + movhps [%1+r1*4-4], m3 +%endif +%endmacro + +%macro DEBLOCK_LUMA 0 +;----------------------------------------------------------------------------- +; void ff_deblock_v_luma_10(uint16_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_v_luma_10, 5,5,8*(mmsize/16) + %assign pad 5*mmsize+12-(stack_offset&15) + %define tcm [rsp] + %define ms1 [rsp+mmsize] + %define ms2 [rsp+mmsize*2] + %define am [rsp+mmsize*3] + %define bm [rsp+mmsize*4] + SUB rsp, pad + shl r2d, 2 + shl r3d, 2 + LOAD_AB m4, m5, r2d, r3d + mov r3, 32/mmsize + mov r2, r0 + sub r0, r1 + mova am, m4 + sub r0, r1 + mova bm, m5 + sub r0, r1 +.loop: + mova m0, [r0+r1] + mova m1, [r0+r1*2] + mova m2, [r2] + mova m3, [r2+r1] + + LOAD_MASK m0, m1, m2, m3, am, bm, m7, m4, m6 + LOAD_TC m6, r4 + mova tcm, m6 + + mova m5, [r0] + LUMA_DEBLOCK_ONE m1, m0, ms1 + mova [r0+r1], m5 + + mova m5, [r2+r1*2] + LUMA_DEBLOCK_ONE m2, m3, ms2 + mova [r2+r1], m5 + + pxor m5, m5 + mova m6, tcm + pcmpgtw m5, tcm + psubw m6, ms1 + pandn m5, m7 + psubw m6, ms2 + pand m5, m6 + DEBLOCK_P0_Q0 m1, m2, m0, m3, m5, m7, m6 + mova [r0+r1*2], m1 + mova [r2], m2 + + add r0, mmsize + add r2, mmsize + add r4, mmsize/8 + dec r3 + jg .loop + ADD rsp, pad + RET + +cglobal deblock_h_luma_10, 5,6,8*(mmsize/16) + %assign pad 7*mmsize+12-(stack_offset&15) + %define tcm [rsp] + %define ms1 [rsp+mmsize] + %define ms2 [rsp+mmsize*2] + %define p1m [rsp+mmsize*3] + %define p2m [rsp+mmsize*4] + %define am [rsp+mmsize*5] + %define bm [rsp+mmsize*6] + SUB rsp, pad + shl r2d, 2 + shl r3d, 2 + LOAD_AB m4, m5, r2d, r3d + mov r3, r1 + mova am, m4 + add r3, r1 + mov r5, 32/mmsize + mova bm, m5 + add r3, r1 +%if mmsize == 16 + mov r2, r0 + add r2, r3 +%endif +.loop: +%if mmsize == 8 + movq m2, [r0-8] ; y q2 q1 q0 + movq m7, [r0+0] + movq m5, [r0+r1-8] + movq m3, [r0+r1+0] + movq m0, [r0+r1*2-8] + movq m6, [r0+r1*2+0] + movq m1, [r0+r3-8] + TRANSPOSE4x4W 2, 5, 0, 1, 4 + SWAP 2, 7 + movq m7, [r0+r3] + TRANSPOSE4x4W 2, 3, 6, 7, 4 +%else + movu m5, [r0-8] ; y q2 q1 q0 p0 p1 p2 x + movu m0, [r0+r1-8] + movu m2, [r0+r1*2-8] + movu m3, [r2-8] + TRANSPOSE4x4W 5, 0, 2, 3, 6 + mova tcm, m3 + + movu m4, [r2+r1-8] + movu m1, [r2+r1*2-8] + movu m3, [r2+r3-8] + movu m7, [r2+r1*4-8] + TRANSPOSE4x4W 4, 1, 3, 7, 6 + + mova m6, tcm + punpcklqdq m6, m7 + punpckhqdq m5, m4 + SBUTTERFLY qdq, 0, 1, 7 + SBUTTERFLY qdq, 2, 3, 7 +%endif + + mova p2m, m6 + LOAD_MASK m0, m1, m2, m3, am, bm, m7, m4, m6 + LOAD_TC m6, r4 + mova tcm, m6 + + LUMA_DEBLOCK_ONE m1, m0, ms1 + mova p1m, m5 + + mova m5, p2m + LUMA_DEBLOCK_ONE m2, m3, ms2 + mova p2m, m5 + + pxor m5, m5 + mova m6, tcm + pcmpgtw m5, tcm + psubw m6, ms1 + pandn m5, m7 + psubw m6, ms2 + pand m5, m6 + DEBLOCK_P0_Q0 m1, m2, m0, m3, m5, m7, m6 + mova m0, p1m + mova m3, p2m + TRANSPOSE4x4W 0, 1, 2, 3, 4 + LUMA_H_STORE r2, r3 + + add r4, mmsize/8 + lea r0, [r0+r1*(mmsize/2)] + lea r2, [r2+r1*(mmsize/2)] + dec r5 + jg .loop + ADD rsp, pad + RET +%endmacro + +%if ARCH_X86_64 +; in: m0=p1, m1=p0, m2=q0, m3=q1, m8=p2, m9=q2 +; m12=alpha, m13=beta +; out: m0=p1', m3=q1', m1=p0', m2=q0' +; clobbers: m4, m5, m6, m7, m10, m11, m14 +%macro DEBLOCK_LUMA_INTER_SSE2 0 + LOAD_MASK m0, m1, m2, m3, m12, m13, m7, m4, m6 + LOAD_TC m6, r4 + DIFF_LT m8, m1, m13, m10, m4 + DIFF_LT m9, m2, m13, m11, m4 + pand m6, m7 + + mova m14, m6 + pxor m4, m4 + pcmpgtw m6, m4 + pand m6, m14 + + mova m5, m10 + pand m5, m6 + LUMA_Q1 m8, m0, m1, m2, m5, m4 + + mova m5, m11 + pand m5, m6 + LUMA_Q1 m9, m3, m1, m2, m5, m4 + + pxor m4, m4 + psubw m6, m10 + pcmpgtw m4, m14 + pandn m4, m7 + psubw m6, m11 + pand m4, m6 + DEBLOCK_P0_Q0 m1, m2, m0, m3, m4, m5, m6 + + SWAP 0, 8 + SWAP 3, 9 +%endmacro + +%macro DEBLOCK_LUMA_64 0 +cglobal deblock_v_luma_10, 5,5,15 + %define p2 m8 + %define p1 m0 + %define p0 m1 + %define q0 m2 + %define q1 m3 + %define q2 m9 + %define mask0 m7 + %define mask1 m10 + %define mask2 m11 + shl r2d, 2 + shl r3d, 2 + LOAD_AB m12, m13, r2d, r3d + mov r2, r0 + sub r0, r1 + sub r0, r1 + sub r0, r1 + mov r3, 2 +.loop: + mova p2, [r0] + mova p1, [r0+r1] + mova p0, [r0+r1*2] + mova q0, [r2] + mova q1, [r2+r1] + mova q2, [r2+r1*2] + DEBLOCK_LUMA_INTER_SSE2 + mova [r0+r1], p1 + mova [r0+r1*2], p0 + mova [r2], q0 + mova [r2+r1], q1 + add r0, mmsize + add r2, mmsize + add r4, 2 + dec r3 + jg .loop + REP_RET + +cglobal deblock_h_luma_10, 5,7,15 + shl r2d, 2 + shl r3d, 2 + LOAD_AB m12, m13, r2d, r3d + mov r2, r1 + add r2, r1 + add r2, r1 + mov r5, r0 + add r5, r2 + mov r6, 2 +.loop: + movu m8, [r0-8] ; y q2 q1 q0 p0 p1 p2 x + movu m0, [r0+r1-8] + movu m2, [r0+r1*2-8] + movu m9, [r5-8] + movu m5, [r5+r1-8] + movu m1, [r5+r1*2-8] + movu m3, [r5+r2-8] + movu m7, [r5+r1*4-8] + + TRANSPOSE4x4W 8, 0, 2, 9, 10 + TRANSPOSE4x4W 5, 1, 3, 7, 10 + + punpckhqdq m8, m5 + SBUTTERFLY qdq, 0, 1, 10 + SBUTTERFLY qdq, 2, 3, 10 + punpcklqdq m9, m7 + + DEBLOCK_LUMA_INTER_SSE2 + + TRANSPOSE4x4W 0, 1, 2, 3, 4 + LUMA_H_STORE r5, r2 + add r4, 2 + lea r0, [r0+r1*8] + lea r5, [r5+r1*8] + dec r6 + jg .loop + REP_RET +%endmacro + +INIT_XMM sse2 +DEBLOCK_LUMA_64 +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_LUMA_64 +%endif +%endif + +%macro SWAPMOVA 2 +%ifid %1 + SWAP %1, %2 +%else + mova %1, %2 +%endif +%endmacro + +; in: t0-t2: tmp registers +; %1=p0 %2=p1 %3=p2 %4=p3 %5=q0 %6=q1 %7=mask0 +; %8=mask1p %9=2 %10=p0' %11=p1' %12=p2' +%macro LUMA_INTRA_P012 12 ; p0..p3 in memory +%if ARCH_X86_64 + paddw t0, %3, %2 + mova t2, %4 + paddw t2, %3 +%else + mova t0, %3 + mova t2, %4 + paddw t0, %2 + paddw t2, %3 +%endif + paddw t0, %1 + paddw t2, t2 + paddw t0, %5 + paddw t2, %9 + paddw t0, %9 ; (p2 + p1 + p0 + q0 + 2) + paddw t2, t0 ; (2*p3 + 3*p2 + p1 + p0 + q0 + 4) + + psrlw t2, 3 + psrlw t1, t0, 2 + psubw t2, %3 + psubw t1, %2 + pand t2, %8 + pand t1, %8 + paddw t2, %3 + paddw t1, %2 + SWAPMOVA %11, t1 + + psubw t1, t0, %3 + paddw t0, t0 + psubw t1, %5 + psubw t0, %3 + paddw t1, %6 + paddw t1, %2 + paddw t0, %6 + psrlw t1, 2 ; (2*p1 + p0 + q1 + 2)/4 + psrlw t0, 3 ; (p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4)>>3 + + pxor t0, t1 + pxor t1, %1 + pand t0, %8 + pand t1, %7 + pxor t0, t1 + pxor t0, %1 + SWAPMOVA %10, t0 + SWAPMOVA %12, t2 +%endmacro + +%macro LUMA_INTRA_INIT 1 + %xdefine pad %1*mmsize+((gprsize*3) % mmsize)-(stack_offset&15) + %define t0 m4 + %define t1 m5 + %define t2 m6 + %define t3 m7 + %assign i 4 +%rep %1 + CAT_XDEFINE t, i, [rsp+mmsize*(i-4)] + %assign i i+1 +%endrep + SUB rsp, pad +%endmacro + +; in: %1-%3=tmp, %4=p2, %5=q2 +%macro LUMA_INTRA_INTER 5 + LOAD_AB t0, t1, r2d, r3d + mova %1, t0 + LOAD_MASK m0, m1, m2, m3, %1, t1, t0, t2, t3 +%if ARCH_X86_64 + mova %2, t0 ; mask0 + psrlw t3, %1, 2 +%else + mova t3, %1 + mova %2, t0 ; mask0 + psrlw t3, 2 +%endif + paddw t3, [pw_2] ; alpha/4+2 + DIFF_LT m1, m2, t3, t2, t0 ; t2 = |p0-q0| < alpha/4+2 + pand t2, %2 + mova t3, %5 ; q2 + mova %1, t2 ; mask1 + DIFF_LT t3, m2, t1, t2, t0 ; t2 = |q2-q0| < beta + pand t2, %1 + mova t3, %4 ; p2 + mova %3, t2 ; mask1q + DIFF_LT t3, m1, t1, t2, t0 ; t2 = |p2-p0| < beta + pand t2, %1 + mova %1, t2 ; mask1p +%endmacro + +%macro LUMA_H_INTRA_LOAD 0 +%if mmsize == 8 + movu t0, [r0-8] + movu t1, [r0+r1-8] + movu m0, [r0+r1*2-8] + movu m1, [r0+r4-8] + TRANSPOSE4x4W 4, 5, 0, 1, 2 + mova t4, t0 ; p3 + mova t5, t1 ; p2 + + movu m2, [r0] + movu m3, [r0+r1] + movu t0, [r0+r1*2] + movu t1, [r0+r4] + TRANSPOSE4x4W 2, 3, 4, 5, 6 + mova t6, t0 ; q2 + mova t7, t1 ; q3 +%else + movu t0, [r0-8] + movu t1, [r0+r1-8] + movu m0, [r0+r1*2-8] + movu m1, [r0+r5-8] + movu m2, [r4-8] + movu m3, [r4+r1-8] + movu t2, [r4+r1*2-8] + movu t3, [r4+r5-8] + TRANSPOSE8x8W 4, 5, 0, 1, 2, 3, 6, 7, t4, t5 + mova t4, t0 ; p3 + mova t5, t1 ; p2 + mova t6, t2 ; q2 + mova t7, t3 ; q3 +%endif +%endmacro + +; in: %1=q3 %2=q2' %3=q1' %4=q0' %5=p0' %6=p1' %7=p2' %8=p3 %9=tmp +%macro LUMA_H_INTRA_STORE 9 +%if mmsize == 8 + TRANSPOSE4x4W %1, %2, %3, %4, %9 + movq [r0-8], m%1 + movq [r0+r1-8], m%2 + movq [r0+r1*2-8], m%3 + movq [r0+r4-8], m%4 + movq m%1, %8 + TRANSPOSE4x4W %5, %6, %7, %1, %9 + movq [r0], m%5 + movq [r0+r1], m%6 + movq [r0+r1*2], m%7 + movq [r0+r4], m%1 +%else + TRANSPOSE2x4x4W %1, %2, %3, %4, %9 + movq [r0-8], m%1 + movq [r0+r1-8], m%2 + movq [r0+r1*2-8], m%3 + movq [r0+r5-8], m%4 + movhps [r4-8], m%1 + movhps [r4+r1-8], m%2 + movhps [r4+r1*2-8], m%3 + movhps [r4+r5-8], m%4 +%ifnum %8 + SWAP %1, %8 +%else + mova m%1, %8 +%endif + TRANSPOSE2x4x4W %5, %6, %7, %1, %9 + movq [r0], m%5 + movq [r0+r1], m%6 + movq [r0+r1*2], m%7 + movq [r0+r5], m%1 + movhps [r4], m%5 + movhps [r4+r1], m%6 + movhps [r4+r1*2], m%7 + movhps [r4+r5], m%1 +%endif +%endmacro + +%if ARCH_X86_64 +;----------------------------------------------------------------------------- +; void ff_deblock_v_luma_intra_10(uint16_t *pix, int stride, int alpha, +; int beta) +;----------------------------------------------------------------------------- +%macro DEBLOCK_LUMA_INTRA_64 0 +cglobal deblock_v_luma_intra_10, 4,7,16 + %define t0 m1 + %define t1 m2 + %define t2 m4 + %define p2 m8 + %define p1 m9 + %define p0 m10 + %define q0 m11 + %define q1 m12 + %define q2 m13 + %define aa m5 + %define bb m14 + lea r4, [r1*4] + lea r5, [r1*3] ; 3*stride + neg r4 + add r4, r0 ; pix-4*stride + mov r6, 2 + mova m0, [pw_2] + shl r2d, 2 + shl r3d, 2 + LOAD_AB aa, bb, r2d, r3d +.loop: + mova p2, [r4+r1] + mova p1, [r4+2*r1] + mova p0, [r4+r5] + mova q0, [r0] + mova q1, [r0+r1] + mova q2, [r0+2*r1] + + LOAD_MASK p1, p0, q0, q1, aa, bb, m3, t0, t1 + mova t2, aa + psrlw t2, 2 + paddw t2, m0 ; alpha/4+2 + DIFF_LT p0, q0, t2, m6, t0 ; m6 = |p0-q0| < alpha/4+2 + DIFF_LT p2, p0, bb, t1, t0 ; m7 = |p2-p0| < beta + DIFF_LT q2, q0, bb, m7, t0 ; t1 = |q2-q0| < beta + pand m6, m3 + pand m7, m6 + pand m6, t1 + LUMA_INTRA_P012 p0, p1, p2, [r4], q0, q1, m3, m6, m0, [r4+r5], [r4+2*r1], [r4+r1] + LUMA_INTRA_P012 q0, q1, q2, [r0+r5], p0, p1, m3, m7, m0, [r0], [r0+r1], [r0+2*r1] + add r0, mmsize + add r4, mmsize + dec r6 + jg .loop + REP_RET + +;----------------------------------------------------------------------------- +; void ff_deblock_h_luma_intra_10(uint16_t *pix, int stride, int alpha, +; int beta) +;----------------------------------------------------------------------------- +cglobal deblock_h_luma_intra_10, 4,7,16 + %define t0 m15 + %define t1 m14 + %define t2 m2 + %define q3 m5 + %define q2 m8 + %define q1 m9 + %define q0 m10 + %define p0 m11 + %define p1 m12 + %define p2 m13 + %define p3 m4 + %define spill [rsp] + %assign pad 24-(stack_offset&15) + SUB rsp, pad + lea r4, [r1*4] + lea r5, [r1*3] ; 3*stride + add r4, r0 ; pix+4*stride + mov r6, 2 + mova m0, [pw_2] + shl r2d, 2 + shl r3d, 2 +.loop: + movu q3, [r0-8] + movu q2, [r0+r1-8] + movu q1, [r0+r1*2-8] + movu q0, [r0+r5-8] + movu p0, [r4-8] + movu p1, [r4+r1-8] + movu p2, [r4+r1*2-8] + movu p3, [r4+r5-8] + TRANSPOSE8x8W 5, 8, 9, 10, 11, 12, 13, 4, 1 + + LOAD_AB m1, m2, r2d, r3d + LOAD_MASK q1, q0, p0, p1, m1, m2, m3, t0, t1 + psrlw m1, 2 + paddw m1, m0 ; alpha/4+2 + DIFF_LT p0, q0, m1, m6, t0 ; m6 = |p0-q0| < alpha/4+2 + DIFF_LT q2, q0, m2, t1, t0 ; t1 = |q2-q0| < beta + DIFF_LT p0, p2, m2, m7, t0 ; m7 = |p2-p0| < beta + pand m6, m3 + pand m7, m6 + pand m6, t1 + + mova spill, q3 + LUMA_INTRA_P012 q0, q1, q2, q3, p0, p1, m3, m6, m0, m5, m1, q2 + LUMA_INTRA_P012 p0, p1, p2, p3, q0, q1, m3, m7, m0, p0, m6, p2 + mova m7, spill + + LUMA_H_INTRA_STORE 7, 8, 1, 5, 11, 6, 13, 4, 14 + + lea r0, [r0+r1*8] + lea r4, [r4+r1*8] + dec r6 + jg .loop + ADD rsp, pad + RET +%endmacro + +INIT_XMM sse2 +DEBLOCK_LUMA_INTRA_64 +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_LUMA_INTRA_64 +%endif + +%endif + +%macro DEBLOCK_LUMA_INTRA 0 +;----------------------------------------------------------------------------- +; void ff_deblock_v_luma_intra_10(uint16_t *pix, int stride, int alpha, +; int beta) +;----------------------------------------------------------------------------- +cglobal deblock_v_luma_intra_10, 4,7,8*(mmsize/16) + LUMA_INTRA_INIT 3 + lea r4, [r1*4] + lea r5, [r1*3] + neg r4 + add r4, r0 + mov r6, 32/mmsize + shl r2d, 2 + shl r3d, 2 +.loop: + mova m0, [r4+r1*2] ; p1 + mova m1, [r4+r5] ; p0 + mova m2, [r0] ; q0 + mova m3, [r0+r1] ; q1 + LUMA_INTRA_INTER t4, t5, t6, [r4+r1], [r0+r1*2] + LUMA_INTRA_P012 m1, m0, t3, [r4], m2, m3, t5, t4, [pw_2], [r4+r5], [r4+2*r1], [r4+r1] + mova t3, [r0+r1*2] ; q2 + LUMA_INTRA_P012 m2, m3, t3, [r0+r5], m1, m0, t5, t6, [pw_2], [r0], [r0+r1], [r0+2*r1] + add r0, mmsize + add r4, mmsize + dec r6 + jg .loop + ADD rsp, pad + RET + +;----------------------------------------------------------------------------- +; void ff_deblock_h_luma_intra_10(uint16_t *pix, int stride, int alpha, +; int beta) +;----------------------------------------------------------------------------- +cglobal deblock_h_luma_intra_10, 4,7,8*(mmsize/16) + LUMA_INTRA_INIT 8 +%if mmsize == 8 + lea r4, [r1*3] + mov r5, 32/mmsize +%else + lea r4, [r1*4] + lea r5, [r1*3] ; 3*stride + add r4, r0 ; pix+4*stride + mov r6, 32/mmsize +%endif + shl r2d, 2 + shl r3d, 2 +.loop: + LUMA_H_INTRA_LOAD + LUMA_INTRA_INTER t8, t9, t10, t5, t6 + + LUMA_INTRA_P012 m1, m0, t3, t4, m2, m3, t9, t8, [pw_2], t8, t5, t11 + mova t3, t6 ; q2 + LUMA_INTRA_P012 m2, m3, t3, t7, m1, m0, t9, t10, [pw_2], m4, t6, m5 + + mova m2, t4 + mova m0, t11 + mova m1, t5 + mova m3, t8 + mova m6, t6 + + LUMA_H_INTRA_STORE 2, 0, 1, 3, 4, 6, 5, t7, 7 + + lea r0, [r0+r1*(mmsize/2)] +%if mmsize == 8 + dec r5 +%else + lea r4, [r4+r1*(mmsize/2)] + dec r6 +%endif + jg .loop + ADD rsp, pad + RET +%endmacro + +%if ARCH_X86_64 == 0 +INIT_MMX mmxext +DEBLOCK_LUMA +DEBLOCK_LUMA_INTRA +INIT_XMM sse2 +DEBLOCK_LUMA +DEBLOCK_LUMA_INTRA +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_LUMA +DEBLOCK_LUMA_INTRA +%endif +%endif + +; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp +; out: %1=p0', %2=q0' +%macro CHROMA_DEBLOCK_P0_Q0_INTRA 7 + mova %6, [pw_2] + paddw %6, %3 + paddw %6, %4 + paddw %7, %6, %2 + paddw %6, %1 + paddw %6, %3 + paddw %7, %4 + psraw %6, 2 + psraw %7, 2 + psubw %6, %1 + psubw %7, %2 + pand %6, %5 + pand %7, %5 + paddw %1, %6 + paddw %2, %7 +%endmacro + +%macro CHROMA_V_LOAD 1 + mova m0, [r0] ; p1 + mova m1, [r0+r1] ; p0 + mova m2, [%1] ; q0 + mova m3, [%1+r1] ; q1 +%endmacro + +%macro CHROMA_V_STORE 0 + mova [r0+1*r1], m1 + mova [r0+2*r1], m2 +%endmacro + +; in: 8 rows of 4 words in %4..%11 +; out: 4 rows of 8 words in m0..m3 +%macro TRANSPOSE4x8W_LOAD 8 + movq m0, %1 + movq m2, %2 + movq m1, %3 + movq m3, %4 + + punpcklwd m0, m2 + punpcklwd m1, m3 + punpckhdq m2, m0, m1 + punpckldq m0, m1 + + movq m4, %5 + movq m6, %6 + movq m5, %7 + movq m3, %8 + + punpcklwd m4, m6 + punpcklwd m5, m3 + punpckhdq m6, m4, m5 + punpckldq m4, m5 + + punpckhqdq m1, m0, m4 + punpcklqdq m0, m4 + punpckhqdq m3, m2, m6 + punpcklqdq m2, m6 +%endmacro + +; in: 4 rows of 8 words in m0..m3 +; out: 8 rows of 4 words in %1..%8 +%macro TRANSPOSE8x4W_STORE 8 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + movq %1, m0 + movhps %2, m0 + movq %3, m1 + movhps %4, m1 + movq %5, m2 + movhps %6, m2 + movq %7, m3 + movhps %8, m3 +%endmacro + +; %1 = base + 3*stride +; %2 = 3*stride (unused on mmx) +; %3, %4 = place to store p1 and q1 values +%macro CHROMA_H_LOAD 4 + %if mmsize == 8 + movq m0, [pix_q - 4] + movq m1, [pix_q + stride_q - 4] + movq m2, [pix_q + 2*stride_q - 4] + movq m3, [%1 - 4] + TRANSPOSE4x4W 0, 1, 2, 3, 4 + %else + TRANSPOSE4x8W_LOAD PASS8ROWS(pix_q-4, %1-4, stride_q, %2) + %endif + mova %3, m0 + mova %4, m3 +%endmacro + +; %1 = base + 3*stride +; %2 = 3*stride (unused on mmx) +; %3, %4 = place to load p1 and q1 values +%macro CHROMA_H_STORE 4 + mova m0, %3 + mova m3, %4 + %if mmsize == 8 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + movq [pix_q - 4], m0 + movq [pix_q + stride_q - 4], m1 + movq [pix_q + 2*stride_q - 4], m2 + movq [%1 - 4], m3 + %else + TRANSPOSE8x4W_STORE PASS8ROWS(pix_q-4, %1-4, stride_q, %2) + %endif +%endmacro + +%macro CHROMA_V_LOAD_TC 2 + movd %1, [%2] + punpcklbw %1, %1 + punpcklwd %1, %1 + psraw %1, 6 +%endmacro + +%macro DEBLOCK_CHROMA 0 +;----------------------------------------------------------------------------- +; void ff_deblock_v_chroma_10(uint16_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_v_chroma_10, 5,7-(mmsize/16),8*(mmsize/16) + mov r5, r0 + sub r0, r1 + sub r0, r1 + shl r2d, 2 + shl r3d, 2 +%if mmsize < 16 + mov r6, 16/mmsize +.loop: +%endif + CHROMA_V_LOAD r5 + LOAD_AB m4, m5, r2d, r3d + LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 + pxor m4, m4 + CHROMA_V_LOAD_TC m6, r4 + psubw m6, [pw_3] + pmaxsw m6, m4 + pand m7, m6 + DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6 + CHROMA_V_STORE +%if mmsize < 16 + add r0, mmsize + add r5, mmsize + add r4, mmsize/4 + dec r6 + jg .loop + REP_RET +%else + RET +%endif + +;----------------------------------------------------------------------------- +; void ff_deblock_v_chroma_intra_10(uint16_t *pix, int stride, int alpha, +; int beta) +;----------------------------------------------------------------------------- +cglobal deblock_v_chroma_intra_10, 4,6-(mmsize/16),8*(mmsize/16) + mov r4, r0 + sub r0, r1 + sub r0, r1 + shl r2d, 2 + shl r3d, 2 +%if mmsize < 16 + mov r5, 16/mmsize +.loop: +%endif + CHROMA_V_LOAD r4 + LOAD_AB m4, m5, r2d, r3d + LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 + CHROMA_DEBLOCK_P0_Q0_INTRA m1, m2, m0, m3, m7, m5, m6 + CHROMA_V_STORE +%if mmsize < 16 + add r0, mmsize + add r4, mmsize + dec r5 + jg .loop + REP_RET +%else + RET +%endif + +;----------------------------------------------------------------------------- +; void ff_deblock_h_chroma_10(uint16_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_h_chroma_10, 5, 7, 8, 0-2*mmsize, pix_, stride_, alpha_, beta_, tc0_ + shl alpha_d, 2 + shl beta_d, 2 + mov r5, pix_q + lea r6, [3*stride_q] + add r5, r6 +%if mmsize == 8 + mov r6d, 2 + .loop: +%endif + + CHROMA_H_LOAD r5, r6, [rsp], [rsp + mmsize] + LOAD_AB m4, m5, alpha_d, beta_d + LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 + pxor m4, m4 + CHROMA_V_LOAD_TC m6, tc0_q + psubw m6, [pw_3] + pmaxsw m6, m4 + pand m7, m6 + DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6 + CHROMA_H_STORE r5, r6, [rsp], [rsp + mmsize] + +%if mmsize == 8 + lea pix_q, [pix_q + 4*stride_q] + lea r5, [r5 + 4*stride_q] + add tc0_q, 2 + dec r6d + jg .loop +%endif +RET + +;----------------------------------------------------------------------------- +; void ff_deblock_h_chroma422_10(uint16_t *pix, int stride, int alpha, int beta, +; int8_t *tc0) +;----------------------------------------------------------------------------- +cglobal deblock_h_chroma422_10, 5, 7, 8, 0-3*mmsize, pix_, stride_, alpha_, beta_, tc0_ + shl alpha_d, 2 + shl beta_d, 2 + + movd m0, [tc0_q] + punpcklbw m0, m0 + psraw m0, 6 + movq [rsp], m0 + + mov r5, pix_q + lea r6, [3*stride_q] + add r5, r6 + + mov r4, -8 + .loop: + + CHROMA_H_LOAD r5, r6, [rsp + 1*mmsize], [rsp + 2*mmsize] + LOAD_AB m4, m5, alpha_d, beta_d + LOAD_MASK m0, m1, m2, m3, m4, m5, m7, m6, m4 + pxor m4, m4 + movd m6, [rsp + r4 + 8] + punpcklwd m6, m6 + punpcklwd m6, m6 + psubw m6, [pw_3] + pmaxsw m6, m4 + pand m7, m6 + DEBLOCK_P0_Q0 m1, m2, m0, m3, m7, m5, m6 + CHROMA_H_STORE r5, r6, [rsp + 1*mmsize], [rsp + 2*mmsize] + + lea pix_q, [pix_q + (mmsize/2)*stride_q] + lea r5, [r5 + (mmsize/2)*stride_q] + add r4, (mmsize/4) + jl .loop +RET + +%endmacro + +%if ARCH_X86_64 == 0 +INIT_MMX mmxext +DEBLOCK_CHROMA +%endif +INIT_XMM sse2 +DEBLOCK_CHROMA +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEBLOCK_CHROMA +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_idct.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_idct.asm new file mode 100644 index 00000000..c54f9f1a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_idct.asm @@ -0,0 +1,1199 @@ +;***************************************************************************** +;* MMX/SSE2-optimized H.264 iDCT +;***************************************************************************** +;* Copyright (C) 2004-2005 Michael Niedermayer, Loren Merritt +;* Copyright (C) 2003-2008 x264 project +;* +;* Authors: Laurent Aimar +;* Loren Merritt +;* Holger Lubitz +;* Min Chen +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +scan8_mem: db 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8 + db 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8 + db 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8 + db 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8 + db 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8 + db 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8 + db 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8 + db 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8 + db 4+11*8, 5+11*8, 4+12*8, 5+12*8 + db 6+11*8, 7+11*8, 6+12*8, 7+12*8 + db 4+13*8, 5+13*8, 4+14*8, 5+14*8 + db 6+13*8, 7+13*8, 6+14*8, 7+14*8 +%ifdef PIC +%define npicregs 1 +%define scan8 picregq +%else +%define npicregs 0 +%define scan8 scan8_mem +%endif + +cextern pw_32 +cextern pw_1 + +SECTION .text + +; %1=uint8_t *dst, %2=int16_t *block, %3=int stride +%macro IDCT4_ADD 3 + ; Load dct coeffs + movq m0, [%2] + movq m1, [%2+8] + movq m2, [%2+16] + movq m3, [%2+24] + + IDCT4_1D w, 0, 1, 2, 3, 4, 5 + mova m6, [pw_32] + %if mmsize == 8 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + %else + punpcklwd m0, m1 + punpcklwd m2, m3 + SBUTTERFLY dq, 0, 2, 4 + MOVHL m1, m0 + MOVHL m3, m2 + %endif + paddw m0, m6 + IDCT4_1D w, 0, 1, 2, 3, 4, 5 + pxor m7, m7 + movq [%2+ 0], m7 + movq [%2+ 8], m7 + movq [%2+16], m7 + movq [%2+24], m7 + + STORE_DIFFx2 m0, m1, m4, m5, m7, 6, %1, %3 + lea %1, [%1+%3*2] + STORE_DIFFx2 m2, m3, m4, m5, m7, 6, %1, %3 +%endmacro + +INIT_MMX mmx +; void ff_h264_idct_add_8_mmx(uint8_t *dst, int16_t *block, int stride) +cglobal h264_idct_add_8, 3, 3, 0 + movsxdifnidn r2, r2d + IDCT4_ADD r0, r1, r2 + RET + +%macro IDCT8_1D 2 + psraw m0, m1, 1 + SWAP 0, 1 + psraw m4, m5, 1 + paddw m4, m5 + paddw m1, m0 + paddw m4, m7 + paddw m1, m5 + psubw m4, m0 + paddw m1, m3 + + psubw m0, m3 + psubw m5, m3 + psraw m3, 1 + paddw m0, m7 + psubw m5, m7 + psraw m7, 1 + psubw m0, m3 + psubw m5, m7 + + psraw m7, m1, 2 + SWAP 7,1 + psraw m3, m4, 2 + paddw m3, m0 + psraw m0, 2 + paddw m1, m5 + psraw m5, 2 + psubw m0, m4 + psubw m7, m5 + + psraw m5, m6, 1 + SWAP 5,6 + psraw m4, m2, 1 + paddw m6, m2 + psubw m4, m5 + + mova m2, %1 + mova m5, %2 + SUMSUB_BA w, 5, 2 + SUMSUB_BA w, 6, 5 + SUMSUB_BA w, 4, 2 + SUMSUB_BA w, 7, 6 + SUMSUB_BA w, 0, 4 + SUMSUB_BA w, 3, 2 + SUMSUB_BA w, 1, 5 + SWAP 7, 6, 4, 5, 2, 3, 1, 0 ; 70315246 -> 01234567 +%endmacro + +%macro IDCT8_1D_FULL 1 + mova m7, [%1+112] + mova m6, [%1+ 96] + mova m5, [%1+ 80] + mova m3, [%1+ 48] + mova m2, [%1+ 32] + mova m1, [%1+ 16] + IDCT8_1D [%1], [%1+ 64] +%endmacro + +; %1=int16_t *block, %2=int16_t *dstblock +%macro IDCT8_ADD_MMX_START 2 + IDCT8_1D_FULL %1 + mova [%1], m7 + TRANSPOSE4x4W 0, 1, 2, 3, 7 + mova m7, [%1] + mova [%2 ], m0 + mova [%2+16], m1 + mova [%2+32], m2 + mova [%2+48], m3 + TRANSPOSE4x4W 4, 5, 6, 7, 3 + mova [%2+ 8], m4 + mova [%2+24], m5 + mova [%2+40], m6 + mova [%2+56], m7 +%endmacro + +; %1=uint8_t *dst, %2=int16_t *block, %3=int stride +%macro IDCT8_ADD_MMX_END 3-4 + IDCT8_1D_FULL %2 + mova [%2 ], m5 + mova [%2+16], m6 + mova [%2+32], m7 + + pxor m7, m7 +%if %0 == 4 + movq [%4+ 0], m7 + movq [%4+ 8], m7 + movq [%4+ 16], m7 + movq [%4+ 24], m7 + movq [%4+ 32], m7 + movq [%4+ 40], m7 + movq [%4+ 48], m7 + movq [%4+ 56], m7 + movq [%4+ 64], m7 + movq [%4+ 72], m7 + movq [%4+ 80], m7 + movq [%4+ 88], m7 + movq [%4+ 96], m7 + movq [%4+104], m7 + movq [%4+112], m7 + movq [%4+120], m7 +%endif + STORE_DIFFx2 m0, m1, m5, m6, m7, 6, %1, %3 + lea %1, [%1+%3*2] + STORE_DIFFx2 m2, m3, m5, m6, m7, 6, %1, %3 + mova m0, [%2 ] + mova m1, [%2+16] + mova m2, [%2+32] + lea %1, [%1+%3*2] + STORE_DIFFx2 m4, m0, m5, m6, m7, 6, %1, %3 + lea %1, [%1+%3*2] + STORE_DIFFx2 m1, m2, m5, m6, m7, 6, %1, %3 +%endmacro + +INIT_MMX mmx +; void ff_h264_idct8_add_8_mmx(uint8_t *dst, int16_t *block, int stride) +cglobal h264_idct8_add_8, 3, 4, 0 + movsxdifnidn r2, r2d + %assign pad 128+4-(stack_offset&7) + SUB rsp, pad + + add word [r1], 32 + IDCT8_ADD_MMX_START r1 , rsp + IDCT8_ADD_MMX_START r1+8, rsp+64 + lea r3, [r0+4] + IDCT8_ADD_MMX_END r0 , rsp, r2, r1 + IDCT8_ADD_MMX_END r3 , rsp+8, r2 + + ADD rsp, pad + RET + +; %1=uint8_t *dst, %2=int16_t *block, %3=int stride +%macro IDCT8_ADD_SSE 4 + IDCT8_1D_FULL %2 +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%2], [%2+16] +%endif + paddw m0, [pw_32] + +%if ARCH_X86_64 == 0 + mova [%2 ], m0 + mova [%2+16], m4 + IDCT8_1D [%2], [%2+ 16] + mova [%2 ], m6 + mova [%2+16], m7 +%else + SWAP 0, 8 + SWAP 4, 9 + IDCT8_1D m8, m9 + SWAP 6, 8 + SWAP 7, 9 +%endif + + pxor m7, m7 + lea %4, [%3*3] + STORE_DIFF m0, m6, m7, [%1 ] + STORE_DIFF m1, m6, m7, [%1+%3 ] + STORE_DIFF m2, m6, m7, [%1+%3*2] + STORE_DIFF m3, m6, m7, [%1+%4 ] +%if ARCH_X86_64 == 0 + mova m0, [%2 ] + mova m1, [%2+16] +%else + SWAP 0, 8 + SWAP 1, 9 +%endif + mova [%2+ 0], m7 + mova [%2+ 16], m7 + mova [%2+ 32], m7 + mova [%2+ 48], m7 + mova [%2+ 64], m7 + mova [%2+ 80], m7 + mova [%2+ 96], m7 + mova [%2+112], m7 + lea %1, [%1+%3*4] + STORE_DIFF m4, m6, m7, [%1 ] + STORE_DIFF m5, m6, m7, [%1+%3 ] + STORE_DIFF m0, m6, m7, [%1+%3*2] + STORE_DIFF m1, m6, m7, [%1+%4 ] +%endmacro + +INIT_XMM sse2 +; void ff_h264_idct8_add_8_sse2(uint8_t *dst, int16_t *block, int stride) +cglobal h264_idct8_add_8, 3, 4, 10 + movsxdifnidn r2, r2d + IDCT8_ADD_SSE r0, r1, r2, r3 + RET + +%macro DC_ADD_MMXEXT_INIT 2 + add %1, 32 + sar %1, 6 + movd m0, %1d + lea %1, [%2*3] + pshufw m0, m0, 0 + pxor m1, m1 + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 +%endmacro + +%macro DC_ADD_MMXEXT_OP 4 + %1 m2, [%2 ] + %1 m3, [%2+%3 ] + %1 m4, [%2+%3*2] + %1 m5, [%2+%4 ] + paddusb m2, m0 + paddusb m3, m0 + paddusb m4, m0 + paddusb m5, m0 + psubusb m2, m1 + psubusb m3, m1 + psubusb m4, m1 + psubusb m5, m1 + %1 [%2 ], m2 + %1 [%2+%3 ], m3 + %1 [%2+%3*2], m4 + %1 [%2+%4 ], m5 +%endmacro + +INIT_MMX mmxext +; void ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) +%if ARCH_X86_64 +cglobal h264_idct_dc_add_8, 3, 4, 0 + movsxd r2, r2d + movsx r3, word [r1] + mov dword [r1], 0 + DC_ADD_MMXEXT_INIT r3, r2 + DC_ADD_MMXEXT_OP movh, r0, r2, r3 + RET + +; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) +cglobal h264_idct8_dc_add_8, 3, 4, 0 + movsxd r2, r2d + movsx r3, word [r1] + mov dword [r1], 0 + DC_ADD_MMXEXT_INIT r3, r2 + DC_ADD_MMXEXT_OP mova, r0, r2, r3 + lea r0, [r0+r2*4] + DC_ADD_MMXEXT_OP mova, r0, r2, r3 + RET +%else +; void ff_h264_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) +cglobal h264_idct_dc_add_8, 2, 3, 0 + movsx r2, word [r1] + mov dword [r1], 0 + mov r1, r2m + DC_ADD_MMXEXT_INIT r2, r1 + DC_ADD_MMXEXT_OP movh, r0, r1, r2 + RET + +; void ff_h264_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *block, int stride) +cglobal h264_idct8_dc_add_8, 2, 3, 0 + movsx r2, word [r1] + mov dword [r1], 0 + mov r1, r2m + DC_ADD_MMXEXT_INIT r2, r1 + DC_ADD_MMXEXT_OP mova, r0, r1, r2 + lea r0, [r0+r1*4] + DC_ADD_MMXEXT_OP mova, r0, r1, r2 + RET +%endif + +INIT_MMX mmx +; void ff_h264_idct_add16_8_mmx(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add16_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg + movsxdifnidn r3, r3d + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .skipblock + mov r6d, dword [r1+r5*4] + lea r6, [r0+r6] + IDCT4_ADD r6, r2, r3 +.skipblock: + inc r5 + add r2, 32 + cmp r5, 16 + jl .nextblock + REP_RET + +; void ff_h264_idct8_add4_8_mmx(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct8_add4_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg + movsxdifnidn r3, r3d + %assign pad 128+4-(stack_offset&7) + SUB rsp, pad + + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .skipblock + mov r6d, dword [r1+r5*4] + add r6, r0 + add word [r2], 32 + IDCT8_ADD_MMX_START r2 , rsp + IDCT8_ADD_MMX_START r2+8, rsp+64 + IDCT8_ADD_MMX_END r6 , rsp, r3, r2 + mov r6d, dword [r1+r5*4] + lea r6, [r0+r6+4] + IDCT8_ADD_MMX_END r6 , rsp+8, r3 +.skipblock: + add r5, 4 + add r2, 128 + cmp r5, 16 + jl .nextblock + ADD rsp, pad + RET + +INIT_MMX mmxext +; void ff_h264_idct_add16_8_mmxext(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add16_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .skipblock + cmp r6, 1 + jnz .no_dc + movsx r6, word [r2] + test r6, r6 + jz .no_dc + mov word [r2], 0 + DC_ADD_MMXEXT_INIT r6, r3 +%if ARCH_X86_64 == 0 +%define dst2q r1 +%define dst2d r1d +%endif + mov dst2d, dword [r1+r5*4] + lea dst2q, [r0+dst2q] + DC_ADD_MMXEXT_OP movh, dst2q, r3, r6 +%if ARCH_X86_64 == 0 + mov r1, r1m +%endif + inc r5 + add r2, 32 + cmp r5, 16 + jl .nextblock + REP_RET +.no_dc: + mov r6d, dword [r1+r5*4] + add r6, r0 + IDCT4_ADD r6, r2, r3 +.skipblock: + inc r5 + add r2, 32 + cmp r5, 16 + jl .nextblock + REP_RET + +INIT_MMX mmx +; void ff_h264_idct_add16intra_8_mmx(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add16intra_8, 5, 7 + npicregs, 0, dst, block_offset, block, stride, nnzc, cntr, coeff, picreg + movsxdifnidn r3, r3d + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + or r6w, word [r2] + test r6, r6 + jz .skipblock + mov r6d, dword [r1+r5*4] + add r6, r0 + IDCT4_ADD r6, r2, r3 +.skipblock: + inc r5 + add r2, 32 + cmp r5, 16 + jl .nextblock + REP_RET + +INIT_MMX mmxext +; void ff_h264_idct_add16intra_8_mmxext(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add16intra_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .try_dc + mov r6d, dword [r1+r5*4] + lea r6, [r0+r6] + IDCT4_ADD r6, r2, r3 + inc r5 + add r2, 32 + cmp r5, 16 + jl .nextblock + REP_RET +.try_dc: + movsx r6, word [r2] + test r6, r6 + jz .skipblock + mov word [r2], 0 + DC_ADD_MMXEXT_INIT r6, r3 +%if ARCH_X86_64 == 0 +%define dst2q r1 +%define dst2d r1d +%endif + mov dst2d, dword [r1+r5*4] + add dst2q, r0 + DC_ADD_MMXEXT_OP movh, dst2q, r3, r6 +%if ARCH_X86_64 == 0 + mov r1, r1m +%endif +.skipblock: + inc r5 + add r2, 32 + cmp r5, 16 + jl .nextblock + REP_RET + +; void ff_h264_idct8_add4_8_mmxext(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct8_add4_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d + %assign pad 128+4-(stack_offset&7) + SUB rsp, pad + + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .skipblock + cmp r6, 1 + jnz .no_dc + movsx r6, word [r2] + test r6, r6 + jz .no_dc + mov word [r2], 0 + DC_ADD_MMXEXT_INIT r6, r3 +%if ARCH_X86_64 == 0 +%define dst2q r1 +%define dst2d r1d +%endif + mov dst2d, dword [r1+r5*4] + lea dst2q, [r0+dst2q] + DC_ADD_MMXEXT_OP mova, dst2q, r3, r6 + lea dst2q, [dst2q+r3*4] + DC_ADD_MMXEXT_OP mova, dst2q, r3, r6 +%if ARCH_X86_64 == 0 + mov r1, r1m +%endif + add r5, 4 + add r2, 128 + cmp r5, 16 + jl .nextblock + + ADD rsp, pad + RET +.no_dc: + mov r6d, dword [r1+r5*4] + add r6, r0 + add word [r2], 32 + IDCT8_ADD_MMX_START r2 , rsp + IDCT8_ADD_MMX_START r2+8, rsp+64 + IDCT8_ADD_MMX_END r6 , rsp, r3, r2 + mov r6d, dword [r1+r5*4] + lea r6, [r0+r6+4] + IDCT8_ADD_MMX_END r6 , rsp+8, r3 +.skipblock: + add r5, 4 + add r2, 128 + cmp r5, 16 + jl .nextblock + + ADD rsp, pad + RET + +INIT_XMM sse2 +; void ff_h264_idct8_add4_8_sse2(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct8_add4_8, 5, 8 + npicregs, 10, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d + xor r5, r5 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .skipblock + cmp r6, 1 + jnz .no_dc + movsx r6, word [r2] + test r6, r6 + jz .no_dc +INIT_MMX cpuname + mov word [r2], 0 + DC_ADD_MMXEXT_INIT r6, r3 +%if ARCH_X86_64 == 0 +%define dst2q r1 +%define dst2d r1d +%endif + mov dst2d, dword [r1+r5*4] + add dst2q, r0 + DC_ADD_MMXEXT_OP mova, dst2q, r3, r6 + lea dst2q, [dst2q+r3*4] + DC_ADD_MMXEXT_OP mova, dst2q, r3, r6 +%if ARCH_X86_64 == 0 + mov r1, r1m +%endif + add r5, 4 + add r2, 128 + cmp r5, 16 + jl .nextblock + REP_RET +.no_dc: +INIT_XMM cpuname + mov dst2d, dword [r1+r5*4] + add dst2q, r0 + IDCT8_ADD_SSE dst2q, r2, r3, r6 +%if ARCH_X86_64 == 0 + mov r1, r1m +%endif +.skipblock: + add r5, 4 + add r2, 128 + cmp r5, 16 + jl .nextblock + REP_RET + +INIT_MMX mmx +h264_idct_add8_mmx_plane: + movsxdifnidn r3, r3d +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + or r6w, word [r2] + test r6, r6 + jz .skipblock +%if ARCH_X86_64 + mov r0d, dword [r1+r5*4] + add r0, [dst2q] +%else + mov r0, r1m ; XXX r1m here is actually r0m of the calling func + mov r0, [r0] + add r0, dword [r1+r5*4] +%endif + IDCT4_ADD r0, r2, r3 +.skipblock: + inc r5 + add r2, 32 + test r5, 3 + jnz .nextblock + rep ret + +; void ff_h264_idct_add8_8_mmx(uint8_t **dest, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d + mov r5, 16 + add r2, 512 +%ifdef PIC + lea picregq, [scan8_mem] +%endif +%if ARCH_X86_64 + mov dst2q, r0 +%endif + call h264_idct_add8_mmx_plane + mov r5, 32 + add r2, 384 +%if ARCH_X86_64 + add dst2q, gprsize +%else + add r0mp, gprsize +%endif + call h264_idct_add8_mmx_plane + RET ; TODO: check rep ret after a function call + +cglobal h264_idct_add8_422_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg +; dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d +%ifdef PIC + lea picregq, [scan8_mem] +%endif +%if ARCH_X86_64 + mov dst2q, r0 +%endif + + mov r5, 16 ; i + add r2, 512 ; i * 16 * sizeof(dctcoef) ; #define dctcoef int16_t + + call h264_idct_add8_mmx_plane + add r5, 4 + call h264_idct_add8_mmx_plane + +%if ARCH_X86_64 + add dst2q, gprsize ; dest[1] +%else + add r0mp, gprsize +%endif + + add r5, 4 ; set to 32 + add r2, 256 ; set to i * 16 * sizeof(dctcoef) + + call h264_idct_add8_mmx_plane + add r5, 4 + call h264_idct_add8_mmx_plane + + RET ; TODO: check rep ret after a function call + +h264_idct_add8_mmxext_plane: + movsxdifnidn r3, r3d +.nextblock: + movzx r6, byte [scan8+r5] + movzx r6, byte [r4+r6] + test r6, r6 + jz .try_dc +%if ARCH_X86_64 + mov r0d, dword [r1+r5*4] + add r0, [dst2q] +%else + mov r0, r1m ; XXX r1m here is actually r0m of the calling func + mov r0, [r0] + add r0, dword [r1+r5*4] +%endif + IDCT4_ADD r0, r2, r3 + inc r5 + add r2, 32 + test r5, 3 + jnz .nextblock + rep ret +.try_dc: + movsx r6, word [r2] + test r6, r6 + jz .skipblock + mov word [r2], 0 + DC_ADD_MMXEXT_INIT r6, r3 +%if ARCH_X86_64 + mov r0d, dword [r1+r5*4] + add r0, [dst2q] +%else + mov r0, r1m ; XXX r1m here is actually r0m of the calling func + mov r0, [r0] + add r0, dword [r1+r5*4] +%endif + DC_ADD_MMXEXT_OP movh, r0, r3, r6 +.skipblock: + inc r5 + add r2, 32 + test r5, 3 + jnz .nextblock + rep ret + +INIT_MMX mmxext +; void ff_h264_idct_add8_8_mmxext(uint8_t **dest, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add8_8, 5, 8 + npicregs, 0, dst1, block_offset, block, stride, nnzc, cntr, coeff, dst2, picreg + movsxdifnidn r3, r3d + mov r5, 16 + add r2, 512 +%if ARCH_X86_64 + mov dst2q, r0 +%endif +%ifdef PIC + lea picregq, [scan8_mem] +%endif + call h264_idct_add8_mmxext_plane + mov r5, 32 + add r2, 384 +%if ARCH_X86_64 + add dst2q, gprsize +%else + add r0mp, gprsize +%endif + call h264_idct_add8_mmxext_plane + RET ; TODO: check rep ret after a function call + +; r0 = uint8_t *dst, r2 = int16_t *block, r3 = int stride, r6=clobbered +h264_idct_dc_add8_mmxext: + movsxdifnidn r3, r3d + movd m0, [r2 ] ; 0 0 X D + mov word [r2+ 0], 0 + punpcklwd m0, [r2+32] ; x X d D + mov word [r2+32], 0 + paddsw m0, [pw_32] + psraw m0, 6 + punpcklwd m0, m0 ; d d D D + pxor m1, m1 ; 0 0 0 0 + psubw m1, m0 ; -d-d-D-D + packuswb m0, m1 ; -d-d-D-D d d D D + pshufw m1, m0, 0xFA ; -d-d-d-d-D-D-D-D + punpcklwd m0, m0 ; d d d d D D D D + lea r6, [r3*3] + DC_ADD_MMXEXT_OP movq, r0, r3, r6 + ret + +ALIGN 16 +INIT_XMM sse2 +; r0 = uint8_t *dst (clobbered), r2 = int16_t *block, r3 = int stride +h264_add8x4_idct_sse2: + movsxdifnidn r3, r3d + movq m0, [r2+ 0] + movq m1, [r2+ 8] + movq m2, [r2+16] + movq m3, [r2+24] + movhps m0, [r2+32] + movhps m1, [r2+40] + movhps m2, [r2+48] + movhps m3, [r2+56] + IDCT4_1D w,0,1,2,3,4,5 + TRANSPOSE2x4x4W 0,1,2,3,4 + paddw m0, [pw_32] + IDCT4_1D w,0,1,2,3,4,5 + pxor m7, m7 + mova [r2+ 0], m7 + mova [r2+16], m7 + mova [r2+32], m7 + mova [r2+48], m7 + STORE_DIFFx2 m0, m1, m4, m5, m7, 6, r0, r3 + lea r0, [r0+r3*2] + STORE_DIFFx2 m2, m3, m4, m5, m7, 6, r0, r3 + ret + +%macro add16_sse2_cycle 2 + movzx r0, word [r4+%2] + test r0, r0 + jz .cycle%1end + mov r0d, dword [r1+%1*8] +%if ARCH_X86_64 + add r0, r5 +%else + add r0, r0m +%endif + call h264_add8x4_idct_sse2 +.cycle%1end: +%if %1 < 7 + add r2, 64 +%endif +%endmacro + +; void ff_h264_idct_add16_8_sse2(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add16_8, 5, 5 + ARCH_X86_64, 8 + movsxdifnidn r3, r3d +%if ARCH_X86_64 + mov r5, r0 +%endif + ; unrolling of the loop leads to an average performance gain of + ; 20-25% + add16_sse2_cycle 0, 0xc + add16_sse2_cycle 1, 0x14 + add16_sse2_cycle 2, 0xe + add16_sse2_cycle 3, 0x16 + add16_sse2_cycle 4, 0x1c + add16_sse2_cycle 5, 0x24 + add16_sse2_cycle 6, 0x1e + add16_sse2_cycle 7, 0x26 +REP_RET + +%macro add16intra_sse2_cycle 2 + movzx r0, word [r4+%2] + test r0, r0 + jz .try%1dc + mov r0d, dword [r1+%1*8] +%if ARCH_X86_64 + add r0, r7 +%else + add r0, r0m +%endif + call h264_add8x4_idct_sse2 + jmp .cycle%1end +.try%1dc: + movsx r0, word [r2 ] + or r0w, word [r2+32] + jz .cycle%1end + mov r0d, dword [r1+%1*8] +%if ARCH_X86_64 + add r0, r7 +%else + add r0, r0m +%endif + call h264_idct_dc_add8_mmxext +.cycle%1end: +%if %1 < 7 + add r2, 64 +%endif +%endmacro + +; void ff_h264_idct_add16intra_8_sse2(uint8_t *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add16intra_8, 5, 7 + ARCH_X86_64, 8 + movsxdifnidn r3, r3d +%if ARCH_X86_64 + mov r7, r0 +%endif + add16intra_sse2_cycle 0, 0xc + add16intra_sse2_cycle 1, 0x14 + add16intra_sse2_cycle 2, 0xe + add16intra_sse2_cycle 3, 0x16 + add16intra_sse2_cycle 4, 0x1c + add16intra_sse2_cycle 5, 0x24 + add16intra_sse2_cycle 6, 0x1e + add16intra_sse2_cycle 7, 0x26 +REP_RET + +%macro add8_sse2_cycle 2 + movzx r0, word [r4+%2] + test r0, r0 + jz .try%1dc +%if ARCH_X86_64 + mov r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))] + add r0, [r7] +%else + mov r0, r0m + mov r0, [r0] + add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] +%endif + call h264_add8x4_idct_sse2 + jmp .cycle%1end +.try%1dc: + movsx r0, word [r2 ] + or r0w, word [r2+32] + jz .cycle%1end +%if ARCH_X86_64 + mov r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))] + add r0, [r7] +%else + mov r0, r0m + mov r0, [r0] + add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] +%endif + call h264_idct_dc_add8_mmxext +.cycle%1end: +%if %1 == 1 + add r2, 384+64 +%elif %1 < 3 + add r2, 64 +%endif +%endmacro + +; void ff_h264_idct_add8_8_sse2(uint8_t **dest, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6 * 8]) +cglobal h264_idct_add8_8, 5, 7 + ARCH_X86_64, 8 + movsxdifnidn r3, r3d + add r2, 512 +%if ARCH_X86_64 + mov r7, r0 +%endif + add8_sse2_cycle 0, 0x34 + add8_sse2_cycle 1, 0x3c +%if ARCH_X86_64 + add r7, gprsize +%else + add r0mp, gprsize +%endif + add8_sse2_cycle 2, 0x5c + add8_sse2_cycle 3, 0x64 +REP_RET + +;void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul) + +%macro WALSH4_1D 5 + SUMSUB_BADC w, %4, %3, %2, %1, %5 + SUMSUB_BADC w, %4, %2, %3, %1, %5 + SWAP %1, %4, %3 +%endmacro + +%macro DEQUANT 1-3 +%if cpuflag(sse2) + movd xmm4, t3d + movq xmm5, [pw_1] + pshufd xmm4, xmm4, 0 + movq2dq xmm0, m0 + movq2dq xmm1, m1 + movq2dq xmm2, m2 + movq2dq xmm3, m3 + punpcklwd xmm0, xmm5 + punpcklwd xmm1, xmm5 + punpcklwd xmm2, xmm5 + punpcklwd xmm3, xmm5 + pmaddwd xmm0, xmm4 + pmaddwd xmm1, xmm4 + pmaddwd xmm2, xmm4 + pmaddwd xmm3, xmm4 + psrad xmm0, %1 + psrad xmm1, %1 + psrad xmm2, %1 + psrad xmm3, %1 + packssdw xmm0, xmm1 + packssdw xmm2, xmm3 +%else + mova m7, [pw_1] + mova m4, %1 + punpcklwd %1, m7 + punpckhwd m4, m7 + mova m5, %2 + punpcklwd %2, m7 + punpckhwd m5, m7 + movd m7, t3d + punpckldq m7, m7 + pmaddwd %1, m7 + pmaddwd %2, m7 + pmaddwd m4, m7 + pmaddwd m5, m7 + psrad %1, %3 + psrad %2, %3 + psrad m4, %3 + psrad m5, %3 + packssdw %1, m4 + packssdw %2, m5 +%endif +%endmacro + +%macro STORE_WORDS 5-9 +%if cpuflag(sse) + movd t0d, %1 + psrldq %1, 4 + movd t1d, %1 + psrldq %1, 4 + mov [t2+%2*32], t0w + mov [t2+%4*32], t1w + shr t0d, 16 + shr t1d, 16 + mov [t2+%3*32], t0w + mov [t2+%5*32], t1w + movd t0d, %1 + psrldq %1, 4 + movd t1d, %1 + mov [t2+%6*32], t0w + mov [t2+%8*32], t1w + shr t0d, 16 + shr t1d, 16 + mov [t2+%7*32], t0w + mov [t2+%9*32], t1w +%else + movd t0d, %1 + psrlq %1, 32 + movd t1d, %1 + mov [t2+%2*32], t0w + mov [t2+%4*32], t1w + shr t0d, 16 + shr t1d, 16 + mov [t2+%3*32], t0w + mov [t2+%5*32], t1w +%endif +%endmacro + +%macro DEQUANT_STORE 1 +%if cpuflag(sse2) + DEQUANT %1 + STORE_WORDS xmm0, 0, 1, 4, 5, 2, 3, 6, 7 + STORE_WORDS xmm2, 8, 9, 12, 13, 10, 11, 14, 15 +%else + DEQUANT m0, m1, %1 + STORE_WORDS m0, 0, 1, 4, 5 + STORE_WORDS m1, 2, 3, 6, 7 + + DEQUANT m2, m3, %1 + STORE_WORDS m2, 8, 9, 12, 13 + STORE_WORDS m3, 10, 11, 14, 15 +%endif +%endmacro + +%macro IDCT_DC_DEQUANT 1 +cglobal h264_luma_dc_dequant_idct, 3, 4, %1 + ; manually spill XMM registers for Win64 because + ; the code here is initialized with INIT_MMX + WIN64_SPILL_XMM %1 + movq m3, [r1+24] + movq m2, [r1+16] + movq m1, [r1+ 8] + movq m0, [r1+ 0] + WALSH4_1D 0,1,2,3,4 + TRANSPOSE4x4W 0,1,2,3,4 + WALSH4_1D 0,1,2,3,4 + +; shift, tmp, output, qmul +%if WIN64 + DECLARE_REG_TMP 0,3,1,2 + ; we can't avoid this, because r0 is the shift register (ecx) on win64 + xchg r0, t2 +%elif ARCH_X86_64 + DECLARE_REG_TMP 3,1,0,2 +%else + DECLARE_REG_TMP 1,3,0,2 +%endif + + cmp t3d, 32767 + jg .big_qmul + add t3d, 128 << 16 + DEQUANT_STORE 8 + RET +.big_qmul: + bsr t0d, t3d + add t3d, 128 << 16 + mov t1d, 7 + cmp t0d, t1d + cmovg t0d, t1d + inc t1d + shr t3d, t0b + sub t1d, t0d +%if cpuflag(sse2) + movd xmm6, t1d + DEQUANT_STORE xmm6 +%else + movd m6, t1d + DEQUANT_STORE m6 +%endif + RET +%endmacro + +INIT_MMX mmx +IDCT_DC_DEQUANT 0 +INIT_MMX sse2 +IDCT_DC_DEQUANT 7 + +%ifdef __NASM_VER__ +%if __NASM_MAJOR__ >= 2 && __NASM_MINOR__ >= 4 +%unmacro STORE_DIFFx2 8 ; remove macro from x86util.asm but yasm doesn't have this yet +%endif +%endif +%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride + movd %3, [%7] + movd %4, [%7+%8] + psraw %1, %6 + psraw %2, %6 + punpcklbw %3, %5 + punpcklbw %4, %5 + paddw %3, %1 + paddw %4, %2 + packuswb %3, %5 + packuswb %4, %5 + movd [%7], %3 + movd [%7+%8], %4 +%endmacro + +%macro DC_ADD_INIT 1 + add %1d, 32 + sar %1d, 6 + movd m0, %1d + pshuflw m0, m0, 0 + lea %1, [3*stride_q] + pxor m1, m1 + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 +%endmacro + +%macro IDCT_XMM 1 + +INIT_XMM %1 + +cglobal h264_idct_add_8, 3, 3, 8, dst_, block_, stride_ + movsxdifnidn stride_q, stride_d + IDCT4_ADD dst_q, block_q, stride_q +RET + +cglobal h264_idct_dc_add_8, 3, 4, 6, dst_, block_, stride_ + movsxdifnidn stride_q, stride_d + movsx r3d, word [block_q] + mov dword [block_q], 0 + DC_ADD_INIT r3 + DC_ADD_MMXEXT_OP movd, dst_q, stride_q, r3 +RET + +%endmacro + +IDCT_XMM sse2 +IDCT_XMM avx diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_idct_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_idct_10bit.asm new file mode 100644 index 00000000..9fd05abb --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_idct_10bit.asm @@ -0,0 +1,657 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 iDCT code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +cextern pw_1023 +%define pw_pixel_max pw_1023 +cextern pd_32 + +;----------------------------------------------------------------------------- +; void ff_h264_idct_add_10(pixel *dst, int16_t *block, int stride) +;----------------------------------------------------------------------------- +%macro STORE_DIFFx2 6 + psrad %1, 6 + psrad %2, 6 + packssdw %1, %2 + movq %3, [%5] + movhps %3, [%5+%6] + paddsw %1, %3 + CLIPW %1, %4, [pw_pixel_max] + movq [%5], %1 + movhps [%5+%6], %1 +%endmacro + +%macro STORE_DIFF16 5 + psrad %1, 6 + psrad %2, 6 + packssdw %1, %2 + paddsw %1, [%5] + CLIPW %1, %3, %4 + mova [%5], %1 +%endmacro + +;dst, in, stride +%macro IDCT4_ADD_10 3 + mova m0, [%2+ 0] + mova m1, [%2+16] + mova m2, [%2+32] + mova m3, [%2+48] + IDCT4_1D d,0,1,2,3,4,5 + TRANSPOSE4x4D 0,1,2,3,4 + paddd m0, [pd_32] + IDCT4_1D d,0,1,2,3,4,5 + pxor m5, m5 + mova [%2+ 0], m5 + mova [%2+16], m5 + mova [%2+32], m5 + mova [%2+48], m5 + STORE_DIFFx2 m0, m1, m4, m5, %1, %3 + lea %1, [%1+%3*2] + STORE_DIFFx2 m2, m3, m4, m5, %1, %3 +%endmacro + +%macro IDCT_ADD_10 0 +cglobal h264_idct_add_10, 3,3 + movsxdifnidn r2, r2d + IDCT4_ADD_10 r0, r1, r2 + RET +%endmacro + +INIT_XMM sse2 +IDCT_ADD_10 +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +IDCT_ADD_10 +%endif + +;----------------------------------------------------------------------------- +; void ff_h264_idct_add16_10(pixel *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6*8]) +;----------------------------------------------------------------------------- +;;;;;;; NO FATE SAMPLES TRIGGER THIS +%macro ADD4x4IDCT 0 +add4x4_idct %+ SUFFIX: + add r5, r0 + mova m0, [r2+ 0] + mova m1, [r2+16] + mova m2, [r2+32] + mova m3, [r2+48] + IDCT4_1D d,0,1,2,3,4,5 + TRANSPOSE4x4D 0,1,2,3,4 + paddd m0, [pd_32] + IDCT4_1D d,0,1,2,3,4,5 + pxor m5, m5 + mova [r2+ 0], m5 + mova [r2+16], m5 + mova [r2+32], m5 + mova [r2+48], m5 + STORE_DIFFx2 m0, m1, m4, m5, r5, r3 + lea r5, [r5+r3*2] + STORE_DIFFx2 m2, m3, m4, m5, r5, r3 + ret +%endmacro + +INIT_XMM sse2 +ALIGN 16 +ADD4x4IDCT +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +ALIGN 16 +ADD4x4IDCT +%endif + +%macro ADD16_OP 2 + cmp byte [r4+%2], 0 + jz .skipblock%1 + mov r5d, [r1+%1*4] + call add4x4_idct %+ SUFFIX +.skipblock%1: +%if %1<15 + add r2, 64 +%endif +%endmacro + +%macro IDCT_ADD16_10 0 +cglobal h264_idct_add16_10, 5,6 + movsxdifnidn r3, r3d + ADD16_OP 0, 4+1*8 + ADD16_OP 1, 5+1*8 + ADD16_OP 2, 4+2*8 + ADD16_OP 3, 5+2*8 + ADD16_OP 4, 6+1*8 + ADD16_OP 5, 7+1*8 + ADD16_OP 6, 6+2*8 + ADD16_OP 7, 7+2*8 + ADD16_OP 8, 4+3*8 + ADD16_OP 9, 5+3*8 + ADD16_OP 10, 4+4*8 + ADD16_OP 11, 5+4*8 + ADD16_OP 12, 6+3*8 + ADD16_OP 13, 7+3*8 + ADD16_OP 14, 6+4*8 + ADD16_OP 15, 7+4*8 + REP_RET +%endmacro + +INIT_XMM sse2 +IDCT_ADD16_10 +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +IDCT_ADD16_10 +%endif + +;----------------------------------------------------------------------------- +; void ff_h264_idct_dc_add_10(pixel *dst, int16_t *block, int stride) +;----------------------------------------------------------------------------- +%macro IDCT_DC_ADD_OP_10 3 + pxor m5, m5 +%if avx_enabled + paddw m1, m0, [%1+0 ] + paddw m2, m0, [%1+%2 ] + paddw m3, m0, [%1+%2*2] + paddw m4, m0, [%1+%3 ] +%else + mova m1, [%1+0 ] + mova m2, [%1+%2 ] + mova m3, [%1+%2*2] + mova m4, [%1+%3 ] + paddw m1, m0 + paddw m2, m0 + paddw m3, m0 + paddw m4, m0 +%endif + CLIPW m1, m5, m6 + CLIPW m2, m5, m6 + CLIPW m3, m5, m6 + CLIPW m4, m5, m6 + mova [%1+0 ], m1 + mova [%1+%2 ], m2 + mova [%1+%2*2], m3 + mova [%1+%3 ], m4 +%endmacro + +INIT_MMX mmxext +cglobal h264_idct_dc_add_10,3,3 + movsxdifnidn r2, r2d + movd m0, [r1] + mov dword [r1], 0 + paddd m0, [pd_32] + psrad m0, 6 + lea r1, [r2*3] + pshufw m0, m0, 0 + mova m6, [pw_pixel_max] + IDCT_DC_ADD_OP_10 r0, r2, r1 + RET + +;----------------------------------------------------------------------------- +; void ff_h264_idct8_dc_add_10(pixel *dst, int16_t *block, int stride) +;----------------------------------------------------------------------------- +%macro IDCT8_DC_ADD 0 +cglobal h264_idct8_dc_add_10,3,4,7 + movsxdifnidn r2, r2d + movd m0, [r1] + mov dword[r1], 0 + paddd m0, [pd_32] + psrad m0, 6 + lea r1, [r2*3] + SPLATW m0, m0, 0 + mova m6, [pw_pixel_max] + IDCT_DC_ADD_OP_10 r0, r2, r1 + lea r0, [r0+r2*4] + IDCT_DC_ADD_OP_10 r0, r2, r1 + RET +%endmacro + +INIT_XMM sse2 +IDCT8_DC_ADD +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +IDCT8_DC_ADD +%endif + +;----------------------------------------------------------------------------- +; void ff_h264_idct_add16intra_10(pixel *dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6*8]) +;----------------------------------------------------------------------------- +%macro AC 1 +.ac%1: + mov r5d, [r1+(%1+0)*4] + call add4x4_idct %+ SUFFIX + mov r5d, [r1+(%1+1)*4] + add r2, 64 + call add4x4_idct %+ SUFFIX + add r2, 64 + jmp .skipadd%1 +%endmacro + +%assign last_block 16 +%macro ADD16_OP_INTRA 2 + cmp word [r4+%2], 0 + jnz .ac%1 + mov r5d, [r2+ 0] + or r5d, [r2+64] + jz .skipblock%1 + mov r5d, [r1+(%1+0)*4] + call idct_dc_add %+ SUFFIX +.skipblock%1: +%if %1 01234567 +%endmacro + +%macro IDCT8_1D_FULL 1 + mova m7, [%1+112*2] + mova m6, [%1+ 96*2] + mova m5, [%1+ 80*2] + mova m3, [%1+ 48*2] + mova m2, [%1+ 32*2] + mova m1, [%1+ 16*2] + IDCT8_1D [%1], [%1+ 64*2] +%endmacro + +; %1=int16_t *block, %2=int16_t *dstblock +%macro IDCT8_ADD_SSE_START 2 + IDCT8_1D_FULL %1 +%if ARCH_X86_64 + TRANSPOSE4x4D 0,1,2,3,8 + mova [%2 ], m0 + TRANSPOSE4x4D 4,5,6,7,8 + mova [%2+8*2], m4 +%else + mova [%1], m7 + TRANSPOSE4x4D 0,1,2,3,7 + mova m7, [%1] + mova [%2 ], m0 + mova [%2+16*2], m1 + mova [%2+32*2], m2 + mova [%2+48*2], m3 + TRANSPOSE4x4D 4,5,6,7,3 + mova [%2+ 8*2], m4 + mova [%2+24*2], m5 + mova [%2+40*2], m6 + mova [%2+56*2], m7 +%endif +%endmacro + +; %1=uint8_t *dst, %2=int16_t *block, %3=int stride +%macro IDCT8_ADD_SSE_END 3 + IDCT8_1D_FULL %2 + mova [%2 ], m6 + mova [%2+16*2], m7 + + pxor m7, m7 + STORE_DIFFx2 m0, m1, m6, m7, %1, %3 + lea %1, [%1+%3*2] + STORE_DIFFx2 m2, m3, m6, m7, %1, %3 + mova m0, [%2 ] + mova m1, [%2+16*2] + lea %1, [%1+%3*2] + STORE_DIFFx2 m4, m5, m6, m7, %1, %3 + lea %1, [%1+%3*2] + STORE_DIFFx2 m0, m1, m6, m7, %1, %3 +%endmacro + +%macro IDCT8_ADD 0 +cglobal h264_idct8_add_10, 3,4,16 + movsxdifnidn r2, r2d +%if UNIX64 == 0 + %assign pad 16-gprsize-(stack_offset&15) + sub rsp, pad + call h264_idct8_add1_10 %+ SUFFIX + add rsp, pad + RET +%endif + +ALIGN 16 +; TODO: does not need to use stack +h264_idct8_add1_10 %+ SUFFIX: +%assign pad 256+16-gprsize + sub rsp, pad + add dword [r1], 32 + +%if ARCH_X86_64 + IDCT8_ADD_SSE_START r1, rsp + SWAP 1, 9 + SWAP 2, 10 + SWAP 3, 11 + SWAP 5, 13 + SWAP 6, 14 + SWAP 7, 15 + IDCT8_ADD_SSE_START r1+16, rsp+128 + PERMUTE 1,9, 2,10, 3,11, 5,1, 6,2, 7,3, 9,13, 10,14, 11,15, 13,5, 14,6, 15,7 + IDCT8_1D [rsp], [rsp+128] + SWAP 0, 8 + SWAP 1, 9 + SWAP 2, 10 + SWAP 3, 11 + SWAP 4, 12 + SWAP 5, 13 + SWAP 6, 14 + SWAP 7, 15 + IDCT8_1D [rsp+16], [rsp+144] + psrad m8, 6 + psrad m0, 6 + packssdw m8, m0 + paddsw m8, [r0] + pxor m0, m0 + mova [r1+ 0], m0 + mova [r1+ 16], m0 + mova [r1+ 32], m0 + mova [r1+ 48], m0 + mova [r1+ 64], m0 + mova [r1+ 80], m0 + mova [r1+ 96], m0 + mova [r1+112], m0 + mova [r1+128], m0 + mova [r1+144], m0 + mova [r1+160], m0 + mova [r1+176], m0 + mova [r1+192], m0 + mova [r1+208], m0 + mova [r1+224], m0 + mova [r1+240], m0 + CLIPW m8, m0, [pw_pixel_max] + mova [r0], m8 + mova m8, [pw_pixel_max] + STORE_DIFF16 m9, m1, m0, m8, r0+r2 + lea r0, [r0+r2*2] + STORE_DIFF16 m10, m2, m0, m8, r0 + STORE_DIFF16 m11, m3, m0, m8, r0+r2 + lea r0, [r0+r2*2] + STORE_DIFF16 m12, m4, m0, m8, r0 + STORE_DIFF16 m13, m5, m0, m8, r0+r2 + lea r0, [r0+r2*2] + STORE_DIFF16 m14, m6, m0, m8, r0 + STORE_DIFF16 m15, m7, m0, m8, r0+r2 +%else + IDCT8_ADD_SSE_START r1, rsp + IDCT8_ADD_SSE_START r1+16, rsp+128 + lea r3, [r0+8] + IDCT8_ADD_SSE_END r0, rsp, r2 + IDCT8_ADD_SSE_END r3, rsp+16, r2 + mova [r1+ 0], m7 + mova [r1+ 16], m7 + mova [r1+ 32], m7 + mova [r1+ 48], m7 + mova [r1+ 64], m7 + mova [r1+ 80], m7 + mova [r1+ 96], m7 + mova [r1+112], m7 + mova [r1+128], m7 + mova [r1+144], m7 + mova [r1+160], m7 + mova [r1+176], m7 + mova [r1+192], m7 + mova [r1+208], m7 + mova [r1+224], m7 + mova [r1+240], m7 +%endif ; ARCH_X86_64 + + add rsp, pad + ret +%endmacro + +INIT_XMM sse2 +IDCT8_ADD +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +IDCT8_ADD +%endif + +;----------------------------------------------------------------------------- +; void ff_h264_idct8_add4_10(pixel **dst, const int *block_offset, +; int16_t *block, int stride, +; const uint8_t nnzc[6*8]) +;----------------------------------------------------------------------------- +;;;;;;; NO FATE SAMPLES TRIGGER THIS +%macro IDCT8_ADD4_OP 2 + cmp byte [r4+%2], 0 + jz .skipblock%1 + mov r0d, [r6+%1*4] + add r0, r5 + call h264_idct8_add1_10 %+ SUFFIX +.skipblock%1: +%if %1<12 + add r1, 256 +%endif +%endmacro + +%macro IDCT8_ADD4 0 +cglobal h264_idct8_add4_10, 0,7,16 + movsxdifnidn r3, r3d + %assign pad 16-gprsize-(stack_offset&15) + SUB rsp, pad + mov r5, r0mp + mov r6, r1mp + mov r1, r2mp + mov r2d, r3m + movifnidn r4, r4mp + IDCT8_ADD4_OP 0, 4+1*8 + IDCT8_ADD4_OP 4, 6+1*8 + IDCT8_ADD4_OP 8, 4+3*8 + IDCT8_ADD4_OP 12, 6+3*8 + ADD rsp, pad + RET +%endmacro ; IDCT8_ADD4 + +INIT_XMM sse2 +IDCT8_ADD4 +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +IDCT8_ADD4 +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred.asm new file mode 100644 index 00000000..b36c198f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred.asm @@ -0,0 +1,2753 @@ +;****************************************************************************** +;* H.264 intra prediction asm optimizations +;* Copyright (c) 2010 Fiona Glaser +;* Copyright (c) 2010 Holger Lubitz +;* Copyright (c) 2010 Loren Merritt +;* Copyright (c) 2010 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +tm_shuf: times 8 db 0x03, 0x80 +pw_ff00: times 8 dw 0xff00 +plane_shuf: db -8, -7, -6, -5, -4, -3, -2, -1 + db 1, 2, 3, 4, 5, 6, 7, 8 +plane8_shuf: db -4, -3, -2, -1, 0, 0, 0, 0 + db 1, 2, 3, 4, 0, 0, 0, 0 +pw_0to7: dw 0, 1, 2, 3, 4, 5, 6, 7 +pw_1to8: dw 1, 2, 3, 4, 5, 6, 7, 8 +pw_m8tom1: dw -8, -7, -6, -5, -4, -3, -2, -1 +pw_m4to4: dw -4, -3, -2, -1, 1, 2, 3, 4 + +SECTION .text + +cextern pb_1 +cextern pb_3 +cextern pw_4 +cextern pw_8 + +;----------------------------------------------------------------------------- +; void ff_pred16x16_vertical_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmx +cglobal pred16x16_vertical_8, 2,3 + sub r0, r1 + mov r2, 8 + movq mm0, [r0+0] + movq mm1, [r0+8] +.loop: + movq [r0+r1*1+0], mm0 + movq [r0+r1*1+8], mm1 + movq [r0+r1*2+0], mm0 + movq [r0+r1*2+8], mm1 + lea r0, [r0+r1*2] + dec r2 + jg .loop + REP_RET + +INIT_XMM sse +cglobal pred16x16_vertical_8, 2,3 + sub r0, r1 + mov r2, 4 + movaps xmm0, [r0] +.loop: + movaps [r0+r1*1], xmm0 + movaps [r0+r1*2], xmm0 + lea r0, [r0+r1*2] + movaps [r0+r1*1], xmm0 + movaps [r0+r1*2], xmm0 + lea r0, [r0+r1*2] + dec r2 + jg .loop + REP_RET + +;----------------------------------------------------------------------------- +; void ff_pred16x16_horizontal_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED16x16_H 0 +cglobal pred16x16_horizontal_8, 2,3 + mov r2, 8 +%if cpuflag(ssse3) + mova m2, [pb_3] +%endif +.loop: + movd m0, [r0+r1*0-4] + movd m1, [r0+r1*1-4] + +%if cpuflag(ssse3) + pshufb m0, m2 + pshufb m1, m2 +%else + punpcklbw m0, m0 + punpcklbw m1, m1 + SPLATW m0, m0, 3 + SPLATW m1, m1, 3 + mova [r0+r1*0+8], m0 + mova [r0+r1*1+8], m1 +%endif + + mova [r0+r1*0], m0 + mova [r0+r1*1], m1 + lea r0, [r0+r1*2] + dec r2 + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +PRED16x16_H +INIT_MMX mmxext +PRED16x16_H +INIT_XMM ssse3 +PRED16x16_H + +;----------------------------------------------------------------------------- +; void ff_pred16x16_dc_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED16x16_DC 0 +cglobal pred16x16_dc_8, 2,7 + mov r4, r0 + sub r0, r1 + pxor mm0, mm0 + pxor mm1, mm1 + psadbw mm0, [r0+0] + psadbw mm1, [r0+8] + dec r0 + movzx r5d, byte [r0+r1*1] + paddw mm0, mm1 + movd r6d, mm0 + lea r0, [r0+r1*2] +%rep 7 + movzx r2d, byte [r0+r1*0] + movzx r3d, byte [r0+r1*1] + add r5d, r2d + add r6d, r3d + lea r0, [r0+r1*2] +%endrep + movzx r2d, byte [r0+r1*0] + add r5d, r6d + lea r2d, [r2+r5+16] + shr r2d, 5 +%if cpuflag(ssse3) + pxor m1, m1 +%endif + SPLATB_REG m0, r2, m1 + +%if mmsize==8 + mov r3d, 8 +.loop: + mova [r4+r1*0+0], m0 + mova [r4+r1*0+8], m0 + mova [r4+r1*1+0], m0 + mova [r4+r1*1+8], m0 +%else + mov r3d, 4 +.loop: + mova [r4+r1*0], m0 + mova [r4+r1*1], m0 + lea r4, [r4+r1*2] + mova [r4+r1*0], m0 + mova [r4+r1*1], m0 +%endif + lea r4, [r4+r1*2] + dec r3d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_DC +INIT_XMM sse2 +PRED16x16_DC +INIT_XMM ssse3 +PRED16x16_DC + +;----------------------------------------------------------------------------- +; void ff_pred16x16_tm_vp8_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED16x16_TM 0 +cglobal pred16x16_tm_vp8_8, 2,5 + sub r0, r1 + pxor mm7, mm7 + movq mm0, [r0+0] + movq mm2, [r0+8] + movq mm1, mm0 + movq mm3, mm2 + punpcklbw mm0, mm7 + punpckhbw mm1, mm7 + punpcklbw mm2, mm7 + punpckhbw mm3, mm7 + movzx r3d, byte [r0-1] + mov r4d, 16 +.loop: + movzx r2d, byte [r0+r1-1] + sub r2d, r3d + movd mm4, r2d + SPLATW mm4, mm4, 0 + movq mm5, mm4 + movq mm6, mm4 + movq mm7, mm4 + paddw mm4, mm0 + paddw mm5, mm1 + paddw mm6, mm2 + paddw mm7, mm3 + packuswb mm4, mm5 + packuswb mm6, mm7 + movq [r0+r1+0], mm4 + movq [r0+r1+8], mm6 + add r0, r1 + dec r4d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +PRED16x16_TM +INIT_MMX mmxext +PRED16x16_TM + +INIT_XMM sse2 +cglobal pred16x16_tm_vp8_8, 2,6,6 + sub r0, r1 + pxor xmm2, xmm2 + movdqa xmm0, [r0] + movdqa xmm1, xmm0 + punpcklbw xmm0, xmm2 + punpckhbw xmm1, xmm2 + movzx r4d, byte [r0-1] + mov r5d, 8 +.loop: + movzx r2d, byte [r0+r1*1-1] + movzx r3d, byte [r0+r1*2-1] + sub r2d, r4d + sub r3d, r4d + movd xmm2, r2d + movd xmm4, r3d + pshuflw xmm2, xmm2, 0 + pshuflw xmm4, xmm4, 0 + punpcklqdq xmm2, xmm2 + punpcklqdq xmm4, xmm4 + movdqa xmm3, xmm2 + movdqa xmm5, xmm4 + paddw xmm2, xmm0 + paddw xmm3, xmm1 + paddw xmm4, xmm0 + paddw xmm5, xmm1 + packuswb xmm2, xmm3 + packuswb xmm4, xmm5 + movdqa [r0+r1*1], xmm2 + movdqa [r0+r1*2], xmm4 + lea r0, [r0+r1*2] + dec r5d + jg .loop + REP_RET + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal pred16x16_tm_vp8_8, 2, 4, 5, dst, stride, stride3, iteration + sub dstq, strideq + pmovzxbw m0, [dstq] + vpbroadcastb xm1, [r0-1] + pmovzxbw m1, xm1 + psubw m0, m1 + mov iterationd, 4 + lea stride3q, [strideq*3] +.loop: + vpbroadcastb xm1, [dstq+strideq*1-1] + vpbroadcastb xm2, [dstq+strideq*2-1] + vpbroadcastb xm3, [dstq+stride3q-1] + vpbroadcastb xm4, [dstq+strideq*4-1] + pmovzxbw m1, xm1 + pmovzxbw m2, xm2 + pmovzxbw m3, xm3 + pmovzxbw m4, xm4 + paddw m1, m0 + paddw m2, m0 + paddw m3, m0 + paddw m4, m0 + vpackuswb m1, m1, m2 + vpackuswb m3, m3, m4 + vpermq m1, m1, q3120 + vpermq m3, m3, q3120 + movdqa [dstq+strideq*1], xm1 + vextracti128 [dstq+strideq*2], m1, 1 + movdqa [dstq+stride3q*1], xm3 + vextracti128 [dstq+strideq*4], m3, 1 + lea dstq, [dstq+strideq*4] + dec iterationd + jg .loop + REP_RET +%endif + +;----------------------------------------------------------------------------- +; void ff_pred16x16_plane_*_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro H264_PRED16x16_PLANE 1 +cglobal pred16x16_plane_%1_8, 2,9,7 + mov r2, r1 ; +stride + neg r1 ; -stride + + movh m0, [r0+r1 -1] +%if mmsize == 8 + pxor m4, m4 + movh m1, [r0+r1 +3 ] + movh m2, [r0+r1 +8 ] + movh m3, [r0+r1 +12] + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpcklbw m3, m4 + pmullw m0, [pw_m8tom1 ] + pmullw m1, [pw_m8tom1+8] + pmullw m2, [pw_1to8 ] + pmullw m3, [pw_1to8 +8] + paddw m0, m2 + paddw m1, m3 +%else ; mmsize == 16 +%if cpuflag(ssse3) + movhps m0, [r0+r1 +8] + pmaddubsw m0, [plane_shuf] ; H coefficients +%else ; sse2 + pxor m2, m2 + movh m1, [r0+r1 +8] + punpcklbw m0, m2 + punpcklbw m1, m2 + pmullw m0, [pw_m8tom1] + pmullw m1, [pw_1to8] + paddw m0, m1 +%endif + movhlps m1, m0 +%endif + paddw m0, m1 +%if cpuflag(mmxext) + PSHUFLW m1, m0, 0xE +%elif cpuflag(mmx) + mova m1, m0 + psrlq m1, 32 +%endif + paddw m0, m1 +%if cpuflag(mmxext) + PSHUFLW m1, m0, 0x1 +%elif cpuflag(mmx) + mova m1, m0 + psrlq m1, 16 +%endif + paddw m0, m1 ; sum of H coefficients + + lea r4, [r0+r2*8-1] + lea r3, [r0+r2*4-1] + add r4, r2 + +%if ARCH_X86_64 +%define e_reg r8 +%else +%define e_reg r0 +%endif + + movzx e_reg, byte [r3+r2*2 ] + movzx r5, byte [r4+r1 ] + sub r5, e_reg + + movzx e_reg, byte [r3+r2 ] + movzx r6, byte [r4 ] + sub r6, e_reg + lea r5, [r5+r6*2] + + movzx e_reg, byte [r3+r1 ] + movzx r6, byte [r4+r2*2 ] + sub r6, e_reg + lea r5, [r5+r6*4] + + movzx e_reg, byte [r3 ] +%if ARCH_X86_64 + movzx r7, byte [r4+r2 ] + sub r7, e_reg +%else + movzx r6, byte [r4+r2 ] + sub r6, e_reg + lea r5, [r5+r6*4] + sub r5, r6 +%endif + + lea e_reg, [r3+r1*4] + lea r3, [r4+r2*4] + + movzx r4, byte [e_reg+r2 ] + movzx r6, byte [r3 ] + sub r6, r4 +%if ARCH_X86_64 + lea r6, [r7+r6*2] + lea r5, [r5+r6*2] + add r5, r6 +%else + lea r5, [r5+r6*4] + lea r5, [r5+r6*2] +%endif + + movzx r4, byte [e_reg ] +%if ARCH_X86_64 + movzx r7, byte [r3 +r2 ] + sub r7, r4 + sub r5, r7 +%else + movzx r6, byte [r3 +r2 ] + sub r6, r4 + lea r5, [r5+r6*8] + sub r5, r6 +%endif + + movzx r4, byte [e_reg+r1 ] + movzx r6, byte [r3 +r2*2] + sub r6, r4 +%if ARCH_X86_64 + add r6, r7 +%endif + lea r5, [r5+r6*8] + + movzx r4, byte [e_reg+r2*2] + movzx r6, byte [r3 +r1 ] + sub r6, r4 + lea r5, [r5+r6*4] + add r5, r6 ; sum of V coefficients + +%if ARCH_X86_64 == 0 + mov r0, r0m +%endif + +%ifidn %1, h264 + lea r5, [r5*5+32] + sar r5, 6 +%elifidn %1, rv40 + lea r5, [r5*5] + sar r5, 6 +%elifidn %1, svq3 + test r5, r5 + lea r6, [r5+3] + cmovs r5, r6 + sar r5, 2 ; V/4 + lea r5, [r5*5] ; 5*(V/4) + test r5, r5 + lea r6, [r5+15] + cmovs r5, r6 + sar r5, 4 ; (5*(V/4))/16 +%endif + + movzx r4, byte [r0+r1 +15] + movzx r3, byte [r3+r2*2 ] + lea r3, [r3+r4+1] + shl r3, 4 + + movd r1d, m0 + movsx r1d, r1w +%ifnidn %1, svq3 +%ifidn %1, h264 + lea r1d, [r1d*5+32] +%else ; rv40 + lea r1d, [r1d*5] +%endif + sar r1d, 6 +%else ; svq3 + test r1d, r1d + lea r4d, [r1d+3] + cmovs r1d, r4d + sar r1d, 2 ; H/4 + lea r1d, [r1d*5] ; 5*(H/4) + test r1d, r1d + lea r4d, [r1d+15] + cmovs r1d, r4d + sar r1d, 4 ; (5*(H/4))/16 +%endif + movd m0, r1d + + add r1d, r5d + add r3d, r1d + shl r1d, 3 + sub r3d, r1d ; a + + movd m1, r5d + movd m3, r3d + SPLATW m0, m0, 0 ; H + SPLATW m1, m1, 0 ; V + SPLATW m3, m3, 0 ; a +%ifidn %1, svq3 + SWAP 0, 1 +%endif + mova m2, m0 +%if mmsize == 8 + mova m5, m0 +%endif + pmullw m0, [pw_0to7] ; 0*H, 1*H, ..., 7*H (words) +%if mmsize == 16 + psllw m2, 3 +%else + psllw m5, 3 + psllw m2, 2 + mova m6, m5 + paddw m6, m2 +%endif + paddw m0, m3 ; a + {0,1,2,3,4,5,6,7}*H + paddw m2, m0 ; a + {8,9,10,11,12,13,14,15}*H +%if mmsize == 8 + paddw m5, m0 ; a + {8,9,10,11}*H + paddw m6, m0 ; a + {12,13,14,15}*H +%endif + + mov r4, 8 +.loop: + mova m3, m0 ; b[0..7] + mova m4, m2 ; b[8..15] + psraw m3, 5 + psraw m4, 5 + packuswb m3, m4 + mova [r0], m3 +%if mmsize == 8 + mova m3, m5 ; b[8..11] + mova m4, m6 ; b[12..15] + psraw m3, 5 + psraw m4, 5 + packuswb m3, m4 + mova [r0+8], m3 +%endif + paddw m0, m1 + paddw m2, m1 +%if mmsize == 8 + paddw m5, m1 + paddw m6, m1 +%endif + + mova m3, m0 ; b[0..7] + mova m4, m2 ; b[8..15] + psraw m3, 5 + psraw m4, 5 + packuswb m3, m4 + mova [r0+r2], m3 +%if mmsize == 8 + mova m3, m5 ; b[8..11] + mova m4, m6 ; b[12..15] + psraw m3, 5 + psraw m4, 5 + packuswb m3, m4 + mova [r0+r2+8], m3 +%endif + paddw m0, m1 + paddw m2, m1 +%if mmsize == 8 + paddw m5, m1 + paddw m6, m1 +%endif + + lea r0, [r0+r2*2] + dec r4 + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +H264_PRED16x16_PLANE h264 +H264_PRED16x16_PLANE rv40 +H264_PRED16x16_PLANE svq3 +INIT_MMX mmxext +H264_PRED16x16_PLANE h264 +H264_PRED16x16_PLANE rv40 +H264_PRED16x16_PLANE svq3 +INIT_XMM sse2 +H264_PRED16x16_PLANE h264 +H264_PRED16x16_PLANE rv40 +H264_PRED16x16_PLANE svq3 +INIT_XMM ssse3 +H264_PRED16x16_PLANE h264 +H264_PRED16x16_PLANE rv40 +H264_PRED16x16_PLANE svq3 + +;----------------------------------------------------------------------------- +; void ff_pred8x8_plane_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro H264_PRED8x8_PLANE 0 +cglobal pred8x8_plane_8, 2,9,7 + mov r2, r1 ; +stride + neg r1 ; -stride + + movd m0, [r0+r1 -1] +%if mmsize == 8 + pxor m2, m2 + movh m1, [r0+r1 +4 ] + punpcklbw m0, m2 + punpcklbw m1, m2 + pmullw m0, [pw_m4to4] + pmullw m1, [pw_m4to4+8] +%else ; mmsize == 16 +%if cpuflag(ssse3) + movhps m0, [r0+r1 +4] ; this reads 4 bytes more than necessary + pmaddubsw m0, [plane8_shuf] ; H coefficients +%else ; sse2 + pxor m2, m2 + movd m1, [r0+r1 +4] + punpckldq m0, m1 + punpcklbw m0, m2 + pmullw m0, [pw_m4to4] +%endif + movhlps m1, m0 +%endif + paddw m0, m1 + +%if notcpuflag(ssse3) +%if cpuflag(mmxext) + PSHUFLW m1, m0, 0xE +%elif cpuflag(mmx) + mova m1, m0 + psrlq m1, 32 +%endif + paddw m0, m1 +%endif ; !ssse3 + +%if cpuflag(mmxext) + PSHUFLW m1, m0, 0x1 +%elif cpuflag(mmx) + mova m1, m0 + psrlq m1, 16 +%endif + paddw m0, m1 ; sum of H coefficients + + lea r4, [r0+r2*4-1] + lea r3, [r0 -1] + add r4, r2 + +%if ARCH_X86_64 +%define e_reg r8 +%else +%define e_reg r0 +%endif + + movzx e_reg, byte [r3+r2*2 ] + movzx r5, byte [r4+r1 ] + sub r5, e_reg + + movzx e_reg, byte [r3 ] +%if ARCH_X86_64 + movzx r7, byte [r4+r2 ] + sub r7, e_reg + sub r5, r7 +%else + movzx r6, byte [r4+r2 ] + sub r6, e_reg + lea r5, [r5+r6*4] + sub r5, r6 +%endif + + movzx e_reg, byte [r3+r1 ] + movzx r6, byte [r4+r2*2 ] + sub r6, e_reg +%if ARCH_X86_64 + add r6, r7 +%endif + lea r5, [r5+r6*4] + + movzx e_reg, byte [r3+r2 ] + movzx r6, byte [r4 ] + sub r6, e_reg + lea r6, [r5+r6*2] + + lea r5, [r6*9+16] + lea r5, [r5+r6*8] + sar r5, 5 + +%if ARCH_X86_64 == 0 + mov r0, r0m +%endif + + movzx r3, byte [r4+r2*2 ] + movzx r4, byte [r0+r1 +7] + lea r3, [r3+r4+1] + shl r3, 4 + movd r1d, m0 + movsx r1d, r1w + imul r1d, 17 + add r1d, 16 + sar r1d, 5 + movd m0, r1d + add r1d, r5d + sub r3d, r1d + add r1d, r1d + sub r3d, r1d ; a + + movd m1, r5d + movd m3, r3d + SPLATW m0, m0, 0 ; H + SPLATW m1, m1, 0 ; V + SPLATW m3, m3, 0 ; a +%if mmsize == 8 + mova m2, m0 +%endif + pmullw m0, [pw_0to7] ; 0*H, 1*H, ..., 7*H (words) + paddw m0, m3 ; a + {0,1,2,3,4,5,6,7}*H +%if mmsize == 8 + psllw m2, 2 + paddw m2, m0 ; a + {4,5,6,7}*H +%endif + + mov r4, 4 +ALIGN 16 +.loop: +%if mmsize == 16 + mova m3, m0 ; b[0..7] + paddw m0, m1 + psraw m3, 5 + mova m4, m0 ; V+b[0..7] + paddw m0, m1 + psraw m4, 5 + packuswb m3, m4 + movh [r0], m3 + movhps [r0+r2], m3 +%else ; mmsize == 8 + mova m3, m0 ; b[0..3] + mova m4, m2 ; b[4..7] + paddw m0, m1 + paddw m2, m1 + psraw m3, 5 + psraw m4, 5 + mova m5, m0 ; V+b[0..3] + mova m6, m2 ; V+b[4..7] + paddw m0, m1 + paddw m2, m1 + psraw m5, 5 + psraw m6, 5 + packuswb m3, m4 + packuswb m5, m6 + mova [r0], m3 + mova [r0+r2], m5 +%endif + + lea r0, [r0+r2*2] + dec r4 + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +H264_PRED8x8_PLANE +INIT_MMX mmxext +H264_PRED8x8_PLANE +INIT_XMM sse2 +H264_PRED8x8_PLANE +INIT_XMM ssse3 +H264_PRED8x8_PLANE + +;----------------------------------------------------------------------------- +; void ff_pred8x8_vertical_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmx +cglobal pred8x8_vertical_8, 2,2 + sub r0, r1 + movq mm0, [r0] +%rep 3 + movq [r0+r1*1], mm0 + movq [r0+r1*2], mm0 + lea r0, [r0+r1*2] +%endrep + movq [r0+r1*1], mm0 + movq [r0+r1*2], mm0 + RET + +;----------------------------------------------------------------------------- +; void ff_pred8x8_horizontal_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8_H 0 +cglobal pred8x8_horizontal_8, 2,3 + mov r2, 4 +%if cpuflag(ssse3) + mova m2, [pb_3] +%endif +.loop: + SPLATB_LOAD m0, r0+r1*0-1, m2 + SPLATB_LOAD m1, r0+r1*1-1, m2 + mova [r0+r1*0], m0 + mova [r0+r1*1], m1 + lea r0, [r0+r1*2] + dec r2 + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +PRED8x8_H +INIT_MMX mmxext +PRED8x8_H +INIT_MMX ssse3 +PRED8x8_H + +;----------------------------------------------------------------------------- +; void ff_pred8x8_top_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_MMX mmxext +cglobal pred8x8_top_dc_8, 2,5 + sub r0, r1 + movq mm0, [r0] + pxor mm1, mm1 + pxor mm2, mm2 + lea r2, [r0+r1*2] + punpckhbw mm1, mm0 + punpcklbw mm0, mm2 + psadbw mm1, mm2 ; s1 + lea r3, [r2+r1*2] + psadbw mm0, mm2 ; s0 + psrlw mm1, 1 + psrlw mm0, 1 + pavgw mm1, mm2 + lea r4, [r3+r1*2] + pavgw mm0, mm2 + pshufw mm1, mm1, 0 + pshufw mm0, mm0, 0 ; dc0 (w) + packuswb mm0, mm1 ; dc0,dc1 (b) + movq [r0+r1*1], mm0 + movq [r0+r1*2], mm0 + lea r0, [r3+r1*2] + movq [r2+r1*1], mm0 + movq [r2+r1*2], mm0 + movq [r3+r1*1], mm0 + movq [r3+r1*2], mm0 + movq [r0+r1*1], mm0 + movq [r0+r1*2], mm0 + RET + +;----------------------------------------------------------------------------- +; void ff_pred8x8_dc_8_mmxext(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred8x8_dc_8, 2,5 + sub r0, r1 + pxor m7, m7 + movd m0, [r0+0] + movd m1, [r0+4] + psadbw m0, m7 ; s0 + mov r4, r0 + psadbw m1, m7 ; s1 + + movzx r2d, byte [r0+r1*1-1] + movzx r3d, byte [r0+r1*2-1] + lea r0, [r0+r1*2] + add r2d, r3d + movzx r3d, byte [r0+r1*1-1] + add r2d, r3d + movzx r3d, byte [r0+r1*2-1] + add r2d, r3d + lea r0, [r0+r1*2] + movd m2, r2d ; s2 + movzx r2d, byte [r0+r1*1-1] + movzx r3d, byte [r0+r1*2-1] + lea r0, [r0+r1*2] + add r2d, r3d + movzx r3d, byte [r0+r1*1-1] + add r2d, r3d + movzx r3d, byte [r0+r1*2-1] + add r2d, r3d + movd m3, r2d ; s3 + + punpcklwd m0, m1 + mov r0, r4 + punpcklwd m2, m3 + punpckldq m0, m2 ; s0, s1, s2, s3 + pshufw m3, m0, 11110110b ; s2, s1, s3, s3 + lea r2, [r0+r1*2] + pshufw m0, m0, 01110100b ; s0, s1, s3, s1 + paddw m0, m3 + lea r3, [r2+r1*2] + psrlw m0, 2 + pavgw m0, m7 ; s0+s2, s1, s3, s1+s3 + lea r4, [r3+r1*2] + packuswb m0, m0 + punpcklbw m0, m0 + movq m1, m0 + punpcklbw m0, m0 + punpckhbw m1, m1 + movq [r0+r1*1], m0 + movq [r0+r1*2], m0 + movq [r2+r1*1], m0 + movq [r2+r1*2], m0 + movq [r3+r1*1], m1 + movq [r3+r1*2], m1 + movq [r4+r1*1], m1 + movq [r4+r1*2], m1 + RET + +;----------------------------------------------------------------------------- +; void ff_pred8x8_dc_rv40_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred8x8_dc_rv40_8, 2,7 + mov r4, r0 + sub r0, r1 + pxor mm0, mm0 + psadbw mm0, [r0] + dec r0 + movzx r5d, byte [r0+r1*1] + movd r6d, mm0 + lea r0, [r0+r1*2] +%rep 3 + movzx r2d, byte [r0+r1*0] + movzx r3d, byte [r0+r1*1] + add r5d, r2d + add r6d, r3d + lea r0, [r0+r1*2] +%endrep + movzx r2d, byte [r0+r1*0] + add r5d, r6d + lea r2d, [r2+r5+8] + shr r2d, 4 + movd mm0, r2d + punpcklbw mm0, mm0 + pshufw mm0, mm0, 0 + mov r3d, 4 +.loop: + movq [r4+r1*0], mm0 + movq [r4+r1*1], mm0 + lea r4, [r4+r1*2] + dec r3d + jg .loop + REP_RET + +;----------------------------------------------------------------------------- +; void ff_pred8x8_tm_vp8_8(uint8_t *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8_TM 0 +cglobal pred8x8_tm_vp8_8, 2,6 + sub r0, r1 + pxor mm7, mm7 + movq mm0, [r0] + movq mm1, mm0 + punpcklbw mm0, mm7 + punpckhbw mm1, mm7 + movzx r4d, byte [r0-1] + mov r5d, 4 +.loop: + movzx r2d, byte [r0+r1*1-1] + movzx r3d, byte [r0+r1*2-1] + sub r2d, r4d + sub r3d, r4d + movd mm2, r2d + movd mm4, r3d + SPLATW mm2, mm2, 0 + SPLATW mm4, mm4, 0 + movq mm3, mm2 + movq mm5, mm4 + paddw mm2, mm0 + paddw mm3, mm1 + paddw mm4, mm0 + paddw mm5, mm1 + packuswb mm2, mm3 + packuswb mm4, mm5 + movq [r0+r1*1], mm2 + movq [r0+r1*2], mm4 + lea r0, [r0+r1*2] + dec r5d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +PRED8x8_TM +INIT_MMX mmxext +PRED8x8_TM + +INIT_XMM sse2 +cglobal pred8x8_tm_vp8_8, 2,6,4 + sub r0, r1 + pxor xmm1, xmm1 + movq xmm0, [r0] + punpcklbw xmm0, xmm1 + movzx r4d, byte [r0-1] + mov r5d, 4 +.loop: + movzx r2d, byte [r0+r1*1-1] + movzx r3d, byte [r0+r1*2-1] + sub r2d, r4d + sub r3d, r4d + movd xmm2, r2d + movd xmm3, r3d + pshuflw xmm2, xmm2, 0 + pshuflw xmm3, xmm3, 0 + punpcklqdq xmm2, xmm2 + punpcklqdq xmm3, xmm3 + paddw xmm2, xmm0 + paddw xmm3, xmm0 + packuswb xmm2, xmm3 + movq [r0+r1*1], xmm2 + movhps [r0+r1*2], xmm2 + lea r0, [r0+r1*2] + dec r5d + jg .loop + REP_RET + +INIT_XMM ssse3 +cglobal pred8x8_tm_vp8_8, 2,3,6 + sub r0, r1 + movdqa xmm4, [tm_shuf] + pxor xmm1, xmm1 + movq xmm0, [r0] + punpcklbw xmm0, xmm1 + movd xmm5, [r0-4] + pshufb xmm5, xmm4 + mov r2d, 4 +.loop: + movd xmm2, [r0+r1*1-4] + movd xmm3, [r0+r1*2-4] + pshufb xmm2, xmm4 + pshufb xmm3, xmm4 + psubw xmm2, xmm5 + psubw xmm3, xmm5 + paddw xmm2, xmm0 + paddw xmm3, xmm0 + packuswb xmm2, xmm3 + movq [r0+r1*1], xmm2 + movhps [r0+r1*2], xmm2 + lea r0, [r0+r1*2] + dec r2d + jg .loop + REP_RET + +; dest, left, right, src, tmp +; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2 +%macro PRED4x4_LOWPASS 5 + mova %5, %2 + pavgb %2, %3 + pxor %3, %5 + mova %1, %4 + pand %3, [pb_1] + psubusb %2, %3 + pavgb %1, %2 +%endmacro + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_top_dc_8(uint8_t *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_TOP_DC 0 +cglobal pred8x8l_top_dc_8, 4,4 + sub r0, r3 + pxor mm7, mm7 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d ; top_left + jz .fix_lt_2 + test r2d, r2d ; top_right + jz .fix_tr_1 + jmp .body +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d ; top_right + jnz .body +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 +.body: + PRED4x4_LOWPASS mm0, mm2, mm1, mm3, mm5 + psadbw mm7, mm0 + paddw mm7, [pw_4] + psrlw mm7, 3 + pshufw mm7, mm7, 0 + packuswb mm7, mm7 +%rep 3 + movq [r0+r3*1], mm7 + movq [r0+r3*2], mm7 + lea r0, [r0+r3*2] +%endrep + movq [r0+r3*1], mm7 + movq [r0+r3*2], mm7 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8L_TOP_DC +INIT_MMX ssse3 +PRED8x8L_TOP_DC + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_dc_8(uint8_t *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8L_DC 0 +cglobal pred8x8l_dc_8, 4,5 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d + jnz .do_left +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .body +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .body +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm4, mm0 + movq mm7, mm2 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + psllq mm1, 56 + PALIGNR mm7, mm1, 7, mm3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 +.body: + lea r1, [r0+r3*2] + PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5 + pxor mm0, mm0 + pxor mm1, mm1 + lea r2, [r1+r3*2] + psadbw mm0, mm7 + psadbw mm1, mm6 + paddw mm0, [pw_8] + paddw mm0, mm1 + lea r4, [r2+r3*2] + psrlw mm0, 4 + pshufw mm0, mm0, 0 + packuswb mm0, mm0 + movq [r0+r3*1], mm0 + movq [r0+r3*2], mm0 + movq [r1+r3*1], mm0 + movq [r1+r3*2], mm0 + movq [r2+r3*1], mm0 + movq [r2+r3*2], mm0 + movq [r4+r3*1], mm0 + movq [r4+r3*2], mm0 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8L_DC +INIT_MMX ssse3 +PRED8x8L_DC + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_horizontal_8(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8L_HORIZONTAL 0 +cglobal pred8x8l_horizontal_8, 4,4 + sub r0, r3 + lea r2, [r0+r3*2] + movq mm0, [r0+r3*1-8] + test r1d, r1d + lea r1, [r0+r3] + cmovnz r1, r0 + punpckhbw mm0, [r1+r3*0-8] + movq mm1, [r2+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r2, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r1+r3*0-8] + mov r0, r2 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm4, mm0 + movq mm7, mm2 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + psllq mm1, 56 + PALIGNR mm7, mm1, 7, mm3 + movq mm3, mm7 + lea r1, [r0+r3*2] + movq mm7, mm3 + punpckhbw mm3, mm3 + punpcklbw mm7, mm7 + pshufw mm0, mm3, 0xff + pshufw mm1, mm3, 0xaa + lea r2, [r1+r3*2] + pshufw mm2, mm3, 0x55 + pshufw mm3, mm3, 0x00 + pshufw mm4, mm7, 0xff + pshufw mm5, mm7, 0xaa + pshufw mm6, mm7, 0x55 + pshufw mm7, mm7, 0x00 + movq [r0+r3*1], mm0 + movq [r0+r3*2], mm1 + movq [r1+r3*1], mm2 + movq [r1+r3*2], mm3 + movq [r2+r3*1], mm4 + movq [r2+r3*2], mm5 + lea r0, [r2+r3*2] + movq [r0+r3*1], mm6 + movq [r0+r3*2], mm7 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8L_HORIZONTAL +INIT_MMX ssse3 +PRED8x8L_HORIZONTAL + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_vertical_8(uint8_t *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8L_VERTICAL 0 +cglobal pred8x8l_vertical_8, 4,4 + sub r0, r3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d ; top_left + jz .fix_lt_2 + test r2d, r2d ; top_right + jz .fix_tr_1 + jmp .body +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d ; top_right + jnz .body +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 +.body: + PRED4x4_LOWPASS mm0, mm2, mm1, mm3, mm5 +%rep 3 + movq [r0+r3*1], mm0 + movq [r0+r3*2], mm0 + lea r0, [r0+r3*2] +%endrep + movq [r0+r3*1], mm0 + movq [r0+r3*2], mm0 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8L_VERTICAL +INIT_MMX ssse3 +PRED8x8L_VERTICAL + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_down_left_8(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred8x8l_down_left_8, 4,5 + sub r0, r3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 + jmp .do_top +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.fix_tr_2: + punpckhbw mm3, mm3 + pshufw mm1, mm3, 0xFF + jmp .do_topright +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq mm7, mm4 + test r2d, r2d + jz .fix_tr_2 + movq mm0, [r0+8] + movq mm5, mm0 + movq mm2, mm0 + movq mm4, mm0 + psrlq mm5, 56 + PALIGNR mm2, mm3, 7, mm3 + PALIGNR mm5, mm4, 1, mm4 + PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4 +.do_topright: + lea r1, [r0+r3*2] + movq mm6, mm1 + psrlq mm1, 56 + movq mm4, mm1 + lea r2, [r1+r3*2] + movq mm2, mm6 + PALIGNR mm2, mm7, 1, mm0 + movq mm3, mm6 + PALIGNR mm3, mm7, 7, mm0 + PALIGNR mm4, mm6, 1, mm0 + movq mm5, mm7 + movq mm1, mm7 + movq mm7, mm6 + lea r4, [r2+r3*2] + psllq mm1, 8 + PRED4x4_LOWPASS mm0, mm1, mm2, mm5, mm6 + PRED4x4_LOWPASS mm1, mm3, mm4, mm7, mm6 + movq [r4+r3*2], mm1 + movq mm2, mm0 + psllq mm1, 8 + psrlq mm2, 56 + psllq mm0, 8 + por mm1, mm2 + movq [r4+r3*1], mm1 + movq mm2, mm0 + psllq mm1, 8 + psrlq mm2, 56 + psllq mm0, 8 + por mm1, mm2 + movq [r2+r3*2], mm1 + movq mm2, mm0 + psllq mm1, 8 + psrlq mm2, 56 + psllq mm0, 8 + por mm1, mm2 + movq [r2+r3*1], mm1 + movq mm2, mm0 + psllq mm1, 8 + psrlq mm2, 56 + psllq mm0, 8 + por mm1, mm2 + movq [r1+r3*2], mm1 + movq mm2, mm0 + psllq mm1, 8 + psrlq mm2, 56 + psllq mm0, 8 + por mm1, mm2 + movq [r1+r3*1], mm1 + movq mm2, mm0 + psllq mm1, 8 + psrlq mm2, 56 + psllq mm0, 8 + por mm1, mm2 + movq [r0+r3*2], mm1 + psllq mm1, 8 + psrlq mm0, 56 + por mm1, mm0 + movq [r0+r3*1], mm1 + RET + +%macro PRED8x8L_DOWN_LEFT 0 +cglobal pred8x8l_down_left_8, 4,4 + sub r0, r3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d ; top_left + jz .fix_lt_2 + test r2d, r2d ; top_right + jz .fix_tr_1 + jmp .do_top +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d ; top_right + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.fix_tr_2: + punpckhbw mm3, mm3 + pshufw mm1, mm3, 0xFF + jmp .do_topright +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq2dq xmm3, mm4 + test r2d, r2d ; top_right + jz .fix_tr_2 + movq mm0, [r0+8] + movq mm5, mm0 + movq mm2, mm0 + movq mm4, mm0 + psrlq mm5, 56 + PALIGNR mm2, mm3, 7, mm3 + PALIGNR mm5, mm4, 1, mm4 + PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4 +.do_topright: + movq2dq xmm4, mm1 + psrlq mm1, 56 + movq2dq xmm5, mm1 + lea r1, [r0+r3*2] + pslldq xmm4, 8 + por xmm3, xmm4 + movdqa xmm2, xmm3 + psrldq xmm2, 1 + pslldq xmm5, 15 + por xmm2, xmm5 + lea r2, [r1+r3*2] + movdqa xmm1, xmm3 + pslldq xmm1, 1 +INIT_XMM cpuname + PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm3, xmm4 + psrldq xmm0, 1 + movq [r0+r3*1], xmm0 + psrldq xmm0, 1 + movq [r0+r3*2], xmm0 + psrldq xmm0, 1 + lea r0, [r2+r3*2] + movq [r1+r3*1], xmm0 + psrldq xmm0, 1 + movq [r1+r3*2], xmm0 + psrldq xmm0, 1 + movq [r2+r3*1], xmm0 + psrldq xmm0, 1 + movq [r2+r3*2], xmm0 + psrldq xmm0, 1 + movq [r0+r3*1], xmm0 + psrldq xmm0, 1 + movq [r0+r3*2], xmm0 + RET +%endmacro + +INIT_MMX sse2 +PRED8x8L_DOWN_LEFT +INIT_MMX ssse3 +PRED8x8L_DOWN_LEFT + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_down_right_8_mmxext(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred8x8l_down_right_8, 4,5 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d ; top_left + jz .fix_lt_1 +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm4, mm0 + movq mm7, mm2 + movq mm6, mm2 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + psllq mm1, 56 + PALIGNR mm7, mm1, 7, mm3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d ; top_left + jz .fix_lt_2 + test r2d, r2d ; top_right + jz .fix_tr_1 +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq mm5, mm4 + jmp .body +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d ; top_right + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.body: + lea r1, [r0+r3*2] + movq mm1, mm7 + movq mm7, mm5 + movq mm5, mm6 + movq mm2, mm7 + lea r2, [r1+r3*2] + PALIGNR mm2, mm6, 1, mm0 + movq mm3, mm7 + PALIGNR mm3, mm6, 7, mm0 + movq mm4, mm7 + lea r4, [r2+r3*2] + psrlq mm4, 8 + PRED4x4_LOWPASS mm0, mm1, mm2, mm5, mm6 + PRED4x4_LOWPASS mm1, mm3, mm4, mm7, mm6 + movq [r4+r3*2], mm0 + movq mm2, mm1 + psrlq mm0, 8 + psllq mm2, 56 + psrlq mm1, 8 + por mm0, mm2 + movq [r4+r3*1], mm0 + movq mm2, mm1 + psrlq mm0, 8 + psllq mm2, 56 + psrlq mm1, 8 + por mm0, mm2 + movq [r2+r3*2], mm0 + movq mm2, mm1 + psrlq mm0, 8 + psllq mm2, 56 + psrlq mm1, 8 + por mm0, mm2 + movq [r2+r3*1], mm0 + movq mm2, mm1 + psrlq mm0, 8 + psllq mm2, 56 + psrlq mm1, 8 + por mm0, mm2 + movq [r1+r3*2], mm0 + movq mm2, mm1 + psrlq mm0, 8 + psllq mm2, 56 + psrlq mm1, 8 + por mm0, mm2 + movq [r1+r3*1], mm0 + movq mm2, mm1 + psrlq mm0, 8 + psllq mm2, 56 + psrlq mm1, 8 + por mm0, mm2 + movq [r0+r3*2], mm0 + psrlq mm0, 8 + psllq mm1, 56 + por mm0, mm1 + movq [r0+r3*1], mm0 + RET + +%macro PRED8x8L_DOWN_RIGHT 0 +cglobal pred8x8l_down_right_8, 4,5 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d + jz .fix_lt_1 + jmp .do_left +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm4, mm0 + movq mm7, mm2 + movq2dq xmm3, mm2 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + psllq mm1, 56 + PALIGNR mm7, mm1, 7, mm3 + movq2dq xmm1, mm7 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq2dq xmm4, mm4 + lea r1, [r0+r3*2] + movdqa xmm0, xmm3 + pslldq xmm4, 8 + por xmm3, xmm4 + lea r2, [r1+r3*2] + pslldq xmm4, 1 + por xmm1, xmm4 + psrldq xmm0, 7 + pslldq xmm0, 15 + psrldq xmm0, 7 + por xmm1, xmm0 + lea r0, [r2+r3*2] + movdqa xmm2, xmm3 + psrldq xmm2, 1 +INIT_XMM cpuname + PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm3, xmm4 + movdqa xmm1, xmm0 + psrldq xmm1, 1 + movq [r0+r3*2], xmm0 + movq [r0+r3*1], xmm1 + psrldq xmm0, 2 + psrldq xmm1, 2 + movq [r2+r3*2], xmm0 + movq [r2+r3*1], xmm1 + psrldq xmm0, 2 + psrldq xmm1, 2 + movq [r1+r3*2], xmm0 + movq [r1+r3*1], xmm1 + psrldq xmm0, 2 + psrldq xmm1, 2 + movq [r4+r3*2], xmm0 + movq [r4+r3*1], xmm1 + RET +%endmacro + +INIT_MMX sse2 +PRED8x8L_DOWN_RIGHT +INIT_MMX ssse3 +PRED8x8L_DOWN_RIGHT + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_vertical_right_8(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred8x8l_vertical_right_8, 4,5 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d + jz .fix_lt_1 + jmp .do_left +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm7, mm2 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 +.do_top: + PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5 + lea r1, [r0+r3*2] + movq mm2, mm6 + movq mm3, mm6 + PALIGNR mm3, mm7, 7, mm0 + PALIGNR mm6, mm7, 6, mm1 + movq mm4, mm3 + pavgb mm3, mm2 + lea r2, [r1+r3*2] + PRED4x4_LOWPASS mm0, mm6, mm2, mm4, mm5 + movq [r0+r3*1], mm3 + movq [r0+r3*2], mm0 + movq mm5, mm0 + movq mm6, mm3 + movq mm1, mm7 + movq mm2, mm1 + psllq mm2, 8 + movq mm3, mm1 + psllq mm3, 16 + lea r4, [r2+r3*2] + PRED4x4_LOWPASS mm0, mm1, mm3, mm2, mm4 + PALIGNR mm6, mm0, 7, mm2 + movq [r1+r3*1], mm6 + psllq mm0, 8 + PALIGNR mm5, mm0, 7, mm1 + movq [r1+r3*2], mm5 + psllq mm0, 8 + PALIGNR mm6, mm0, 7, mm2 + movq [r2+r3*1], mm6 + psllq mm0, 8 + PALIGNR mm5, mm0, 7, mm1 + movq [r2+r3*2], mm5 + psllq mm0, 8 + PALIGNR mm6, mm0, 7, mm2 + movq [r4+r3*1], mm6 + psllq mm0, 8 + PALIGNR mm5, mm0, 7, mm1 + movq [r4+r3*2], mm5 + RET + +%macro PRED8x8L_VERTICAL_RIGHT 0 +cglobal pred8x8l_vertical_right_8, 4,5,7 + ; manually spill XMM registers for Win64 because + ; the code here is initialized with INIT_MMX + WIN64_SPILL_XMM 7 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d + jnz .do_left +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq2dq xmm0, mm2 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 +.do_top: + PRED4x4_LOWPASS mm6, mm2, mm1, mm3, mm5 + lea r1, [r0+r3*2] + movq2dq xmm4, mm6 + pslldq xmm4, 8 + por xmm0, xmm4 + movdqa xmm6, [pw_ff00] + movdqa xmm1, xmm0 + lea r2, [r1+r3*2] + movdqa xmm2, xmm0 + movdqa xmm3, xmm0 + pslldq xmm0, 1 + pslldq xmm1, 2 + pavgb xmm2, xmm0 +INIT_XMM cpuname + PRED4x4_LOWPASS xmm4, xmm3, xmm1, xmm0, xmm5 + pandn xmm6, xmm4 + movdqa xmm5, xmm4 + psrlw xmm4, 8 + packuswb xmm6, xmm4 + movhlps xmm4, xmm6 + movhps [r0+r3*2], xmm5 + movhps [r0+r3*1], xmm2 + psrldq xmm5, 4 + movss xmm5, xmm6 + psrldq xmm2, 4 + movss xmm2, xmm4 + lea r0, [r2+r3*2] + psrldq xmm5, 1 + psrldq xmm2, 1 + movq [r0+r3*2], xmm5 + movq [r0+r3*1], xmm2 + psrldq xmm5, 1 + psrldq xmm2, 1 + movq [r2+r3*2], xmm5 + movq [r2+r3*1], xmm2 + psrldq xmm5, 1 + psrldq xmm2, 1 + movq [r1+r3*2], xmm5 + movq [r1+r3*1], xmm2 + RET +%endmacro + +INIT_MMX sse2 +PRED8x8L_VERTICAL_RIGHT +INIT_MMX ssse3 +PRED8x8L_VERTICAL_RIGHT + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_vertical_left_8(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8L_VERTICAL_LEFT 0 +cglobal pred8x8l_vertical_left_8, 4,4 + sub r0, r3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 + jmp .do_top +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.fix_tr_2: + punpckhbw mm3, mm3 + pshufw mm1, mm3, 0xFF + jmp .do_topright +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq2dq xmm4, mm4 + test r2d, r2d + jz .fix_tr_2 + movq mm0, [r0+8] + movq mm5, mm0 + movq mm2, mm0 + movq mm4, mm0 + psrlq mm5, 56 + PALIGNR mm2, mm3, 7, mm3 + PALIGNR mm5, mm4, 1, mm4 + PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4 +.do_topright: + movq2dq xmm3, mm1 + lea r1, [r0+r3*2] + pslldq xmm3, 8 + por xmm4, xmm3 + movdqa xmm2, xmm4 + movdqa xmm1, xmm4 + movdqa xmm3, xmm4 + psrldq xmm2, 1 + pslldq xmm1, 1 + pavgb xmm3, xmm2 + lea r2, [r1+r3*2] +INIT_XMM cpuname + PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm4, xmm5 + psrldq xmm0, 1 + movq [r0+r3*1], xmm3 + movq [r0+r3*2], xmm0 + lea r0, [r2+r3*2] + psrldq xmm3, 1 + psrldq xmm0, 1 + movq [r1+r3*1], xmm3 + movq [r1+r3*2], xmm0 + psrldq xmm3, 1 + psrldq xmm0, 1 + movq [r2+r3*1], xmm3 + movq [r2+r3*2], xmm0 + psrldq xmm3, 1 + psrldq xmm0, 1 + movq [r0+r3*1], xmm3 + movq [r0+r3*2], xmm0 + RET +%endmacro + +INIT_MMX sse2 +PRED8x8L_VERTICAL_LEFT +INIT_MMX ssse3 +PRED8x8L_VERTICAL_LEFT + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_horizontal_up_8(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED8x8L_HORIZONTAL_UP 0 +cglobal pred8x8l_horizontal_up_8, 4,4 + sub r0, r3 + lea r2, [r0+r3*2] + movq mm0, [r0+r3*1-8] + test r1d, r1d + lea r1, [r0+r3] + cmovnz r1, r0 + punpckhbw mm0, [r1+r3*0-8] + movq mm1, [r2+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r2, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r1+r3*0-8] + mov r0, r2 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm4, mm0 + movq mm7, mm2 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + psllq mm1, 56 + PALIGNR mm7, mm1, 7, mm3 + lea r1, [r0+r3*2] + pshufw mm0, mm7, 00011011b ; l6 l7 l4 l5 l2 l3 l0 l1 + psllq mm7, 56 ; l7 .. .. .. .. .. .. .. + movq mm2, mm0 + psllw mm0, 8 + psrlw mm2, 8 + por mm2, mm0 ; l7 l6 l5 l4 l3 l2 l1 l0 + movq mm3, mm2 + movq mm4, mm2 + movq mm5, mm2 + psrlq mm2, 8 + psrlq mm3, 16 + lea r2, [r1+r3*2] + por mm2, mm7 ; l7 l7 l6 l5 l4 l3 l2 l1 + punpckhbw mm7, mm7 + por mm3, mm7 ; l7 l7 l7 l6 l5 l4 l3 l2 + pavgb mm4, mm2 + PRED4x4_LOWPASS mm1, mm3, mm5, mm2, mm6 + movq mm5, mm4 + punpcklbw mm4, mm1 ; p4 p3 p2 p1 + punpckhbw mm5, mm1 ; p8 p7 p6 p5 + movq mm6, mm5 + movq mm7, mm5 + movq mm0, mm5 + PALIGNR mm5, mm4, 2, mm1 + pshufw mm1, mm6, 11111001b + PALIGNR mm6, mm4, 4, mm2 + pshufw mm2, mm7, 11111110b + PALIGNR mm7, mm4, 6, mm3 + pshufw mm3, mm0, 11111111b + movq [r0+r3*1], mm4 + movq [r0+r3*2], mm5 + lea r0, [r2+r3*2] + movq [r1+r3*1], mm6 + movq [r1+r3*2], mm7 + movq [r2+r3*1], mm0 + movq [r2+r3*2], mm1 + movq [r0+r3*1], mm2 + movq [r0+r3*2], mm3 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8L_HORIZONTAL_UP +INIT_MMX ssse3 +PRED8x8L_HORIZONTAL_UP + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_horizontal_down_8(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred8x8l_horizontal_down_8, 4,5 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d + jnz .do_left +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq mm4, mm0 + movq mm7, mm2 + movq mm6, mm2 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + psllq mm1, 56 + PALIGNR mm7, mm1, 7, mm3 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq mm5, mm4 + lea r1, [r0+r3*2] + psllq mm7, 56 + movq mm2, mm5 + movq mm3, mm6 + movq mm4, mm2 + PALIGNR mm2, mm6, 7, mm5 + PALIGNR mm6, mm7, 7, mm0 + lea r2, [r1+r3*2] + PALIGNR mm4, mm3, 1, mm7 + movq mm5, mm3 + pavgb mm3, mm6 + PRED4x4_LOWPASS mm0, mm4, mm6, mm5, mm7 + movq mm4, mm2 + movq mm1, mm2 + lea r4, [r2+r3*2] + psrlq mm4, 16 + psrlq mm1, 8 + PRED4x4_LOWPASS mm6, mm4, mm2, mm1, mm5 + movq mm7, mm3 + punpcklbw mm3, mm0 + punpckhbw mm7, mm0 + movq mm1, mm7 + movq mm0, mm7 + movq mm4, mm7 + movq [r4+r3*2], mm3 + PALIGNR mm7, mm3, 2, mm5 + movq [r4+r3*1], mm7 + PALIGNR mm1, mm3, 4, mm5 + movq [r2+r3*2], mm1 + PALIGNR mm0, mm3, 6, mm3 + movq [r2+r3*1], mm0 + movq mm2, mm6 + movq mm3, mm6 + movq [r1+r3*2], mm4 + PALIGNR mm6, mm4, 2, mm5 + movq [r1+r3*1], mm6 + PALIGNR mm2, mm4, 4, mm5 + movq [r0+r3*2], mm2 + PALIGNR mm3, mm4, 6, mm4 + movq [r0+r3*1], mm3 + RET + +%macro PRED8x8L_HORIZONTAL_DOWN 0 +cglobal pred8x8l_horizontal_down_8, 4,5 + sub r0, r3 + lea r4, [r0+r3*2] + movq mm0, [r0+r3*1-8] + punpckhbw mm0, [r0+r3*0-8] + movq mm1, [r4+r3*1-8] + punpckhbw mm1, [r0+r3*2-8] + mov r4, r0 + punpckhwd mm1, mm0 + lea r0, [r0+r3*4] + movq mm2, [r0+r3*1-8] + punpckhbw mm2, [r0+r3*0-8] + lea r0, [r0+r3*2] + movq mm3, [r0+r3*1-8] + punpckhbw mm3, [r0+r3*0-8] + punpckhwd mm3, mm2 + punpckhdq mm3, mm1 + lea r0, [r0+r3*2] + movq mm0, [r0+r3*0-8] + movq mm1, [r4] + mov r0, r4 + movq mm4, mm3 + movq mm2, mm3 + PALIGNR mm4, mm0, 7, mm0 + PALIGNR mm1, mm2, 1, mm2 + test r1d, r1d + jnz .do_left +.fix_lt_1: + movq mm5, mm3 + pxor mm5, mm4 + psrlq mm5, 56 + psllq mm5, 48 + pxor mm1, mm5 + jmp .do_left +.fix_lt_2: + movq mm5, mm3 + pxor mm5, mm2 + psllq mm5, 56 + psrlq mm5, 56 + pxor mm2, mm5 + test r2d, r2d + jnz .do_top +.fix_tr_1: + movq mm5, mm3 + pxor mm5, mm1 + psrlq mm5, 56 + psllq mm5, 56 + pxor mm1, mm5 + jmp .do_top +.fix_tr_2: + punpckhbw mm3, mm3 + pshufw mm1, mm3, 0xFF + jmp .do_topright +.do_left: + movq mm0, mm4 + PRED4x4_LOWPASS mm2, mm1, mm4, mm3, mm5 + movq2dq xmm0, mm2 + pslldq xmm0, 8 + movq mm4, mm0 + PRED4x4_LOWPASS mm1, mm3, mm0, mm4, mm5 + movq2dq xmm2, mm1 + pslldq xmm2, 15 + psrldq xmm2, 8 + por xmm0, xmm2 + movq mm0, [r0-8] + movq mm3, [r0] + movq mm1, [r0+8] + movq mm2, mm3 + movq mm4, mm3 + PALIGNR mm2, mm0, 7, mm0 + PALIGNR mm1, mm4, 1, mm4 + test r1d, r1d + jz .fix_lt_2 + test r2d, r2d + jz .fix_tr_1 +.do_top: + PRED4x4_LOWPASS mm4, mm2, mm1, mm3, mm5 + movq2dq xmm1, mm4 + test r2d, r2d + jz .fix_tr_2 + movq mm0, [r0+8] + movq mm5, mm0 + movq mm2, mm0 + movq mm4, mm0 + psrlq mm5, 56 + PALIGNR mm2, mm3, 7, mm3 + PALIGNR mm5, mm4, 1, mm4 + PRED4x4_LOWPASS mm1, mm2, mm5, mm0, mm4 +.do_topright: + movq2dq xmm5, mm1 + pslldq xmm5, 8 + por xmm1, xmm5 +INIT_XMM cpuname + lea r2, [r4+r3*2] + movdqa xmm2, xmm1 + movdqa xmm3, xmm1 + PALIGNR xmm1, xmm0, 7, xmm4 + PALIGNR xmm2, xmm0, 9, xmm5 + lea r1, [r2+r3*2] + PALIGNR xmm3, xmm0, 8, xmm0 + movdqa xmm4, xmm1 + pavgb xmm4, xmm3 + lea r0, [r1+r3*2] + PRED4x4_LOWPASS xmm0, xmm1, xmm2, xmm3, xmm5 + punpcklbw xmm4, xmm0 + movhlps xmm0, xmm4 + movq [r0+r3*2], xmm4 + movq [r2+r3*2], xmm0 + psrldq xmm4, 2 + psrldq xmm0, 2 + movq [r0+r3*1], xmm4 + movq [r2+r3*1], xmm0 + psrldq xmm4, 2 + psrldq xmm0, 2 + movq [r1+r3*2], xmm4 + movq [r4+r3*2], xmm0 + psrldq xmm4, 2 + psrldq xmm0, 2 + movq [r1+r3*1], xmm4 + movq [r4+r3*1], xmm0 + RET +%endmacro + +INIT_MMX sse2 +PRED8x8L_HORIZONTAL_DOWN +INIT_MMX ssse3 +PRED8x8L_HORIZONTAL_DOWN + +;------------------------------------------------------------------------------- +; void ff_pred4x4_dc_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred4x4_dc_8, 3,5 + pxor mm7, mm7 + mov r4, r0 + sub r0, r2 + movd mm0, [r0] + psadbw mm0, mm7 + movzx r1d, byte [r0+r2*1-1] + movd r3d, mm0 + add r3d, r1d + movzx r1d, byte [r0+r2*2-1] + lea r0, [r0+r2*2] + add r3d, r1d + movzx r1d, byte [r0+r2*1-1] + add r3d, r1d + movzx r1d, byte [r0+r2*2-1] + add r3d, r1d + add r3d, 4 + shr r3d, 3 + imul r3d, 0x01010101 + mov [r4+r2*0], r3d + mov [r0+r2*0], r3d + mov [r0+r2*1], r3d + mov [r0+r2*2], r3d + RET + +;----------------------------------------------------------------------------- +; void ff_pred4x4_tm_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- + +%macro PRED4x4_TM 0 +cglobal pred4x4_tm_vp8_8, 3,6 + sub r0, r2 + pxor mm7, mm7 + movd mm0, [r0] + punpcklbw mm0, mm7 + movzx r4d, byte [r0-1] + mov r5d, 2 +.loop: + movzx r1d, byte [r0+r2*1-1] + movzx r3d, byte [r0+r2*2-1] + sub r1d, r4d + sub r3d, r4d + movd mm2, r1d + movd mm4, r3d +%if cpuflag(mmxext) + pshufw mm2, mm2, 0 + pshufw mm4, mm4, 0 +%else + punpcklwd mm2, mm2 + punpcklwd mm4, mm4 + punpckldq mm2, mm2 + punpckldq mm4, mm4 +%endif + paddw mm2, mm0 + paddw mm4, mm0 + packuswb mm2, mm2 + packuswb mm4, mm4 + movd [r0+r2*1], mm2 + movd [r0+r2*2], mm4 + lea r0, [r0+r2*2] + dec r5d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmx +PRED4x4_TM +INIT_MMX mmxext +PRED4x4_TM + +INIT_XMM ssse3 +cglobal pred4x4_tm_vp8_8, 3,3 + sub r0, r2 + movq mm6, [tm_shuf] + pxor mm1, mm1 + movd mm0, [r0] + punpcklbw mm0, mm1 + movd mm7, [r0-4] + pshufb mm7, mm6 + lea r1, [r0+r2*2] + movd mm2, [r0+r2*1-4] + movd mm3, [r0+r2*2-4] + movd mm4, [r1+r2*1-4] + movd mm5, [r1+r2*2-4] + pshufb mm2, mm6 + pshufb mm3, mm6 + pshufb mm4, mm6 + pshufb mm5, mm6 + psubw mm0, mm7 + paddw mm2, mm0 + paddw mm3, mm0 + paddw mm4, mm0 + paddw mm5, mm0 + packuswb mm2, mm2 + packuswb mm3, mm3 + packuswb mm4, mm4 + packuswb mm5, mm5 + movd [r0+r2*1], mm2 + movd [r0+r2*2], mm3 + movd [r1+r2*1], mm4 + movd [r1+r2*2], mm5 + RET + +;----------------------------------------------------------------------------- +; void ff_pred4x4_vertical_vp8_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred4x4_vertical_vp8_8, 3,3 + sub r0, r2 + movd m1, [r0-1] + movd m0, [r0] + mova m2, m0 ;t0 t1 t2 t3 + punpckldq m0, [r1] ;t0 t1 t2 t3 t4 t5 t6 t7 + lea r1, [r0+r2*2] + psrlq m0, 8 ;t1 t2 t3 t4 + PRED4x4_LOWPASS m3, m1, m0, m2, m4 + movd [r0+r2*1], m3 + movd [r0+r2*2], m3 + movd [r1+r2*1], m3 + movd [r1+r2*2], m3 + RET + +;----------------------------------------------------------------------------- +; void ff_pred4x4_down_left_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_MMX mmxext +cglobal pred4x4_down_left_8, 3,3 + sub r0, r2 + movq m1, [r0] + punpckldq m1, [r1] + movq m2, m1 + movq m3, m1 + psllq m1, 8 + pxor m2, m1 + psrlq m2, 8 + pxor m2, m3 + PRED4x4_LOWPASS m0, m1, m2, m3, m4 + lea r1, [r0+r2*2] + psrlq m0, 8 + movd [r0+r2*1], m0 + psrlq m0, 8 + movd [r0+r2*2], m0 + psrlq m0, 8 + movd [r1+r2*1], m0 + psrlq m0, 8 + movd [r1+r2*2], m0 + RET + +;------------------------------------------------------------------------------ +; void ff_pred4x4_vertical_left_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------ + +INIT_MMX mmxext +cglobal pred4x4_vertical_left_8, 3,3 + sub r0, r2 + movq m1, [r0] + punpckldq m1, [r1] + movq m3, m1 + movq m2, m1 + psrlq m3, 8 + psrlq m2, 16 + movq m4, m3 + pavgb m4, m1 + PRED4x4_LOWPASS m0, m1, m2, m3, m5 + lea r1, [r0+r2*2] + movh [r0+r2*1], m4 + movh [r0+r2*2], m0 + psrlq m4, 8 + psrlq m0, 8 + movh [r1+r2*1], m4 + movh [r1+r2*2], m0 + RET + +;------------------------------------------------------------------------------ +; void ff_pred4x4_horizontal_up_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------ + +INIT_MMX mmxext +cglobal pred4x4_horizontal_up_8, 3,3 + sub r0, r2 + lea r1, [r0+r2*2] + movd m0, [r0+r2*1-4] + punpcklbw m0, [r0+r2*2-4] + movd m1, [r1+r2*1-4] + punpcklbw m1, [r1+r2*2-4] + punpckhwd m0, m1 + movq m1, m0 + punpckhbw m1, m1 + pshufw m1, m1, 0xFF + punpckhdq m0, m1 + movq m2, m0 + movq m3, m0 + movq m7, m0 + psrlq m2, 16 + psrlq m3, 8 + pavgb m7, m3 + PRED4x4_LOWPASS m4, m0, m2, m3, m5 + punpcklbw m7, m4 + movd [r0+r2*1], m7 + psrlq m7, 16 + movd [r0+r2*2], m7 + psrlq m7, 16 + movd [r1+r2*1], m7 + movd [r1+r2*2], m1 + RET + +;------------------------------------------------------------------------------ +; void ff_pred4x4_horizontal_down_8_mmxext(uint8_t *src, +; const uint8_t *topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------ + +INIT_MMX mmxext +cglobal pred4x4_horizontal_down_8, 3,3 + sub r0, r2 + lea r1, [r0+r2*2] + movh m0, [r0-4] ; lt .. + punpckldq m0, [r0] ; t3 t2 t1 t0 lt .. .. .. + psllq m0, 8 ; t2 t1 t0 lt .. .. .. .. + movd m1, [r1+r2*2-4] ; l3 + punpcklbw m1, [r1+r2*1-4] ; l2 l3 + movd m2, [r0+r2*2-4] ; l1 + punpcklbw m2, [r0+r2*1-4] ; l0 l1 + punpckhwd m1, m2 ; l0 l1 l2 l3 + punpckhdq m1, m0 ; t2 t1 t0 lt l0 l1 l2 l3 + movq m0, m1 + movq m2, m1 + movq m5, m1 + psrlq m0, 16 ; .. .. t2 t1 t0 lt l0 l1 + psrlq m2, 8 ; .. t2 t1 t0 lt l0 l1 l2 + pavgb m5, m2 + PRED4x4_LOWPASS m3, m1, m0, m2, m4 + punpcklbw m5, m3 + psrlq m3, 32 + PALIGNR m3, m5, 6, m4 + movh [r1+r2*2], m5 + psrlq m5, 16 + movh [r1+r2*1], m5 + psrlq m5, 16 + movh [r0+r2*2], m5 + movh [r0+r2*1], m3 + RET + +;----------------------------------------------------------------------------- +; void ff_pred4x4_vertical_right_8_mmxext(uint8_t *src, +; const uint8_t *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred4x4_vertical_right_8, 3,3 + sub r0, r2 + lea r1, [r0+r2*2] + movh m0, [r0] ; ........t3t2t1t0 + movq m5, m0 + PALIGNR m0, [r0-8], 7, m1 ; ......t3t2t1t0lt + pavgb m5, m0 + PALIGNR m0, [r0+r2*1-8], 7, m1 ; ....t3t2t1t0ltl0 + movq m1, m0 + PALIGNR m0, [r0+r2*2-8], 7, m2 ; ..t3t2t1t0ltl0l1 + movq m2, m0 + PALIGNR m0, [r1+r2*1-8], 7, m3 ; t3t2t1t0ltl0l1l2 + PRED4x4_LOWPASS m3, m1, m0, m2, m4 + movq m1, m3 + psrlq m3, 16 + psllq m1, 48 + movh [r0+r2*1], m5 + movh [r0+r2*2], m3 + PALIGNR m5, m1, 7, m2 + psllq m1, 8 + movh [r1+r2*1], m5 + PALIGNR m3, m1, 7, m1 + movh [r1+r2*2], m3 + RET + +;----------------------------------------------------------------------------- +; void ff_pred4x4_down_right_8_mmxext(uint8_t *src, const uint8_t *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred4x4_down_right_8, 3,3 + sub r0, r2 + lea r1, [r0+r2*2] + movq m1, [r1-8] + movq m2, [r0+r2*1-8] + punpckhbw m2, [r0-8] + movh m3, [r0] + punpckhwd m1, m2 + PALIGNR m3, m1, 5, m1 + movq m1, m3 + PALIGNR m3, [r1+r2*1-8], 7, m4 + movq m2, m3 + PALIGNR m3, [r1+r2*2-8], 7, m4 + PRED4x4_LOWPASS m0, m3, m1, m2, m4 + movh [r1+r2*2], m0 + psrlq m0, 8 + movh [r1+r2*1], m0 + psrlq m0, 8 + movh [r0+r2*2], m0 + psrlq m0, 8 + movh [r0+r2*1], m0 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred_10bit.asm new file mode 100644 index 00000000..629e0a72 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred_10bit.asm @@ -0,0 +1,1199 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 intra prediction code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pw_1023 +%define pw_pixel_max pw_1023 +cextern pw_512 +cextern pw_16 +cextern pw_8 +cextern pw_4 +cextern pw_2 +cextern pw_1 +cextern pd_16 + +pw_m32101234: dw -3, -2, -1, 0, 1, 2, 3, 4 +pw_m3: times 8 dw -3 +pd_17: times 4 dd 17 + +SECTION .text + +; dest, left, right, src +; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2 +%macro PRED4x4_LOWPASS 4 + paddw %2, %3 + psrlw %2, 1 + pavgw %1, %4, %2 +%endmacro + +;----------------------------------------------------------------------------- +; void ff_pred4x4_down_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED4x4_DR 0 +cglobal pred4x4_down_right_10, 3, 3 + sub r0, r2 + lea r1, [r0+r2*2] + movhps m1, [r1-8] + movhps m2, [r0+r2*1-8] + movhps m4, [r0-8] + punpckhwd m2, m4 + movq m3, [r0] + punpckhdq m1, m2 + PALIGNR m3, m1, 10, m1 + movhps m4, [r1+r2*1-8] + PALIGNR m0, m3, m4, 14, m4 + movhps m4, [r1+r2*2-8] + PALIGNR m2, m0, m4, 14, m4 + PRED4x4_LOWPASS m0, m2, m3, m0 + movq [r1+r2*2], m0 + psrldq m0, 2 + movq [r1+r2*1], m0 + psrldq m0, 2 + movq [r0+r2*2], m0 + psrldq m0, 2 + movq [r0+r2*1], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED4x4_DR +INIT_XMM ssse3 +PRED4x4_DR +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED4x4_DR +%endif + +;------------------------------------------------------------------------------ +; void ff_pred4x4_vertical_right_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------ +%macro PRED4x4_VR 0 +cglobal pred4x4_vertical_right_10, 3, 3, 6 + sub r0, r2 + lea r1, [r0+r2*2] + movq m5, [r0] ; ........t3t2t1t0 + movhps m1, [r0-8] + PALIGNR m0, m5, m1, 14, m1 ; ......t3t2t1t0lt + pavgw m5, m0 + movhps m1, [r0+r2*1-8] + PALIGNR m0, m1, 14, m1 ; ....t3t2t1t0ltl0 + movhps m2, [r0+r2*2-8] + PALIGNR m1, m0, m2, 14, m2 ; ..t3t2t1t0ltl0l1 + movhps m3, [r1+r2*1-8] + PALIGNR m2, m1, m3, 14, m3 ; t3t2t1t0ltl0l1l2 + PRED4x4_LOWPASS m1, m0, m2, m1 + pslldq m0, m1, 12 + psrldq m1, 4 + movq [r0+r2*1], m5 + movq [r0+r2*2], m1 + PALIGNR m5, m0, 14, m2 + pslldq m0, 2 + movq [r1+r2*1], m5 + PALIGNR m1, m0, 14, m0 + movq [r1+r2*2], m1 + RET +%endmacro + +INIT_XMM sse2 +PRED4x4_VR +INIT_XMM ssse3 +PRED4x4_VR +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED4x4_VR +%endif + +;------------------------------------------------------------------------------- +; void ff_pred4x4_horizontal_down_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------- +%macro PRED4x4_HD 0 +cglobal pred4x4_horizontal_down_10, 3, 3 + sub r0, r2 + lea r1, [r0+r2*2] + movq m0, [r0-8] ; lt .. + movhps m0, [r0] + pslldq m0, 2 ; t2 t1 t0 lt .. .. .. .. + movq m1, [r1+r2*2-8] ; l3 + movq m3, [r1+r2*1-8] + punpcklwd m1, m3 ; l2 l3 + movq m2, [r0+r2*2-8] ; l1 + movq m3, [r0+r2*1-8] + punpcklwd m2, m3 ; l0 l1 + punpckhdq m1, m2 ; l0 l1 l2 l3 + punpckhqdq m1, m0 ; t2 t1 t0 lt l0 l1 l2 l3 + psrldq m0, m1, 4 ; .. .. t2 t1 t0 lt l0 l1 + psrldq m3, m1, 2 ; .. t2 t1 t0 lt l0 l1 l2 + pavgw m5, m1, m3 + PRED4x4_LOWPASS m3, m1, m0, m3 + punpcklwd m5, m3 + psrldq m3, 8 + PALIGNR m3, m5, 12, m4 + movq [r1+r2*2], m5 + movhps [r0+r2*2], m5 + psrldq m5, 4 + movq [r1+r2*1], m5 + movq [r0+r2*1], m3 + RET +%endmacro + +INIT_XMM sse2 +PRED4x4_HD +INIT_XMM ssse3 +PRED4x4_HD +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED4x4_HD +%endif + +;----------------------------------------------------------------------------- +; void ff_pred4x4_dc_10(pixel *src, const pixel *topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- + +INIT_MMX mmxext +cglobal pred4x4_dc_10, 3, 3 + sub r0, r2 + lea r1, [r0+r2*2] + movq m2, [r0+r2*1-8] + paddw m2, [r0+r2*2-8] + paddw m2, [r1+r2*1-8] + paddw m2, [r1+r2*2-8] + psrlq m2, 48 + movq m0, [r0] + HADDW m0, m1 + paddw m0, [pw_4] + paddw m0, m2 + psrlw m0, 3 + SPLATW m0, m0, 0 + movq [r0+r2*1], m0 + movq [r0+r2*2], m0 + movq [r1+r2*1], m0 + movq [r1+r2*2], m0 + RET + +;----------------------------------------------------------------------------- +; void ff_pred4x4_down_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED4x4_DL 0 +cglobal pred4x4_down_left_10, 3, 3 + sub r0, r2 + movq m0, [r0] + movhps m0, [r1] + psrldq m2, m0, 2 + pslldq m3, m0, 2 + pshufhw m2, m2, 10100100b + PRED4x4_LOWPASS m0, m3, m2, m0 + lea r1, [r0+r2*2] + movhps [r1+r2*2], m0 + psrldq m0, 2 + movq [r0+r2*1], m0 + psrldq m0, 2 + movq [r0+r2*2], m0 + psrldq m0, 2 + movq [r1+r2*1], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED4x4_DL +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED4x4_DL +%endif + +;----------------------------------------------------------------------------- +; void ff_pred4x4_vertical_left_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED4x4_VL 0 +cglobal pred4x4_vertical_left_10, 3, 3 + sub r0, r2 + movu m1, [r0] + movhps m1, [r1] + psrldq m0, m1, 2 + psrldq m2, m1, 4 + pavgw m4, m0, m1 + PRED4x4_LOWPASS m0, m1, m2, m0 + lea r1, [r0+r2*2] + movq [r0+r2*1], m4 + movq [r0+r2*2], m0 + psrldq m4, 2 + psrldq m0, 2 + movq [r1+r2*1], m4 + movq [r1+r2*2], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED4x4_VL +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED4x4_VL +%endif + +;----------------------------------------------------------------------------- +; void ff_pred4x4_horizontal_up_10(pixel *src, const pixel *topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_MMX mmxext +cglobal pred4x4_horizontal_up_10, 3, 3 + sub r0, r2 + lea r1, [r0+r2*2] + movq m0, [r0+r2*1-8] + punpckhwd m0, [r0+r2*2-8] + movq m1, [r1+r2*1-8] + punpckhwd m1, [r1+r2*2-8] + punpckhdq m0, m1 + pshufw m1, m1, 0xFF + movq [r1+r2*2], m1 + movd [r1+r2*1+4], m1 + pshufw m2, m0, 11111001b + movq m1, m2 + pavgw m2, m0 + + pshufw m5, m0, 11111110b + PRED4x4_LOWPASS m1, m0, m5, m1 + movq m6, m2 + punpcklwd m6, m1 + movq [r0+r2*1], m6 + psrlq m2, 16 + psrlq m1, 16 + punpcklwd m2, m1 + movq [r0+r2*2], m2 + psrlq m2, 32 + movd [r1+r2*1], m2 + RET + + + +;----------------------------------------------------------------------------- +; void ff_pred8x8_vertical_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pred8x8_vertical_10, 2, 2 + sub r0, r1 + mova m0, [r0] +%rep 3 + mova [r0+r1*1], m0 + mova [r0+r1*2], m0 + lea r0, [r0+r1*2] +%endrep + mova [r0+r1*1], m0 + mova [r0+r1*2], m0 + RET + +;----------------------------------------------------------------------------- +; void ff_pred8x8_horizontal_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pred8x8_horizontal_10, 2, 3 + mov r2d, 4 +.loop: + movq m0, [r0+r1*0-8] + movq m1, [r0+r1*1-8] + pshuflw m0, m0, 0xff + pshuflw m1, m1, 0xff + punpcklqdq m0, m0 + punpcklqdq m1, m1 + mova [r0+r1*0], m0 + mova [r0+r1*1], m1 + lea r0, [r0+r1*2] + dec r2d + jg .loop + REP_RET + +;----------------------------------------------------------------------------- +; void ff_predict_8x8_dc_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro MOV8 2-3 +; sort of a hack, but it works +%if mmsize==8 + movq [%1+0], %2 + movq [%1+8], %3 +%else + movdqa [%1], %2 +%endif +%endmacro + +%macro PRED8x8_DC 1 +cglobal pred8x8_dc_10, 2, 6 + sub r0, r1 + pxor m4, m4 + movq m0, [r0+0] + movq m1, [r0+8] +%if mmsize==16 + punpcklwd m0, m1 + movhlps m1, m0 + paddw m0, m1 +%else + pshufw m2, m0, 00001110b + pshufw m3, m1, 00001110b + paddw m0, m2 + paddw m1, m3 + punpcklwd m0, m1 +%endif + %1 m2, m0, 00001110b + paddw m0, m2 + + lea r5, [r1*3] + lea r4, [r0+r1*4] + movzx r2d, word [r0+r1*1-2] + movzx r3d, word [r0+r1*2-2] + add r2d, r3d + movzx r3d, word [r0+r5*1-2] + add r2d, r3d + movzx r3d, word [r4-2] + add r2d, r3d + movd m2, r2d ; s2 + + movzx r2d, word [r4+r1*1-2] + movzx r3d, word [r4+r1*2-2] + add r2d, r3d + movzx r3d, word [r4+r5*1-2] + add r2d, r3d + movzx r3d, word [r4+r1*4-2] + add r2d, r3d + movd m3, r2d ; s3 + + punpcklwd m2, m3 + punpckldq m0, m2 ; s0, s1, s2, s3 + %1 m3, m0, 11110110b ; s2, s1, s3, s3 + %1 m0, m0, 01110100b ; s0, s1, s3, s1 + paddw m0, m3 + psrlw m0, 2 + pavgw m0, m4 ; s0+s2, s1, s3, s1+s3 +%if mmsize==16 + punpcklwd m0, m0 + pshufd m3, m0, 11111010b + punpckldq m0, m0 + SWAP 0,1 +%else + pshufw m1, m0, 0x00 + pshufw m2, m0, 0x55 + pshufw m3, m0, 0xaa + pshufw m4, m0, 0xff +%endif + MOV8 r0+r1*1, m1, m2 + MOV8 r0+r1*2, m1, m2 + MOV8 r0+r5*1, m1, m2 + MOV8 r0+r1*4, m1, m2 + MOV8 r4+r1*1, m3, m4 + MOV8 r4+r1*2, m3, m4 + MOV8 r4+r5*1, m3, m4 + MOV8 r4+r1*4, m3, m4 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8_DC pshufw +INIT_XMM sse2 +PRED8x8_DC pshuflw + +;----------------------------------------------------------------------------- +; void ff_pred8x8_top_dc_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pred8x8_top_dc_10, 2, 4 + sub r0, r1 + mova m0, [r0] + pshuflw m1, m0, 0x4e + pshufhw m1, m1, 0x4e + paddw m0, m1 + pshuflw m1, m0, 0xb1 + pshufhw m1, m1, 0xb1 + paddw m0, m1 + lea r2, [r1*3] + lea r3, [r0+r1*4] + paddw m0, [pw_2] + psrlw m0, 2 + mova [r0+r1*1], m0 + mova [r0+r1*2], m0 + mova [r0+r2*1], m0 + mova [r0+r1*4], m0 + mova [r3+r1*1], m0 + mova [r3+r1*2], m0 + mova [r3+r2*1], m0 + mova [r3+r1*4], m0 + RET + +;----------------------------------------------------------------------------- +; void ff_pred8x8_plane_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pred8x8_plane_10, 2, 7, 7 + sub r0, r1 + lea r2, [r1*3] + lea r3, [r0+r1*4] + mova m2, [r0] + pmaddwd m2, [pw_m32101234] + HADDD m2, m1 + movd m0, [r0-4] + psrld m0, 14 + psubw m2, m0 ; H + movd m0, [r3+r1*4-4] + movd m1, [r0+12] + paddw m0, m1 + psllw m0, 4 ; 16*(src[7*stride-1] + src[-stride+7]) + movzx r4d, word [r3+r1*1-2] ; src[4*stride-1] + movzx r5d, word [r0+r2*1-2] ; src[2*stride-1] + sub r4d, r5d + movzx r6d, word [r3+r1*2-2] ; src[5*stride-1] + movzx r5d, word [r0+r1*2-2] ; src[1*stride-1] + sub r6d, r5d + lea r4d, [r4+r6*2] + movzx r5d, word [r3+r2*1-2] ; src[6*stride-1] + movzx r6d, word [r0+r1*1-2] ; src[0*stride-1] + sub r5d, r6d + lea r5d, [r5*3] + add r4d, r5d + movzx r6d, word [r3+r1*4-2] ; src[7*stride-1] + movzx r5d, word [r0+r1*0-2] ; src[ -stride-1] + sub r6d, r5d + lea r4d, [r4+r6*4] + movd m3, r4d ; V + punpckldq m2, m3 + pmaddwd m2, [pd_17] + paddd m2, [pd_16] + psrad m2, 5 ; b, c + + mova m3, [pw_pixel_max] + pxor m1, m1 + SPLATW m0, m0, 1 + SPLATW m4, m2, 2 + SPLATW m2, m2, 0 + pmullw m2, [pw_m32101234] ; b + pmullw m5, m4, [pw_m3] ; c + paddw m5, [pw_16] + mov r2d, 8 + add r0, r1 +.loop: + paddsw m6, m2, m5 + paddsw m6, m0 + psraw m6, 5 + CLIPW m6, m1, m3 + mova [r0], m6 + paddw m5, m4 + add r0, r1 + dec r2d + jg .loop + REP_RET + + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_128_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_128_DC 0 +cglobal pred8x8l_128_dc_10, 4, 4 + mova m0, [pw_512] ; (1<<(BIT_DEPTH-1)) + lea r1, [r3*3] + lea r2, [r0+r3*4] + MOV8 r0+r3*0, m0, m0 + MOV8 r0+r3*1, m0, m0 + MOV8 r0+r3*2, m0, m0 + MOV8 r0+r1*1, m0, m0 + MOV8 r2+r3*0, m0, m0 + MOV8 r2+r3*1, m0, m0 + MOV8 r2+r3*2, m0, m0 + MOV8 r2+r1*1, m0, m0 + RET +%endmacro + +INIT_MMX mmxext +PRED8x8L_128_DC +INIT_XMM sse2 +PRED8x8L_128_DC + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_top_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_TOP_DC 0 +cglobal pred8x8l_top_dc_10, 4, 4, 6 + sub r0, r3 + mova m0, [r0] + shr r1d, 14 + shr r2d, 13 + neg r1 + pslldq m1, m0, 2 + psrldq m2, m0, 2 + pinsrw m1, [r0+r1], 0 + pinsrw m2, [r0+r2+14], 7 + lea r1, [r3*3] + lea r2, [r0+r3*4] + PRED4x4_LOWPASS m0, m2, m1, m0 + HADDW m0, m1 + paddw m0, [pw_4] + psrlw m0, 3 + SPLATW m0, m0, 0 + mova [r0+r3*1], m0 + mova [r0+r3*2], m0 + mova [r0+r1*1], m0 + mova [r0+r3*4], m0 + mova [r2+r3*1], m0 + mova [r2+r3*2], m0 + mova [r2+r1*1], m0 + mova [r2+r3*4], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_TOP_DC +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_TOP_DC +%endif + +;------------------------------------------------------------------------------- +; void ff_pred8x8l_dc_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;------------------------------------------------------------------------------- +;TODO: see if scalar is faster +%macro PRED8x8L_DC 0 +cglobal pred8x8l_dc_10, 4, 6, 6 + sub r0, r3 + lea r4, [r0+r3*4] + lea r5, [r3*3] + mova m0, [r0+r3*2-16] + punpckhwd m0, [r0+r3*1-16] + mova m1, [r4+r3*0-16] + punpckhwd m1, [r0+r5*1-16] + punpckhdq m1, m0 + mova m2, [r4+r3*2-16] + punpckhwd m2, [r4+r3*1-16] + mova m3, [r4+r3*4-16] + punpckhwd m3, [r4+r5*1-16] + punpckhdq m3, m2 + punpckhqdq m3, m1 + mova m0, [r0] + shr r1d, 14 + shr r2d, 13 + neg r1 + pslldq m1, m0, 2 + psrldq m2, m0, 2 + pinsrw m1, [r0+r1], 0 + pinsrw m2, [r0+r2+14], 7 + not r1 + and r1, r3 + pslldq m4, m3, 2 + psrldq m5, m3, 2 + pshuflw m4, m4, 11100101b + pinsrw m5, [r0+r1-2], 7 + PRED4x4_LOWPASS m3, m4, m5, m3 + PRED4x4_LOWPASS m0, m2, m1, m0 + paddw m0, m3 + HADDW m0, m1 + paddw m0, [pw_8] + psrlw m0, 4 + SPLATW m0, m0 + mova [r0+r3*1], m0 + mova [r0+r3*2], m0 + mova [r0+r5*1], m0 + mova [r0+r3*4], m0 + mova [r4+r3*1], m0 + mova [r4+r3*2], m0 + mova [r4+r5*1], m0 + mova [r4+r3*4], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_DC +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_DC +%endif + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_vertical_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_VERTICAL 0 +cglobal pred8x8l_vertical_10, 4, 4, 6 + sub r0, r3 + mova m0, [r0] + shr r1d, 14 + shr r2d, 13 + neg r1 + pslldq m1, m0, 2 + psrldq m2, m0, 2 + pinsrw m1, [r0+r1], 0 + pinsrw m2, [r0+r2+14], 7 + lea r1, [r3*3] + lea r2, [r0+r3*4] + PRED4x4_LOWPASS m0, m2, m1, m0 + mova [r0+r3*1], m0 + mova [r0+r3*2], m0 + mova [r0+r1*1], m0 + mova [r0+r3*4], m0 + mova [r2+r3*1], m0 + mova [r2+r3*2], m0 + mova [r2+r1*1], m0 + mova [r2+r3*4], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_VERTICAL +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_VERTICAL +%endif + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_horizontal_10(uint8_t *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_HORIZONTAL 0 +cglobal pred8x8l_horizontal_10, 4, 4, 5 + mova m0, [r0-16] + shr r1d, 14 + dec r1 + and r1, r3 + sub r1, r3 + punpckhwd m0, [r0+r1-16] + mova m1, [r0+r3*2-16] + punpckhwd m1, [r0+r3*1-16] + lea r2, [r0+r3*4] + lea r1, [r3*3] + punpckhdq m1, m0 + mova m2, [r2+r3*0-16] + punpckhwd m2, [r0+r1-16] + mova m3, [r2+r3*2-16] + punpckhwd m3, [r2+r3*1-16] + punpckhdq m3, m2 + punpckhqdq m3, m1 + PALIGNR m4, m3, [r2+r1-16], 14, m0 + pslldq m0, m4, 2 + pshuflw m0, m0, 11100101b + PRED4x4_LOWPASS m4, m3, m0, m4 + punpckhwd m3, m4, m4 + punpcklwd m4, m4 + pshufd m0, m3, 0xff + pshufd m1, m3, 0xaa + pshufd m2, m3, 0x55 + pshufd m3, m3, 0x00 + mova [r0+r3*0], m0 + mova [r0+r3*1], m1 + mova [r0+r3*2], m2 + mova [r0+r1*1], m3 + pshufd m0, m4, 0xff + pshufd m1, m4, 0xaa + pshufd m2, m4, 0x55 + pshufd m3, m4, 0x00 + mova [r2+r3*0], m0 + mova [r2+r3*1], m1 + mova [r2+r3*2], m2 + mova [r2+r1*1], m3 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_HORIZONTAL +INIT_XMM ssse3 +PRED8x8L_HORIZONTAL +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_HORIZONTAL +%endif + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_down_left_10(pixel *src, int has_topleft, int has_topright, +; ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_DOWN_LEFT 0 +cglobal pred8x8l_down_left_10, 4, 4, 7 + sub r0, r3 + mova m3, [r0] + shr r1d, 14 + neg r1 + shr r2d, 13 + pslldq m1, m3, 2 + psrldq m2, m3, 2 + pinsrw m1, [r0+r1], 0 + pinsrw m2, [r0+r2+14], 7 + PRED4x4_LOWPASS m6, m2, m1, m3 + jz .fix_tr ; flags from shr r2d + mova m1, [r0+16] + psrldq m5, m1, 2 + PALIGNR m2, m1, m3, 14, m3 + pshufhw m5, m5, 10100100b + PRED4x4_LOWPASS m1, m2, m5, m1 +.do_topright: + lea r1, [r3*3] + psrldq m5, m1, 14 + lea r2, [r0+r3*4] + PALIGNR m2, m1, m6, 2, m0 + PALIGNR m3, m1, m6, 14, m0 + PALIGNR m5, m1, 2, m0 + pslldq m4, m6, 2 + PRED4x4_LOWPASS m6, m4, m2, m6 + PRED4x4_LOWPASS m1, m3, m5, m1 + mova [r2+r3*4], m1 + PALIGNR m1, m6, 14, m2 + pslldq m6, 2 + mova [r2+r1*1], m1 + PALIGNR m1, m6, 14, m2 + pslldq m6, 2 + mova [r2+r3*2], m1 + PALIGNR m1, m6, 14, m2 + pslldq m6, 2 + mova [r2+r3*1], m1 + PALIGNR m1, m6, 14, m2 + pslldq m6, 2 + mova [r0+r3*4], m1 + PALIGNR m1, m6, 14, m2 + pslldq m6, 2 + mova [r0+r1*1], m1 + PALIGNR m1, m6, 14, m2 + pslldq m6, 2 + mova [r0+r3*2], m1 + PALIGNR m1, m6, 14, m6 + mova [r0+r3*1], m1 + RET +.fix_tr: + punpckhwd m3, m3 + pshufd m1, m3, 0xFF + jmp .do_topright +%endmacro + +INIT_XMM sse2 +PRED8x8L_DOWN_LEFT +INIT_XMM ssse3 +PRED8x8L_DOWN_LEFT +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_DOWN_LEFT +%endif + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_down_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_DOWN_RIGHT 0 +; standard forbids this when has_topleft is false +; no need to check +cglobal pred8x8l_down_right_10, 4, 5, 8 + sub r0, r3 + lea r4, [r0+r3*4] + lea r1, [r3*3] + mova m0, [r0+r3*1-16] + punpckhwd m0, [r0+r3*0-16] + mova m1, [r0+r1*1-16] + punpckhwd m1, [r0+r3*2-16] + punpckhdq m1, m0 + mova m2, [r4+r3*1-16] + punpckhwd m2, [r4+r3*0-16] + mova m3, [r4+r1*1-16] + punpckhwd m3, [r4+r3*2-16] + punpckhdq m3, m2 + punpckhqdq m3, m1 + mova m0, [r4+r3*4-16] + mova m1, [r0] + PALIGNR m4, m3, m0, 14, m0 + PALIGNR m1, m3, 2, m2 + pslldq m0, m4, 2 + pshuflw m0, m0, 11100101b + PRED4x4_LOWPASS m6, m1, m4, m3 + PRED4x4_LOWPASS m4, m3, m0, m4 + mova m3, [r0] + shr r2d, 13 + pslldq m1, m3, 2 + psrldq m2, m3, 2 + pinsrw m1, [r0-2], 0 + pinsrw m2, [r0+r2+14], 7 + PRED4x4_LOWPASS m3, m2, m1, m3 + PALIGNR m2, m3, m6, 2, m0 + PALIGNR m5, m3, m6, 14, m0 + psrldq m7, m3, 2 + PRED4x4_LOWPASS m6, m4, m2, m6 + PRED4x4_LOWPASS m3, m5, m7, m3 + mova [r4+r3*4], m6 + PALIGNR m3, m6, 14, m2 + pslldq m6, 2 + mova [r0+r3*1], m3 + PALIGNR m3, m6, 14, m2 + pslldq m6, 2 + mova [r0+r3*2], m3 + PALIGNR m3, m6, 14, m2 + pslldq m6, 2 + mova [r0+r1*1], m3 + PALIGNR m3, m6, 14, m2 + pslldq m6, 2 + mova [r0+r3*4], m3 + PALIGNR m3, m6, 14, m2 + pslldq m6, 2 + mova [r4+r3*1], m3 + PALIGNR m3, m6, 14, m2 + pslldq m6, 2 + mova [r4+r3*2], m3 + PALIGNR m3, m6, 14, m6 + mova [r4+r1*1], m3 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_DOWN_RIGHT +INIT_XMM ssse3 +PRED8x8L_DOWN_RIGHT +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_DOWN_RIGHT +%endif + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_vertical_right_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_VERTICAL_RIGHT 0 +; likewise with 8x8l_down_right +cglobal pred8x8l_vertical_right_10, 4, 5, 7 + sub r0, r3 + lea r4, [r0+r3*4] + lea r1, [r3*3] + mova m0, [r0+r3*1-16] + punpckhwd m0, [r0+r3*0-16] + mova m1, [r0+r1*1-16] + punpckhwd m1, [r0+r3*2-16] + punpckhdq m1, m0 + mova m2, [r4+r3*1-16] + punpckhwd m2, [r4+r3*0-16] + mova m3, [r4+r1*1-16] + punpckhwd m3, [r4+r3*2-16] + punpckhdq m3, m2 + punpckhqdq m3, m1 + mova m0, [r4+r3*4-16] + mova m1, [r0] + PALIGNR m4, m3, m0, 14, m0 + PALIGNR m1, m3, 2, m2 + PRED4x4_LOWPASS m3, m1, m4, m3 + mova m2, [r0] + shr r2d, 13 + pslldq m1, m2, 2 + psrldq m5, m2, 2 + pinsrw m1, [r0-2], 0 + pinsrw m5, [r0+r2+14], 7 + PRED4x4_LOWPASS m2, m5, m1, m2 + PALIGNR m6, m2, m3, 12, m1 + PALIGNR m5, m2, m3, 14, m0 + PRED4x4_LOWPASS m0, m6, m2, m5 + pavgw m2, m5 + mova [r0+r3*2], m0 + mova [r0+r3*1], m2 + pslldq m6, m3, 4 + pslldq m1, m3, 2 + PRED4x4_LOWPASS m1, m3, m6, m1 + PALIGNR m2, m1, 14, m4 + mova [r0+r1*1], m2 + pslldq m1, 2 + PALIGNR m0, m1, 14, m3 + mova [r0+r3*4], m0 + pslldq m1, 2 + PALIGNR m2, m1, 14, m4 + mova [r4+r3*1], m2 + pslldq m1, 2 + PALIGNR m0, m1, 14, m3 + mova [r4+r3*2], m0 + pslldq m1, 2 + PALIGNR m2, m1, 14, m4 + mova [r4+r1*1], m2 + pslldq m1, 2 + PALIGNR m0, m1, 14, m1 + mova [r4+r3*4], m0 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_VERTICAL_RIGHT +INIT_XMM ssse3 +PRED8x8L_VERTICAL_RIGHT +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_VERTICAL_RIGHT +%endif + +;----------------------------------------------------------------------------- +; void ff_pred8x8l_horizontal_up_10(pixel *src, int has_topleft, +; int has_topright, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED8x8L_HORIZONTAL_UP 0 +cglobal pred8x8l_horizontal_up_10, 4, 4, 6 + mova m0, [r0+r3*0-16] + punpckhwd m0, [r0+r3*1-16] + shr r1d, 14 + dec r1 + and r1, r3 + sub r1, r3 + mova m4, [r0+r1*1-16] + lea r1, [r3*3] + lea r2, [r0+r3*4] + mova m1, [r0+r3*2-16] + punpckhwd m1, [r0+r1*1-16] + punpckhdq m0, m1 + mova m2, [r2+r3*0-16] + punpckhwd m2, [r2+r3*1-16] + mova m3, [r2+r3*2-16] + punpckhwd m3, [r2+r1*1-16] + punpckhdq m2, m3 + punpckhqdq m0, m2 + PALIGNR m1, m0, m4, 14, m4 + psrldq m2, m0, 2 + pshufhw m2, m2, 10100100b + PRED4x4_LOWPASS m0, m1, m2, m0 + psrldq m1, m0, 2 + psrldq m2, m0, 4 + pshufhw m1, m1, 10100100b + pshufhw m2, m2, 01010100b + pavgw m4, m0, m1 + PRED4x4_LOWPASS m1, m2, m0, m1 + punpckhwd m5, m4, m1 + punpcklwd m4, m1 + mova [r2+r3*0], m5 + mova [r0+r3*0], m4 + pshufd m0, m5, 11111001b + pshufd m1, m5, 11111110b + pshufd m2, m5, 11111111b + mova [r2+r3*1], m0 + mova [r2+r3*2], m1 + mova [r2+r1*1], m2 + PALIGNR m2, m5, m4, 4, m0 + PALIGNR m3, m5, m4, 8, m1 + PALIGNR m5, m5, m4, 12, m4 + mova [r0+r3*1], m2 + mova [r0+r3*2], m3 + mova [r0+r1*1], m5 + RET +%endmacro + +INIT_XMM sse2 +PRED8x8L_HORIZONTAL_UP +INIT_XMM ssse3 +PRED8x8L_HORIZONTAL_UP +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +PRED8x8L_HORIZONTAL_UP +%endif + + +;----------------------------------------------------------------------------- +; void ff_pred16x16_vertical_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro MOV16 3-5 + mova [%1+ 0], %2 + mova [%1+mmsize], %3 +%if mmsize==8 + mova [%1+ 16], %4 + mova [%1+ 24], %5 +%endif +%endmacro + +%macro PRED16x16_VERTICAL 0 +cglobal pred16x16_vertical_10, 2, 3 + sub r0, r1 + mov r2d, 8 + mova m0, [r0+ 0] + mova m1, [r0+mmsize] +%if mmsize==8 + mova m2, [r0+16] + mova m3, [r0+24] +%endif +.loop: + MOV16 r0+r1*1, m0, m1, m2, m3 + MOV16 r0+r1*2, m0, m1, m2, m3 + lea r0, [r0+r1*2] + dec r2d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_VERTICAL +INIT_XMM sse2 +PRED16x16_VERTICAL + +;----------------------------------------------------------------------------- +; void ff_pred16x16_horizontal_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED16x16_HORIZONTAL 0 +cglobal pred16x16_horizontal_10, 2, 3 + mov r2d, 8 +.vloop: + movd m0, [r0+r1*0-4] + movd m1, [r0+r1*1-4] + SPLATW m0, m0, 1 + SPLATW m1, m1, 1 + MOV16 r0+r1*0, m0, m0, m0, m0 + MOV16 r0+r1*1, m1, m1, m1, m1 + lea r0, [r0+r1*2] + dec r2d + jg .vloop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_HORIZONTAL +INIT_XMM sse2 +PRED16x16_HORIZONTAL + +;----------------------------------------------------------------------------- +; void ff_pred16x16_dc_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED16x16_DC 0 +cglobal pred16x16_dc_10, 2, 6 + mov r5, r0 + sub r0, r1 + mova m0, [r0+0] + paddw m0, [r0+mmsize] +%if mmsize==8 + paddw m0, [r0+16] + paddw m0, [r0+24] +%endif + HADDW m0, m2 + + lea r0, [r0+r1-2] + movzx r3d, word [r0] + movzx r4d, word [r0+r1] +%rep 7 + lea r0, [r0+r1*2] + movzx r2d, word [r0] + add r3d, r2d + movzx r2d, word [r0+r1] + add r4d, r2d +%endrep + lea r3d, [r3+r4+16] + + movd m1, r3d + paddw m0, m1 + psrlw m0, 5 + SPLATW m0, m0 + mov r3d, 8 +.loop: + MOV16 r5+r1*0, m0, m0, m0, m0 + MOV16 r5+r1*1, m0, m0, m0, m0 + lea r5, [r5+r1*2] + dec r3d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_DC +INIT_XMM sse2 +PRED16x16_DC + +;----------------------------------------------------------------------------- +; void ff_pred16x16_top_dc_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED16x16_TOP_DC 0 +cglobal pred16x16_top_dc_10, 2, 3 + sub r0, r1 + mova m0, [r0+0] + paddw m0, [r0+mmsize] +%if mmsize==8 + paddw m0, [r0+16] + paddw m0, [r0+24] +%endif + HADDW m0, m2 + + SPLATW m0, m0 + paddw m0, [pw_8] + psrlw m0, 4 + mov r2d, 8 +.loop: + MOV16 r0+r1*1, m0, m0, m0, m0 + MOV16 r0+r1*2, m0, m0, m0, m0 + lea r0, [r0+r1*2] + dec r2d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_TOP_DC +INIT_XMM sse2 +PRED16x16_TOP_DC + +;----------------------------------------------------------------------------- +; void ff_pred16x16_left_dc_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED16x16_LEFT_DC 0 +cglobal pred16x16_left_dc_10, 2, 6 + mov r5, r0 + + sub r0, 2 + movzx r3d, word [r0] + movzx r4d, word [r0+r1] +%rep 7 + lea r0, [r0+r1*2] + movzx r2d, word [r0] + add r3d, r2d + movzx r2d, word [r0+r1] + add r4d, r2d +%endrep + lea r3d, [r3+r4+8] + shr r3d, 4 + + movd m0, r3d + SPLATW m0, m0 + mov r3d, 8 +.loop: + MOV16 r5+r1*0, m0, m0, m0, m0 + MOV16 r5+r1*1, m0, m0, m0, m0 + lea r5, [r5+r1*2] + dec r3d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_LEFT_DC +INIT_XMM sse2 +PRED16x16_LEFT_DC + +;----------------------------------------------------------------------------- +; void ff_pred16x16_128_dc_10(pixel *src, ptrdiff_t stride) +;----------------------------------------------------------------------------- +%macro PRED16x16_128_DC 0 +cglobal pred16x16_128_dc_10, 2,3 + mova m0, [pw_512] + mov r2d, 8 +.loop: + MOV16 r0+r1*0, m0, m0, m0, m0 + MOV16 r0+r1*1, m0, m0, m0, m0 + lea r0, [r0+r1*2] + dec r2d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PRED16x16_128_DC +INIT_XMM sse2 +PRED16x16_128_DC diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred_init.c new file mode 100644 index 00000000..bdd5125d --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_intrapred_init.c @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2010 Fiona Glaser + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/h264pred.h" + +#define PRED4x4(TYPE, DEPTH, OPT) \ +void ff_pred4x4_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + const uint8_t *topright, \ + ptrdiff_t stride); + +PRED4x4(dc, 10, mmxext) +PRED4x4(down_left, 10, sse2) +PRED4x4(down_left, 10, avx) +PRED4x4(down_right, 10, sse2) +PRED4x4(down_right, 10, ssse3) +PRED4x4(down_right, 10, avx) +PRED4x4(vertical_left, 10, sse2) +PRED4x4(vertical_left, 10, avx) +PRED4x4(vertical_right, 10, sse2) +PRED4x4(vertical_right, 10, ssse3) +PRED4x4(vertical_right, 10, avx) +PRED4x4(horizontal_up, 10, mmxext) +PRED4x4(horizontal_down, 10, sse2) +PRED4x4(horizontal_down, 10, ssse3) +PRED4x4(horizontal_down, 10, avx) + +#define PRED8x8(TYPE, DEPTH, OPT) \ +void ff_pred8x8_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + ptrdiff_t stride); + +PRED8x8(dc, 10, mmxext) +PRED8x8(dc, 10, sse2) +PRED8x8(top_dc, 10, sse2) +PRED8x8(plane, 10, sse2) +PRED8x8(vertical, 10, sse2) +PRED8x8(horizontal, 10, sse2) + +#define PRED8x8L(TYPE, DEPTH, OPT)\ +void ff_pred8x8l_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + int has_topleft, \ + int has_topright, \ + ptrdiff_t stride); + +PRED8x8L(dc, 10, sse2) +PRED8x8L(dc, 10, avx) +PRED8x8L(128_dc, 10, mmxext) +PRED8x8L(128_dc, 10, sse2) +PRED8x8L(top_dc, 10, sse2) +PRED8x8L(top_dc, 10, avx) +PRED8x8L(vertical, 10, sse2) +PRED8x8L(vertical, 10, avx) +PRED8x8L(horizontal, 10, sse2) +PRED8x8L(horizontal, 10, ssse3) +PRED8x8L(horizontal, 10, avx) +PRED8x8L(down_left, 10, sse2) +PRED8x8L(down_left, 10, ssse3) +PRED8x8L(down_left, 10, avx) +PRED8x8L(down_right, 10, sse2) +PRED8x8L(down_right, 10, ssse3) +PRED8x8L(down_right, 10, avx) +PRED8x8L(vertical_right, 10, sse2) +PRED8x8L(vertical_right, 10, ssse3) +PRED8x8L(vertical_right, 10, avx) +PRED8x8L(horizontal_up, 10, sse2) +PRED8x8L(horizontal_up, 10, ssse3) +PRED8x8L(horizontal_up, 10, avx) + +#define PRED16x16(TYPE, DEPTH, OPT)\ +void ff_pred16x16_ ## TYPE ## _ ## DEPTH ## _ ## OPT (uint8_t *src, \ + ptrdiff_t stride); + +PRED16x16(dc, 10, mmxext) +PRED16x16(dc, 10, sse2) +PRED16x16(top_dc, 10, mmxext) +PRED16x16(top_dc, 10, sse2) +PRED16x16(128_dc, 10, mmxext) +PRED16x16(128_dc, 10, sse2) +PRED16x16(left_dc, 10, mmxext) +PRED16x16(left_dc, 10, sse2) +PRED16x16(vertical, 10, mmxext) +PRED16x16(vertical, 10, sse2) +PRED16x16(horizontal, 10, mmxext) +PRED16x16(horizontal, 10, sse2) + +/* 8-bit versions */ +PRED16x16(vertical, 8, mmx) +PRED16x16(vertical, 8, sse) +PRED16x16(horizontal, 8, mmx) +PRED16x16(horizontal, 8, mmxext) +PRED16x16(horizontal, 8, ssse3) +PRED16x16(dc, 8, mmxext) +PRED16x16(dc, 8, sse2) +PRED16x16(dc, 8, ssse3) +PRED16x16(plane_h264, 8, mmx) +PRED16x16(plane_h264, 8, mmxext) +PRED16x16(plane_h264, 8, sse2) +PRED16x16(plane_h264, 8, ssse3) +PRED16x16(plane_rv40, 8, mmx) +PRED16x16(plane_rv40, 8, mmxext) +PRED16x16(plane_rv40, 8, sse2) +PRED16x16(plane_rv40, 8, ssse3) +PRED16x16(plane_svq3, 8, mmx) +PRED16x16(plane_svq3, 8, mmxext) +PRED16x16(plane_svq3, 8, sse2) +PRED16x16(plane_svq3, 8, ssse3) +PRED16x16(tm_vp8, 8, mmx) +PRED16x16(tm_vp8, 8, mmxext) +PRED16x16(tm_vp8, 8, sse2) +PRED16x16(tm_vp8, 8, avx2) + +PRED8x8(top_dc, 8, mmxext) +PRED8x8(dc_rv40, 8, mmxext) +PRED8x8(dc, 8, mmxext) +PRED8x8(vertical, 8, mmx) +PRED8x8(horizontal, 8, mmx) +PRED8x8(horizontal, 8, mmxext) +PRED8x8(horizontal, 8, ssse3) +PRED8x8(plane, 8, mmx) +PRED8x8(plane, 8, mmxext) +PRED8x8(plane, 8, sse2) +PRED8x8(plane, 8, ssse3) +PRED8x8(tm_vp8, 8, mmx) +PRED8x8(tm_vp8, 8, mmxext) +PRED8x8(tm_vp8, 8, sse2) +PRED8x8(tm_vp8, 8, ssse3) + +PRED8x8L(top_dc, 8, mmxext) +PRED8x8L(top_dc, 8, ssse3) +PRED8x8L(dc, 8, mmxext) +PRED8x8L(dc, 8, ssse3) +PRED8x8L(horizontal, 8, mmxext) +PRED8x8L(horizontal, 8, ssse3) +PRED8x8L(vertical, 8, mmxext) +PRED8x8L(vertical, 8, ssse3) +PRED8x8L(down_left, 8, mmxext) +PRED8x8L(down_left, 8, sse2) +PRED8x8L(down_left, 8, ssse3) +PRED8x8L(down_right, 8, mmxext) +PRED8x8L(down_right, 8, sse2) +PRED8x8L(down_right, 8, ssse3) +PRED8x8L(vertical_right, 8, mmxext) +PRED8x8L(vertical_right, 8, sse2) +PRED8x8L(vertical_right, 8, ssse3) +PRED8x8L(vertical_left, 8, sse2) +PRED8x8L(vertical_left, 8, ssse3) +PRED8x8L(horizontal_up, 8, mmxext) +PRED8x8L(horizontal_up, 8, ssse3) +PRED8x8L(horizontal_down, 8, mmxext) +PRED8x8L(horizontal_down, 8, sse2) +PRED8x8L(horizontal_down, 8, ssse3) + +PRED4x4(dc, 8, mmxext) +PRED4x4(down_left, 8, mmxext) +PRED4x4(down_right, 8, mmxext) +PRED4x4(vertical_left, 8, mmxext) +PRED4x4(vertical_right, 8, mmxext) +PRED4x4(horizontal_up, 8, mmxext) +PRED4x4(horizontal_down, 8, mmxext) +PRED4x4(tm_vp8, 8, mmx) +PRED4x4(tm_vp8, 8, mmxext) +PRED4x4(tm_vp8, 8, ssse3) +PRED4x4(vertical_vp8, 8, mmxext) + +av_cold void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, + const int bit_depth, + const int chroma_format_idc) +{ + int cpu_flags = av_get_cpu_flags(); + + if (bit_depth == 8) { + if (EXTERNAL_MMX(cpu_flags)) { + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_8_mmx; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmx; + if (chroma_format_idc <= 1) { + h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_8_mmx; + h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmx; + } + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_mmx; + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_mmx; + h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_mmx; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmx; + if (codec_id == AV_CODEC_ID_SVQ3) { + if (cpu_flags & AV_CPU_FLAG_CMOV) + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_mmx; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_mmx; + } else { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_8_mmx; + } + } + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_mmxext; + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_mmxext; + if (chroma_format_idc <= 1) + h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_mmxext; + h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_mmxext; + h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_mmxext; + h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_8_mmxext; + h->pred8x8l [VERT_PRED ] = ff_pred8x8l_vertical_8_mmxext; + h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_mmxext; + h->pred8x8l [VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_8_mmxext; + h->pred8x8l [HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_8_mmxext; + h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_mmxext; + h->pred8x8l [HOR_DOWN_PRED ] = ff_pred8x8l_horizontal_down_8_mmxext; + h->pred4x4 [DIAG_DOWN_RIGHT_PRED ] = ff_pred4x4_down_right_8_mmxext; + h->pred4x4 [VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_8_mmxext; + h->pred4x4 [HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_8_mmxext; + h->pred4x4 [DC_PRED ] = ff_pred4x4_dc_8_mmxext; + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8 || + codec_id == AV_CODEC_ID_H264) { + h->pred4x4 [DIAG_DOWN_LEFT_PRED] = ff_pred4x4_down_left_8_mmxext; + } + if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { + h->pred4x4 [VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_8_mmxext; + } + if (codec_id != AV_CODEC_ID_RV40) { + h->pred4x4 [HOR_UP_PRED ] = ff_pred4x4_horizontal_up_8_mmxext; + } + if (codec_id == AV_CODEC_ID_SVQ3 || codec_id == AV_CODEC_ID_H264) { + if (chroma_format_idc <= 1) { + h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_8_mmxext; + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_8_mmxext; + } + } + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_mmxext; + h->pred8x8 [DC_PRED8x8 ] = ff_pred8x8_dc_rv40_8_mmxext; + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_mmxext; + h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_mmxext; + h->pred4x4 [VERT_PRED ] = ff_pred4x4_vertical_vp8_8_mmxext; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_mmxext; + if (codec_id == AV_CODEC_ID_SVQ3) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_8_mmxext; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_rv40_8_mmxext; + } else { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_h264_8_mmxext; + } + } + } + + if (EXTERNAL_SSE(cpu_flags)) { + h->pred16x16[VERT_PRED8x8] = ff_pred16x16_vertical_8_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_sse2; + h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_sse2; + h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_sse2; + h->pred8x8l [VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_8_sse2; + h->pred8x8l [VERT_LEFT_PRED ] = ff_pred8x8l_vertical_left_8_sse2; + h->pred8x8l [HOR_DOWN_PRED ] = ff_pred8x8l_horizontal_down_8_sse2; + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_sse2; + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_sse2; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_sse2; + if (codec_id == AV_CODEC_ID_SVQ3) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_sse2; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_sse2; + } else { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_8_sse2; + } + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_8_ssse3; + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_8_ssse3; + if (chroma_format_idc <= 1) + h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_8_ssse3; + h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_8_ssse3; + h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_8_ssse3; + h->pred8x8l [HOR_PRED ] = ff_pred8x8l_horizontal_8_ssse3; + h->pred8x8l [VERT_PRED ] = ff_pred8x8l_vertical_8_ssse3; + h->pred8x8l [DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_8_ssse3; + h->pred8x8l [DIAG_DOWN_RIGHT_PRED ] = ff_pred8x8l_down_right_8_ssse3; + h->pred8x8l [VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_8_ssse3; + h->pred8x8l [VERT_LEFT_PRED ] = ff_pred8x8l_vertical_left_8_ssse3; + h->pred8x8l [HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_8_ssse3; + h->pred8x8l [HOR_DOWN_PRED ] = ff_pred8x8l_horizontal_down_8_ssse3; + if (codec_id == AV_CODEC_ID_VP7 || codec_id == AV_CODEC_ID_VP8) { + h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_8_ssse3; + h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_8_ssse3; + } else { + if (chroma_format_idc <= 1) + h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_8_ssse3; + if (codec_id == AV_CODEC_ID_SVQ3) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_8_ssse3; + } else if (codec_id == AV_CODEC_ID_RV40) { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_8_ssse3; + } else { + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_h264_8_ssse3; + } + } + } + + if(EXTERNAL_AVX2(cpu_flags)){ + if (codec_id == AV_CODEC_ID_VP8) { + h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_8_avx2; + } + } + } else if (bit_depth == 10) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; + h->pred4x4[HOR_UP_PRED ] = ff_pred4x4_horizontal_up_10_mmxext; + + if (chroma_format_idc <= 1) + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_mmxext; + + h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_mmxext; + + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_10_mmxext; + h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_10_mmxext; + h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_10_mmxext; + h->pred16x16[LEFT_DC_PRED8x8 ] = ff_pred16x16_left_dc_10_mmxext; + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_mmxext; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_sse2; + h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_sse2; + h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_sse2; + h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_sse2; + h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_sse2; + + if (chroma_format_idc <= 1) { + h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_sse2; + h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_10_sse2; + h->pred8x8[PLANE_PRED8x8 ] = ff_pred8x8_plane_10_sse2; + h->pred8x8[VERT_PRED8x8 ] = ff_pred8x8_vertical_10_sse2; + h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_10_sse2; + } + + h->pred8x8l[VERT_PRED ] = ff_pred8x8l_vertical_10_sse2; + h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_sse2; + h->pred8x8l[DC_PRED ] = ff_pred8x8l_dc_10_sse2; + h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_sse2; + h->pred8x8l[TOP_DC_PRED ] = ff_pred8x8l_top_dc_10_sse2; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_sse2; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_sse2; + h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_sse2; + h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_sse2; + + h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_10_sse2; + h->pred16x16[TOP_DC_PRED8x8 ] = ff_pred16x16_top_dc_10_sse2; + h->pred16x16[DC_128_PRED8x8 ] = ff_pred16x16_128_dc_10_sse2; + h->pred16x16[LEFT_DC_PRED8x8 ] = ff_pred16x16_left_dc_10_sse2; + h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_10_sse2; + h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_10_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_ssse3; + h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_ssse3; + h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_ssse3; + + h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_ssse3; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_ssse3; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_ssse3; + h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_ssse3; + h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + h->pred4x4[DIAG_DOWN_LEFT_PRED ] = ff_pred4x4_down_left_10_avx; + h->pred4x4[DIAG_DOWN_RIGHT_PRED] = ff_pred4x4_down_right_10_avx; + h->pred4x4[VERT_LEFT_PRED ] = ff_pred4x4_vertical_left_10_avx; + h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_avx; + h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_avx; + + h->pred8x8l[VERT_PRED ] = ff_pred8x8l_vertical_10_avx; + h->pred8x8l[HOR_PRED ] = ff_pred8x8l_horizontal_10_avx; + h->pred8x8l[DC_PRED ] = ff_pred8x8l_dc_10_avx; + h->pred8x8l[TOP_DC_PRED ] = ff_pred8x8l_top_dc_10_avx; + h->pred8x8l[DIAG_DOWN_RIGHT_PRED] = ff_pred8x8l_down_right_10_avx; + h->pred8x8l[DIAG_DOWN_LEFT_PRED ] = ff_pred8x8l_down_left_10_avx; + h->pred8x8l[VERT_RIGHT_PRED ] = ff_pred8x8l_vertical_right_10_avx; + h->pred8x8l[HOR_UP_PRED ] = ff_pred8x8l_horizontal_up_10_avx; + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel.c new file mode 100644 index 00000000..a2d8a649 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel.c @@ -0,0 +1,635 @@ +/* + * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt + * Copyright (c) 2011 Daniel Kang + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h264dec.h" +#include "libavcodec/h264qpel.h" +#include "libavcodec/pixels.h" +#include "fpel.h" + +#if HAVE_X86ASM +void ff_put_pixels4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels4_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_pixels8_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels8_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_pixels16_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels16_l2_mmxext(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +#define ff_put_pixels8_l2_sse2 ff_put_pixels8_l2_mmxext +#define ff_avg_pixels8_l2_sse2 ff_avg_pixels8_l2_mmxext +#define ff_put_pixels16_l2_sse2 ff_put_pixels16_l2_mmxext +#define ff_avg_pixels16_l2_sse2 ff_avg_pixels16_l2_mmxext +#define ff_put_pixels16_mmxext ff_put_pixels16_mmx +#define ff_put_pixels8_mmxext ff_put_pixels8_mmx +#define ff_put_pixels4_mmxext ff_put_pixels4_mmx + +#define DEF_QPEL(OPNAME)\ +void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_ssse3(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel4_h_lowpass_l2_mmxext(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_l2_mmxext(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride);\ +void ff_ ## OPNAME ## _h264_qpel8_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride);\ +void ff_ ## OPNAME ## _h264_qpel4_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel8or16_v_lowpass_op_mmxext(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h);\ +void ff_ ## OPNAME ## _h264_qpel8or16_v_lowpass_sse2(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h);\ +void ff_ ## OPNAME ## _h264_qpel4_hv_lowpass_v_mmxext(const uint8_t *src, int16_t *tmp, int srcStride);\ +void ff_ ## OPNAME ## _h264_qpel4_hv_lowpass_h_mmxext(int16_t *tmp, uint8_t *dst, int dstStride);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv1_lowpass_op_mmxext(const uint8_t *src, int16_t *tmp, int srcStride, int size);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv1_lowpass_op_sse2(const uint8_t *src, int16_t *tmp, int srcStride, int size);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv2_lowpass_op_mmxext(uint8_t *dst, int16_t *tmp, int dstStride, int unused, int h);\ +void ff_ ## OPNAME ## _h264_qpel8or16_hv2_lowpass_ssse3(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size);\ +void ff_ ## OPNAME ## _pixels4_l2_shift5_mmxext(uint8_t *dst, const int16_t *src16, const uint8_t *src8, int dstStride, int src8Stride, int h);\ +void ff_ ## OPNAME ## _pixels8_l2_shift5_mmxext(uint8_t *dst, const int16_t *src16, const uint8_t *src8, int dstStride, int src8Stride, int h); + +DEF_QPEL(avg) +DEF_QPEL(put) + +static av_always_inline void ff_put_h264_qpel8or16_hv1_lowpass_mmxext(int16_t *tmp, const uint8_t *src, int tmpStride, int srcStride, int size) +{ + int w = (size + 8) >> 2; + src -= 2 * srcStride + 2; + while (w--) { + ff_put_h264_qpel8or16_hv1_lowpass_op_mmxext(src, tmp, srcStride, size); + tmp += 4; + src += 4; + } +} + +#define QPEL_H264(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel4_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + int w=3;\ + src -= 2*srcStride+2;\ + while(w--){\ + ff_ ## OPNAME ## h264_qpel4_hv_lowpass_v_mmxext(src, tmp, srcStride);\ + tmp += 4;\ + src += 4;\ + }\ + tmp -= 3*4;\ + ff_ ## OPNAME ## h264_qpel4_hv_lowpass_h_mmxext(tmp, dst, dstStride);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int h){\ + src -= 2*srcStride;\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_op_mmxext(dst, src, dstStride, srcStride, h);\ + src += 4;\ + dst += 4;\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_op_mmxext(dst, src, dstStride, srcStride, h);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, int dstStride, int tmpStride, int size){\ + int w = size>>4;\ + do{\ + ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_op_mmxext(dst, tmp, dstStride, 0, size);\ + tmp += 8;\ + dst += 8;\ + }while(w--);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 16);\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ + src += 8*dstStride;\ + dst += 8*dstStride;\ + src2 += 8*src2Stride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + ff_put_h264_qpel8or16_hv1_lowpass_ ## MMX(tmp, src, tmpStride, srcStride, size);\ + ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 8);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst , tmp , src , dstStride, tmpStride, srcStride, 16);\ +}\ +\ +static av_always_inline void ff_ ## OPNAME ## pixels16_l2_shift5_ ## MMX(uint8_t *dst, const int16_t *src16, const uint8_t *src8, int dstStride, int src8Stride, int h)\ +{\ + ff_ ## OPNAME ## pixels8_l2_shift5_ ## MMX(dst , src16 , src8 , dstStride, src8Stride, h);\ + ff_ ## OPNAME ## pixels8_l2_shift5_ ## MMX(dst+8, src16+8, src8+8, dstStride, src8Stride, h);\ +}\ + + +#if ARCH_X86_64 +#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ + +void ff_avg_h264_qpel16_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride); +void ff_put_h264_qpel16_h_lowpass_l2_ssse3(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride); + +#else // ARCH_X86_64 +#define QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_l2_ ## MMX(uint8_t *dst, const uint8_t *src, const uint8_t *src2, int dstStride, int src2Stride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ + src += 8*dstStride;\ + dst += 8*dstStride;\ + src2 += 8*src2Stride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst , src , src2 , dstStride, src2Stride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_l2_ ## MMX(dst+8, src+8, src2+8, dstStride, src2Stride);\ +} +#endif // ARCH_X86_64 + +#define QPEL_H264_H_XMM(OPNAME, OP, MMX)\ +QPEL_H264_H16_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_h_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ + src += 8*srcStride;\ + dst += 8*dstStride;\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst , src , dstStride, srcStride);\ + ff_ ## OPNAME ## h264_qpel8_h_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride);\ +}\ + +#define QPEL_H264_V_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 8);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_v_lowpass_ ## MMX(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst , src , dstStride, srcStride, 16);\ + ff_ ## OPNAME ## h264_qpel8or16_v_lowpass_ ## MMX(dst+8, src+8, dstStride, srcStride, 16);\ +} + +static av_always_inline void put_h264_qpel8or16_hv1_lowpass_sse2(int16_t *tmp, + const uint8_t *src, + int tmpStride, + int srcStride, + int size) +{ + int w = (size+8)>>3; + src -= 2*srcStride+2; + while(w--){ + ff_put_h264_qpel8or16_hv1_lowpass_op_sse2(src, tmp, srcStride, size); + tmp += 8; + src += 8; + } +} + +#define QPEL_H264_HV_XMM(OPNAME, OP, MMX)\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride, int size){\ + put_h264_qpel8or16_hv1_lowpass_sse2(tmp, src, tmpStride, srcStride, size);\ + ff_ ## OPNAME ## h264_qpel8or16_hv2_lowpass_ ## MMX(dst, tmp, dstStride, tmpStride, size);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel8_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst, tmp, src, dstStride, tmpStride, srcStride, 8);\ +}\ +static av_always_inline void ff_ ## OPNAME ## h264_qpel16_hv_lowpass_ ## MMX(uint8_t *dst, int16_t *tmp, const uint8_t *src, int dstStride, int tmpStride, int srcStride){\ + ff_ ## OPNAME ## h264_qpel8or16_hv_lowpass_ ## MMX(dst, tmp, src, dstStride, tmpStride, srcStride, 16);\ +}\ + +#define ff_put_h264_qpel8_h_lowpass_l2_sse2 ff_put_h264_qpel8_h_lowpass_l2_mmxext +#define ff_avg_h264_qpel8_h_lowpass_l2_sse2 ff_avg_h264_qpel8_h_lowpass_l2_mmxext +#define ff_put_h264_qpel16_h_lowpass_l2_sse2 ff_put_h264_qpel16_h_lowpass_l2_mmxext +#define ff_avg_h264_qpel16_h_lowpass_l2_sse2 ff_avg_h264_qpel16_h_lowpass_l2_mmxext + +#define ff_put_h264_qpel8_v_lowpass_ssse3 ff_put_h264_qpel8_v_lowpass_sse2 +#define ff_avg_h264_qpel8_v_lowpass_ssse3 ff_avg_h264_qpel8_v_lowpass_sse2 +#define ff_put_h264_qpel16_v_lowpass_ssse3 ff_put_h264_qpel16_v_lowpass_sse2 +#define ff_avg_h264_qpel16_v_lowpass_ssse3 ff_avg_h264_qpel16_v_lowpass_sse2 + +#define ff_put_h264_qpel8or16_hv2_lowpass_sse2 ff_put_h264_qpel8or16_hv2_lowpass_mmxext +#define ff_avg_h264_qpel8or16_hv2_lowpass_sse2 ff_avg_h264_qpel8or16_hv2_lowpass_mmxext + +#define H264_MC(OPNAME, SIZE, MMX, ALIGN) \ +H264_MC_C(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_V(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_H(OPNAME, SIZE, MMX, ALIGN)\ +H264_MC_HV(OPNAME, SIZE, MMX, ALIGN)\ + +static void put_h264_qpel16_mc00_sse2 (uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_put_pixels16_sse2(dst, src, stride, 16); +} +static void avg_h264_qpel16_mc00_sse2 (uint8_t *dst, const uint8_t *src, + ptrdiff_t stride) +{ + ff_avg_pixels16_sse2(dst, src, stride, 16); +} +#define put_h264_qpel8_mc00_sse2 put_h264_qpel8_mc00_mmxext +#define avg_h264_qpel8_mc00_sse2 avg_h264_qpel8_mc00_mmxext + +#define H264_MC_C(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc00_ ## MMX (uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## pixels ## SIZE ## _ ## MMX(dst, src, stride, SIZE);\ +}\ + +#define H264_MC_H(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc10_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc20_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc30_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, src+1, stride, stride);\ +}\ + +#define H264_MC_V(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc01_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src, temp, stride, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc02_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _v_lowpass_ ## MMX(dst, src, stride, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc03_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_ ## MMX(dst, src+stride, temp, stride, stride, SIZE);\ +}\ + +#define H264_MC_HV(OPNAME, SIZE, MMX, ALIGN) \ +static void OPNAME ## h264_qpel ## SIZE ## _mc11_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc31_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc13_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc33_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*SIZE]);\ + ff_put_h264_qpel ## SIZE ## _v_lowpass_ ## MMX(temp, src+1, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, temp, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc22_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint16_t, temp, [SIZE*(SIZE<8?12:24)]);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(dst, temp, src, stride, SIZE, stride);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc21_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src, halfHV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc23_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## h264_qpel ## SIZE ## _h_lowpass_l2_ ## MMX(dst, src+stride, halfHV, stride, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc12_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+2, halfHV, stride, SIZE, SIZE);\ +}\ +\ +static void OPNAME ## h264_qpel ## SIZE ## _mc32_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\ +{\ + LOCAL_ALIGNED(ALIGN, uint8_t, temp, [SIZE*(SIZE<8?12:24)*2 + SIZE*SIZE]);\ + uint8_t * const halfHV= temp;\ + int16_t * const halfV= (int16_t*)(temp + SIZE*SIZE);\ + av_assert2(((int)temp & 7) == 0);\ + ff_put_h264_qpel ## SIZE ## _hv_lowpass_ ## MMX(halfHV, halfV, src, SIZE, SIZE, stride);\ + ff_ ## OPNAME ## pixels ## SIZE ## _l2_shift5_mmxext(dst, halfV+3, halfHV, stride, SIZE, SIZE);\ +}\ + +#define H264_MC_4816(MMX)\ +H264_MC(put_, 4, MMX, 8)\ +H264_MC(put_, 8, MMX, 8)\ +H264_MC(put_, 16,MMX, 8)\ +H264_MC(avg_, 4, MMX, 8)\ +H264_MC(avg_, 8, MMX, 8)\ +H264_MC(avg_, 16,MMX, 8)\ + +#define H264_MC_816(QPEL, XMM)\ +QPEL(put_, 8, XMM, 16)\ +QPEL(put_, 16,XMM, 16)\ +QPEL(avg_, 8, XMM, 16)\ +QPEL(avg_, 16,XMM, 16)\ + +QPEL_H264(put_, PUT_OP, mmxext) +QPEL_H264(avg_, AVG_MMXEXT_OP, mmxext) +QPEL_H264_V_XMM(put_, PUT_OP, sse2) +QPEL_H264_V_XMM(avg_,AVG_MMXEXT_OP, sse2) +QPEL_H264_HV_XMM(put_, PUT_OP, sse2) +QPEL_H264_HV_XMM(avg_,AVG_MMXEXT_OP, sse2) +QPEL_H264_H_XMM(put_, PUT_OP, ssse3) +QPEL_H264_H_XMM(avg_,AVG_MMXEXT_OP, ssse3) +QPEL_H264_HV_XMM(put_, PUT_OP, ssse3) +QPEL_H264_HV_XMM(avg_,AVG_MMXEXT_OP, ssse3) + +H264_MC_4816(mmxext) +H264_MC_816(H264_MC_V, sse2) +H264_MC_816(H264_MC_HV, sse2) +H264_MC_816(H264_MC_H, ssse3) +H264_MC_816(H264_MC_HV, ssse3) + + +//10bit +#define LUMA_MC_OP(OP, NUM, DEPTH, TYPE, OPT) \ +void ff_ ## OP ## _h264_qpel ## NUM ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, const uint8_t *src, ptrdiff_t stride); + +#define LUMA_MC_ALL(DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 4, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 4, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT) + +#define LUMA_MC_816(DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 8, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(put, 16, DEPTH, TYPE, OPT) \ + LUMA_MC_OP(avg, 16, DEPTH, TYPE, OPT) + +LUMA_MC_ALL(10, mc00, mmxext) +LUMA_MC_ALL(10, mc10, mmxext) +LUMA_MC_ALL(10, mc20, mmxext) +LUMA_MC_ALL(10, mc30, mmxext) +LUMA_MC_ALL(10, mc01, mmxext) +LUMA_MC_ALL(10, mc11, mmxext) +LUMA_MC_ALL(10, mc21, mmxext) +LUMA_MC_ALL(10, mc31, mmxext) +LUMA_MC_ALL(10, mc02, mmxext) +LUMA_MC_ALL(10, mc12, mmxext) +LUMA_MC_ALL(10, mc22, mmxext) +LUMA_MC_ALL(10, mc32, mmxext) +LUMA_MC_ALL(10, mc03, mmxext) +LUMA_MC_ALL(10, mc13, mmxext) +LUMA_MC_ALL(10, mc23, mmxext) +LUMA_MC_ALL(10, mc33, mmxext) + +LUMA_MC_816(10, mc00, sse2) +LUMA_MC_816(10, mc10, sse2) +LUMA_MC_816(10, mc10, sse2_cache64) +LUMA_MC_816(10, mc10, ssse3_cache64) +LUMA_MC_816(10, mc20, sse2) +LUMA_MC_816(10, mc20, sse2_cache64) +LUMA_MC_816(10, mc20, ssse3_cache64) +LUMA_MC_816(10, mc30, sse2) +LUMA_MC_816(10, mc30, sse2_cache64) +LUMA_MC_816(10, mc30, ssse3_cache64) +LUMA_MC_816(10, mc01, sse2) +LUMA_MC_816(10, mc11, sse2) +LUMA_MC_816(10, mc21, sse2) +LUMA_MC_816(10, mc31, sse2) +LUMA_MC_816(10, mc02, sse2) +LUMA_MC_816(10, mc12, sse2) +LUMA_MC_816(10, mc22, sse2) +LUMA_MC_816(10, mc32, sse2) +LUMA_MC_816(10, mc03, sse2) +LUMA_MC_816(10, mc13, sse2) +LUMA_MC_816(10, mc23, sse2) +LUMA_MC_816(10, mc33, sse2) + +#define QPEL16_OPMC(OP, MC, MMX)\ +void ff_ ## OP ## _h264_qpel16_ ## MC ## _10_ ## MMX(uint8_t *dst, const uint8_t *src, ptrdiff_t stride){\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst , src , stride);\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\ + src += 8*stride;\ + dst += 8*stride;\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst , src , stride);\ + ff_ ## OP ## _h264_qpel8_ ## MC ## _10_ ## MMX(dst+16, src+16, stride);\ +} + +#define QPEL16_OP(MC, MMX)\ +QPEL16_OPMC(put, MC, MMX)\ +QPEL16_OPMC(avg, MC, MMX) + +#define QPEL16(MMX)\ +QPEL16_OP(mc00, MMX)\ +QPEL16_OP(mc01, MMX)\ +QPEL16_OP(mc02, MMX)\ +QPEL16_OP(mc03, MMX)\ +QPEL16_OP(mc10, MMX)\ +QPEL16_OP(mc11, MMX)\ +QPEL16_OP(mc12, MMX)\ +QPEL16_OP(mc13, MMX)\ +QPEL16_OP(mc20, MMX)\ +QPEL16_OP(mc21, MMX)\ +QPEL16_OP(mc22, MMX)\ +QPEL16_OP(mc23, MMX)\ +QPEL16_OP(mc30, MMX)\ +QPEL16_OP(mc31, MMX)\ +QPEL16_OP(mc32, MMX)\ +QPEL16_OP(mc33, MMX) + +#if ARCH_X86_32 // ARCH_X86_64 implies SSE2+ +QPEL16(mmxext) +#endif + +#endif /* HAVE_X86ASM */ + +#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \ + do { \ + c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \ + } while (0) + +#define H264_QPEL_FUNCS(x, y, CPU) \ + do { \ + c->put_h264_qpel_pixels_tab[0][x + y * 4] = put_h264_qpel16_mc ## x ## y ## _ ## CPU; \ + c->put_h264_qpel_pixels_tab[1][x + y * 4] = put_h264_qpel8_mc ## x ## y ## _ ## CPU; \ + c->avg_h264_qpel_pixels_tab[0][x + y * 4] = avg_h264_qpel16_mc ## x ## y ## _ ## CPU; \ + c->avg_h264_qpel_pixels_tab[1][x + y * 4] = avg_h264_qpel8_mc ## x ## y ## _ ## CPU; \ + } while (0) + +#define H264_QPEL_FUNCS_10(x, y, CPU) \ + do { \ + c->put_h264_qpel_pixels_tab[0][x + y * 4] = ff_put_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \ + c->put_h264_qpel_pixels_tab[1][x + y * 4] = ff_put_h264_qpel8_mc ## x ## y ## _10_ ## CPU; \ + c->avg_h264_qpel_pixels_tab[0][x + y * 4] = ff_avg_h264_qpel16_mc ## x ## y ## _10_ ## CPU; \ + c->avg_h264_qpel_pixels_tab[1][x + y * 4] = ff_avg_h264_qpel8_mc ## x ## y ## _10_ ## CPU; \ + } while (0) + +av_cold void ff_h264qpel_init_x86(H264QpelContext *c, int bit_depth) +{ +#if HAVE_X86ASM + int high_bit_depth = bit_depth > 8; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMXEXT(cpu_flags)) { + if (!high_bit_depth) { + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, mmxext, ); + SET_QPEL_FUNCS(put_h264_qpel, 2, 4, mmxext, ); + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, mmxext, ); + SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, mmxext, ); + } else if (bit_depth == 10) { +#if ARCH_X86_32 + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_mmxext, ff_); + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_mmxext, ff_); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 10_mmxext, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 10_mmxext, ff_); +#endif + SET_QPEL_FUNCS(put_h264_qpel, 2, 4, 10_mmxext, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 2, 4, 10_mmxext, ff_); + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + if (!high_bit_depth) { + H264_QPEL_FUNCS(0, 1, sse2); + H264_QPEL_FUNCS(0, 2, sse2); + H264_QPEL_FUNCS(0, 3, sse2); + H264_QPEL_FUNCS(1, 1, sse2); + H264_QPEL_FUNCS(1, 2, sse2); + H264_QPEL_FUNCS(1, 3, sse2); + H264_QPEL_FUNCS(2, 1, sse2); + H264_QPEL_FUNCS(2, 2, sse2); + H264_QPEL_FUNCS(2, 3, sse2); + H264_QPEL_FUNCS(3, 1, sse2); + H264_QPEL_FUNCS(3, 2, sse2); + H264_QPEL_FUNCS(3, 3, sse2); + } + + if (bit_depth == 10) { + SET_QPEL_FUNCS(put_h264_qpel, 0, 16, 10_sse2, ff_); + SET_QPEL_FUNCS(put_h264_qpel, 1, 8, 10_sse2, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 0, 16, 10_sse2, ff_); + SET_QPEL_FUNCS(avg_h264_qpel, 1, 8, 10_sse2, ff_); + H264_QPEL_FUNCS_10(1, 0, sse2_cache64); + H264_QPEL_FUNCS_10(2, 0, sse2_cache64); + H264_QPEL_FUNCS_10(3, 0, sse2_cache64); + } + } + + if (EXTERNAL_SSE2_FAST(cpu_flags)) { + if (!high_bit_depth) { + H264_QPEL_FUNCS(0, 0, sse2); + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + if (!high_bit_depth) { + H264_QPEL_FUNCS(1, 0, ssse3); + H264_QPEL_FUNCS(1, 1, ssse3); + H264_QPEL_FUNCS(1, 2, ssse3); + H264_QPEL_FUNCS(1, 3, ssse3); + H264_QPEL_FUNCS(2, 0, ssse3); + H264_QPEL_FUNCS(2, 1, ssse3); + H264_QPEL_FUNCS(2, 2, ssse3); + H264_QPEL_FUNCS(2, 3, ssse3); + H264_QPEL_FUNCS(3, 0, ssse3); + H264_QPEL_FUNCS(3, 1, ssse3); + H264_QPEL_FUNCS(3, 2, ssse3); + H264_QPEL_FUNCS(3, 3, ssse3); + } + + if (bit_depth == 10) { + H264_QPEL_FUNCS_10(1, 0, ssse3_cache64); + H264_QPEL_FUNCS_10(2, 0, ssse3_cache64); + H264_QPEL_FUNCS_10(3, 0, ssse3_cache64); + } + } + + if (EXTERNAL_AVX(cpu_flags)) { + /* AVX implies 64 byte cache lines without the need to avoid unaligned + * memory accesses that cross the boundary between two cache lines. + * TODO: Port X264_CPU_CACHELINE_32/64 detection from x264 to avoid + * having to treat SSE2 functions with such properties as AVX. */ + if (bit_depth == 10) { + H264_QPEL_FUNCS_10(1, 0, sse2); + H264_QPEL_FUNCS_10(2, 0, sse2); + H264_QPEL_FUNCS_10(3, 0, sse2); + } + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel_10bit.asm new file mode 100644 index 00000000..87226830 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel_10bit.asm @@ -0,0 +1,884 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 qpel code +;***************************************************************************** +;* Copyright (C) 2011 x264 project +;* +;* Authors: Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +cextern pd_65535 +cextern pw_1023 +%define pw_pixel_max pw_1023 +cextern pw_16 +cextern pw_1 +cextern pb_0 + +pad10: times 8 dw 10*1023 +pad20: times 8 dw 20*1023 +pad30: times 8 dw 30*1023 +depad: times 4 dd 32*20*1023 + 512 +depad2: times 8 dw 20*1023 + 16*1022 + 16 +unpad: times 8 dw 16*1022/32 ; needs to be mod 16 + +tap1: times 4 dw 1, -5 +tap2: times 4 dw 20, 20 +tap3: times 4 dw -5, 1 + +SECTION .text + + +%macro AVG_MOV 2 + pavgw %2, %1 + mova %1, %2 +%endmacro + +%macro ADDW 3 +%if mmsize == 8 + paddw %1, %2 +%else + movu %3, %2 + paddw %1, %3 +%endif +%endmacro + +%macro FILT_H 4 + paddw %1, %4 + psubw %1, %2 ; a-b + psraw %1, 2 ; (a-b)/4 + psubw %1, %2 ; (a-b)/4-b + paddw %1, %3 ; (a-b)/4-b+c + psraw %1, 2 ; ((a-b)/4-b+c)/4 + paddw %1, %3 ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16 +%endmacro + +%macro PRELOAD_V 0 + lea r3, [r2*3] + sub r1, r3 + movu m0, [r1+r2] + movu m1, [r1+r2*2] + add r1, r3 + movu m2, [r1] + movu m3, [r1+r2] + movu m4, [r1+r2*2] + add r1, r3 +%endmacro + +%macro FILT_V 8 + movu %6, [r1] + paddw %1, %6 + mova %7, %2 + paddw %7, %5 + mova %8, %3 + paddw %8, %4 + FILT_H %1, %7, %8, [pw_16] + psraw %1, 1 + CLIPW %1, [pb_0], [pw_pixel_max] +%endmacro + +%macro MC 1 +%define OP_MOV mova +INIT_MMX mmxext +%1 put, 4 +INIT_XMM sse2 +%1 put, 8 + +%define OP_MOV AVG_MOV +INIT_MMX mmxext +%1 avg, 4 +INIT_XMM sse2 +%1 avg, 8 +%endmacro + +%macro MCAxA_OP 7 +%if ARCH_X86_32 +cglobal %1_h264_qpel%4_%2_10, %5,%6,%7 + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + mov r0, r0m + mov r1, r1m + add r0, %3*2 + add r1, %3*2 + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + mov r0, r0m + mov r1, r1m + lea r0, [r0+r2*%3] + lea r1, [r1+r2*%3] + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + mov r0, r0m + mov r1, r1m + lea r0, [r0+r2*%3+%3*2] + lea r1, [r1+r2*%3+%3*2] + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + RET +%else ; ARCH_X86_64 +cglobal %1_h264_qpel%4_%2_10, %5,%6 + 2,%7 + mov r%6, r0 +%assign p1 %6+1 + mov r %+ p1, r1 + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + lea r0, [r%6+%3*2] + lea r1, [r %+ p1+%3*2] + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + lea r0, [r%6+r2*%3] + lea r1, [r %+ p1+r2*%3] + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + lea r0, [r%6+r2*%3+%3*2] + lea r1, [r %+ p1+r2*%3+%3*2] +%if UNIX64 == 0 ; fall through to function + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + RET +%endif +%endif +%endmacro + +;cpu, put/avg, mc, 4/8, ... +%macro cglobal_mc 6 +%assign i %3*2 +%if ARCH_X86_32 || cpuflag(sse2) +MCAxA_OP %1, %2, %3, i, %4,%5,%6 +%endif + +cglobal %1_h264_qpel%3_%2_10, %4,%5,%6 +%if UNIX64 == 0 ; no prologue or epilogue for UNIX64 + call stub_%1_h264_qpel%3_%2_10 %+ SUFFIX + RET +%endif + +stub_%1_h264_qpel%3_%2_10 %+ SUFFIX: +%endmacro + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc00(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro COPY4 0 + movu m0, [r1 ] + OP_MOV [r0 ], m0 + movu m0, [r1+r2 ] + OP_MOV [r0+r2 ], m0 + movu m0, [r1+r2*2] + OP_MOV [r0+r2*2], m0 + movu m0, [r1+r3 ] + OP_MOV [r0+r3 ], m0 +%endmacro + +%macro MC00 1 +INIT_MMX mmxext +cglobal_mc %1, mc00, 4, 3,4,0 + lea r3, [r2*3] + COPY4 + ret + +INIT_XMM sse2 +cglobal %1_h264_qpel8_mc00_10, 3,4 + lea r3, [r2*3] + COPY4 + lea r0, [r0+r2*4] + lea r1, [r1+r2*4] + COPY4 + RET + +cglobal %1_h264_qpel16_mc00_10, 3,4 + mov r3d, 8 +.loop: + movu m0, [r1 ] + movu m1, [r1 +16] + OP_MOV [r0 ], m0 + OP_MOV [r0 +16], m1 + movu m0, [r1+r2 ] + movu m1, [r1+r2+16] + OP_MOV [r0+r2 ], m0 + OP_MOV [r0+r2+16], m1 + lea r0, [r0+r2*2] + lea r1, [r1+r2*2] + dec r3d + jg .loop + REP_RET +%endmacro + +%define OP_MOV mova +MC00 put + +%define OP_MOV AVG_MOV +MC00 avg + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc20(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC_CACHE 1 +%define OP_MOV mova +INIT_MMX mmxext +%1 put, 4 +INIT_XMM sse2, cache64 +%1 put, 8 +INIT_XMM ssse3, cache64 +%1 put, 8 +INIT_XMM sse2 +%1 put, 8 + +%define OP_MOV AVG_MOV +INIT_MMX mmxext +%1 avg, 4 +INIT_XMM sse2, cache64 +%1 avg, 8 +INIT_XMM ssse3, cache64 +%1 avg, 8 +INIT_XMM sse2 +%1 avg, 8 +%endmacro + +%macro MC20 2 +cglobal_mc %1, mc20, %2, 3,4,9 + mov r3d, %2 + mova m1, [pw_pixel_max] +%if num_mmregs > 8 + mova m8, [pw_16] + %define p16 m8 +%else + %define p16 [pw_16] +%endif +.nextrow: +%if %0 == 4 + movu m2, [r1-4] + movu m3, [r1-2] + movu m4, [r1+0] + ADDW m2, [r1+6], m5 + ADDW m3, [r1+4], m5 + ADDW m4, [r1+2], m5 +%else ; movu is slow on these processors +%if mmsize==16 + movu m2, [r1-4] + movu m0, [r1+6] + mova m6, m0 + psrldq m0, 6 + + paddw m6, m2 + PALIGNR m3, m0, m2, 2, m5 + PALIGNR m7, m0, m2, 8, m5 + paddw m3, m7 + PALIGNR m4, m0, m2, 4, m5 + PALIGNR m7, m0, m2, 6, m5 + paddw m4, m7 + SWAP 2, 6 +%else + movu m2, [r1-4] + movu m6, [r1+4] + PALIGNR m3, m6, m2, 2, m5 + paddw m3, m6 + PALIGNR m4, m6, m2, 4, m5 + PALIGNR m7, m6, m2, 6, m5 + paddw m4, m7 + paddw m2, [r1+6] +%endif +%endif + + FILT_H m2, m3, m4, p16 + psraw m2, 1 + pxor m0, m0 + CLIPW m2, m0, m1 + OP_MOV [r0], m2 + add r0, r2 + add r1, r2 + dec r3d + jg .nextrow + rep ret +%endmacro + +MC_CACHE MC20 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc30(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC30 2 +cglobal_mc %1, mc30, %2, 3,5,9 + lea r4, [r1+2] + jmp stub_%1_h264_qpel%2_mc10_10 %+ SUFFIX %+ .body +%endmacro + +MC_CACHE MC30 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc10(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC10 2 +cglobal_mc %1, mc10, %2, 3,5,9 + mov r4, r1 +.body: + mov r3d, %2 + mova m1, [pw_pixel_max] +%if num_mmregs > 8 + mova m8, [pw_16] + %define p16 m8 +%else + %define p16 [pw_16] +%endif +.nextrow: +%if %0 == 4 + movu m2, [r1-4] + movu m3, [r1-2] + movu m4, [r1+0] + ADDW m2, [r1+6], m5 + ADDW m3, [r1+4], m5 + ADDW m4, [r1+2], m5 +%else ; movu is slow on these processors +%if mmsize==16 + movu m2, [r1-4] + movu m0, [r1+6] + mova m6, m0 + psrldq m0, 6 + + paddw m6, m2 + PALIGNR m3, m0, m2, 2, m5 + PALIGNR m7, m0, m2, 8, m5 + paddw m3, m7 + PALIGNR m4, m0, m2, 4, m5 + PALIGNR m7, m0, m2, 6, m5 + paddw m4, m7 + SWAP 2, 6 +%else + movu m2, [r1-4] + movu m6, [r1+4] + PALIGNR m3, m6, m2, 2, m5 + paddw m3, m6 + PALIGNR m4, m6, m2, 4, m5 + PALIGNR m7, m6, m2, 6, m5 + paddw m4, m7 + paddw m2, [r1+6] +%endif +%endif + + FILT_H m2, m3, m4, p16 + psraw m2, 1 + pxor m0, m0 + CLIPW m2, m0, m1 + movu m3, [r4] + pavgw m2, m3 + OP_MOV [r0], m2 + add r0, r2 + add r1, r2 + add r4, r2 + dec r3d + jg .nextrow + rep ret +%endmacro + +MC_CACHE MC10 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc02(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro V_FILT 10 +v_filt%9_%10_10: + add r4, r2 +.no_addr4: + FILT_V m0, m1, m2, m3, m4, m5, m6, m7 + add r1, r2 + add r0, r2 + ret +%endmacro + +INIT_MMX mmxext +RESET_MM_PERMUTATION +%assign i 0 +%rep 4 +V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 4, i +SWAP 0,1,2,3,4,5 +%assign i i+1 +%endrep + +INIT_XMM sse2 +RESET_MM_PERMUTATION +%assign i 0 +%rep 6 +V_FILT m0, m1, m2, m3, m4, m5, m6, m7, 8, i +SWAP 0,1,2,3,4,5 +%assign i i+1 +%endrep + +%macro MC02 2 +cglobal_mc %1, mc02, %2, 3,4,8 + PRELOAD_V + + sub r0, r2 +%assign j 0 +%rep %2 + %assign i (j % 6) + call v_filt%2_ %+ i %+ _10.no_addr4 + OP_MOV [r0], m0 + SWAP 0,1,2,3,4,5 + %assign j j+1 +%endrep + ret +%endmacro + +MC MC02 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc01(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC01 2 +cglobal_mc %1, mc01, %2, 3,5,8 + mov r4, r1 +.body: + PRELOAD_V + + sub r4, r2 + sub r0, r2 +%assign j 0 +%rep %2 + %assign i (j % 6) + call v_filt%2_ %+ i %+ _10 + movu m7, [r4] + pavgw m0, m7 + OP_MOV [r0], m0 + SWAP 0,1,2,3,4,5 + %assign j j+1 +%endrep + ret +%endmacro + +MC MC01 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc03(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC03 2 +cglobal_mc %1, mc03, %2, 3,5,8 + lea r4, [r1+r2] + jmp stub_%1_h264_qpel%2_mc01_10 %+ SUFFIX %+ .body +%endmacro + +MC MC03 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc11(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro H_FILT_AVG 2-3 +h_filt%1_%2_10: +;FILT_H with fewer registers and averaged with the FILT_V result +;m6,m7 are tmp registers, m0 is the FILT_V result, the rest are to be used next in the next iteration +;unfortunately I need three registers, so m5 will have to be re-read from memory + movu m5, [r4-4] + ADDW m5, [r4+6], m7 + movu m6, [r4-2] + ADDW m6, [r4+4], m7 + paddw m5, [pw_16] + psubw m5, m6 ; a-b + psraw m5, 2 ; (a-b)/4 + psubw m5, m6 ; (a-b)/4-b + movu m6, [r4+0] + ADDW m6, [r4+2], m7 + paddw m5, m6 ; (a-b)/4-b+c + psraw m5, 2 ; ((a-b)/4-b+c)/4 + paddw m5, m6 ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16 + psraw m5, 1 + CLIPW m5, [pb_0], [pw_pixel_max] +;avg FILT_V, FILT_H + pavgw m0, m5 +%if %0!=4 + movu m5, [r1+r5] +%endif + ret +%endmacro + +INIT_MMX mmxext +RESET_MM_PERMUTATION +%assign i 0 +%rep 3 +H_FILT_AVG 4, i +SWAP 0,1,2,3,4,5 +%assign i i+1 +%endrep +H_FILT_AVG 4, i, 0 + +INIT_XMM sse2 +RESET_MM_PERMUTATION +%assign i 0 +%rep 6 +%if i==1 +H_FILT_AVG 8, i, 0 +%else +H_FILT_AVG 8, i +%endif +SWAP 0,1,2,3,4,5 +%assign i i+1 +%endrep + +%macro MC11 2 +; this REALLY needs x86_64 +cglobal_mc %1, mc11, %2, 3,6,8 + mov r4, r1 +.body: + PRELOAD_V + + sub r0, r2 + sub r4, r2 + mov r5, r2 + neg r5 +%assign j 0 +%rep %2 + %assign i (j % 6) + call v_filt%2_ %+ i %+ _10 + call h_filt%2_ %+ i %+ _10 +%if %2==8 && i==1 + movu m5, [r1+r5] +%endif + OP_MOV [r0], m0 + SWAP 0,1,2,3,4,5 + %assign j j+1 +%endrep + ret +%endmacro + +MC MC11 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc31(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC31 2 +cglobal_mc %1, mc31, %2, 3,6,8 + mov r4, r1 + add r1, 2 + jmp stub_%1_h264_qpel%2_mc11_10 %+ SUFFIX %+ .body +%endmacro + +MC MC31 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc13(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC13 2 +cglobal_mc %1, mc13, %2, 3,7,12 + lea r4, [r1+r2] + jmp stub_%1_h264_qpel%2_mc11_10 %+ SUFFIX %+ .body +%endmacro + +MC MC13 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc33(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC33 2 +cglobal_mc %1, mc33, %2, 3,6,8 + lea r4, [r1+r2] + add r1, 2 + jmp stub_%1_h264_qpel%2_mc11_10 %+ SUFFIX %+ .body +%endmacro + +MC MC33 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc22(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro FILT_H2 3 + psubw %1, %2 ; a-b + psubw %2, %3 ; b-c + psllw %2, 2 + psubw %1, %2 ; a-5*b+4*c + psllw %3, 4 + paddw %1, %3 ; a-5*b+20*c +%endmacro + +%macro FILT_VNRD 8 + movu %6, [r1] + paddw %1, %6 + mova %7, %2 + paddw %7, %5 + mova %8, %3 + paddw %8, %4 + FILT_H2 %1, %7, %8 +%endmacro + +%macro HV 1 +%if mmsize==16 +%define PAD 12 +%define COUNT 2 +%else +%define PAD 4 +%define COUNT 3 +%endif +put_hv%1_10: + neg r2 ; This actually saves instructions + lea r1, [r1+r2*2-mmsize+PAD] + lea r4, [rsp+PAD+gprsize] + mov r3d, COUNT +.v_loop: + movu m0, [r1] + sub r1, r2 + movu m1, [r1] + sub r1, r2 + movu m2, [r1] + sub r1, r2 + movu m3, [r1] + sub r1, r2 + movu m4, [r1] + sub r1, r2 +%assign i 0 +%rep %1-1 + FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7 + psubw m0, [pad20] + movu [r4+i*mmsize*3], m0 + sub r1, r2 + SWAP 0,1,2,3,4,5 +%assign i i+1 +%endrep + FILT_VNRD m0, m1, m2, m3, m4, m5, m6, m7 + psubw m0, [pad20] + movu [r4+i*mmsize*3], m0 + add r4, mmsize + lea r1, [r1+r2*8+mmsize] +%if %1==8 + lea r1, [r1+r2*4] +%endif + dec r3d + jg .v_loop + neg r2 + ret +%endmacro + +INIT_MMX mmxext +HV 4 +INIT_XMM sse2 +HV 8 + +%macro H_LOOP 1 +%if num_mmregs > 8 + %define s1 m8 + %define s2 m9 + %define s3 m10 + %define d1 m11 +%else + %define s1 [tap1] + %define s2 [tap2] + %define s3 [tap3] + %define d1 [depad] +%endif +h%1_loop_op: + movu m1, [r1+mmsize-4] + movu m2, [r1+mmsize-2] + mova m3, [r1+mmsize+0] + movu m4, [r1+mmsize+2] + movu m5, [r1+mmsize+4] + movu m6, [r1+mmsize+6] +%if num_mmregs > 8 + pmaddwd m1, s1 + pmaddwd m2, s1 + pmaddwd m3, s2 + pmaddwd m4, s2 + pmaddwd m5, s3 + pmaddwd m6, s3 + paddd m1, d1 + paddd m2, d1 +%else + mova m0, s1 + pmaddwd m1, m0 + pmaddwd m2, m0 + mova m0, s2 + pmaddwd m3, m0 + pmaddwd m4, m0 + mova m0, s3 + pmaddwd m5, m0 + pmaddwd m6, m0 + mova m0, d1 + paddd m1, m0 + paddd m2, m0 +%endif + paddd m3, m5 + paddd m4, m6 + paddd m1, m3 + paddd m2, m4 + psrad m1, 10 + psrad m2, 10 + pslld m2, 16 + pand m1, [pd_65535] + por m1, m2 +%if num_mmregs <= 8 + pxor m0, m0 +%endif + CLIPW m1, m0, m7 + add r1, mmsize*3 + ret +%endmacro + +INIT_MMX mmxext +H_LOOP 4 +INIT_XMM sse2 +H_LOOP 8 + +%macro MC22 2 +cglobal_mc %1, mc22, %2, 3,7,12 +%define PAD mmsize*8*4*2 ; SIZE*16*4*sizeof(pixel) + mov r6, rsp ; backup stack pointer + and rsp, ~(mmsize-1) ; align stack + sub rsp, PAD + + call put_hv%2_10 + + mov r3d, %2 + mova m7, [pw_pixel_max] +%if num_mmregs > 8 + pxor m0, m0 + mova m8, [tap1] + mova m9, [tap2] + mova m10, [tap3] + mova m11, [depad] +%endif + mov r1, rsp +.h_loop: + call h%2_loop_op + + OP_MOV [r0], m1 + add r0, r2 + dec r3d + jg .h_loop + + mov rsp, r6 ; restore stack pointer + ret +%endmacro + +MC MC22 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc12(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC12 2 +cglobal_mc %1, mc12, %2, 3,7,12 +%define PAD mmsize*8*4*2 ; SIZE*16*4*sizeof(pixel) + mov r6, rsp ; backup stack pointer + and rsp, ~(mmsize-1) ; align stack + sub rsp, PAD + + call put_hv%2_10 + + xor r4d, r4d +.body: + mov r3d, %2 + pxor m0, m0 + mova m7, [pw_pixel_max] +%if num_mmregs > 8 + mova m8, [tap1] + mova m9, [tap2] + mova m10, [tap3] + mova m11, [depad] +%endif + mov r1, rsp +.h_loop: + call h%2_loop_op + + movu m3, [r1+r4-2*mmsize] ; movu needed for mc32, etc + paddw m3, [depad2] + psrlw m3, 5 + psubw m3, [unpad] + CLIPW m3, m0, m7 + pavgw m1, m3 + + OP_MOV [r0], m1 + add r0, r2 + dec r3d + jg .h_loop + + mov rsp, r6 ; restore stack pointer + ret +%endmacro + +MC MC12 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc32(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC32 2 +cglobal_mc %1, mc32, %2, 3,7,12 +%define PAD mmsize*8*3*2 ; SIZE*16*4*sizeof(pixel) + mov r6, rsp ; backup stack pointer + and rsp, ~(mmsize-1) ; align stack + sub rsp, PAD + + call put_hv%2_10 + + mov r4d, 2 ; sizeof(pixel) + jmp stub_%1_h264_qpel%2_mc12_10 %+ SUFFIX %+ .body +%endmacro + +MC MC32 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc21(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro H_NRD 1 +put_h%1_10: + add rsp, gprsize + mov r3d, %1 + xor r4d, r4d + mova m6, [pad20] +.nextrow: + movu m2, [r5-4] + movu m3, [r5-2] + movu m4, [r5+0] + ADDW m2, [r5+6], m5 + ADDW m3, [r5+4], m5 + ADDW m4, [r5+2], m5 + + FILT_H2 m2, m3, m4 + psubw m2, m6 + mova [rsp+r4], m2 + add r4d, mmsize*3 + add r5, r2 + dec r3d + jg .nextrow + sub rsp, gprsize + ret +%endmacro + +INIT_MMX mmxext +H_NRD 4 +INIT_XMM sse2 +H_NRD 8 + +%macro MC21 2 +cglobal_mc %1, mc21, %2, 3,7,12 + mov r5, r1 +.body: +%define PAD mmsize*8*3*2 ; SIZE*16*4*sizeof(pixel) + mov r6, rsp ; backup stack pointer + and rsp, ~(mmsize-1) ; align stack + + sub rsp, PAD + call put_h%2_10 + + sub rsp, PAD + call put_hv%2_10 + + mov r4d, PAD-mmsize ; H buffer + jmp stub_%1_h264_qpel%2_mc12_10 %+ SUFFIX %+ .body +%endmacro + +MC MC21 + +;----------------------------------------------------------------------------- +; void ff_h264_qpel_mc23(uint8_t *dst, uint8_t *src, int stride) +;----------------------------------------------------------------------------- +%macro MC23 2 +cglobal_mc %1, mc23, %2, 3,7,12 + lea r5, [r1+r2] + jmp stub_%1_h264_qpel%2_mc21_10 %+ SUFFIX %+ .body +%endmacro + +MC MC23 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel_8bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel_8bit.asm new file mode 100644 index 00000000..2d287ba4 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_qpel_8bit.asm @@ -0,0 +1,862 @@ +;***************************************************************************** +;* MMX/SSE2/SSSE3-optimized H.264 QPEL code +;***************************************************************************** +;* Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt +;* Copyright (C) 2012 Daniel Kang +;* +;* Authors: Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +cextern pw_16 +cextern pw_5 +cextern pb_0 + +SECTION .text + + +%macro op_avgh 3 + movh %3, %2 + pavgb %1, %3 + movh %2, %1 +%endmacro + +%macro op_avg 2-3 + pavgb %1, %2 + mova %2, %1 +%endmacro + +%macro op_puth 2-3 + movh %2, %1 +%endmacro + +%macro op_put 2-3 + mova %2, %1 +%endmacro + +%macro QPEL4_H_LOWPASS_OP 1 +cglobal %1_h264_qpel4_h_lowpass, 4,5 ; dst, src, dstStride, srcStride + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + pxor m7, m7 + mova m4, [pw_5] + mova m5, [pw_16] + mov r4d, 4 +.loop: + movh m1, [r1-1] + movh m2, [r1+0] + movh m3, [r1+1] + movh m0, [r1+2] + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m0, m7 + paddw m1, m0 + paddw m2, m3 + movh m0, [r1-2] + movh m3, [r1+3] + punpcklbw m0, m7 + punpcklbw m3, m7 + paddw m0, m3 + psllw m2, 2 + psubw m2, m1 + pmullw m2, m4 + paddw m0, m5 + paddw m0, m2 + psraw m0, 5 + packuswb m0, m0 + op_%1h m0, [r0], m6 + add r0, r2 + add r1, r3 + dec r4d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL4_H_LOWPASS_OP put +QPEL4_H_LOWPASS_OP avg + +%macro QPEL8_H_LOWPASS_OP 1 +cglobal %1_h264_qpel8_h_lowpass, 4,5 ; dst, src, dstStride, srcStride + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + mov r4d, 8 + pxor m7, m7 + mova m6, [pw_5] +.loop: + mova m0, [r1] + mova m2, [r1+1] + mova m1, m0 + mova m3, m2 + punpcklbw m0, m7 + punpckhbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + paddw m0, m2 + paddw m1, m3 + psllw m0, 2 + psllw m1, 2 + mova m2, [r1-1] + mova m4, [r1+2] + mova m3, m2 + mova m5, m4 + punpcklbw m2, m7 + punpckhbw m3, m7 + punpcklbw m4, m7 + punpckhbw m5, m7 + paddw m2, m4 + paddw m5, m3 + psubw m0, m2 + psubw m1, m5 + pmullw m0, m6 + pmullw m1, m6 + movd m2, [r1-2] + movd m5, [r1+7] + punpcklbw m2, m7 + punpcklbw m5, m7 + paddw m2, m3 + paddw m4, m5 + mova m5, [pw_16] + paddw m2, m5 + paddw m4, m5 + paddw m0, m2 + paddw m1, m4 + psraw m0, 5 + psraw m1, 5 + packuswb m0, m1 + op_%1 m0, [r0], m4 + add r0, r2 + add r1, r3 + dec r4d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL8_H_LOWPASS_OP put +QPEL8_H_LOWPASS_OP avg + +%macro QPEL8_H_LOWPASS_OP_XMM 1 +cglobal %1_h264_qpel8_h_lowpass, 4,5,8 ; dst, src, dstStride, srcStride + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + mov r4d, 8 + pxor m7, m7 + mova m6, [pw_5] +.loop: + movu m1, [r1-2] + mova m0, m1 + punpckhbw m1, m7 + punpcklbw m0, m7 + mova m2, m1 + mova m3, m1 + mova m4, m1 + mova m5, m1 + palignr m4, m0, 2 + palignr m3, m0, 4 + palignr m2, m0, 6 + palignr m1, m0, 8 + palignr m5, m0, 10 + paddw m0, m5 + paddw m2, m3 + paddw m1, m4 + psllw m2, 2 + psubw m2, m1 + paddw m0, [pw_16] + pmullw m2, m6 + paddw m2, m0 + psraw m2, 5 + packuswb m2, m2 + op_%1h m2, [r0], m4 + add r1, r3 + add r0, r2 + dec r4d + jne .loop + REP_RET +%endmacro + +INIT_XMM ssse3 +QPEL8_H_LOWPASS_OP_XMM put +QPEL8_H_LOWPASS_OP_XMM avg + + +%macro QPEL4_H_LOWPASS_L2_OP 1 +cglobal %1_h264_qpel4_h_lowpass_l2, 5,6 ; dst, src, src2, dstStride, srcStride + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + pxor m7, m7 + mova m4, [pw_5] + mova m5, [pw_16] + mov r5d, 4 +.loop: + movh m1, [r1-1] + movh m2, [r1+0] + movh m3, [r1+1] + movh m0, [r1+2] + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m0, m7 + paddw m1, m0 + paddw m2, m3 + movh m0, [r1-2] + movh m3, [r1+3] + punpcklbw m0, m7 + punpcklbw m3, m7 + paddw m0, m3 + psllw m2, 2 + psubw m2, m1 + pmullw m2, m4 + paddw m0, m5 + paddw m0, m2 + movh m3, [r2] + psraw m0, 5 + packuswb m0, m0 + pavgb m0, m3 + op_%1h m0, [r0], m6 + add r0, r3 + add r1, r3 + add r2, r4 + dec r5d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL4_H_LOWPASS_L2_OP put +QPEL4_H_LOWPASS_L2_OP avg + + +%macro QPEL8_H_LOWPASS_L2_OP 1 +cglobal %1_h264_qpel8_h_lowpass_l2, 5,6 ; dst, src, src2, dstStride, srcStride + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + mov r5d, 8 + pxor m7, m7 + mova m6, [pw_5] +.loop: + mova m0, [r1] + mova m2, [r1+1] + mova m1, m0 + mova m3, m2 + punpcklbw m0, m7 + punpckhbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + paddw m0, m2 + paddw m1, m3 + psllw m0, 2 + psllw m1, 2 + mova m2, [r1-1] + mova m4, [r1+2] + mova m3, m2 + mova m5, m4 + punpcklbw m2, m7 + punpckhbw m3, m7 + punpcklbw m4, m7 + punpckhbw m5, m7 + paddw m2, m4 + paddw m5, m3 + psubw m0, m2 + psubw m1, m5 + pmullw m0, m6 + pmullw m1, m6 + movd m2, [r1-2] + movd m5, [r1+7] + punpcklbw m2, m7 + punpcklbw m5, m7 + paddw m2, m3 + paddw m4, m5 + mova m5, [pw_16] + paddw m2, m5 + paddw m4, m5 + paddw m0, m2 + paddw m1, m4 + psraw m0, 5 + psraw m1, 5 + mova m4, [r2] + packuswb m0, m1 + pavgb m0, m4 + op_%1 m0, [r0], m4 + add r0, r3 + add r1, r3 + add r2, r4 + dec r5d + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL8_H_LOWPASS_L2_OP put +QPEL8_H_LOWPASS_L2_OP avg + + +%macro QPEL8_H_LOWPASS_L2_OP_XMM 1 +cglobal %1_h264_qpel8_h_lowpass_l2, 5,6,8 ; dst, src, src2, dstStride, src2Stride + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + mov r5d, 8 + pxor m7, m7 + mova m6, [pw_5] +.loop: + lddqu m1, [r1-2] + mova m0, m1 + punpckhbw m1, m7 + punpcklbw m0, m7 + mova m2, m1 + mova m3, m1 + mova m4, m1 + mova m5, m1 + palignr m4, m0, 2 + palignr m3, m0, 4 + palignr m2, m0, 6 + palignr m1, m0, 8 + palignr m5, m0, 10 + paddw m0, m5 + paddw m2, m3 + paddw m1, m4 + psllw m2, 2 + movh m3, [r2] + psubw m2, m1 + paddw m0, [pw_16] + pmullw m2, m6 + paddw m2, m0 + psraw m2, 5 + packuswb m2, m2 + pavgb m2, m3 + op_%1h m2, [r0], m4 + add r1, r3 + add r0, r3 + add r2, r4 + dec r5d + jg .loop + REP_RET +%endmacro + +INIT_XMM ssse3 +QPEL8_H_LOWPASS_L2_OP_XMM put +QPEL8_H_LOWPASS_L2_OP_XMM avg + + +; All functions that call this are required to have function arguments of +; dst, src, dstStride, srcStride +%macro FILT_V 1 + mova m6, m2 + movh m5, [r1] + paddw m6, m3 + psllw m6, 2 + psubw m6, m1 + psubw m6, m4 + punpcklbw m5, m7 + pmullw m6, [pw_5] + paddw m0, [pw_16] + add r1, r3 + paddw m0, m5 + paddw m6, m0 + psraw m6, 5 + packuswb m6, m6 + op_%1h m6, [r0], m0 ; 1 + add r0, r2 + SWAP 0, 1, 2, 3, 4, 5 +%endmacro + +%macro QPEL4_V_LOWPASS_OP 1 +cglobal %1_h264_qpel4_v_lowpass, 4,4 ; dst, src, dstStride, srcStride + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + sub r1, r3 + sub r1, r3 + pxor m7, m7 + movh m0, [r1] + movh m1, [r1+r3] + lea r1, [r1+2*r3] + movh m2, [r1] + movh m3, [r1+r3] + lea r1, [r1+2*r3] + movh m4, [r1] + add r1, r3 + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + RET +%endmacro + +INIT_MMX mmxext +QPEL4_V_LOWPASS_OP put +QPEL4_V_LOWPASS_OP avg + + + +%macro QPEL8OR16_V_LOWPASS_OP 1 +%if cpuflag(sse2) +cglobal %1_h264_qpel8or16_v_lowpass, 5,5,8 ; dst, src, dstStride, srcStride, h + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + sub r1, r3 + sub r1, r3 +%else +cglobal %1_h264_qpel8or16_v_lowpass_op, 5,5,8 ; dst, src, dstStride, srcStride, h + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d +%endif + pxor m7, m7 + movh m0, [r1] + movh m1, [r1+r3] + lea r1, [r1+2*r3] + movh m2, [r1] + movh m3, [r1+r3] + lea r1, [r1+2*r3] + movh m4, [r1] + add r1, r3 + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + cmp r4d, 16 + jne .end + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 + FILT_V %1 +.end: + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL8OR16_V_LOWPASS_OP put +QPEL8OR16_V_LOWPASS_OP avg + +INIT_XMM sse2 +QPEL8OR16_V_LOWPASS_OP put +QPEL8OR16_V_LOWPASS_OP avg + + +; All functions that use this are required to have args: +; src, tmp, srcSize +%macro FILT_HV 1 ; offset + mova m6, m2 + movh m5, [r0] + paddw m6, m3 + psllw m6, 2 + paddw m0, [pw_16] + psubw m6, m1 + psubw m6, m4 + punpcklbw m5, m7 + pmullw m6, [pw_5] + paddw m0, m5 + add r0, r2 + paddw m6, m0 + mova [r1+%1], m6 + SWAP 0, 1, 2, 3, 4, 5 +%endmacro + +%macro QPEL4_HV1_LOWPASS_OP 1 +cglobal %1_h264_qpel4_hv_lowpass_v, 3,3 ; src, tmp, srcStride + movsxdifnidn r2, r2d + pxor m7, m7 + movh m0, [r0] + movh m1, [r0+r2] + lea r0, [r0+2*r2] + movh m2, [r0] + movh m3, [r0+r2] + lea r0, [r0+2*r2] + movh m4, [r0] + add r0, r2 + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + FILT_HV 0*24 + FILT_HV 1*24 + FILT_HV 2*24 + FILT_HV 3*24 + RET + +cglobal %1_h264_qpel4_hv_lowpass_h, 3,4 ; tmp, dst, dstStride + movsxdifnidn r2, r2d + mov r3d, 4 +.loop: + mova m0, [r0] + paddw m0, [r0+10] + mova m1, [r0+2] + paddw m1, [r0+8] + mova m2, [r0+4] + paddw m2, [r0+6] + psubw m0, m1 + psraw m0, 2 + psubw m0, m1 + paddsw m0, m2 + psraw m0, 2 + paddw m0, m2 + psraw m0, 6 + packuswb m0, m0 + op_%1h m0, [r1], m7 + add r0, 24 + add r1, r2 + dec r3d + jnz .loop + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL4_HV1_LOWPASS_OP put +QPEL4_HV1_LOWPASS_OP avg + +%macro QPEL8OR16_HV1_LOWPASS_OP 1 +cglobal %1_h264_qpel8or16_hv1_lowpass_op, 4,4,8 ; src, tmp, srcStride, size + movsxdifnidn r2, r2d + pxor m7, m7 + movh m0, [r0] + movh m1, [r0+r2] + lea r0, [r0+2*r2] + movh m2, [r0] + movh m3, [r0+r2] + lea r0, [r0+2*r2] + movh m4, [r0] + add r0, r2 + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + FILT_HV 0*48 + FILT_HV 1*48 + FILT_HV 2*48 + FILT_HV 3*48 + FILT_HV 4*48 + FILT_HV 5*48 + FILT_HV 6*48 + FILT_HV 7*48 + cmp r3d, 16 + jne .end + FILT_HV 8*48 + FILT_HV 9*48 + FILT_HV 10*48 + FILT_HV 11*48 + FILT_HV 12*48 + FILT_HV 13*48 + FILT_HV 14*48 + FILT_HV 15*48 +.end: + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL8OR16_HV1_LOWPASS_OP put +QPEL8OR16_HV1_LOWPASS_OP avg + +INIT_XMM sse2 +QPEL8OR16_HV1_LOWPASS_OP put + + + +%macro QPEL8OR16_HV2_LOWPASS_OP 1 +; unused is to match ssse3 and mmxext args +cglobal %1_h264_qpel8or16_hv2_lowpass_op, 5,5 ; dst, tmp, dstStride, unused, h + movsxdifnidn r2, r2d +.loop: + mova m0, [r1] + mova m3, [r1+8] + mova m1, [r1+2] + mova m4, [r1+10] + paddw m0, m4 + paddw m1, m3 + paddw m3, [r1+18] + paddw m4, [r1+16] + mova m2, [r1+4] + mova m5, [r1+12] + paddw m2, [r1+6] + paddw m5, [r1+14] + psubw m0, m1 + psubw m3, m4 + psraw m0, 2 + psraw m3, 2 + psubw m0, m1 + psubw m3, m4 + paddsw m0, m2 + paddsw m3, m5 + psraw m0, 2 + psraw m3, 2 + paddw m0, m2 + paddw m3, m5 + psraw m0, 6 + psraw m3, 6 + packuswb m0, m3 + op_%1 m0, [r0], m7 + add r1, 48 + add r0, r2 + dec r4d + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +QPEL8OR16_HV2_LOWPASS_OP put +QPEL8OR16_HV2_LOWPASS_OP avg + +%macro QPEL8OR16_HV2_LOWPASS_OP_XMM 1 +cglobal %1_h264_qpel8or16_hv2_lowpass, 5,5,8 ; dst, tmp, dstStride, tmpStride, size + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + cmp r4d, 16 + je .op16 +.loop8: + mova m1, [r1+16] + mova m0, [r1] + mova m2, m1 + mova m3, m1 + mova m4, m1 + mova m5, m1 + palignr m5, m0, 10 + palignr m4, m0, 8 + palignr m3, m0, 6 + palignr m2, m0, 4 + palignr m1, m0, 2 + paddw m0, m5 + paddw m1, m4 + paddw m2, m3 + psubw m0, m1 + psraw m0, 2 + psubw m0, m1 + paddw m0, m2 + psraw m0, 2 + paddw m0, m2 + psraw m0, 6 + packuswb m0, m0 + op_%1h m0, [r0], m7 + add r1, 48 + add r0, r2 + dec r4d + jne .loop8 + jmp .done +.op16: + mova m4, [r1+32] + mova m5, [r1+16] + mova m7, [r1] + mova m3, m4 + mova m2, m4 + mova m1, m4 + mova m0, m4 + palignr m0, m5, 10 + palignr m1, m5, 8 + palignr m2, m5, 6 + palignr m3, m5, 4 + palignr m4, m5, 2 + paddw m0, m5 + paddw m1, m4 + paddw m2, m3 + mova m6, m5 + mova m4, m5 + mova m3, m5 + palignr m4, m7, 8 + palignr m6, m7, 2 + palignr m3, m7, 10 + paddw m4, m6 + mova m6, m5 + palignr m5, m7, 6 + palignr m6, m7, 4 + paddw m3, m7 + paddw m5, m6 + psubw m0, m1 + psubw m3, m4 + psraw m0, 2 + psraw m3, 2 + psubw m0, m1 + psubw m3, m4 + paddw m0, m2 + paddw m3, m5 + psraw m0, 2 + psraw m3, 2 + paddw m0, m2 + paddw m3, m5 + psraw m0, 6 + psraw m3, 6 + packuswb m3, m0 + op_%1 m3, [r0], m7 + add r1, 48 + add r0, r2 + dec r4d + jne .op16 +.done: + REP_RET +%endmacro + +INIT_XMM ssse3 +QPEL8OR16_HV2_LOWPASS_OP_XMM put +QPEL8OR16_HV2_LOWPASS_OP_XMM avg + + +%macro PIXELS4_L2_SHIFT5 1 +cglobal %1_pixels4_l2_shift5,6,6 ; dst, src16, src8, dstStride, src8Stride, h + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + mova m0, [r1] + mova m1, [r1+24] + psraw m0, 5 + psraw m1, 5 + packuswb m0, m0 + packuswb m1, m1 + pavgb m0, [r2] + pavgb m1, [r2+r4] + op_%1h m0, [r0], m4 + op_%1h m1, [r0+r3], m5 + lea r2, [r2+r4*2] + lea r0, [r0+r3*2] + mova m0, [r1+48] + mova m1, [r1+72] + psraw m0, 5 + psraw m1, 5 + packuswb m0, m0 + packuswb m1, m1 + pavgb m0, [r2] + pavgb m1, [r2+r4] + op_%1h m0, [r0], m4 + op_%1h m1, [r0+r3], m5 + RET +%endmacro + +INIT_MMX mmxext +PIXELS4_L2_SHIFT5 put +PIXELS4_L2_SHIFT5 avg + + +%macro PIXELS8_L2_SHIFT5 1 +cglobal %1_pixels8_l2_shift5, 6, 6 ; dst, src16, src8, dstStride, src8Stride, h + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d +.loop: + mova m0, [r1] + mova m1, [r1+8] + mova m2, [r1+48] + mova m3, [r1+48+8] + psraw m0, 5 + psraw m1, 5 + psraw m2, 5 + psraw m3, 5 + packuswb m0, m1 + packuswb m2, m3 + pavgb m0, [r2] + pavgb m2, [r2+r4] + op_%1 m0, [r0], m4 + op_%1 m2, [r0+r3], m5 + lea r2, [r2+2*r4] + add r1, 48*2 + lea r0, [r0+2*r3] + sub r5d, 2 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PIXELS8_L2_SHIFT5 put +PIXELS8_L2_SHIFT5 avg + + +%if ARCH_X86_64 +%macro QPEL16_H_LOWPASS_L2_OP 1 +cglobal %1_h264_qpel16_h_lowpass_l2, 5, 6, 16 ; dst, src, src2, dstStride, src2Stride + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + mov r5d, 16 + pxor m15, m15 + mova m14, [pw_5] + mova m13, [pw_16] +.loop: + lddqu m1, [r1+6] + lddqu m7, [r1-2] + mova m0, m1 + punpckhbw m1, m15 + punpcklbw m0, m15 + punpcklbw m7, m15 + mova m2, m1 + mova m6, m0 + mova m3, m1 + mova m8, m0 + mova m4, m1 + mova m9, m0 + mova m12, m0 + mova m11, m1 + palignr m11, m0, 10 + palignr m12, m7, 10 + palignr m4, m0, 2 + palignr m9, m7, 2 + palignr m3, m0, 4 + palignr m8, m7, 4 + palignr m2, m0, 6 + palignr m6, m7, 6 + paddw m11, m0 + palignr m1, m0, 8 + palignr m0, m7, 8 + paddw m7, m12 + paddw m2, m3 + paddw m6, m8 + paddw m1, m4 + paddw m0, m9 + psllw m2, 2 + psllw m6, 2 + psubw m2, m1 + psubw m6, m0 + paddw m11, m13 + paddw m7, m13 + pmullw m2, m14 + pmullw m6, m14 + lddqu m3, [r2] + paddw m2, m11 + paddw m6, m7 + psraw m2, 5 + psraw m6, 5 + packuswb m6, m2 + pavgb m6, m3 + op_%1 m6, [r0], m11 + add r1, r3 + add r0, r3 + add r2, r4 + dec r5d + jg .loop + REP_RET +%endmacro + +INIT_XMM ssse3 +QPEL16_H_LOWPASS_L2_OP put +QPEL16_H_LOWPASS_L2_OP avg +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_weight.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_weight.asm new file mode 100644 index 00000000..0975d74f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_weight.asm @@ -0,0 +1,320 @@ +;***************************************************************************** +;* SSE2-optimized weighted prediction code +;***************************************************************************** +;* Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt +;* Copyright (C) 2010 Eli Friedman +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; biweight pred: +; +; void ff_h264_biweight_16_sse2(uint8_t *dst, uint8_t *src, int stride, +; int height, int log2_denom, int weightd, +; int weights, int offset); +; and +; void ff_h264_weight_16_sse2(uint8_t *dst, int stride, int height, +; int log2_denom, int weight, int offset); +;----------------------------------------------------------------------------- + +%macro WEIGHT_SETUP 0 + add r5, r5 + inc r5 + movd m3, r4d + movd m5, r5d + movd m6, r3d + pslld m5, m6 + psrld m5, 1 +%if mmsize == 16 + pshuflw m3, m3, 0 + pshuflw m5, m5, 0 + punpcklqdq m3, m3 + punpcklqdq m5, m5 +%else + pshufw m3, m3, 0 + pshufw m5, m5, 0 +%endif + pxor m7, m7 +%endmacro + +%macro WEIGHT_OP 2 + movh m0, [r0+%1] + movh m1, [r0+%2] + punpcklbw m0, m7 + punpcklbw m1, m7 + pmullw m0, m3 + pmullw m1, m3 + paddsw m0, m5 + paddsw m1, m5 + psraw m0, m6 + psraw m1, m6 + packuswb m0, m1 +%endmacro + +INIT_MMX mmxext +cglobal h264_weight_16, 6, 6, 0 + WEIGHT_SETUP +.nextrow: + WEIGHT_OP 0, 4 + mova [r0 ], m0 + WEIGHT_OP 8, 12 + mova [r0+8], m0 + add r0, r1 + dec r2d + jnz .nextrow + REP_RET + +%macro WEIGHT_FUNC_MM 2 +cglobal h264_weight_%1, 6, 6, %2 + WEIGHT_SETUP +.nextrow: + WEIGHT_OP 0, mmsize/2 + mova [r0], m0 + add r0, r1 + dec r2d + jnz .nextrow + REP_RET +%endmacro + +INIT_MMX mmxext +WEIGHT_FUNC_MM 8, 0 +INIT_XMM sse2 +WEIGHT_FUNC_MM 16, 8 + +%macro WEIGHT_FUNC_HALF_MM 2 +cglobal h264_weight_%1, 6, 6, %2 + WEIGHT_SETUP + sar r2d, 1 + lea r3, [r1*2] +.nextrow: + WEIGHT_OP 0, r1 + movh [r0], m0 +%if mmsize == 16 + movhps [r0+r1], m0 +%else + psrlq m0, 32 + movh [r0+r1], m0 +%endif + add r0, r3 + dec r2d + jnz .nextrow + REP_RET +%endmacro + +INIT_MMX mmxext +WEIGHT_FUNC_HALF_MM 4, 0 +INIT_XMM sse2 +WEIGHT_FUNC_HALF_MM 8, 8 + +%macro BIWEIGHT_SETUP 0 +%if ARCH_X86_64 +%define off_regd r7d +%else +%define off_regd r3d +%endif + mov off_regd, r7m + add off_regd, 1 + or off_regd, 1 + add r4d, 1 + cmp r6d, 128 + je .nonnormal + cmp r5d, 128 + jne .normal +.nonnormal: + sar r5d, 1 + sar r6d, 1 + sar off_regd, 1 + sub r4d, 1 +.normal: +%if cpuflag(ssse3) + movd m4, r5d + movd m0, r6d +%else + movd m3, r5d + movd m4, r6d +%endif + movd m5, off_regd + movd m6, r4d + pslld m5, m6 + psrld m5, 1 +%if cpuflag(ssse3) + punpcklbw m4, m0 + pshuflw m4, m4, 0 + pshuflw m5, m5, 0 + punpcklqdq m4, m4 + punpcklqdq m5, m5 + +%else +%if mmsize == 16 + pshuflw m3, m3, 0 + pshuflw m4, m4, 0 + pshuflw m5, m5, 0 + punpcklqdq m3, m3 + punpcklqdq m4, m4 + punpcklqdq m5, m5 +%else + pshufw m3, m3, 0 + pshufw m4, m4, 0 + pshufw m5, m5, 0 +%endif + pxor m7, m7 +%endif +%endmacro + +%macro BIWEIGHT_STEPA 3 + movh m%1, [r0+%3] + movh m%2, [r1+%3] + punpcklbw m%1, m7 + punpcklbw m%2, m7 + pmullw m%1, m3 + pmullw m%2, m4 + paddsw m%1, m%2 +%endmacro + +%macro BIWEIGHT_STEPB 0 + paddsw m0, m5 + paddsw m1, m5 + psraw m0, m6 + psraw m1, m6 + packuswb m0, m1 +%endmacro + +INIT_MMX mmxext +cglobal h264_biweight_16, 7, 8, 0 + BIWEIGHT_SETUP + movifnidn r3d, r3m +.nextrow: + BIWEIGHT_STEPA 0, 1, 0 + BIWEIGHT_STEPA 1, 2, 4 + BIWEIGHT_STEPB + mova [r0], m0 + BIWEIGHT_STEPA 0, 1, 8 + BIWEIGHT_STEPA 1, 2, 12 + BIWEIGHT_STEPB + mova [r0+8], m0 + add r0, r2 + add r1, r2 + dec r3d + jnz .nextrow + REP_RET + +%macro BIWEIGHT_FUNC_MM 2 +cglobal h264_biweight_%1, 7, 8, %2 + BIWEIGHT_SETUP + movifnidn r3d, r3m +.nextrow: + BIWEIGHT_STEPA 0, 1, 0 + BIWEIGHT_STEPA 1, 2, mmsize/2 + BIWEIGHT_STEPB + mova [r0], m0 + add r0, r2 + add r1, r2 + dec r3d + jnz .nextrow + REP_RET +%endmacro + +INIT_MMX mmxext +BIWEIGHT_FUNC_MM 8, 0 +INIT_XMM sse2 +BIWEIGHT_FUNC_MM 16, 8 + +%macro BIWEIGHT_FUNC_HALF_MM 2 +cglobal h264_biweight_%1, 7, 8, %2 + BIWEIGHT_SETUP + movifnidn r3d, r3m + sar r3, 1 + lea r4, [r2*2] +.nextrow: + BIWEIGHT_STEPA 0, 1, 0 + BIWEIGHT_STEPA 1, 2, r2 + BIWEIGHT_STEPB + movh [r0], m0 +%if mmsize == 16 + movhps [r0+r2], m0 +%else + psrlq m0, 32 + movh [r0+r2], m0 +%endif + add r0, r4 + add r1, r4 + dec r3d + jnz .nextrow + REP_RET +%endmacro + +INIT_MMX mmxext +BIWEIGHT_FUNC_HALF_MM 4, 0 +INIT_XMM sse2 +BIWEIGHT_FUNC_HALF_MM 8, 8 + +%macro BIWEIGHT_SSSE3_OP 0 + pmaddubsw m0, m4 + pmaddubsw m2, m4 + paddsw m0, m5 + paddsw m2, m5 + psraw m0, m6 + psraw m2, m6 + packuswb m0, m2 +%endmacro + +INIT_XMM ssse3 +cglobal h264_biweight_16, 7, 8, 8 + BIWEIGHT_SETUP + movifnidn r3d, r3m + +.nextrow: + movh m0, [r0] + movh m2, [r0+8] + movh m3, [r1+8] + punpcklbw m0, [r1] + punpcklbw m2, m3 + BIWEIGHT_SSSE3_OP + mova [r0], m0 + add r0, r2 + add r1, r2 + dec r3d + jnz .nextrow + REP_RET + +INIT_XMM ssse3 +cglobal h264_biweight_8, 7, 8, 8 + BIWEIGHT_SETUP + movifnidn r3d, r3m + sar r3, 1 + lea r4, [r2*2] + +.nextrow: + movh m0, [r0] + movh m1, [r1] + movh m2, [r0+r2] + movh m3, [r1+r2] + punpcklbw m0, m1 + punpcklbw m2, m3 + BIWEIGHT_SSSE3_OP + movh [r0], m0 + movhps [r0+r2], m0 + add r0, r4 + add r1, r4 + dec r3d + jnz .nextrow + REP_RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_weight_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_weight_10bit.asm new file mode 100644 index 00000000..f924e558 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264_weight_10bit.asm @@ -0,0 +1,284 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 weighted prediction code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +sq_1: dq 1 + dq 0 + +cextern pw_1 +cextern pw_1023 +%define pw_pixel_max pw_1023 + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_h264_weight_16_10(uint8_t *dst, int stride, int height, +; int log2_denom, int weight, int offset); +;----------------------------------------------------------------------------- +%macro WEIGHT_PROLOGUE 0 +.prologue: + PROLOGUE 0,6,8 + movifnidn r0, r0mp + movifnidn r1d, r1m + movifnidn r2d, r2m + movifnidn r4d, r4m + movifnidn r5d, r5m +%endmacro + +%macro WEIGHT_SETUP 0 + mova m0, [pw_1] + movd m2, r3m + pslld m0, m2 ; 1< + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h264chroma.h" + +void ff_put_h264_chroma_mc8_rnd_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc8_rnd_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc8_rnd_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_h264_chroma_mc4_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc4_mmxext (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc4_3dnow (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_h264_chroma_mc2_mmxext (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc2_mmxext (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_put_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_avg_h264_chroma_mc8_rnd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +#define CHROMA_MC(OP, NUM, DEPTH, OPT) \ +void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, uint8_t *src, \ + ptrdiff_t stride, int h, int x, int y); + +CHROMA_MC(put, 2, 10, mmxext) +CHROMA_MC(avg, 2, 10, mmxext) +CHROMA_MC(put, 4, 10, mmxext) +CHROMA_MC(avg, 4, 10, mmxext) +CHROMA_MC(put, 8, 10, sse2) +CHROMA_MC(avg, 8, 10, sse2) +CHROMA_MC(put, 8, 10, avx) +CHROMA_MC(avg, 8, 10, avx) + +av_cold void ff_h264chroma_init_x86(H264ChromaContext *c, int bit_depth) +{ + int high_bit_depth = bit_depth > 8; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags) && !high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_mmx; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_mmx; + } + + if (EXTERNAL_AMD3DNOW(cpu_flags) && !high_bit_depth) { + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_3dnow; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_3dnow; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && !high_bit_depth) { + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_mmxext; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_mmxext; + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_mmxext; + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_mmxext; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { + c->put_h264_chroma_pixels_tab[2] = ff_put_h264_chroma_mc2_10_mmxext; + c->avg_h264_chroma_pixels_tab[2] = ff_avg_h264_chroma_mc2_10_mmxext; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_10_mmxext; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_10_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_sse2; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags) && !high_bit_depth) { + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_rnd_ssse3; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_rnd_ssse3; + c->put_h264_chroma_pixels_tab[1] = ff_put_h264_chroma_mc4_ssse3; + c->avg_h264_chroma_pixels_tab[1] = ff_avg_h264_chroma_mc4_ssse3; + } + + if (EXTERNAL_AVX(cpu_flags) && bit_depth > 8 && bit_depth <= 10) { + // AVX implies !cache64. + // TODO: Port cache(32|64) detection from x264. + c->put_h264_chroma_pixels_tab[0] = ff_put_h264_chroma_mc8_10_avx; + c->avg_h264_chroma_pixels_tab[0] = ff_avg_h264_chroma_mc8_10_avx; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264dsp_init.c new file mode 100644 index 00000000..08eb7ead --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/h264dsp_init.c @@ -0,0 +1,448 @@ +/* + * Copyright (c) 2004-2005 Michael Niedermayer, Loren Merritt + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/h264dsp.h" + +/***********************************/ +/* IDCT */ +#define IDCT_ADD_FUNC(NUM, DEPTH, OPT) \ +void ff_h264_idct ## NUM ## _add_ ## DEPTH ## _ ## OPT(uint8_t *dst, \ + int16_t *block, \ + int stride); + +IDCT_ADD_FUNC(, 8, mmx) +IDCT_ADD_FUNC(, 8, sse2) +IDCT_ADD_FUNC(, 8, avx) +IDCT_ADD_FUNC(, 10, sse2) +IDCT_ADD_FUNC(_dc, 8, mmxext) +IDCT_ADD_FUNC(_dc, 8, sse2) +IDCT_ADD_FUNC(_dc, 8, avx) +IDCT_ADD_FUNC(_dc, 10, mmxext) +IDCT_ADD_FUNC(8_dc, 8, mmxext) +IDCT_ADD_FUNC(8_dc, 10, sse2) +IDCT_ADD_FUNC(8, 8, mmx) +IDCT_ADD_FUNC(8, 8, sse2) +IDCT_ADD_FUNC(8, 10, sse2) +IDCT_ADD_FUNC(, 10, avx) +IDCT_ADD_FUNC(8_dc, 10, avx) +IDCT_ADD_FUNC(8, 10, avx) + + +#define IDCT_ADD_REP_FUNC(NUM, REP, DEPTH, OPT) \ +void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, const int *block_offset, \ + int16_t *block, int stride, const uint8_t nnzc[6 * 8]); + +IDCT_ADD_REP_FUNC(8, 4, 8, mmx) +IDCT_ADD_REP_FUNC(8, 4, 8, mmxext) +IDCT_ADD_REP_FUNC(8, 4, 8, sse2) +IDCT_ADD_REP_FUNC(8, 4, 10, sse2) +IDCT_ADD_REP_FUNC(8, 4, 10, avx) +IDCT_ADD_REP_FUNC(, 16, 8, mmx) +IDCT_ADD_REP_FUNC(, 16, 8, mmxext) +IDCT_ADD_REP_FUNC(, 16, 8, sse2) +IDCT_ADD_REP_FUNC(, 16, 10, sse2) +IDCT_ADD_REP_FUNC(, 16intra, 8, mmx) +IDCT_ADD_REP_FUNC(, 16intra, 8, mmxext) +IDCT_ADD_REP_FUNC(, 16intra, 8, sse2) +IDCT_ADD_REP_FUNC(, 16intra, 10, sse2) +IDCT_ADD_REP_FUNC(, 16, 10, avx) +IDCT_ADD_REP_FUNC(, 16intra, 10, avx) + + +#define IDCT_ADD_REP_FUNC2(NUM, REP, DEPTH, OPT) \ +void ff_h264_idct ## NUM ## _add ## REP ## _ ## DEPTH ## _ ## OPT \ + (uint8_t **dst, const int *block_offset, \ + int16_t *block, int stride, const uint8_t nnzc[6 * 8]); + +IDCT_ADD_REP_FUNC2(, 8, 8, mmx) +IDCT_ADD_REP_FUNC2(, 8, 8, mmxext) +IDCT_ADD_REP_FUNC2(, 8, 8, sse2) +IDCT_ADD_REP_FUNC2(, 8, 10, sse2) +IDCT_ADD_REP_FUNC2(, 8, 10, avx) + +IDCT_ADD_REP_FUNC2(, 8_422, 8, mmx) + +IDCT_ADD_REP_FUNC2(, 8_422, 10, sse2) +IDCT_ADD_REP_FUNC2(, 8_422, 10, avx) + +void ff_h264_luma_dc_dequant_idct_mmx(int16_t *output, int16_t *input, int qmul); +void ff_h264_luma_dc_dequant_idct_sse2(int16_t *output, int16_t *input, int qmul); + +/***********************************/ +/* deblocking */ + +void ff_h264_loop_filter_strength_mmxext(int16_t bS[2][4][4], uint8_t nnz[40], + int8_t ref[2][40], + int16_t mv[2][40][2], + int bidir, int edges, int step, + int mask_mv0, int mask_mv1, int field); + +#define LF_FUNC(DIR, TYPE, DEPTH, OPT) \ +void ff_deblock_ ## DIR ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT(uint8_t *pix, \ + ptrdiff_t stride, \ + int alpha, \ + int beta, \ + int8_t *tc0); +#define LF_IFUNC(DIR, TYPE, DEPTH, OPT) \ +void ff_deblock_ ## DIR ## _ ## TYPE ## _ ## DEPTH ## _ ## OPT(uint8_t *pix, \ + ptrdiff_t stride, \ + int alpha, \ + int beta); + +#define LF_FUNCS(type, depth) \ +LF_FUNC(h, chroma, depth, mmxext) \ +LF_IFUNC(h, chroma_intra, depth, mmxext) \ +LF_FUNC(h, chroma422, depth, mmxext) \ +LF_IFUNC(h, chroma422_intra, depth, mmxext) \ +LF_FUNC(v, chroma, depth, mmxext) \ +LF_IFUNC(v, chroma_intra, depth, mmxext) \ +LF_FUNC(h, luma, depth, mmxext) \ +LF_IFUNC(h, luma_intra, depth, mmxext) \ +LF_FUNC(h, luma, depth, sse2) \ +LF_IFUNC(h, luma_intra, depth, sse2) \ +LF_FUNC(v, luma, depth, sse2) \ +LF_IFUNC(v, luma_intra, depth, sse2) \ +LF_FUNC(h, chroma, depth, sse2) \ +LF_IFUNC(h, chroma_intra, depth, sse2) \ +LF_FUNC(h, chroma422, depth, sse2) \ +LF_IFUNC(h, chroma422_intra, depth, sse2) \ +LF_FUNC(v, chroma, depth, sse2) \ +LF_IFUNC(v, chroma_intra, depth, sse2) \ +LF_FUNC(h, luma, depth, avx) \ +LF_IFUNC(h, luma_intra, depth, avx) \ +LF_FUNC(v, luma, depth, avx) \ +LF_IFUNC(v, luma_intra, depth, avx) \ +LF_FUNC(h, chroma, depth, avx) \ +LF_IFUNC(h, chroma_intra, depth, avx) \ +LF_FUNC(h, chroma422, depth, avx) \ +LF_IFUNC(h, chroma422_intra, depth, avx) \ +LF_FUNC(v, chroma, depth, avx) \ +LF_IFUNC(v, chroma_intra, depth, avx) + +LF_FUNC(h, luma_mbaff, 8, sse2) +LF_FUNC(h, luma_mbaff, 8, avx) + +LF_FUNCS(uint8_t, 8) +LF_FUNCS(uint16_t, 10) + +#if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL +LF_FUNC(v8, luma, 8, mmxext) +static void deblock_v_luma_8_mmxext(uint8_t *pix, int stride, int alpha, + int beta, int8_t *tc0) +{ + if ((tc0[0] & tc0[1]) >= 0) + ff_deblock_v8_luma_8_mmxext(pix + 0, stride, alpha, beta, tc0); + if ((tc0[2] & tc0[3]) >= 0) + ff_deblock_v8_luma_8_mmxext(pix + 8, stride, alpha, beta, tc0 + 2); +} +LF_IFUNC(v8, luma_intra, 8, mmxext) +static void deblock_v_luma_intra_8_mmxext(uint8_t *pix, int stride, + int alpha, int beta) +{ + ff_deblock_v8_luma_intra_8_mmxext(pix + 0, stride, alpha, beta); + ff_deblock_v8_luma_intra_8_mmxext(pix + 8, stride, alpha, beta); +} +#endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */ + +LF_FUNC(v, luma, 10, mmxext) +LF_IFUNC(v, luma_intra, 10, mmxext) + +/***********************************/ +/* weighted prediction */ + +#define H264_WEIGHT(W, OPT) \ +void ff_h264_weight_ ## W ## _ ## OPT(uint8_t *dst, ptrdiff_t stride, \ + int height, int log2_denom, \ + int weight, int offset); + +#define H264_BIWEIGHT(W, OPT) \ +void ff_h264_biweight_ ## W ## _ ## OPT(uint8_t *dst, uint8_t *src, \ + ptrdiff_t stride, int height, \ + int log2_denom, int weightd, \ + int weights, int offset); + +#define H264_BIWEIGHT_MMX(W) \ + H264_WEIGHT(W, mmxext) \ + H264_BIWEIGHT(W, mmxext) + +#define H264_BIWEIGHT_MMX_SSE(W) \ + H264_BIWEIGHT_MMX(W) \ + H264_WEIGHT(W, sse2) \ + H264_BIWEIGHT(W, sse2) \ + H264_BIWEIGHT(W, ssse3) + +H264_BIWEIGHT_MMX_SSE(16) +H264_BIWEIGHT_MMX_SSE(8) +H264_BIWEIGHT_MMX(4) + +#define H264_WEIGHT_10(W, DEPTH, OPT) \ +void ff_h264_weight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst, \ + ptrdiff_t stride, \ + int height, \ + int log2_denom, \ + int weight, \ + int offset); + +#define H264_BIWEIGHT_10(W, DEPTH, OPT) \ +void ff_h264_biweight_ ## W ## _ ## DEPTH ## _ ## OPT(uint8_t *dst, \ + uint8_t *src, \ + ptrdiff_t stride, \ + int height, \ + int log2_denom, \ + int weightd, \ + int weights, \ + int offset); + +#define H264_BIWEIGHT_10_SSE(W, DEPTH) \ + H264_WEIGHT_10(W, DEPTH, sse2) \ + H264_WEIGHT_10(W, DEPTH, sse4) \ + H264_BIWEIGHT_10(W, DEPTH, sse2) \ + H264_BIWEIGHT_10(W, DEPTH, sse4) + +H264_BIWEIGHT_10_SSE(16, 10) +H264_BIWEIGHT_10_SSE(8, 10) +H264_BIWEIGHT_10_SSE(4, 10) + +av_cold void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, + const int chroma_format_idc) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMXEXT(cpu_flags) && chroma_format_idc <= 1) + c->h264_loop_filter_strength = ff_h264_loop_filter_strength_mmxext; + + if (bit_depth == 8) { + if (EXTERNAL_MMX(cpu_flags)) { + c->h264_idct_dc_add = + c->h264_idct_add = ff_h264_idct_add_8_mmx; + c->h264_idct8_dc_add = + c->h264_idct8_add = ff_h264_idct8_add_8_mmx; + + c->h264_idct_add16 = ff_h264_idct_add16_8_mmx; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmx; + if (chroma_format_idc <= 1) { + c->h264_idct_add8 = ff_h264_idct_add8_8_mmx; + } else { + c->h264_idct_add8 = ff_h264_idct_add8_422_8_mmx; + } + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx; + if (cpu_flags & AV_CPU_FLAG_CMOV) + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx; + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmxext; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmxext; + c->h264_idct_add16 = ff_h264_idct_add16_8_mmxext; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmxext; + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_mmxext; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmxext; + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_mmxext; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_mmxext; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_mmxext; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_mmxext; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_8_mmxext; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma422_intra_8_mmxext; + } +#if ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL + c->h264_v_loop_filter_luma = deblock_v_luma_8_mmxext; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_mmxext; + c->h264_v_loop_filter_luma_intra = deblock_v_luma_intra_8_mmxext; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_mmxext; +#endif /* ARCH_X86_32 && HAVE_MMXEXT_EXTERNAL */ + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_mmxext; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_mmxext; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_mmxext; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_mmxext; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_mmxext; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->h264_idct8_add = ff_h264_idct8_add_8_sse2; + + c->h264_idct_add16 = ff_h264_idct_add16_8_sse2; + c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2; + if (chroma_format_idc <= 1) + c->h264_idct_add8 = ff_h264_idct_add8_8_sse2; + c->h264_idct_add16intra = ff_h264_idct_add16intra_8_sse2; + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_sse2; + + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_sse2; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_sse2; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_sse2; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_sse2; + + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_sse2; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_sse2; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_sse2; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_sse2; + +#if ARCH_X86_64 + c->h264_h_loop_filter_luma_mbaff = ff_deblock_h_luma_mbaff_8_sse2; +#endif + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_sse2; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_sse2; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_sse2; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_sse2; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_8_sse2; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma422_intra_8_sse2; + } + + c->h264_idct_add = ff_h264_idct_add_8_sse2; + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_ssse3; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_ssse3; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_avx; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_avx; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_8_avx; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_8_avx; +#if ARCH_X86_64 + c->h264_h_loop_filter_luma_mbaff = ff_deblock_h_luma_mbaff_8_avx; +#endif + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_8_avx; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_8_avx; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_8_avx; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma_intra_8_avx; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_8_avx; + c->h264_h_loop_filter_chroma_intra = ff_deblock_h_chroma422_intra_8_avx; + } + + c->h264_idct_add = ff_h264_idct_add_8_avx; + c->h264_idct_dc_add = ff_h264_idct_dc_add_8_avx; + } + } else if (bit_depth == 10) { + if (EXTERNAL_MMXEXT(cpu_flags)) { +#if ARCH_X86_32 + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_mmxext; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_mmxext; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_10_mmxext; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_10_mmxext; + } + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_mmxext; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_mmxext; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_mmxext; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_mmxext; +#endif /* ARCH_X86_32 */ + c->h264_idct_dc_add = ff_h264_idct_dc_add_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->h264_idct_add = ff_h264_idct_add_10_sse2; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2; + + c->h264_idct_add16 = ff_h264_idct_add16_10_sse2; + if (chroma_format_idc <= 1) { + c->h264_idct_add8 = ff_h264_idct_add8_10_sse2; + } else { + c->h264_idct_add8 = ff_h264_idct_add8_422_10_sse2; + } + c->h264_idct_add16intra = ff_h264_idct_add16intra_10_sse2; +#if HAVE_ALIGNED_STACK + c->h264_idct8_add = ff_h264_idct8_add_10_sse2; + c->h264_idct8_add4 = ff_h264_idct8_add4_10_sse2; +#endif /* HAVE_ALIGNED_STACK */ + + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse2; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse2; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse2; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse2; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse2; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse2; + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_sse2; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_sse2; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_10_sse2; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_10_sse2; + } +#if HAVE_ALIGNED_STACK + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_sse2; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_sse2; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_sse2; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_sse2; +#endif /* HAVE_ALIGNED_STACK */ + } + if (EXTERNAL_SSE4(cpu_flags)) { + c->weight_h264_pixels_tab[0] = ff_h264_weight_16_10_sse4; + c->weight_h264_pixels_tab[1] = ff_h264_weight_8_10_sse4; + c->weight_h264_pixels_tab[2] = ff_h264_weight_4_10_sse4; + + c->biweight_h264_pixels_tab[0] = ff_h264_biweight_16_10_sse4; + c->biweight_h264_pixels_tab[1] = ff_h264_biweight_8_10_sse4; + c->biweight_h264_pixels_tab[2] = ff_h264_biweight_4_10_sse4; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->h264_idct_dc_add = + c->h264_idct_add = ff_h264_idct_add_10_avx; + c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx; + + c->h264_idct_add16 = ff_h264_idct_add16_10_avx; + if (chroma_format_idc <= 1) { + c->h264_idct_add8 = ff_h264_idct_add8_10_avx; + } else { + c->h264_idct_add8 = ff_h264_idct_add8_422_10_avx; + } + c->h264_idct_add16intra = ff_h264_idct_add16intra_10_avx; +#if HAVE_ALIGNED_STACK + c->h264_idct8_add = ff_h264_idct8_add_10_avx; + c->h264_idct8_add4 = ff_h264_idct8_add4_10_avx; +#endif /* HAVE_ALIGNED_STACK */ + + c->h264_v_loop_filter_chroma = ff_deblock_v_chroma_10_avx; + c->h264_v_loop_filter_chroma_intra = ff_deblock_v_chroma_intra_10_avx; + if (chroma_format_idc <= 1) { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma_10_avx; + } else { + c->h264_h_loop_filter_chroma = ff_deblock_h_chroma422_10_avx; + } +#if HAVE_ALIGNED_STACK + c->h264_v_loop_filter_luma = ff_deblock_v_luma_10_avx; + c->h264_h_loop_filter_luma = ff_deblock_h_luma_10_avx; + c->h264_v_loop_filter_luma_intra = ff_deblock_v_luma_intra_10_avx; + c->h264_h_loop_filter_luma_intra = ff_deblock_h_luma_intra_10_avx; +#endif /* HAVE_ALIGNED_STACK */ + } + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_add_res.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_add_res.asm new file mode 100644 index 00000000..c6c40078 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_add_res.asm @@ -0,0 +1,369 @@ +; ***************************************************************************** +; * Provide SIMD optimizations for add_residual functions for HEVC decoding +; * Copyright (c) 2014 Pierre-Edouard LEPERE +; * +; * 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 "libavutil/x86/x86util.asm" + +SECTION .text + +cextern pw_1023 +%define max_pixels_10 pw_1023 + +; the add_res macros and functions were largely inspired by h264_idct.asm from the x264 project +%macro ADD_RES_MMX_4_8 0 + mova m0, [r1] + mova m2, [r1+8] + + movd m1, [r0] + movd m3, [r0+r2] + punpcklbw m1, m4 + punpcklbw m3, m4 + + paddsw m0, m1 + paddsw m2, m3 + packuswb m0, m4 + packuswb m2, m4 + + movd [r0], m0 + movd [r0+r2], m2 +%endmacro + + +INIT_MMX mmxext +; void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_4_8, 3, 3, 6 + pxor m4, m4 + ADD_RES_MMX_4_8 + add r1, 16 + lea r0, [r0+r2*2] + ADD_RES_MMX_4_8 + RET + +%macro ADD_RES_SSE_8_8 0 + movq m0, [r0] + movq m1, [r0+r2] + punpcklbw m0, m4 + punpcklbw m1, m4 + mova m2, [r1] + mova m3, [r1+16] + paddsw m0, m2 + paddsw m1, m3 + packuswb m0, m1 + + movq m2, [r0+r2*2] + movq m3, [r0+r3] + punpcklbw m2, m4 + punpcklbw m3, m4 + mova m6, [r1+32] + mova m7, [r1+48] + paddsw m2, m6 + paddsw m3, m7 + packuswb m2, m3 + + movq [r0], m0 + movhps [r0+r2], m0 + movq [r0+r2*2], m2 + movhps [r0+r3], m2 +%endmacro + +%macro ADD_RES_SSE_16_32_8 3 + mova m1, [%2] + mova m2, m1 + punpcklbw m1, m0 + punpckhbw m2, m0 + mova xm5, [r1+%1] + mova xm6, [r1+%1+16] +%if cpuflag(avx2) + vinserti128 m5, m5, [r1+%1+32], 1 + vinserti128 m6, m6, [r1+%1+48], 1 +%endif + paddsw m1, m5 + paddsw m2, m6 + + mova m3, [%3] + mova m4, m3 + punpcklbw m3, m0 + punpckhbw m4, m0 + mova xm5, [r1+%1+mmsize*2] + mova xm6, [r1+%1+mmsize*2+16] +%if cpuflag(avx2) + vinserti128 m5, m5, [r1+%1+96], 1 + vinserti128 m6, m6, [r1+%1+112], 1 +%endif + paddsw m3, m5 + paddsw m4, m6 + + packuswb m1, m2 + packuswb m3, m4 + mova [%2], m1 + mova [%3], m3 +%endmacro + + +%macro TRANSFORM_ADD_8 0 +; void ff_hevc_add_residual_8_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_8_8, 3, 4, 8 + pxor m4, m4 + lea r3, [r2*3] + ADD_RES_SSE_8_8 + add r1, 64 + lea r0, [r0+r2*4] + ADD_RES_SSE_8_8 + RET + +; void ff_hevc_add_residual_16_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_16_8, 3, 5, 7 + pxor m0, m0 + lea r3, [r2*3] + mov r4d, 4 +.loop: + ADD_RES_SSE_16_32_8 0, r0, r0+r2 + ADD_RES_SSE_16_32_8 64, r0+r2*2, r0+r3 + add r1, 128 + lea r0, [r0+r2*4] + dec r4d + jg .loop + RET + +; void ff_hevc_add_residual_32_8_(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_32_8, 3, 5, 7 + pxor m0, m0 + mov r4d, 16 +.loop: + ADD_RES_SSE_16_32_8 0, r0, r0+16 + ADD_RES_SSE_16_32_8 64, r0+r2, r0+r2+16 + add r1, 128 + lea r0, [r0+r2*2] + dec r4d + jg .loop + RET +%endmacro + +INIT_XMM sse2 +TRANSFORM_ADD_8 +INIT_XMM avx +TRANSFORM_ADD_8 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +; void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride) +cglobal hevc_add_residual_32_8, 3, 5, 7 + pxor m0, m0 + lea r3, [r2*3] + mov r4d, 8 +.loop: + ADD_RES_SSE_16_32_8 0, r0, r0+r2 + ADD_RES_SSE_16_32_8 128, r0+r2*2, r0+r3 + add r1, 256 + lea r0, [r0+r2*4] + dec r4d + jg .loop + RET +%endif ;HAVE_AVX2_EXTERNAL + +%macro ADD_RES_SSE_8_10 4 + mova m0, [%4] + mova m1, [%4+16] + mova m2, [%4+32] + mova m3, [%4+48] + paddw m0, [%1+0] + paddw m1, [%1+%2] + paddw m2, [%1+%2*2] + paddw m3, [%1+%3] + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1+0], m0 + mova [%1+%2], m1 + mova [%1+%2*2], m2 + mova [%1+%3], m3 +%endmacro + +%macro ADD_RES_MMX_4_10 3 + mova m0, [%1+0] + mova m1, [%1+%2] + paddw m0, [%3] + paddw m1, [%3+8] + CLIPW m0, m2, m3 + CLIPW m1, m2, m3 + mova [%1+0], m0 + mova [%1+%2], m1 +%endmacro + +%macro ADD_RES_SSE_16_10 3 + mova m0, [%3] + mova m1, [%3+16] + mova m2, [%3+32] + mova m3, [%3+48] + paddw m0, [%1] + paddw m1, [%1+16] + paddw m2, [%1+%2] + paddw m3, [%1+%2+16] + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1], m0 + mova [%1+16], m1 + mova [%1+%2], m2 + mova [%1+%2+16], m3 +%endmacro + +%macro ADD_RES_SSE_32_10 2 + mova m0, [%2] + mova m1, [%2+16] + mova m2, [%2+32] + mova m3, [%2+48] + + paddw m0, [%1] + paddw m1, [%1+16] + paddw m2, [%1+32] + paddw m3, [%1+48] + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1], m0 + mova [%1+16], m1 + mova [%1+32], m2 + mova [%1+48], m3 +%endmacro + +%macro ADD_RES_AVX2_16_10 4 + mova m0, [%4] + mova m1, [%4+32] + mova m2, [%4+64] + mova m3, [%4+96] + + paddw m0, [%1+0] + paddw m1, [%1+%2] + paddw m2, [%1+%2*2] + paddw m3, [%1+%3] + + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1+0], m0 + mova [%1+%2], m1 + mova [%1+%2*2], m2 + mova [%1+%3], m3 +%endmacro + +%macro ADD_RES_AVX2_32_10 3 + mova m0, [%3] + mova m1, [%3+32] + mova m2, [%3+64] + mova m3, [%3+96] + + paddw m0, [%1] + paddw m1, [%1+32] + paddw m2, [%1+%2] + paddw m3, [%1+%2+32] + + CLIPW m0, m4, m5 + CLIPW m1, m4, m5 + CLIPW m2, m4, m5 + CLIPW m3, m4, m5 + mova [%1], m0 + mova [%1+32], m1 + mova [%1+%2], m2 + mova [%1+%2+32], m3 +%endmacro + +; void ff_hevc_add_residual_<4|8|16|32>_10(pixel *dst, int16_t *block, ptrdiff_t stride) +INIT_MMX mmxext +cglobal hevc_add_residual_4_10, 3, 3, 6 + pxor m2, m2 + mova m3, [max_pixels_10] + ADD_RES_MMX_4_10 r0, r2, r1 + add r1, 16 + lea r0, [r0+2*r2] + ADD_RES_MMX_4_10 r0, r2, r1 + RET + +INIT_XMM sse2 +cglobal hevc_add_residual_8_10, 3, 4, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + lea r3, [r2*3] + + ADD_RES_SSE_8_10 r0, r2, r3, r1 + lea r0, [r0+r2*4] + add r1, 64 + ADD_RES_SSE_8_10 r0, r2, r3, r1 + RET + +cglobal hevc_add_residual_16_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + + mov r4d, 8 +.loop: + ADD_RES_SSE_16_10 r0, r2, r1 + lea r0, [r0+r2*2] + add r1, 64 + dec r4d + jg .loop + RET + +cglobal hevc_add_residual_32_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + + mov r4d, 32 +.loop: + ADD_RES_SSE_32_10 r0, r1 + lea r0, [r0+r2] + add r1, 64 + dec r4d + jg .loop + RET + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal hevc_add_residual_16_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + lea r3, [r2*3] + + mov r4d, 4 +.loop: + ADD_RES_AVX2_16_10 r0, r2, r3, r1 + lea r0, [r0+r2*4] + add r1, 128 + dec r4d + jg .loop + RET + +cglobal hevc_add_residual_32_10, 3, 5, 6 + pxor m4, m4 + mova m5, [max_pixels_10] + + mov r4d, 16 +.loop: + ADD_RES_AVX2_32_10 r0, r2, r1 + lea r0, [r0+r2*2] + add r1, 128 + dec r4d + jg .loop + RET +%endif ;HAVE_AVX2_EXTERNAL diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_deblock.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_deblock.asm new file mode 100644 index 00000000..85ee4800 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_deblock.asm @@ -0,0 +1,871 @@ +;***************************************************************************** +;* SSE2-optimized HEVC deblocking code +;***************************************************************************** +;* Copyright (C) 2013 VTT +;* +;* Authors: Seppo Tomperi +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pw_1023 +%define pw_pixel_max_10 pw_1023 +pw_pixel_max_12: times 8 dw ((1 << 12)-1) +pw_m2: times 8 dw -2 +pd_1 : times 4 dd 1 + +cextern pw_4 +cextern pw_8 +cextern pw_m1 + +SECTION .text +INIT_XMM sse2 + +; in: 8 rows of 4 bytes in %4..%11 +; out: 4 rows of 8 words in m0..m3 +%macro TRANSPOSE4x8B_LOAD 8 + movd m0, %1 + movd m2, %2 + movd m1, %3 + movd m3, %4 + + punpcklbw m0, m2 + punpcklbw m1, m3 + punpcklwd m0, m1 + + movd m4, %5 + movd m6, %6 + movd m5, %7 + movd m3, %8 + + punpcklbw m4, m6 + punpcklbw m5, m3 + punpcklwd m4, m5 + + punpckhdq m2, m0, m4 + punpckldq m0, m4 + + pxor m5, m5 + punpckhbw m1, m0, m5 + punpcklbw m0, m5 + punpckhbw m3, m2, m5 + punpcklbw m2, m5 +%endmacro + +; in: 4 rows of 8 words in m0..m3 +; out: 8 rows of 4 bytes in %1..%8 +%macro TRANSPOSE8x4B_STORE 8 + packuswb m0, m2 + packuswb m1, m3 + SBUTTERFLY bw, 0, 1, 2 + SBUTTERFLY wd, 0, 1, 2 + + movd %1, m0 + pshufd m0, m0, 0x39 + movd %2, m0 + pshufd m0, m0, 0x39 + movd %3, m0 + pshufd m0, m0, 0x39 + movd %4, m0 + + movd %5, m1 + pshufd m1, m1, 0x39 + movd %6, m1 + pshufd m1, m1, 0x39 + movd %7, m1 + pshufd m1, m1, 0x39 + movd %8, m1 +%endmacro + +; in: 8 rows of 4 words in %4..%11 +; out: 4 rows of 8 words in m0..m3 +%macro TRANSPOSE4x8W_LOAD 8 + movq m0, %1 + movq m2, %2 + movq m1, %3 + movq m3, %4 + + punpcklwd m0, m2 + punpcklwd m1, m3 + punpckhdq m2, m0, m1 + punpckldq m0, m1 + + movq m4, %5 + movq m6, %6 + movq m5, %7 + movq m3, %8 + + punpcklwd m4, m6 + punpcklwd m5, m3 + punpckhdq m6, m4, m5 + punpckldq m4, m5 + + punpckhqdq m1, m0, m4 + punpcklqdq m0, m4 + punpckhqdq m3, m2, m6 + punpcklqdq m2, m6 + +%endmacro + +; in: 4 rows of 8 words in m0..m3 +; out: 8 rows of 4 words in %1..%8 +%macro TRANSPOSE8x4W_STORE 9 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + + pxor m5, m5; zeros reg + CLIPW m0, m5, %9 + CLIPW m1, m5, %9 + CLIPW m2, m5, %9 + CLIPW m3, m5, %9 + + movq %1, m0 + movhps %2, m0 + movq %3, m1 + movhps %4, m1 + movq %5, m2 + movhps %6, m2 + movq %7, m3 + movhps %8, m3 +%endmacro + +; in: 8 rows of 8 bytes in %1..%8 +; out: 8 rows of 8 words in m0..m7 +%macro TRANSPOSE8x8B_LOAD 8 + movq m7, %1 + movq m2, %2 + movq m1, %3 + movq m3, %4 + + punpcklbw m7, m2 + punpcklbw m1, m3 + punpcklwd m3, m7, m1 + punpckhwd m7, m1 + + movq m4, %5 + movq m6, %6 + movq m5, %7 + movq m15, %8 + + punpcklbw m4, m6 + punpcklbw m5, m15 + punpcklwd m9, m4, m5 + punpckhwd m4, m5 + + punpckldq m1, m3, m9; 0, 1 + punpckhdq m3, m9; 2, 3 + + punpckldq m5, m7, m4; 4, 5 + punpckhdq m7, m4; 6, 7 + + pxor m13, m13 + + punpcklbw m0, m1, m13; 0 in 16 bit + punpckhbw m1, m13; 1 in 16 bit + + punpcklbw m2, m3, m13; 2 + punpckhbw m3, m13; 3 + + punpcklbw m4, m5, m13; 4 + punpckhbw m5, m13; 5 + + punpcklbw m6, m7, m13; 6 + punpckhbw m7, m13; 7 +%endmacro + + +; in: 8 rows of 8 words in m0..m8 +; out: 8 rows of 8 bytes in %1..%8 +%macro TRANSPOSE8x8B_STORE 8 + packuswb m0, m4 + packuswb m1, m5 + packuswb m2, m6 + packuswb m3, m7 + TRANSPOSE2x4x4B 0, 1, 2, 3, 4 + + movq %1, m0 + movhps %2, m0 + movq %3, m1 + movhps %4, m1 + movq %5, m2 + movhps %6, m2 + movq %7, m3 + movhps %8, m3 +%endmacro + +; in: 8 rows of 8 words in %1..%8 +; out: 8 rows of 8 words in m0..m7 +%macro TRANSPOSE8x8W_LOAD 8 + movdqu m0, %1 + movdqu m1, %2 + movdqu m2, %3 + movdqu m3, %4 + movdqu m4, %5 + movdqu m5, %6 + movdqu m6, %7 + movdqu m7, %8 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 +%endmacro + +; in: 8 rows of 8 words in m0..m8 +; out: 8 rows of 8 words in %1..%8 +%macro TRANSPOSE8x8W_STORE 9 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 + + pxor m8, m8 + CLIPW m0, m8, %9 + CLIPW m1, m8, %9 + CLIPW m2, m8, %9 + CLIPW m3, m8, %9 + CLIPW m4, m8, %9 + CLIPW m5, m8, %9 + CLIPW m6, m8, %9 + CLIPW m7, m8, %9 + + movdqu %1, m0 + movdqu %2, m1 + movdqu %3, m2 + movdqu %4, m3 + movdqu %5, m4 + movdqu %6, m5 + movdqu %7, m6 + movdqu %8, m7 +%endmacro + + +; in: %2 clobbered +; out: %1 +; mask in m11 +; clobbers m10 +%macro MASKED_COPY 2 + pand %2, m11 ; and mask + pandn m10, m11, %1; and -mask + por %2, m10 + mova %1, %2 +%endmacro + +; in: %2 clobbered +; out: %1 +; mask in %3, will be clobbered +%macro MASKED_COPY2 3 + pand %2, %3 ; and mask + pandn %3, %1; and -mask + por %2, %3 + mova %1, %2 +%endmacro + +ALIGN 16 +; input in m0 ... m3 and tcs in r2. Output in m1 and m2 +%macro CHROMA_DEBLOCK_BODY 1 + psubw m4, m2, m1; q0 - p0 + psubw m5, m0, m3; p1 - q1 + psllw m4, 2; << 2 + paddw m5, m4; + + ;tc calculations + movq m6, [tcq]; tc0 + punpcklwd m6, m6 + pshufd m6, m6, 0xA0; tc0, tc1 +%if cpuflag(ssse3) + psignw m4, m6, [pw_m1]; -tc0, -tc1 +%else + pmullw m4, m6, [pw_m1]; -tc0, -tc1 +%endif + ;end tc calculations + + paddw m5, [pw_4]; +4 + psraw m5, 3; >> 3 + +%if %1 > 8 + psllw m4, %1-8; << (BIT_DEPTH - 8) + psllw m6, %1-8; << (BIT_DEPTH - 8) +%endif + pmaxsw m5, m4 + pminsw m5, m6 + paddw m1, m5; p0 + delta0 + psubw m2, m5; q0 - delta0 +%endmacro + +; input in m0 ... m7, beta in r2 tcs in r3. Output in m1...m6 +%macro LUMA_DEBLOCK_BODY 2 + psllw m9, m2, 1; *2 + psubw m10, m1, m9 + paddw m10, m3 + ABS1 m10, m11 ; 0dp0, 0dp3 , 1dp0, 1dp3 + + psllw m9, m5, 1; *2 + psubw m11, m6, m9 + paddw m11, m4 + ABS1 m11, m13 ; 0dq0, 0dq3 , 1dq0, 1dq3 + + ;beta calculations +%if %1 > 8 + shl betaq, %1 - 8 +%endif + movd m13, betad + SPLATW m13, m13, 0 + ;end beta calculations + + paddw m9, m10, m11; 0d0, 0d3 , 1d0, 1d3 + + pshufhw m14, m9, 0x0f ;0b00001111; 0d3 0d3 0d0 0d0 in high + pshuflw m14, m14, 0x0f ;0b00001111; 1d3 1d3 1d0 1d0 in low + + pshufhw m9, m9, 0xf0 ;0b11110000; 0d0 0d0 0d3 0d3 + pshuflw m9, m9, 0xf0 ;0b11110000; 1d0 1d0 1d3 1d3 + + paddw m14, m9; 0d0+0d3, 1d0+1d3 + + ;compare + pcmpgtw m15, m13, m14 + movmskps r13, m15 ;filtering mask 0d0 + 0d3 < beta0 (bit 2 or 3) , 1d0 + 1d3 < beta1 (bit 0 or 1) + test r13, r13 + je .bypassluma + + ;weak / strong decision compare to beta_2 + psraw m15, m13, 2; beta >> 2 + psllw m8, m9, 1; + pcmpgtw m15, m8; (d0 << 1) < beta_2, (d3 << 1) < beta_2 + movmskps r6, m15; + ;end weak / strong decision + + ; weak filter nd_p/q calculation + pshufd m8, m10, 0x31 + psrld m8, 16 + paddw m8, m10 + movd r7d, m8 + pshufd m8, m8, 0x4E + movd r8d, m8 + + pshufd m8, m11, 0x31 + psrld m8, 16 + paddw m8, m11 + movd r9d, m8 + pshufd m8, m8, 0x4E + movd r10d, m8 + ; end calc for weak filter + + ; filtering mask + mov r11, r13 + shr r11, 3 + movd m15, r11d + and r13, 1 + movd m11, r13d + shufps m11, m15, 0 + shl r11, 1 + or r13, r11 + + pcmpeqd m11, [pd_1]; filtering mask + + ;decide between strong and weak filtering + ;tc25 calculations + mov r11d, [tcq]; +%if %1 > 8 + shl r11, %1 - 8 +%endif + movd m8, r11d; tc0 + mov r3d, [tcq+4]; +%if %1 > 8 + shl r3, %1 - 8 +%endif + add r11d, r3d; tc0 + tc1 + jz .bypassluma + movd m9, r3d; tc1 + punpcklwd m8, m8 + punpcklwd m9, m9 + shufps m8, m9, 0; tc0, tc1 + mova m9, m8 + psllw m8, 2; tc << 2 + pavgw m8, m9; tc25 = ((tc * 5 + 1) >> 1) + ;end tc25 calculations + + ;----beta_3 comparison----- + psubw m12, m0, m3; p3 - p0 + ABS1 m12, m14; abs(p3 - p0) + + psubw m15, m7, m4; q3 - q0 + ABS1 m15, m14; abs(q3 - q0) + + paddw m12, m15; abs(p3 - p0) + abs(q3 - q0) + + pshufhw m12, m12, 0xf0 ;0b11110000; + pshuflw m12, m12, 0xf0 ;0b11110000; + + psraw m13, 3; beta >> 3 + pcmpgtw m13, m12; + movmskps r11, m13; + and r6, r11; strong mask , beta_2 and beta_3 comparisons + ;----beta_3 comparison end----- + ;----tc25 comparison--- + psubw m12, m3, m4; p0 - q0 + ABS1 m12, m14; abs(p0 - q0) + + pshufhw m12, m12, 0xf0 ;0b11110000; + pshuflw m12, m12, 0xf0 ;0b11110000; + + pcmpgtw m8, m12; tc25 comparisons + movmskps r11, m8; + and r6, r11; strong mask, beta_2, beta_3 and tc25 comparisons + ;----tc25 comparison end--- + mov r11, r6; + shr r11, 1; + and r6, r11; strong mask, bits 2 and 0 + + pmullw m14, m9, [pw_m2]; -tc * 2 + paddw m9, m9 + + and r6, 5; 0b101 + mov r11, r6; strong mask + shr r6, 2; + movd m12, r6d; store to xmm for mask generation + shl r6, 1 + and r11, 1 + movd m10, r11d; store to xmm for mask generation + or r6, r11; final strong mask, bits 1 and 0 + jz .weakfilter + + shufps m10, m12, 0 + pcmpeqd m10, [pd_1]; strong mask + + mova m13, [pw_4]; 4 in every cell + pand m11, m10; combine filtering mask and strong mask + paddw m12, m2, m3; p1 + p0 + paddw m12, m4; p1 + p0 + q0 + mova m10, m12; copy + paddw m12, m12; 2*p1 + 2*p0 + 2*q0 + paddw m12, m1; p2 + 2*p1 + 2*p0 + 2*q0 + paddw m12, m5; p2 + 2*p1 + 2*p0 + 2*q0 + q1 + paddw m12, m13; p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 + psraw m12, 3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) + psubw m12, m3; ((p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4) >> 3) - p0 + pmaxsw m12, m14 + pminsw m12, m9; av_clip( , -2 * tc, 2 * tc) + paddw m12, m3; p0' + + paddw m15, m1, m10; p2 + p1 + p0 + q0 + psrlw m13, 1; 2 in every cell + paddw m15, m13; p2 + p1 + p0 + q0 + 2 + psraw m15, 2; (p2 + p1 + p0 + q0 + 2) >> 2 + psubw m15, m2;((p2 + p1 + p0 + q0 + 2) >> 2) - p1 + pmaxsw m15, m14 + pminsw m15, m9; av_clip( , -2 * tc, 2 * tc) + paddw m15, m2; p1' + + paddw m8, m1, m0; p3 + p2 + paddw m8, m8; 2*p3 + 2*p2 + paddw m8, m1; 2*p3 + 3*p2 + paddw m8, m10; 2*p3 + 3*p2 + p1 + p0 + q0 + paddw m13, m13 + paddw m8, m13; 2*p3 + 3*p2 + p1 + p0 + q0 + 4 + psraw m8, 3; (2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3 + psubw m8, m1; ((2*p3 + 3*p2 + p1 + p0 + q0 + 4) >> 3) - p2 + pmaxsw m8, m14 + pminsw m8, m9; av_clip( , -2 * tc, 2 * tc) + paddw m8, m1; p2' + MASKED_COPY m1, m8 + + paddw m8, m3, m4; p0 + q0 + paddw m8, m5; p0 + q0 + q1 + paddw m8, m8; 2*p0 + 2*q0 + 2*q1 + paddw m8, m2; p1 + 2*p0 + 2*q0 + 2*q1 + paddw m8, m6; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + paddw m8, m13; p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4 + psraw m8, 3; (p1 + 2*p0 + 2*q0 + 2*q1 + q2 + 4) >>3 + psubw m8, m4; + pmaxsw m8, m14 + pminsw m8, m9; av_clip( , -2 * tc, 2 * tc) + paddw m8, m4; q0' + MASKED_COPY m2, m15 + + paddw m15, m3, m4; p0 + q0 + paddw m15, m5; p0 + q0 + q1 + mova m10, m15; + paddw m15, m6; p0 + q0 + q1 + q2 + psrlw m13, 1; 2 in every cell + paddw m15, m13; p0 + q0 + q1 + q2 + 2 + psraw m15, 2; (p0 + q0 + q1 + q2 + 2) >> 2 + psubw m15, m5; ((p0 + q0 + q1 + q2 + 2) >> 2) - q1 + pmaxsw m15, m14 + pminsw m15, m9; av_clip( , -2 * tc, 2 * tc) + paddw m15, m5; q1' + + paddw m13, m7; q3 + 2 + paddw m13, m6; q3 + q2 + 2 + paddw m13, m13; 2*q3 + 2*q2 + 4 + paddw m13, m6; 2*q3 + 3*q2 + 4 + paddw m13, m10; 2*q3 + 3*q2 + q1 + q0 + p0 + 4 + psraw m13, 3; (2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3 + psubw m13, m6; ((2*q3 + 3*q2 + q1 + q0 + p0 + 4) >> 3) - q2 + pmaxsw m13, m14 + pminsw m13, m9; av_clip( , -2 * tc, 2 * tc) + paddw m13, m6; q2' + + MASKED_COPY m6, m13 + MASKED_COPY m5, m15 + MASKED_COPY m4, m8 + MASKED_COPY m3, m12 + +.weakfilter: + not r6; strong mask -> weak mask + and r6, r13; final weak filtering mask, bits 0 and 1 + jz .store + + ; weak filtering mask + mov r11, r6 + shr r11, 1 + movd m12, r11d + and r6, 1 + movd m11, r6d + shufps m11, m12, 0 + pcmpeqd m11, [pd_1]; filtering mask + + mov r13, betaq + shr r13, 1; + add betaq, r13 + shr betaq, 3; ((beta + (beta >> 1)) >> 3)) + + mova m13, [pw_8] + psubw m12, m4, m3 ; q0 - p0 + psllw m10, m12, 3; 8 * (q0 - p0) + paddw m12, m10 ; 9 * (q0 - p0) + + psubw m10, m5, m2 ; q1 - p1 + psllw m8, m10, 1; 2 * ( q1 - p1 ) + paddw m10, m8; 3 * ( q1 - p1 ) + psubw m12, m10; 9 * (q0 - p0) - 3 * ( q1 - p1 ) + paddw m12, m13; + 8 + psraw m12, 4; >> 4 , delta0 + PABSW m13, m12; abs(delta0) + + + psllw m10, m9, 2; 8 * tc + paddw m10, m9; 10 * tc + pcmpgtw m10, m13 + pand m11, m10 + + psraw m9, 1; tc * 2 -> tc + psraw m14, 1; -tc * 2 -> -tc + + pmaxsw m12, m14 + pminsw m12, m9; av_clip(delta0, -tc, tc) + + psraw m9, 1; tc -> tc / 2 +%if cpuflag(ssse3) + psignw m14, m9, [pw_m1]; -tc / 2 +%else + pmullw m14, m9, [pw_m1]; -tc / 2 +%endif + + pavgw m15, m1, m3; (p2 + p0 + 1) >> 1 + psubw m15, m2; ((p2 + p0 + 1) >> 1) - p1 + paddw m15, m12; ((p2 + p0 + 1) >> 1) - p1 + delta0 + psraw m15, 1; (((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1 + pmaxsw m15, m14 + pminsw m15, m9; av_clip(deltap1, -tc/2, tc/2) + paddw m15, m2; p1' + + ;beta calculations + movd m10, betad + SPLATW m10, m10, 0 + + movd m13, r7d; 1dp0 + 1dp3 + movd m8, r8d; 0dp0 + 0dp3 + punpcklwd m8, m8 + punpcklwd m13, m13 + shufps m13, m8, 0; + pcmpgtw m8, m10, m13 + pand m8, m11 + ;end beta calculations + MASKED_COPY2 m2, m15, m8; write p1' + + pavgw m8, m6, m4; (q2 + q0 + 1) >> 1 + psubw m8, m5; ((q2 + q0 + 1) >> 1) - q1 + psubw m8, m12; ((q2 + q0 + 1) >> 1) - q1 - delta0) + psraw m8, 1; ((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1 + pmaxsw m8, m14 + pminsw m8, m9; av_clip(deltaq1, -tc/2, tc/2) + paddw m8, m5; q1' + + movd m13, r9d; + movd m15, r10d; + punpcklwd m15, m15 + punpcklwd m13, m13 + shufps m13, m15, 0; dq0 + dq3 + + pcmpgtw m10, m13; compare to ((beta+(beta>>1))>>3) + pand m10, m11 + MASKED_COPY2 m5, m8, m10; write q1' + + paddw m15, m3, m12 ; p0 + delta0 + MASKED_COPY m3, m15 + + psubw m8, m4, m12 ; q0 - delta0 + MASKED_COPY m4, m8 +%endmacro + +;----------------------------------------------------------------------------- +; void ff_hevc_v_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int32_t *tc, +; uint8_t *_no_p, uint8_t *_no_q); +;----------------------------------------------------------------------------- +%macro LOOP_FILTER_CHROMA 0 +cglobal hevc_v_loop_filter_chroma_8, 3, 5, 7, pix, stride, tc, pix0, r3stride + sub pixq, 2 + lea r3strideq, [3*strideq] + mov pix0q, pixq + add pixq, r3strideq + TRANSPOSE4x8B_LOAD PASS8ROWS(pix0q, pixq, strideq, r3strideq) + CHROMA_DEBLOCK_BODY 8 + TRANSPOSE8x4B_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq) + RET + +cglobal hevc_v_loop_filter_chroma_10, 3, 5, 7, pix, stride, tc, pix0, r3stride + sub pixq, 4 + lea r3strideq, [3*strideq] + mov pix0q, pixq + add pixq, r3strideq + TRANSPOSE4x8W_LOAD PASS8ROWS(pix0q, pixq, strideq, r3strideq) + CHROMA_DEBLOCK_BODY 10 + TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_10] + RET + +cglobal hevc_v_loop_filter_chroma_12, 3, 5, 7, pix, stride, tc, pix0, r3stride + sub pixq, 4 + lea r3strideq, [3*strideq] + mov pix0q, pixq + add pixq, r3strideq + TRANSPOSE4x8W_LOAD PASS8ROWS(pix0q, pixq, strideq, r3strideq) + CHROMA_DEBLOCK_BODY 12 + TRANSPOSE8x4W_STORE PASS8ROWS(pix0q, pixq, strideq, r3strideq), [pw_pixel_max_12] + RET + +;----------------------------------------------------------------------------- +; void ff_hevc_h_loop_filter_chroma(uint8_t *_pix, ptrdiff_t _stride, int32_t *tc, +; uint8_t *_no_p, uint8_t *_no_q); +;----------------------------------------------------------------------------- +cglobal hevc_h_loop_filter_chroma_8, 3, 4, 7, pix, stride, tc, pix0 + mov pix0q, pixq + sub pix0q, strideq + sub pix0q, strideq + movq m0, [pix0q]; p1 + movq m1, [pix0q+strideq]; p0 + movq m2, [pixq]; q0 + movq m3, [pixq+strideq]; q1 + pxor m5, m5; zeros reg + punpcklbw m0, m5 + punpcklbw m1, m5 + punpcklbw m2, m5 + punpcklbw m3, m5 + CHROMA_DEBLOCK_BODY 8 + packuswb m1, m2 + movh[pix0q+strideq], m1 + movhps [pixq], m1 + RET + +cglobal hevc_h_loop_filter_chroma_10, 3, 4, 7, pix, stride, tc, pix0 + mov pix0q, pixq + sub pix0q, strideq + sub pix0q, strideq + movu m0, [pix0q]; p1 + movu m1, [pix0q+strideq]; p0 + movu m2, [pixq]; q0 + movu m3, [pixq+strideq]; q1 + CHROMA_DEBLOCK_BODY 10 + pxor m5, m5; zeros reg + CLIPW m1, m5, [pw_pixel_max_10] + CLIPW m2, m5, [pw_pixel_max_10] + movu [pix0q+strideq], m1 + movu [pixq], m2 + RET + +cglobal hevc_h_loop_filter_chroma_12, 3, 4, 7, pix, stride, tc, pix0 + mov pix0q, pixq + sub pix0q, strideq + sub pix0q, strideq + movu m0, [pix0q]; p1 + movu m1, [pix0q+strideq]; p0 + movu m2, [pixq]; q0 + movu m3, [pixq+strideq]; q1 + CHROMA_DEBLOCK_BODY 12 + pxor m5, m5; zeros reg + CLIPW m1, m5, [pw_pixel_max_12] + CLIPW m2, m5, [pw_pixel_max_12] + movu [pix0q+strideq], m1 + movu [pixq], m2 + RET +%endmacro + +INIT_XMM sse2 +LOOP_FILTER_CHROMA +INIT_XMM avx +LOOP_FILTER_CHROMA + +%if ARCH_X86_64 +%macro LOOP_FILTER_LUMA 0 +;----------------------------------------------------------------------------- +; void ff_hevc_v_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta, +; int32_t *tc, uint8_t *_no_p, uint8_t *_no_q); +;----------------------------------------------------------------------------- +cglobal hevc_v_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride + sub pixq, 4 + lea pix0q, [3 * r1] + mov src3strideq, pixq + add pixq, pix0q + TRANSPOSE8x8B_LOAD PASS8ROWS(src3strideq, pixq, r1, pix0q) + LUMA_DEBLOCK_BODY 8, v +.store: + TRANSPOSE8x8B_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q) +.bypassluma: + RET + +cglobal hevc_v_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride + sub pixq, 8 + lea pix0q, [3 * strideq] + mov src3strideq, pixq + add pixq, pix0q + TRANSPOSE8x8W_LOAD PASS8ROWS(src3strideq, pixq, strideq, pix0q) + LUMA_DEBLOCK_BODY 10, v +.store: + TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_10] +.bypassluma: + RET + +cglobal hevc_v_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride + sub pixq, 8 + lea pix0q, [3 * strideq] + mov src3strideq, pixq + add pixq, pix0q + TRANSPOSE8x8W_LOAD PASS8ROWS(src3strideq, pixq, strideq, pix0q) + LUMA_DEBLOCK_BODY 12, v +.store: + TRANSPOSE8x8W_STORE PASS8ROWS(src3strideq, pixq, r1, pix0q), [pw_pixel_max_12] +.bypassluma: + RET + +;----------------------------------------------------------------------------- +; void ff_hevc_h_loop_filter_luma(uint8_t *_pix, ptrdiff_t _stride, int beta, +; int32_t *tc, uint8_t *_no_p, uint8_t *_no_q); +;----------------------------------------------------------------------------- +cglobal hevc_h_loop_filter_luma_8, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride + lea src3strideq, [3 * strideq] + mov pix0q, pixq + sub pix0q, src3strideq + sub pix0q, strideq + movq m0, [pix0q]; p3 + movq m1, [pix0q + strideq]; p2 + movq m2, [pix0q + 2 * strideq]; p1 + movq m3, [pix0q + src3strideq]; p0 + movq m4, [pixq]; q0 + movq m5, [pixq + strideq]; q1 + movq m6, [pixq + 2 * strideq]; q2 + movq m7, [pixq + src3strideq]; q3 + pxor m8, m8 + punpcklbw m0, m8 + punpcklbw m1, m8 + punpcklbw m2, m8 + punpcklbw m3, m8 + punpcklbw m4, m8 + punpcklbw m5, m8 + punpcklbw m6, m8 + punpcklbw m7, m8 + LUMA_DEBLOCK_BODY 8, h +.store: + packuswb m1, m2 + packuswb m3, m4 + packuswb m5, m6 + movh [pix0q + strideq], m1 + movhps [pix0q + 2 * strideq], m1 + movh [pix0q + src3strideq], m3 + movhps [pixq ], m3 + movh [pixq + strideq], m5 + movhps [pixq + 2 * strideq], m5 +.bypassluma: + RET + +cglobal hevc_h_loop_filter_luma_10, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride + lea src3strideq, [3 * strideq] + mov pix0q, pixq + sub pix0q, src3strideq + sub pix0q, strideq + movdqu m0, [pix0q]; p3 + movdqu m1, [pix0q + strideq]; p2 + movdqu m2, [pix0q + 2 * strideq]; p1 + movdqu m3, [pix0q + src3strideq]; p0 + movdqu m4, [pixq]; q0 + movdqu m5, [pixq + strideq]; q1 + movdqu m6, [pixq + 2 * strideq]; q2 + movdqu m7, [pixq + src3strideq]; q3 + LUMA_DEBLOCK_BODY 10, h +.store: + pxor m8, m8; zeros reg + CLIPW m1, m8, [pw_pixel_max_10] + CLIPW m2, m8, [pw_pixel_max_10] + CLIPW m3, m8, [pw_pixel_max_10] + CLIPW m4, m8, [pw_pixel_max_10] + CLIPW m5, m8, [pw_pixel_max_10] + CLIPW m6, m8, [pw_pixel_max_10] + movdqu [pix0q + strideq], m1; p2 + movdqu [pix0q + 2 * strideq], m2; p1 + movdqu [pix0q + src3strideq], m3; p0 + movdqu [pixq ], m4; q0 + movdqu [pixq + strideq], m5; q1 + movdqu [pixq + 2 * strideq], m6; q2 +.bypassluma: + RET + +cglobal hevc_h_loop_filter_luma_12, 4, 14, 16, pix, stride, beta, tc, pix0, src3stride + lea src3strideq, [3 * strideq] + mov pix0q, pixq + sub pix0q, src3strideq + sub pix0q, strideq + movdqu m0, [pix0q]; p3 + movdqu m1, [pix0q + strideq]; p2 + movdqu m2, [pix0q + 2 * strideq]; p1 + movdqu m3, [pix0q + src3strideq]; p0 + movdqu m4, [pixq]; q0 + movdqu m5, [pixq + strideq]; q1 + movdqu m6, [pixq + 2 * strideq]; q2 + movdqu m7, [pixq + src3strideq]; q3 + LUMA_DEBLOCK_BODY 12, h +.store: + pxor m8, m8; zeros reg + CLIPW m1, m8, [pw_pixel_max_12] + CLIPW m2, m8, [pw_pixel_max_12] + CLIPW m3, m8, [pw_pixel_max_12] + CLIPW m4, m8, [pw_pixel_max_12] + CLIPW m5, m8, [pw_pixel_max_12] + CLIPW m6, m8, [pw_pixel_max_12] + movdqu [pix0q + strideq], m1; p2 + movdqu [pix0q + 2 * strideq], m2; p1 + movdqu [pix0q + src3strideq], m3; p0 + movdqu [pixq ], m4; q0 + movdqu [pixq + strideq], m5; q1 + movdqu [pixq + 2 * strideq], m6; q2 +.bypassluma: + RET + +%endmacro + +INIT_XMM sse2 +LOOP_FILTER_LUMA +INIT_XMM ssse3 +LOOP_FILTER_LUMA +INIT_XMM avx +LOOP_FILTER_LUMA +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_idct.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_idct.asm new file mode 100644 index 00000000..1eb1973f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_idct.asm @@ -0,0 +1,853 @@ +;******************************************************************************* +;* SIMD-optimized IDCT functions for HEVC decoding +;* Copyright (c) 2014 Pierre-Edouard LEPERE +;* Copyright (c) 2014 James Almer +;* Copyright (c) 2016 Alexandra Hájková +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pd_64: times 4 dd 64 +pd_2048: times 4 dd 2048 +pd_512: times 4 dd 512 + +; 4x4 transform coeffs +cextern pw_64 +pw_64_m64: times 4 dw 64, -64 +pw_83_36: times 4 dw 83, 36 +pw_36_m83: times 4 dw 36, -83 + +; 8x8 transform coeffs +pw_89_75: times 4 dw 89, 75 +pw_50_18: times 4 dw 50, 18 + +pw_75_m18: times 4 dw 75, -18 +pw_m89_m50: times 4 dw -89, -50 + +pw_50_m89: times 4 dw 50, -89 +pw_18_75: times 4 dw 18, 75 + +pw_18_m50: times 4 dw 18, -50 +pw_75_m89: times 4 dw 75, -89 + +; 16x16 transformation coeffs +trans_coeffs16: times 4 dw 90, 87 +times 4 dw 80, 70 +times 4 dw 57, 43 +times 4 dw 25, 9 + +times 4 dw 87, 57 +times 4 dw 9, -43 +times 4 dw -80, -90 +times 4 dw -70, -25 + +times 4 dw 80, 9 +times 4 dw -70, -87 +times 4 dw -25, 57 +times 4 dw 90, 43 + +times 4 dw 70, -43 +times 4 dw -87, 9 +times 4 dw 90, 25 +times 4 dw -80, -57 + +times 4 dw 57, -80 +times 4 dw -25, 90 +times 4 dw -9, -87 +times 4 dw 43, 70 + +times 4 dw 43, -90 +times 4 dw 57, 25 +times 4 dw -87, 70 +times 4 dw 9, -80 + +times 4 dw 25, -70 +times 4 dw 90, -80 +times 4 dw 43, 9 +times 4 dw -57, 87 + +times 4 dw 9, -25 +times 4 dw 43, -57 +times 4 dw 70, -80 +times 4 dw 87, -90 + +; 32x32 transform coeffs +trans_coeff32: times 8 dw 90 +times 4 dw 88, 85 +times 4 dw 82, 78 +times 4 dw 73, 67 +times 4 dw 61, 54 +times 4 dw 46, 38 +times 4 dw 31, 22 +times 4 dw 13, 4 + +times 4 dw 90, 82 +times 4 dw 67, 46 +times 4 dw 22, -4 +times 4 dw -31, -54 +times 4 dw -73, -85 +times 4 dw -90, -88 +times 4 dw -78, -61 +times 4 dw -38, -13 + +times 4 dw 88, 67 +times 4 dw 31, -13 +times 4 dw -54, -82 +times 4 dw -90, -78 +times 4 dw -46, -4 +times 4 dw 38, 73 +times 4 dw 90, 85 +times 4 dw 61, 22 + +times 4 dw 85, 46 +times 4 dw -13, -67 +times 4 dw -90, -73 +times 4 dw -22, 38 +times 4 dw 82, 88 +times 4 dw 54, -4 +times 4 dw -61, -90 +times 4 dw -78, -31 + +times 4 dw 82, 22 +times 4 dw -54, -90 +times 4 dw -61, 13 +times 4 dw 78, 85 +times 4 dw 31, -46 +times 4 dw -90, -67 +times 4 dw 4, 73 +times 4 dw 88, 38 + +times 4 dw 78, -4 +times 4 dw -82, -73 +times 4 dw 13, 85 +times 4 dw 67, -22 +times 4 dw -88, -61 +times 4 dw 31, 90 +times 4 dw 54, -38 +times 4 dw -90, -46 + +times 4 dw 73, -31 +times 4 dw -90, -22 +times 4 dw 78, 67 +times 4 dw -38, -90 +times 4 dw -13, 82 +times 4 dw 61, -46 +times 4 dw -88, -4 +times 4 dw 85, 54 + +times 4 dw 67, -54 +times 4 dw -78, 38 +times 4 dw 85, -22 +times 4 dw -90, 4 +times 4 dw 90, 13 +times 4 dw -88, -31 +times 4 dw 82, 46 +times 4 dw -73, -61 + +times 4 dw 61, -73 +times 4 dw -46, 82 +times 4 dw 31, -88 +times 4 dw -13, 90 +times 4 dw -4, -90 +times 4 dw 22, 85 +times 4 dw -38, -78 +times 4 dw 54, 67 + +times 4 dw 54, -85 +times 4 dw -4, 88 +times 4 dw -46, -61 +times 4 dw 82, 13 +times 4 dw -90, 38 +times 4 dw 67, -78 +times 4 dw -22, 90 +times 4 dw -31, -73 + +times 4 dw 46, -90 +times 4 dw 38, 54 +times 4 dw -90, 31 +times 4 dw 61, -88 +times 4 dw 22, 67 +times 4 dw -85, 13 +times 4 dw 73, -82 +times 4 dw 4, 78 + +times 4 dw 38, -88 +times 4 dw 73, -4 +times 4 dw -67, 90 +times 4 dw -46, -31 +times 4 dw 85, -78 +times 4 dw 13, 61 +times 4 dw -90, 54 +times 4 dw 22, -82 + +times 4 dw 31, -78 +times 4 dw 90, -61 +times 4 dw 4, 54 +times 4 dw -88, 82 +times 4 dw -38, -22 +times 4 dw 73, -90 +times 4 dw 67, -13 +times 4 dw -46, 85 + +times 4 dw 22, -61 +times 4 dw 85, -90 +times 4 dw 73, -38 +times 4 dw -4, 46 +times 4 dw -78, 90 +times 4 dw -82, 54 +times 4 dw -13, -31 +times 4 dw 67, -88 + +times 4 dw 13, -38 +times 4 dw 61, -78 +times 4 dw 88, -90 +times 4 dw 85, -73 +times 4 dw 54, -31 +times 4 dw 4, 22 +times 4 dw -46, 67 +times 4 dw -82, 90 + +times 4 dw 4, -13 +times 4 dw 22, -31 +times 4 dw 38, -46 +times 4 dw 54, -61 +times 4 dw 67, -73 +times 4 dw 78, -82 +times 4 dw 85, -88 +times 4 dw 90, -90 + +SECTION .text + +; void ff_hevc_idct_HxW_dc_{8,10}_(int16_t *coeffs) +; %1 = HxW +; %2 = number of loops +; %3 = bitdepth +%macro IDCT_DC 3 +cglobal hevc_idct_%1x%1_dc_%3, 1, 2, 1, coeff, tmp + movsx tmpd, word [coeffq] + add tmpd, (1 << (14 - %3)) + 1 + sar tmpd, (15 - %3) + movd xm0, tmpd + SPLATW m0, xm0 + DEFINE_ARGS coeff, cnt + mov cntd, %2 +.loop: + mova [coeffq+mmsize*0], m0 + mova [coeffq+mmsize*1], m0 + mova [coeffq+mmsize*2], m0 + mova [coeffq+mmsize*3], m0 + add coeffq, mmsize*8 + mova [coeffq+mmsize*-4], m0 + mova [coeffq+mmsize*-3], m0 + mova [coeffq+mmsize*-2], m0 + mova [coeffq+mmsize*-1], m0 + dec cntd + jg .loop + RET +%endmacro + +; %1 = HxW +; %2 = bitdepth +%macro IDCT_DC_NL 2 ; No loop +cglobal hevc_idct_%1x%1_dc_%2, 1, 2, 1, coeff, tmp + movsx tmpd, word [coeffq] + add tmpd, (1 << (14 - %2)) + 1 + sar tmpd, (15 - %2) + movd m0, tmpd + SPLATW m0, xm0 + mova [coeffq+mmsize*0], m0 + mova [coeffq+mmsize*1], m0 + mova [coeffq+mmsize*2], m0 + mova [coeffq+mmsize*3], m0 +%if mmsize == 16 + mova [coeffq+mmsize*4], m0 + mova [coeffq+mmsize*5], m0 + mova [coeffq+mmsize*6], m0 + mova [coeffq+mmsize*7], m0 +%endif + RET +%endmacro + +; IDCT 4x4, expects input in m0, m1 +; %1 - shift +; %2 - 1/0 - SCALE and Transpose or not +; %3 - 1/0 add constant or not +%macro TR_4x4 3 + ; interleaves src0 with src2 to m0 + ; and src1 with scr3 to m2 + ; src0: 00 01 02 03 m0: 00 20 01 21 02 22 03 23 + ; src1: 10 11 12 13 --> + ; src2: 20 21 22 23 m1: 10 30 11 31 12 32 13 33 + ; src3: 30 31 32 33 + + SBUTTERFLY wd, 0, 1, 2 + + pmaddwd m2, m0, [pw_64] ; e0 + pmaddwd m3, m1, [pw_83_36] ; o0 + pmaddwd m0, [pw_64_m64] ; e1 + pmaddwd m1, [pw_36_m83] ; o1 + +%if %3 == 1 + %assign %%add 1 << (%1 - 1) + mova m4, [pd_ %+ %%add] + paddd m2, m4 + paddd m0, m4 +%endif + + SUMSUB_BADC d, 3, 2, 1, 0, 4 + +%if %2 == 1 + psrad m3, %1 ; e0 + o0 + psrad m1, %1 ; e1 + o1 + psrad m2, %1 ; e0 - o0 + psrad m0, %1 ; e1 - o1 + ;clip16 + packssdw m3, m1 + packssdw m0, m2 + ; Transpose + SBUTTERFLY wd, 3, 0, 1 + SBUTTERFLY wd, 3, 0, 1 + SWAP 3, 1, 0 +%else + SWAP 3, 2, 0 +%endif +%endmacro + +%macro DEFINE_BIAS 1 + %assign shift (20 - %1) + %assign c_add (1 << (shift - 1)) + %define arr_add pd_ %+ c_add +%endmacro + +; %1 - bit_depth +; %2 - register add constant +; is loaded to +; shift = 20 - bit_depth +%macro LOAD_BIAS 2 + DEFINE_BIAS %1 + mova %2, [arr_add] +%endmacro + +; %1, %2 - registers to load packed 16 bit values to +; %3, %4, %5, %6 - vertical offsets +; %7 - horizontal offset +%macro LOAD_BLOCK 7 + movq %1, [r0 + %3 + %7] + movhps %1, [r0 + %5 + %7] + movq %2, [r0 + %4 + %7] + movhps %2, [r0 + %6 + %7] +%endmacro + +; void ff_hevc_idct_4x4__{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_4x4 1 +cglobal hevc_idct_4x4_%1, 1, 1, 5, coeffs + mova m0, [coeffsq] + mova m1, [coeffsq + 16] + + TR_4x4 7, 1, 1 + TR_4x4 20 - %1, 1, 1 + + mova [coeffsq], m0 + mova [coeffsq + 16], m1 + RET +%endmacro + +; scale, pack (clip16) and store the residuals 0 e8[0] + o8[0] --> + %1 +; 4 at one time (4 columns) 1 e8[1] + o8[1] +; from %5: e8/16 + o8/16, with %1 offset ... +; and %3: e8/16 - o8/16, with %2 offset 6 e8[1] - o8[1] +; %4 - shift 7 e8[0] - o8[0] --> + %2 +%macro STORE_8 7 + psrad %5, %4 + psrad %3, %4 + packssdw %5, %3 + movq [coeffsq + %1], %5 + movhps [coeffsq + %2], %5 +%endmacro + +; %1 - horizontal offset +; %2 - shift +; %3, %4 - transform coeffs +; %5 - vertical offset for e8 + o8 +; %6 - vertical offset for e8 - o8 +; %7 - register with e8 inside +; %8 - block_size +; %9 - register to store e8 +o8 +; %10 - register to store e8 - o8 +%macro E8_O8 10 + pmaddwd m6, m4, %3 + pmaddwd m7, m5, %4 + + paddd m6, m7 + paddd m7, m6, %7 ; o8 + e8 + psubd %7, m6 ; e8 - o8 +%if %8 == 8 + STORE_8 %5 + %1, %6 + %1, %7, %2, m7, 0, 0 +%else + SWAP m7, %9 + SWAP %7, %10 +%endif +%endmacro + +; 8x4 residuals are processed and stored +; %1 - horizontal offset +; %2 - shift +; %3 - offset of the even row +; %4 - step: 1 for 8x8, 2 for 16x16, 4 for 32x32 +; %5 - offset of the odd row +; %6 - block size +; %7 - 1/0 add a constant in TR_4x4 or not +; I want to add a constant for 8x8 transform but not for 16x16 and 32x32 +%macro TR_8x4 7 + ; load 4 columns of even rows + LOAD_BLOCK m0, m1, 0, 2 * %4 * %3, %4 * %3, 3 * %4 * %3, %1 + + TR_4x4 %2, 0, %7 ; e8: m0, m1, m2, m3, for 4 columns only + + ; load 4 columns of odd rows + LOAD_BLOCK m4, m5, %4 * %5, 3 * %4 * %5, 5 * %4 * %5, 7 * %4 * %5, %1 + + ; 00 01 02 03 + ; 10 11 12 13 m4: 10 30 11 31 12 32 13 33 + + ; ... -- > + ; m5: 50 70 51 71 52 72 53 73 + ; 70 71 72 73 + SBUTTERFLY wd, 4, 5, 6 + + E8_O8 %1, %2, [pw_89_75], [pw_50_18], 0, %5 * 7, m0, %6, m8, m15 + E8_O8 %1, %2, [pw_75_m18], [pw_m89_m50], %5, %5 * 6, m1, %6, m9, m14 + E8_O8 %1, %2, [pw_50_m89], [pw_18_75], %5 * 2, %5 * 5, m2, %6, m10, m13 + E8_O8 %1, %2, [pw_18_m50], [pw_75_m89], %5 * 3, %5 * 4, m3, %6, m11, m12 +%endmacro + +%macro STORE_PACKED 7 + movq [r0 + %3 + %7], %1 + movhps [r0 + %4 + %7], %1 + movq [r0 + %5 + %7], %2 + movhps [r0 + %6 + %7], %2 +%endmacro + +; transpose 4x4 block packed +; in %1 and %2 registers +; %3 - temporary register +%macro TRANSPOSE_4x4 3 + SBUTTERFLY wd, %1, %2, %3 + SBUTTERFLY dq, %1, %2, %3 +%endmacro + +; %1 - horizontal offset of the block i +; %2 - vertical offset of the block i +; %3 - width in bytes +; %4 - vertical offset for the block j +; %5 - horizontal offset for the block j +%macro SWAP_BLOCKS 5 + ; M_j + LOAD_BLOCK m4, m5, %4, %4 + %3, %4 + 2 * %3, %4 + 3 * %3, %5 + TRANSPOSE_4x4 4, 5, 6 + + ; M_i + LOAD_BLOCK m6, m7, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 + + STORE_PACKED m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 + + ; transpose and store M_i + SWAP m6, m4 + SWAP m7, m5 + TRANSPOSE_4x4 4, 5, 6 + STORE_PACKED m4, m5, %4, %4 + %3, %4 + 2 * %3, %4 + 3 * %3, %5 +%endmacro + +; %1 - horizontal offset +; %2 - vertical offset of the block +; %3 - width in bytes +%macro TRANSPOSE_BLOCK 3 + LOAD_BLOCK m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 + TRANSPOSE_4x4 4, 5, 6 + STORE_PACKED m4, m5, %2, %2 + %3, %2 + 2 * %3, %2 + 3 * %3, %1 +%endmacro + +%macro TRANSPOSE_8x8 0 +cglobal hevc_idct_transpose_8x8, 0, 0, 0 + ; M1 M2 ^T = M1^t M3^t + ; M3 M4 M2^t M4^t + + ; M1 4x4 block + TRANSPOSE_BLOCK 0, 0, 16 + + ; M2 and M3 + SWAP_BLOCKS 0, 64, 16, 0, 8 + + ; M4 + TRANSPOSE_BLOCK 8, 64, 16 + + ret +%endmacro + +; void ff_hevc_idct_8x8_{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_8x8 1 +cglobal hevc_idct_8x8_%1, 1, 1, 8, coeffs + TR_8x4 0, 7, 32, 1, 16, 8, 1 + TR_8x4 8, 7, 32, 1, 16, 8, 1 + + call hevc_idct_transpose_8x8_ %+ cpuname + + DEFINE_BIAS %1 + TR_8x4 0, shift, 32, 1, 16, 8, 1 + TR_8x4 8, shift, 32, 1, 16, 8, 1 + + TAIL_CALL hevc_idct_transpose_8x8_ %+ cpuname, 1 +%endmacro + +; store intermedite e32 coeffs on stack +; as 16x4 matrix +; from m10: e8 + o8, with %6 offset +; and %3: e8 - o8, with %7 offset +; %4 - shift, unused here +%macro STORE_16 7 + mova [rsp + %6], %5 + mova [rsp + %7], %3 +%endmacro + +; %1, %2 - transform constants +; %3, %4 - regs with interleaved coeffs +; %5 - 1/0 SWAP or add +; %6, %7 - registers for intermidiate sums +; %8 - accumulator register +%macro ADD_ROWS 8 + pmaddwd %6, %3, %1 + pmaddwd %7, %4, %2 + paddd %6, %7 +%if %5 == 1 + SWAP %6, %8 +%else + paddd %8, %6 +%endif +%endmacro + +; %1 - transform coeffs +; %2, %3 offsets for storing e+o/e-o back to coeffsq +; %4 - shift +; %5 - add +; %6 - block_size +; %7 - register with e16 +; %8, %9 - stack offsets for storing e+o/e-o +%macro E16_O16 9 + ADD_ROWS [%1], [%1 + 16], m0, m1, 1, m5, m6, m7 + ADD_ROWS [%1 + 2 * 16], [%1 + 3 * 16], m2, m3, 0, m5, m6, m7 + +%if %6 == 8 + paddd %7, %5 +%endif + + paddd m4, m7, %7 ; o16 + e16 + psubd %7, m7 ; e16 - o16 + STORE_%6 %2, %3, %7, %4, m4, %8, %9 +%endmacro + +%macro TR_16x4 10 + ; produce 8x4 matrix of e16 coeffs + ; for 4 first rows and store it on stack (128 bytes) + TR_8x4 %1, 7, %4, %5, %6, %8, 0 + + ; load 8 even rows + LOAD_BLOCK m0, m1, %9 * %6, %9 * 3 * %6, %9 * 5 * %6, %9 * 7 * %6, %1 + LOAD_BLOCK m2, m3, %9 * 9 * %6, %9 * 11 * %6, %9 * 13 * %6, %9 * 15 * %6, %1 + + SBUTTERFLY wd, 0, 1, 4 + SBUTTERFLY wd, 2, 3, 4 + + E16_O16 trans_coeffs16, 0 + %1, 15 * %6 + %1, %2, %3, %7, m8, 0, 15 * 16 + mova m8, %3 + E16_O16 trans_coeffs16 + 64, %6 + %1, 14 * %6 + %1, %2, m8, %7, m9, 16, 14 * 16 + E16_O16 trans_coeffs16 + 2 * 64, 2 * %6 + %1, 13 * %6 + %1, %2, m8, %7, m10, 2 * 16, 13 * 16 + E16_O16 trans_coeffs16 + 3 * 64, 3 * %6 + %1, 12 * %6 + %1, %2, m8, %7, m11, 3 * 16, 12 * 16 + E16_O16 trans_coeffs16 + 4 * 64, 4 * %6 + %1, 11 * %6 + %1, %2, m8, %7, m12, 4 * 16, 11 * 16 + E16_O16 trans_coeffs16 + 5 * 64, 5 * %6 + %1, 10 * %6 + %1, %2, m8, %7, m13, 5 * 16, 10 * 16 + E16_O16 trans_coeffs16 + 6 * 64, 6 * %6 + %1, 9 * %6 + %1, %2, m8, %7, m14, 6 * 16, 9 * 16 + E16_O16 trans_coeffs16 + 7 * 64, 7 * %6 + %1, 8 * %6 + %1, %2, m8, %7, m15, 7 * 16, 8 * 16 +%endmacro + +%macro TRANSPOSE_16x16 0 +cglobal hevc_idct_transpose_16x16, 0, 0, 0 +; M1 M2 M3 M4 ^T m1 m5 m9 m13 M_i^T = m_i +; M5 M6 M7 M8 --> m2 m6 m10 m14 +; M9 M10 M11 M12 m3 m7 m11 m15 +; M13 M14 M15 M16 m4 m8 m12 m16 + + ; M1 4x4 block + TRANSPOSE_BLOCK 0, 0, 32 + + ; M5, M2 + SWAP_BLOCKS 0, 128, 32, 0, 8 + ; M9, M3 + SWAP_BLOCKS 0, 256, 32, 0, 16 + ; M13, M4 + SWAP_BLOCKS 0, 384, 32, 0, 24 + + ;M6 + TRANSPOSE_BLOCK 8, 128, 32 + + ; M10, M7 + SWAP_BLOCKS 8, 256, 32, 128, 16 + ; M14, M8 + SWAP_BLOCKS 8, 384, 32, 128, 24 + + ;M11 + TRANSPOSE_BLOCK 16, 256, 32 + + ; M15, M12 + SWAP_BLOCKS 16, 384, 32, 256, 24 + + ;M16 + TRANSPOSE_BLOCK 24, 384, 32 + + ret +%endmacro + +; void ff_hevc_idct_16x16_{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_16x16 1 +cglobal hevc_idct_16x16_%1, 1, 2, 16, coeffs + mov r1d, 3 +.loop16: + TR_16x4 8 * r1, 7, [pd_64], 64, 2, 32, 8, 16, 1, 0 + dec r1d + jge .loop16 + + call hevc_idct_transpose_16x16_ %+ cpuname + + DEFINE_BIAS %1 + mov r1d, 3 +.loop16_2: + TR_16x4 8 * r1, shift, [arr_add], 64, 2, 32, 8, 16, 1, 1 + dec r1d + jge .loop16_2 + + TAIL_CALL hevc_idct_transpose_16x16_ %+ cpuname, 1 +%endmacro + +; scale, pack (clip16) and store the residuals 0 e32[0] + o32[0] --> %1 +; 4 at one time (4 columns) 1 e32[1] + o32[1] +; %1 - address to store e32 + o32 +; %2 - address to store e32 - e32 +; %5 - reg with e32 + o32 ... +; %3 - reg with e32 - o32 30 e32[1] - o32[1] +; %4 - shift 31 e32[0] - o32[0] --> %2 +%macro STORE_32 5 + psrad %5, %4 + psrad %3, %4 + packssdw %5, %3 + movq [%1], %5 + movhps [%2], %5 +%endmacro + +; %1 - transform coeffs +; %2 - stack offset for e32 +; %2, %3 offsets for storing e+o/e-o back to coeffsq +; %4 - shift +; %5 - stack offset of e32 +%macro E32_O32 5 + ADD_ROWS [%1], [%1 + 16], m0, m1, 1, m8, m9, m10 + ADD_ROWS [%1 + 2 * 16], [%1 + 3 * 16], m2, m3, 0, m8, m9, m10 + ADD_ROWS [%1 + 4 * 16], [%1 + 5 * 16], m4, m5, 0, m8, m9, m10 + ADD_ROWS [%1 + 6 * 16], [%1 + 7 * 16], m6, m7, 0, m8, m9, m10 + + paddd m11, m14, [rsp + %5] + paddd m12, m10, m11 ; o32 + e32 + psubd m11, m10 ; e32 - o32 + STORE_32 %2, %3, m11, %4, m12 +%endmacro + +; %1 - horizontal offset +; %2 - bitdepth +%macro TR_32x4 3 + TR_16x4 %1, 7, [pd_64], 128, 4, 64, 16, 16, 2, 0 + + LOAD_BLOCK m0, m1, 64, 3 * 64, 5 * 64, 7 * 64, %1 + LOAD_BLOCK m2, m3, 9 * 64, 11 * 64, 13 * 64, 15 * 64, %1 + LOAD_BLOCK m4, m5, 17 * 64, 19 * 64, 21 * 64, 23 * 64, %1 + LOAD_BLOCK m6, m7, 25 * 64, 27 * 64, 29 * 64, 31 * 64, %1 + + SBUTTERFLY wd, 0, 1, 8 + SBUTTERFLY wd, 2, 3, 8 + SBUTTERFLY wd, 4, 5, 8 + SBUTTERFLY wd, 6, 7, 8 + +%if %3 == 1 + %assign shift 7 + mova m14, [pd_64] +%else + LOAD_BIAS %2, m14 +%endif + + lea r2, [trans_coeff32 + 15 * 128] + lea r3, [coeffsq + %1] + lea r4, [r3 + 16 * 64] + mov r5d, 15 * 16 +%%loop: + E32_O32 r2, r3 + r5 * 4, r4, shift, r5 + sub r2, 128 + add r4, 64 + sub r5d, 16 + jge %%loop +%endmacro + +%macro TRANSPOSE_32x32 0 +cglobal hevc_idct_transpose_32x32, 0, 0, 0 + ; M0 M1 ... M7 + ; M8 M15 + ; + ; ... + ; + ; M56 M63 + + TRANSPOSE_BLOCK 0, 0, 64 ; M1 + mov r1d, 7 + mov r2d, 7 * 256 +.loop_transpose: + SWAP_BLOCKS 0, r2, 64, 0, r1 * 8 + sub r2d, 256 + dec r1d + jg .loop_transpose + + TRANSPOSE_BLOCK 8, 256, 64 ; M9 + mov r1d, 6 + mov r2d, 512 + mov r3d, 16 +.loop_transpose2: + SWAP_BLOCKS 8, r2, 64, 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose2 + + TRANSPOSE_BLOCK 2 * 8, 2 * 256, 64 ; M9 + mov r1d, 5 + mov r2d, 768 + mov r3d, 24 +.loop_transpose3: + SWAP_BLOCKS 2 * 8, r2, 64, 2 * 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose3 + + TRANSPOSE_BLOCK 3 * 8, 3 * 256, 64 ; M27 + mov r1d, 4 + mov r2d, 1024 + mov r3d, 32 +.loop_transpose4: + SWAP_BLOCKS 3 * 8, r2, 64, 3 * 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose4 + + TRANSPOSE_BLOCK 4 * 8, 4 * 256, 64 ; M36 + mov r1d, 3 + mov r2d, 1280 + mov r3d, 40 +.loop_transpose5: + SWAP_BLOCKS 4 * 8, r2, 64, 4 * 256, r3 + add r3d, 8 + add r2d, 256 + dec r1d + jg .loop_transpose5 + + TRANSPOSE_BLOCK 5 * 8, 5 * 256, 64 ; M45 + SWAP_BLOCKS 5 * 8, 6 * 256, 64, 5 * 256, 6 * 8 + SWAP_BLOCKS 5 * 8, 7 * 256, 64, 5 * 256, 7 * 8 + + TRANSPOSE_BLOCK 6 * 8, 6 * 256, 64 ; M54 + SWAP_BLOCKS 6 * 8, 7 * 256, 64, 6 * 256, 7 * 8 + + TRANSPOSE_BLOCK 7 * 8, 7 * 256, 64 ; M63 + + ret +%endmacro + +; void ff_hevc_idct_32x32_{8,10}_(int16_t *coeffs, int col_limit) +; %1 = bitdepth +%macro IDCT_32x32 1 +cglobal hevc_idct_32x32_%1, 1, 6, 16, 256, coeffs + mov r1d, 7 +.loop32: + TR_32x4 8 * r1, %1, 1 + dec r1d + jge .loop32 + + call hevc_idct_transpose_32x32_ %+ cpuname + + mov r1d, 7 +.loop32_2: + TR_32x4 8 * r1, %1, 0 + dec r1d + jge .loop32_2 + + TAIL_CALL hevc_idct_transpose_32x32_ %+ cpuname, 1 +%endmacro + +%macro INIT_IDCT_DC 1 +INIT_MMX mmxext +IDCT_DC_NL 4, %1 +IDCT_DC 8, 2, %1 + +INIT_XMM sse2 +IDCT_DC_NL 8, %1 +IDCT_DC 16, 4, %1 +IDCT_DC 32, 16, %1 + +%if HAVE_AVX2_EXTERNAL + INIT_YMM avx2 + IDCT_DC 16, 2, %1 + IDCT_DC 32, 8, %1 +%endif ;HAVE_AVX2_EXTERNAL +%endmacro + +%macro INIT_IDCT 2 +INIT_XMM %2 +%if %1 == 8 + TRANSPOSE_8x8 + %if ARCH_X86_64 + TRANSPOSE_16x16 + TRANSPOSE_32x32 + %endif +%endif +%if ARCH_X86_64 + IDCT_32x32 %1 + IDCT_16x16 %1 +%endif +IDCT_8x8 %1 +IDCT_4x4 %1 +%endmacro + +INIT_IDCT_DC 8 +INIT_IDCT_DC 10 +INIT_IDCT_DC 12 +INIT_IDCT 8, sse2 +INIT_IDCT 8, avx +INIT_IDCT 10, sse2 +INIT_IDCT 10, avx +;INIT_IDCT 12, sse2 +;INIT_IDCT 12, avx diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_mc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_mc.asm new file mode 100644 index 00000000..ff6ed071 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_mc.asm @@ -0,0 +1,1672 @@ +; /* +; * Provide SSE luma and chroma mc functions for HEVC decoding +; * Copyright (c) 2013 Pierre-Edouard LEPERE +; * +; * 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 +cextern pw_255 +cextern pw_512 +cextern pw_2048 +cextern pw_8192 +cextern pw_1023 +cextern pw_1024 +cextern pw_4096 +%define pw_8 pw_512 +%define pw_10 pw_2048 +%define pw_12 pw_8192 +%define pw_bi_10 pw_1024 +%define pw_bi_12 pw_4096 +%define max_pixels_8 pw_255 +%define max_pixels_10 pw_1023 +pw_bi_8: times 16 dw (1 << 8) +max_pixels_12: times 16 dw ((1 << 12)-1) +cextern pd_1 +cextern pb_0 + +%macro EPEL_TABLE 4 +hevc_epel_filters_%4_%1 times %2 d%3 -2, 58 + times %2 d%3 10, -2 + times %2 d%3 -4, 54 + times %2 d%3 16, -2 + times %2 d%3 -6, 46 + times %2 d%3 28, -4 + times %2 d%3 -4, 36 + times %2 d%3 36, -4 + times %2 d%3 -4, 28 + times %2 d%3 46, -6 + times %2 d%3 -2, 16 + times %2 d%3 54, -4 + times %2 d%3 -2, 10 + times %2 d%3 58, -2 +%endmacro + + +EPEL_TABLE 8,16, b, avx2 +EPEL_TABLE 10, 8, w, avx2 + +EPEL_TABLE 8, 8, b, sse4 +EPEL_TABLE 10, 4, w, sse4 +EPEL_TABLE 12, 4, w, sse4 + +%macro QPEL_TABLE 4 +hevc_qpel_filters_%4_%1 times %2 d%3 -1, 4 + times %2 d%3 -10, 58 + times %2 d%3 17, -5 + times %2 d%3 1, 0 + times %2 d%3 -1, 4 + times %2 d%3 -11, 40 + times %2 d%3 40,-11 + times %2 d%3 4, -1 + times %2 d%3 0, 1 + times %2 d%3 -5, 17 + times %2 d%3 58,-10 + times %2 d%3 4, -1 +%endmacro + +QPEL_TABLE 8, 8, b, sse4 +QPEL_TABLE 10, 4, w, sse4 +QPEL_TABLE 12, 4, w, sse4 + +QPEL_TABLE 8,16, b, avx2 +QPEL_TABLE 10, 8, w, avx2 + +SECTION .text + +%define MAX_PB_SIZE 64 + +%define hevc_qpel_filters_sse4_14 hevc_qpel_filters_sse4_10 + +%define hevc_qpel_filters_avx2_14 hevc_qpel_filters_avx2_10 + +%if ARCH_X86_64 + +%macro SIMPLE_BILOAD 4 ;width, tab, r1, r2 +%if %1 <= 4 + movq %3, [%2] ; load data from source2 +%elif %1 <= 8 + movdqa %3, [%2] ; load data from source2 +%elif %1 <= 12 +%if cpuflag(avx2) + mova %3, [%2] +%else + movdqa %3, [%2] ; load data from source2 + movq %4, [%2+16] ; load data from source2 +%endif ;avx +%elif %1 <= 16 +%if cpuflag(avx2) + mova %3, [%2] +%else + movdqa %3, [%2] ; load data from source2 + movdqa %4, [%2+16] ; load data from source2 +%endif ; avx +%else ; %1 = 32 + mova %3, [%2] + mova %4, [%2+32] +%endif +%endmacro + +%macro SIMPLE_LOAD 4 ;width, bitd, tab, r1 +%if %1 == 2 || (%2 == 8 && %1 <= 4) + movd %4, [%3] ; load data from source +%elif %1 == 4 || (%2 == 8 && %1 <= 8) + movq %4, [%3] ; load data from source +%elif notcpuflag(avx) + movu %4, [%3] ; load data from source +%elif %1 <= 8 || (%2 == 8 && %1 <= 16) + movdqu %4, [%3] +%else + movu %4, [%3] +%endif +%endmacro + + +%macro EPEL_FILTER 5 ; bit depth, filter index, xmma, xmmb, gprtmp +%if cpuflag(avx2) +%assign %%offset 32 +%ifdef PIC + lea %5q, [hevc_epel_filters_avx2_%1] + %define FILTER %5q +%else + %define FILTER hevc_epel_filters_avx2_%1 +%endif +%else +%assign %%offset 16 +%ifdef PIC + lea %5q, [hevc_epel_filters_sse4_%1] + %define FILTER %5q +%else + %define FILTER hevc_epel_filters_sse4_%1 +%endif +%endif ;cpuflag(avx2) + sub %2q, 1 +%if cpuflag(avx2) + shl %2q, 6 ; multiply by 64 + %else + shl %2q, 5 ; multiply by 32 +%endif + mova %3, [FILTER + %2q] ; get 2 first values of filters + mova %4, [FILTER + %2q+%%offset] ; get 2 last values of filters +%endmacro + +%macro EPEL_HV_FILTER 1 +%if cpuflag(avx2) +%assign %%offset 32 +%assign %%shift 6 +%define %%table hevc_epel_filters_avx2_%1 +%else +%assign %%offset 16 +%assign %%shift 5 +%define %%table hevc_epel_filters_sse4_%1 +%endif + +%ifdef PIC + lea r3srcq, [%%table] + %define FILTER r3srcq +%else + %define FILTER %%table +%endif + sub mxq, 1 + sub myq, 1 + shl mxq, %%shift ; multiply by 32 + shl myq, %%shift ; multiply by 32 + mova m14, [FILTER + mxq] ; get 2 first values of filters + mova m15, [FILTER + mxq+%%offset] ; get 2 last values of filters + +%if cpuflag(avx2) +%define %%table hevc_epel_filters_avx2_10 +%else +%define %%table hevc_epel_filters_sse4_10 +%endif +%ifdef PIC + lea r3srcq, [%%table] + %define FILTER r3srcq +%else + %define FILTER %%table +%endif + mova m12, [FILTER + myq] ; get 2 first values of filters + mova m13, [FILTER + myq+%%offset] ; get 2 last values of filters + lea r3srcq, [srcstrideq*3] +%endmacro + +%macro QPEL_FILTER 2 + +%if cpuflag(avx2) +%assign %%offset 32 +%assign %%shift 7 +%define %%table hevc_qpel_filters_avx2_%1 +%else +%assign %%offset 16 +%assign %%shift 6 +%define %%table hevc_qpel_filters_sse4_%1 +%endif + +%ifdef PIC + lea rfilterq, [%%table] +%else + %define rfilterq %%table +%endif + sub %2q, 1 + shl %2q, %%shift ; multiply by 32 + mova m12, [rfilterq + %2q] ; get 4 first values of filters + mova m13, [rfilterq + %2q + %%offset] ; get 4 first values of filters + mova m14, [rfilterq + %2q + 2*%%offset] ; get 4 first values of filters + mova m15, [rfilterq + %2q + 3*%%offset] ; get 4 first values of filters +%endmacro + +%macro EPEL_LOAD 4 +%if (%1 == 8 && %4 <= 4) +%define %%load movd +%elif (%1 == 8 && %4 <= 8) || (%1 > 8 && %4 <= 4) +%define %%load movq +%else +%define %%load movdqu +%endif + + %%load m0, [%2q ] +%ifnum %3 + %%load m1, [%2q+ %3] + %%load m2, [%2q+2*%3] + %%load m3, [%2q+3*%3] +%else + %%load m1, [%2q+ %3q] + %%load m2, [%2q+2*%3q] + %%load m3, [%2q+r3srcq] +%endif +%if %1 == 8 +%if %4 > 8 + SBUTTERFLY bw, 0, 1, 7 + SBUTTERFLY bw, 2, 3, 7 +%else + punpcklbw m0, m1 + punpcklbw m2, m3 +%endif +%else +%if %4 > 4 + SBUTTERFLY wd, 0, 1, 7 + SBUTTERFLY wd, 2, 3, 7 +%else + punpcklwd m0, m1 + punpcklwd m2, m3 +%endif +%endif +%endmacro + + +%macro QPEL_H_LOAD 4 +%assign %%stride (%1+7)/8 +%if %1 == 8 +%if %3 <= 4 +%define %%load movd +%elif %3 == 8 +%define %%load movq +%else +%define %%load movu +%endif +%else +%if %3 == 2 +%define %%load movd +%elif %3 == 4 +%define %%load movq +%else +%define %%load movu +%endif +%endif + %%load m0, [%2-3*%%stride] ;load data from source + %%load m1, [%2-2*%%stride] + %%load m2, [%2-%%stride ] + %%load m3, [%2 ] + %%load m4, [%2+%%stride ] + %%load m5, [%2+2*%%stride] + %%load m6, [%2+3*%%stride] + %%load m7, [%2+4*%%stride] + +%if %1 == 8 +%if %3 > 8 + SBUTTERFLY wd, 0, 1, %4 + SBUTTERFLY wd, 2, 3, %4 + SBUTTERFLY wd, 4, 5, %4 + SBUTTERFLY wd, 6, 7, %4 +%else + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 +%endif +%else +%if %3 > 4 + SBUTTERFLY dq, 0, 1, %4 + SBUTTERFLY dq, 2, 3, %4 + SBUTTERFLY dq, 4, 5, %4 + SBUTTERFLY dq, 6, 7, %4 +%else + punpcklwd m0, m1 + punpcklwd m2, m3 + punpcklwd m4, m5 + punpcklwd m6, m7 +%endif +%endif +%endmacro + +%macro QPEL_V_LOAD 5 + lea %5q, [%2] + sub %5q, r3srcq + movu m0, [%5q ] ;load x- 3*srcstride + movu m1, [%5q+ %3q ] ;load x- 2*srcstride + movu m2, [%5q+ 2*%3q ] ;load x-srcstride + movu m3, [%2 ] ;load x + movu m4, [%2+ %3q] ;load x+stride + movu m5, [%2+ 2*%3q] ;load x+2*stride + movu m6, [%2+r3srcq] ;load x+3*stride + movu m7, [%2+ 4*%3q] ;load x+4*stride +%if %1 == 8 +%if %4 > 8 + SBUTTERFLY bw, 0, 1, 8 + SBUTTERFLY bw, 2, 3, 8 + SBUTTERFLY bw, 4, 5, 8 + SBUTTERFLY bw, 6, 7, 8 +%else + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 +%endif +%else +%if %4 > 4 + SBUTTERFLY wd, 0, 1, 8 + SBUTTERFLY wd, 2, 3, 8 + SBUTTERFLY wd, 4, 5, 8 + SBUTTERFLY wd, 6, 7, 8 +%else + punpcklwd m0, m1 + punpcklwd m2, m3 + punpcklwd m4, m5 + punpcklwd m6, m7 +%endif +%endif +%endmacro + +%macro PEL_12STORE2 3 + movd [%1], %2 +%endmacro +%macro PEL_12STORE4 3 + movq [%1], %2 +%endmacro +%macro PEL_12STORE6 3 + movq [%1], %2 + psrldq %2, 8 + movd [%1+8], %2 +%endmacro +%macro PEL_12STORE8 3 + movdqa [%1], %2 +%endmacro +%macro PEL_12STORE12 3 + movdqa [%1], %2 + movq [%1+16], %3 +%endmacro +%macro PEL_12STORE16 3 + PEL_12STORE8 %1, %2, %3 + movdqa [%1+16], %3 +%endmacro + +%macro PEL_10STORE2 3 + movd [%1], %2 +%endmacro +%macro PEL_10STORE4 3 + movq [%1], %2 +%endmacro +%macro PEL_10STORE6 3 + movq [%1], %2 + psrldq %2, 8 + movd [%1+8], %2 +%endmacro +%macro PEL_10STORE8 3 + movdqa [%1], %2 +%endmacro +%macro PEL_10STORE12 3 + movdqa [%1], %2 + movq [%1+16], %3 +%endmacro +%macro PEL_10STORE16 3 +%if cpuflag(avx2) + movu [%1], %2 +%else + PEL_10STORE8 %1, %2, %3 + movdqa [%1+16], %3 +%endif +%endmacro + +%macro PEL_10STORE32 3 + PEL_10STORE16 %1, %2, %3 + movu [%1+32], %3 +%endmacro + +%macro PEL_8STORE2 3 + pextrw [%1], %2, 0 +%endmacro +%macro PEL_8STORE4 3 + movd [%1], %2 +%endmacro +%macro PEL_8STORE6 3 + movd [%1], %2 + pextrw [%1+4], %2, 2 +%endmacro +%macro PEL_8STORE8 3 + movq [%1], %2 +%endmacro +%macro PEL_8STORE12 3 + movq [%1], %2 + psrldq %2, 8 + movd [%1+8], %2 +%endmacro +%macro PEL_8STORE16 3 +%if cpuflag(avx2) + movdqu [%1], %2 +%else + mova [%1], %2 +%endif ; avx +%endmacro +%macro PEL_8STORE32 3 + movu [%1], %2 +%endmacro + +%macro LOOP_END 3 + add %1q, 2*MAX_PB_SIZE ; dst += dststride + add %2q, %3q ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop +%endmacro + + +%macro MC_PIXEL_COMPUTE 2-3 ;width, bitdepth +%if %2 == 8 +%if cpuflag(avx2) && %0 ==3 +%if %1 > 16 + vextracti128 xm1, m0, 1 + pmovzxbw m1, xm1 + psllw m1, 14-%2 +%endif + pmovzxbw m0, xm0 +%else ; not avx +%if %1 > 8 + punpckhbw m1, m0, m2 + psllw m1, 14-%2 +%endif + punpcklbw m0, m2 +%endif +%endif ;avx + psllw m0, 14-%2 +%endmacro + +%macro EPEL_COMPUTE 4-8 ; bitdepth, width, filter1, filter2, HV/m0, m2, m1, m3 +%if %0 == 8 +%define %%reg0 %5 +%define %%reg2 %6 +%define %%reg1 %7 +%define %%reg3 %8 +%else +%define %%reg0 m0 +%define %%reg2 m2 +%define %%reg1 m1 +%define %%reg3 m3 +%endif +%if %1 == 8 +%if cpuflag(avx2) && (%0 == 5) +%if %2 > 16 + vperm2i128 m10, m0, m1, q0301 +%endif + vinserti128 m0, m0, xm1, 1 + mova m1, m10 +%if %2 > 16 + vperm2i128 m10, m2, m3, q0301 +%endif + vinserti128 m2, m2, xm3, 1 + mova m3, m10 +%endif + pmaddubsw %%reg0, %3 ;x1*c1+x2*c2 + pmaddubsw %%reg2, %4 ;x3*c3+x4*c4 + paddw %%reg0, %%reg2 +%if %2 > 8 + pmaddubsw %%reg1, %3 + pmaddubsw %%reg3, %4 + paddw %%reg1, %%reg3 +%endif +%else + pmaddwd %%reg0, %3 + pmaddwd %%reg2, %4 + paddd %%reg0, %%reg2 +%if %2 > 4 + pmaddwd %%reg1, %3 + pmaddwd %%reg3, %4 + paddd %%reg1, %%reg3 +%if %1 != 8 + psrad %%reg1, %1-8 +%endif +%endif +%if %1 != 8 + psrad %%reg0, %1-8 +%endif + packssdw %%reg0, %%reg1 +%endif +%endmacro + +%macro QPEL_HV_COMPUTE 4 ; width, bitdepth, filter idx + +%if cpuflag(avx2) +%assign %%offset 32 +%define %%table hevc_qpel_filters_avx2_%2 +%else +%assign %%offset 16 +%define %%table hevc_qpel_filters_sse4_%2 +%endif + +%ifdef PIC + lea rfilterq, [%%table] +%else + %define rfilterq %%table +%endif + +%if %2 == 8 + pmaddubsw m0, [rfilterq + %3q*8 ] ;x1*c1+x2*c2 + pmaddubsw m2, [rfilterq + %3q*8+%%offset] ;x3*c3+x4*c4 + pmaddubsw m4, [rfilterq + %3q*8+2*%%offset] ;x5*c5+x6*c6 + pmaddubsw m6, [rfilterq + %3q*8+3*%%offset] ;x7*c7+x8*c8 + paddw m0, m2 + paddw m4, m6 + paddw m0, m4 +%else + pmaddwd m0, [rfilterq + %3q*8 ] + pmaddwd m2, [rfilterq + %3q*8+%%offset] + pmaddwd m4, [rfilterq + %3q*8+2*%%offset] + pmaddwd m6, [rfilterq + %3q*8+3*%%offset] + paddd m0, m2 + paddd m4, m6 + paddd m0, m4 +%if %2 != 8 + psrad m0, %2-8 +%endif +%if %1 > 4 + pmaddwd m1, [rfilterq + %3q*8 ] + pmaddwd m3, [rfilterq + %3q*8+%%offset] + pmaddwd m5, [rfilterq + %3q*8+2*%%offset] + pmaddwd m7, [rfilterq + %3q*8+3*%%offset] + paddd m1, m3 + paddd m5, m7 + paddd m1, m5 +%if %2 != 8 + psrad m1, %2-8 +%endif +%endif + p%4 m0, m1 +%endif +%endmacro + +%macro QPEL_COMPUTE 2-3 ; width, bitdepth +%if %2 == 8 +%if cpuflag(avx2) && (%0 == 3) + + vperm2i128 m10, m0, m1, q0301 + vinserti128 m0, m0, xm1, 1 + SWAP 1, 10 + + vperm2i128 m10, m2, m3, q0301 + vinserti128 m2, m2, xm3, 1 + SWAP 3, 10 + + + vperm2i128 m10, m4, m5, q0301 + vinserti128 m4, m4, xm5, 1 + SWAP 5, 10 + + vperm2i128 m10, m6, m7, q0301 + vinserti128 m6, m6, xm7, 1 + SWAP 7, 10 +%endif + + pmaddubsw m0, m12 ;x1*c1+x2*c2 + pmaddubsw m2, m13 ;x3*c3+x4*c4 + pmaddubsw m4, m14 ;x5*c5+x6*c6 + pmaddubsw m6, m15 ;x7*c7+x8*c8 + paddw m0, m2 + paddw m4, m6 + paddw m0, m4 +%if %1 > 8 + pmaddubsw m1, m12 + pmaddubsw m3, m13 + pmaddubsw m5, m14 + pmaddubsw m7, m15 + paddw m1, m3 + paddw m5, m7 + paddw m1, m5 +%endif +%else + pmaddwd m0, m12 + pmaddwd m2, m13 + pmaddwd m4, m14 + pmaddwd m6, m15 + paddd m0, m2 + paddd m4, m6 + paddd m0, m4 +%if %2 != 8 + psrad m0, %2-8 +%endif +%if %1 > 4 + pmaddwd m1, m12 + pmaddwd m3, m13 + pmaddwd m5, m14 + pmaddwd m7, m15 + paddd m1, m3 + paddd m5, m7 + paddd m1, m5 +%if %2 != 8 + psrad m1, %2-8 +%endif +%endif +%endif +%endmacro + +%macro BI_COMPUTE 7-8 ; width, bitd, src1l, src1h, scr2l, scr2h, pw + paddsw %3, %5 +%if %1 > 8 + paddsw %4, %6 +%endif + UNI_COMPUTE %1, %2, %3, %4, %7 +%if %0 == 8 && cpuflag(avx2) && (%2 == 8) + vpermq %3, %3, 216 + vpermq %4, %4, 216 +%endif +%endmacro + +%macro UNI_COMPUTE 5 + pmulhrsw %3, %5 +%if %1 > 8 || (%2 > 8 && %1 > 4) + pmulhrsw %4, %5 +%endif +%if %2 == 8 + packuswb %3, %4 +%else + CLIPW %3, [pb_0], [max_pixels_%2] +%if (%1 > 8 && notcpuflag(avx)) || %1 > 16 + CLIPW %4, [pb_0], [max_pixels_%2] +%endif +%endif +%endmacro + + +; ****************************** +; void put_hevc_mc_pixels(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my) +; ****************************** + +%macro HEVC_PUT_HEVC_PEL_PIXELS 2 +HEVC_PEL_PIXELS %1, %2 +HEVC_UNI_PEL_PIXELS %1, %2 +HEVC_BI_PEL_PIXELS %1, %2 +%endmacro + +%macro HEVC_PEL_PIXELS 2 +cglobal hevc_put_hevc_pel_pixels%1_%2, 4, 4, 3, dst, src, srcstride,height + pxor m2, m2 +.loop: + SIMPLE_LOAD %1, %2, srcq, m0 + MC_PIXEL_COMPUTE %1, %2, 1 + PEL_10STORE%1 dstq, m0, m1 + LOOP_END dst, src, srcstride + RET + %endmacro + +%macro HEVC_UNI_PEL_PIXELS 2 +cglobal hevc_put_hevc_uni_pel_pixels%1_%2, 5, 5, 2, dst, dststride, src, srcstride,height +.loop: + SIMPLE_LOAD %1, %2, srcq, m0 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET +%endmacro + +%macro HEVC_BI_PEL_PIXELS 2 +cglobal hevc_put_hevc_bi_pel_pixels%1_%2, 6, 6, 6, dst, dststride, src, srcstride, src2, height + pxor m2, m2 + movdqa m5, [pw_bi_%2] +.loop: + SIMPLE_LOAD %1, %2, srcq, m0 + SIMPLE_BILOAD %1, src2q, m3, m4 + MC_PIXEL_COMPUTE %1, %2, 1 + BI_COMPUTE %1, %2, m0, m1, m3, m4, m5, 1 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET +%endmacro + + +; ****************************** +; void put_hevc_epel_hX(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my, int width); +; ****************************** + + +%macro HEVC_PUT_HEVC_EPEL 2 +%if cpuflag(avx2) +%define XMM_REGS 11 +%else +%define XMM_REGS 8 +%endif + +cglobal hevc_put_hevc_epel_h%1_%2, 5, 6, XMM_REGS, dst, src, srcstride, height, mx, rfilter +%assign %%stride ((%2 + 7)/8) + EPEL_FILTER %2, mx, m4, m5, rfilter +.loop: + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m4, m5, 1 + PEL_10STORE%1 dstq, m0, m1 + LOOP_END dst, src, srcstride + RET + +cglobal hevc_put_hevc_uni_epel_h%1_%2, 6, 7, XMM_REGS, dst, dststride, src, srcstride, height, mx, rfilter +%assign %%stride ((%2 + 7)/8) + movdqa m6, [pw_%2] + EPEL_FILTER %2, mx, m4, m5, rfilter +.loop: + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m4, m5 + UNI_COMPUTE %1, %2, m0, m1, m6 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +cglobal hevc_put_hevc_bi_epel_h%1_%2, 7, 8, XMM_REGS, dst, dststride, src, srcstride, src2, height, mx, rfilter + movdqa m6, [pw_bi_%2] + EPEL_FILTER %2, mx, m4, m5, rfilter +.loop: + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m4, m5, 1 + SIMPLE_BILOAD %1, src2q, m2, m3 + BI_COMPUTE %1, %2, m0, m1, m2, m3, m6, 1 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +; ****************************** +; void put_hevc_epel_v(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my, int width) +; ****************************** + +cglobal hevc_put_hevc_epel_v%1_%2, 4, 6, XMM_REGS, dst, src, srcstride, height, r3src, my + movifnidn myd, mym + sub srcq, srcstrideq + EPEL_FILTER %2, my, m4, m5, r3src + lea r3srcq, [srcstrideq*3] +.loop: + EPEL_LOAD %2, srcq, srcstride, %1 + EPEL_COMPUTE %2, %1, m4, m5, 1 + PEL_10STORE%1 dstq, m0, m1 + LOOP_END dst, src, srcstride + RET + +cglobal hevc_put_hevc_uni_epel_v%1_%2, 5, 7, XMM_REGS, dst, dststride, src, srcstride, height, r3src, my + movifnidn myd, mym + movdqa m6, [pw_%2] + sub srcq, srcstrideq + EPEL_FILTER %2, my, m4, m5, r3src + lea r3srcq, [srcstrideq*3] +.loop: + EPEL_LOAD %2, srcq, srcstride, %1 + EPEL_COMPUTE %2, %1, m4, m5 + UNI_COMPUTE %1, %2, m0, m1, m6 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + + +cglobal hevc_put_hevc_bi_epel_v%1_%2, 6, 8, XMM_REGS, dst, dststride, src, srcstride, src2, height, r3src, my + movifnidn myd, mym + movdqa m6, [pw_bi_%2] + sub srcq, srcstrideq + EPEL_FILTER %2, my, m4, m5, r3src + lea r3srcq, [srcstrideq*3] +.loop: + EPEL_LOAD %2, srcq, srcstride, %1 + EPEL_COMPUTE %2, %1, m4, m5, 1 + SIMPLE_BILOAD %1, src2q, m2, m3 + BI_COMPUTE %1, %2, m0, m1, m2, m3, m6, 1 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET +%endmacro + + +; ****************************** +; void put_hevc_epel_hv(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my, int width) +; ****************************** + +%macro HEVC_PUT_HEVC_EPEL_HV 2 +cglobal hevc_put_hevc_epel_hv%1_%2, 6, 7, 16 , dst, src, srcstride, height, mx, my, r3src +%assign %%stride ((%2 + 7)/8) + sub srcq, srcstrideq + EPEL_HV_FILTER %2 + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m8, m1 +%endif + SWAP m4, m0 + add srcq, srcstrideq + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m9, m1 +%endif + SWAP m5, m0 + add srcq, srcstrideq + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m10, m1 +%endif + SWAP m6, m0 + add srcq, srcstrideq +.loop: + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m11, m1 +%endif + SWAP m7, m0 + punpcklwd m0, m4, m5 + punpcklwd m2, m6, m7 +%if %1 > 4 + punpckhwd m1, m4, m5 + punpckhwd m3, m6, m7 +%endif + EPEL_COMPUTE 14, %1, m12, m13 +%if (%1 > 8 && (%2 == 8)) + punpcklwd m4, m8, m9 + punpcklwd m2, m10, m11 + punpckhwd m8, m8, m9 + punpckhwd m3, m10, m11 + EPEL_COMPUTE 14, %1, m12, m13, m4, m2, m8, m3 +%if cpuflag(avx2) + vinserti128 m2, m0, xm4, 1 + vperm2i128 m3, m0, m4, q0301 + PEL_10STORE%1 dstq, m2, m3 +%else + PEL_10STORE%1 dstq, m0, m4 +%endif +%else + PEL_10STORE%1 dstq, m0, m1 +%endif + movdqa m4, m5 + movdqa m5, m6 + movdqa m6, m7 +%if (%1 > 8 && (%2 == 8)) + mova m8, m9 + mova m9, m10 + mova m10, m11 +%endif + LOOP_END dst, src, srcstride + RET + +cglobal hevc_put_hevc_uni_epel_hv%1_%2, 7, 8, 16 , dst, dststride, src, srcstride, height, mx, my, r3src +%assign %%stride ((%2 + 7)/8) + sub srcq, srcstrideq + EPEL_HV_FILTER %2 + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m8, m1 +%endif + SWAP m4, m0 + add srcq, srcstrideq + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m9, m1 +%endif + SWAP m5, m0 + add srcq, srcstrideq + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m10, m1 +%endif + SWAP m6, m0 + add srcq, srcstrideq +.loop: + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m11, m1 +%endif + mova m7, m0 + punpcklwd m0, m4, m5 + punpcklwd m2, m6, m7 +%if %1 > 4 + punpckhwd m1, m4, m5 + punpckhwd m3, m6, m7 +%endif + EPEL_COMPUTE 14, %1, m12, m13 +%if (%1 > 8 && (%2 == 8)) + punpcklwd m4, m8, m9 + punpcklwd m2, m10, m11 + punpckhwd m8, m8, m9 + punpckhwd m3, m10, m11 + EPEL_COMPUTE 14, %1, m12, m13, m4, m2, m8, m3 + UNI_COMPUTE %1, %2, m0, m4, [pw_%2] +%else + UNI_COMPUTE %1, %2, m0, m1, [pw_%2] +%endif + PEL_%2STORE%1 dstq, m0, m1 + mova m4, m5 + mova m5, m6 + mova m6, m7 +%if (%1 > 8 && (%2 == 8)) + mova m8, m9 + mova m9, m10 + mova m10, m11 +%endif + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +cglobal hevc_put_hevc_bi_epel_hv%1_%2, 8, 9, 16, dst, dststride, src, srcstride, src2, height, mx, my, r3src +%assign %%stride ((%2 + 7)/8) + sub srcq, srcstrideq + EPEL_HV_FILTER %2 + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m8, m1 +%endif + SWAP m4, m0 + add srcq, srcstrideq + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m9, m1 +%endif + SWAP m5, m0 + add srcq, srcstrideq + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m10, m1 +%endif + SWAP m6, m0 + add srcq, srcstrideq +.loop: + EPEL_LOAD %2, srcq-%%stride, %%stride, %1 + EPEL_COMPUTE %2, %1, m14, m15 +%if (%1 > 8 && (%2 == 8)) + SWAP m11, m1 +%endif + SWAP m7, m0 + punpcklwd m0, m4, m5 + punpcklwd m2, m6, m7 +%if %1 > 4 + punpckhwd m1, m4, m5 + punpckhwd m3, m6, m7 +%endif + EPEL_COMPUTE 14, %1, m12, m13 +%if (%1 > 8 && (%2 == 8)) + punpcklwd m4, m8, m9 + punpcklwd m2, m10, m11 + punpckhwd m8, m8, m9 + punpckhwd m3, m10, m11 + EPEL_COMPUTE 14, %1, m12, m13, m4, m2, m8, m3 + SIMPLE_BILOAD %1, src2q, m8, m3 +%if cpuflag(avx2) + vinserti128 m1, m8, xm3, 1 + vperm2i128 m2, m8, m3, q0301 + BI_COMPUTE %1, %2, m0, m4, m1, m2, [pw_bi_%2] +%else + BI_COMPUTE %1, %2, m0, m4, m8, m3, [pw_bi_%2] +%endif +%else + SIMPLE_BILOAD %1, src2q, m8, m9 + BI_COMPUTE %1, %2, m0, m1, m8, m9, [pw_bi_%2] +%endif + PEL_%2STORE%1 dstq, m0, m4 + mova m4, m5 + mova m5, m6 + mova m6, m7 +%if (%1 > 8 && (%2 == 8)) + mova m8, m9 + mova m9, m10 + mova m10, m11 +%endif + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET +%endmacro + +; ****************************** +; void put_hevc_qpel_hX_X_X(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my, int width) +; ****************************** + +%macro HEVC_PUT_HEVC_QPEL 2 +cglobal hevc_put_hevc_qpel_h%1_%2, 5, 6, 16, dst, src, srcstride, height, mx, rfilter + QPEL_FILTER %2, mx +.loop: + QPEL_H_LOAD %2, srcq, %1, 10 + QPEL_COMPUTE %1, %2, 1 +%if %2 > 8 + packssdw m0, m1 +%endif + PEL_10STORE%1 dstq, m0, m1 + LOOP_END dst, src, srcstride + RET + +cglobal hevc_put_hevc_uni_qpel_h%1_%2, 6, 7, 16 , dst, dststride, src, srcstride, height, mx, rfilter + mova m9, [pw_%2] + QPEL_FILTER %2, mx +.loop: + QPEL_H_LOAD %2, srcq, %1, 10 + QPEL_COMPUTE %1, %2 +%if %2 > 8 + packssdw m0, m1 +%endif + UNI_COMPUTE %1, %2, m0, m1, m9 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +cglobal hevc_put_hevc_bi_qpel_h%1_%2, 7, 8, 16 , dst, dststride, src, srcstride, src2, height, mx, rfilter + movdqa m9, [pw_bi_%2] + QPEL_FILTER %2, mx +.loop: + QPEL_H_LOAD %2, srcq, %1, 10 + QPEL_COMPUTE %1, %2, 1 +%if %2 > 8 + packssdw m0, m1 +%endif + SIMPLE_BILOAD %1, src2q, m10, m11 + BI_COMPUTE %1, %2, m0, m1, m10, m11, m9, 1 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + + +; ****************************** +; void put_hevc_qpel_vX_X_X(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my, int width) +; ****************************** + +cglobal hevc_put_hevc_qpel_v%1_%2, 4, 8, 16, dst, src, srcstride, height, r3src, my, rfilter + movifnidn myd, mym + lea r3srcq, [srcstrideq*3] + QPEL_FILTER %2, my +.loop: + QPEL_V_LOAD %2, srcq, srcstride, %1, r7 + QPEL_COMPUTE %1, %2, 1 +%if %2 > 8 + packssdw m0, m1 +%endif + PEL_10STORE%1 dstq, m0, m1 + LOOP_END dst, src, srcstride + RET + +cglobal hevc_put_hevc_uni_qpel_v%1_%2, 5, 9, 16, dst, dststride, src, srcstride, height, r3src, my, rfilter + movifnidn myd, mym + movdqa m9, [pw_%2] + lea r3srcq, [srcstrideq*3] + QPEL_FILTER %2, my +.loop: + QPEL_V_LOAD %2, srcq, srcstride, %1, r8 + QPEL_COMPUTE %1, %2 +%if %2 > 8 + packssdw m0, m1 +%endif + UNI_COMPUTE %1, %2, m0, m1, m9 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +cglobal hevc_put_hevc_bi_qpel_v%1_%2, 6, 10, 16, dst, dststride, src, srcstride, src2, height, r3src, my, rfilter + movifnidn myd, mym + movdqa m9, [pw_bi_%2] + lea r3srcq, [srcstrideq*3] + QPEL_FILTER %2, my +.loop: + QPEL_V_LOAD %2, srcq, srcstride, %1, r9 + QPEL_COMPUTE %1, %2, 1 +%if %2 > 8 + packssdw m0, m1 +%endif + SIMPLE_BILOAD %1, src2q, m10, m11 + BI_COMPUTE %1, %2, m0, m1, m10, m11, m9, 1 + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET +%endmacro + + +; ****************************** +; void put_hevc_qpel_hvX_X(int16_t *dst, ptrdiff_t dststride, +; uint8_t *_src, ptrdiff_t _srcstride, +; int height, int mx, int my) +; ****************************** +%macro HEVC_PUT_HEVC_QPEL_HV 2 +cglobal hevc_put_hevc_qpel_hv%1_%2, 6, 8, 16, dst, src, srcstride, height, mx, my, r3src, rfilter +%if cpuflag(avx2) +%assign %%shift 4 +%else +%assign %%shift 3 +%endif + sub mxq, 1 + sub myq, 1 + shl mxq, %%shift ; multiply by 32 + shl myq, %%shift ; multiply by 32 + lea r3srcq, [srcstrideq*3] + sub srcq, r3srcq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m8, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m9, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m10, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m11, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m12, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m13, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m14, m0 + add srcq, srcstrideq +.loop: + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m15, m0 + punpcklwd m0, m8, m9 + punpcklwd m2, m10, m11 + punpcklwd m4, m12, m13 + punpcklwd m6, m14, m15 +%if %1 > 4 + punpckhwd m1, m8, m9 + punpckhwd m3, m10, m11 + punpckhwd m5, m12, m13 + punpckhwd m7, m14, m15 +%endif + QPEL_HV_COMPUTE %1, 14, my, ackssdw + PEL_10STORE%1 dstq, m0, m1 +%if %1 <= 4 + movq m8, m9 + movq m9, m10 + movq m10, m11 + movq m11, m12 + movq m12, m13 + movq m13, m14 + movq m14, m15 +%else + movdqa m8, m9 + movdqa m9, m10 + movdqa m10, m11 + movdqa m11, m12 + movdqa m12, m13 + movdqa m13, m14 + movdqa m14, m15 +%endif + LOOP_END dst, src, srcstride + RET + +cglobal hevc_put_hevc_uni_qpel_hv%1_%2, 7, 9, 16 , dst, dststride, src, srcstride, height, mx, my, r3src, rfilter +%if cpuflag(avx2) +%assign %%shift 4 +%else +%assign %%shift 3 +%endif + sub mxq, 1 + sub myq, 1 + shl mxq, %%shift ; multiply by 32 + shl myq, %%shift ; multiply by 32 + lea r3srcq, [srcstrideq*3] + sub srcq, r3srcq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m8, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m9, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m10, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m11, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m12, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m13, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m14, m0 + add srcq, srcstrideq +.loop: + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m15, m0 + punpcklwd m0, m8, m9 + punpcklwd m2, m10, m11 + punpcklwd m4, m12, m13 + punpcklwd m6, m14, m15 +%if %1 > 4 + punpckhwd m1, m8, m9 + punpckhwd m3, m10, m11 + punpckhwd m5, m12, m13 + punpckhwd m7, m14, m15 +%endif + QPEL_HV_COMPUTE %1, 14, my, ackusdw + UNI_COMPUTE %1, %2, m0, m1, [pw_%2] + PEL_%2STORE%1 dstq, m0, m1 + +%if %1 <= 4 + movq m8, m9 + movq m9, m10 + movq m10, m11 + movq m11, m12 + movq m12, m13 + movq m13, m14 + movq m14, m15 +%else + mova m8, m9 + mova m9, m10 + mova m10, m11 + mova m11, m12 + mova m12, m13 + mova m13, m14 + mova m14, m15 +%endif + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +cglobal hevc_put_hevc_bi_qpel_hv%1_%2, 8, 10, 16, dst, dststride, src, srcstride, src2, height, mx, my, r3src, rfilter +%if cpuflag(avx2) +%assign %%shift 4 +%else +%assign %%shift 3 +%endif + sub mxq, 1 + sub myq, 1 + shl mxq, %%shift ; multiply by 32 + shl myq, %%shift ; multiply by 32 + lea r3srcq, [srcstrideq*3] + sub srcq, r3srcq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m8, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m9, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m10, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m11, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m12, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m13, m0 + add srcq, srcstrideq + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m14, m0 + add srcq, srcstrideq +.loop: + QPEL_H_LOAD %2, srcq, %1, 15 + QPEL_HV_COMPUTE %1, %2, mx, ackssdw + SWAP m15, m0 + punpcklwd m0, m8, m9 + punpcklwd m2, m10, m11 + punpcklwd m4, m12, m13 + punpcklwd m6, m14, m15 +%if %1 > 4 + punpckhwd m1, m8, m9 + punpckhwd m3, m10, m11 + punpckhwd m5, m12, m13 + punpckhwd m7, m14, m15 +%endif + QPEL_HV_COMPUTE %1, 14, my, ackssdw + SIMPLE_BILOAD %1, src2q, m8, m9 ;m9 not used in this case + BI_COMPUTE %1, %2, m0, m1, m8, m9, [pw_bi_%2] + PEL_%2STORE%1 dstq, m0, m1 + +%if %1 <= 4 + movq m8, m9 + movq m9, m10 + movq m10, m11 + movq m11, m12 + movq m12, m13 + movq m13, m14 + movq m14, m15 +%else + movdqa m8, m9 + movdqa m9, m10 + movdqa m10, m11 + movdqa m11, m12 + movdqa m12, m13 + movdqa m13, m14 + movdqa m14, m15 +%endif + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET +%endmacro + +%macro WEIGHTING_FUNCS 2 +%if WIN64 || ARCH_X86_32 +cglobal hevc_put_hevc_uni_w%1_%2, 4, 5, 7, dst, dststride, src, height, denom, wx, ox + mov r4d, denomm +%define SHIFT r4d +%else +cglobal hevc_put_hevc_uni_w%1_%2, 6, 6, 7, dst, dststride, src, height, denom, wx, ox +%define SHIFT denomd +%endif + lea SHIFT, [SHIFT+14-%2] ; shift = 14 - bitd + denom +%if %1 <= 4 + pxor m1, m1 +%endif + movd m2, wxm ; WX + movd m4, SHIFT ; shift +%if %1 <= 4 + punpcklwd m2, m1 +%else + punpcklwd m2, m2 +%endif + dec SHIFT + movdqu m5, [pd_1] + movd m6, SHIFT + pshufd m2, m2, 0 + mov SHIFT, oxm + pslld m5, m6 +%if %2 != 8 + shl SHIFT, %2-8 ; ox << (bitd - 8) +%endif + movd m3, SHIFT ; OX + pshufd m3, m3, 0 +%if WIN64 || ARCH_X86_32 + mov SHIFT, heightm +%endif +.loop: + SIMPLE_LOAD %1, 10, srcq, m0 +%if %1 <= 4 + punpcklwd m0, m1 + pmaddwd m0, m2 + paddd m0, m5 + psrad m0, m4 + paddd m0, m3 +%else + pmulhw m6, m0, m2 + pmullw m0, m2 + punpckhwd m1, m0, m6 + punpcklwd m0, m6 + paddd m0, m5 + paddd m1, m5 + psrad m0, m4 + psrad m1, m4 + paddd m0, m3 + paddd m1, m3 +%endif + packssdw m0, m1 +%if %2 == 8 + packuswb m0, m0 +%else + CLIPW m0, [pb_0], [max_pixels_%2] +%endif + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, 2*MAX_PB_SIZE ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + RET + +cglobal hevc_put_hevc_bi_w%1_%2, 4, 6, 10, dst, dststride, src, src2, height, denom, wx0, wx1, ox0, ox1 + movifnidn r5d, denomm +%if %1 <= 4 + pxor m1, m1 +%endif + movd m2, wx0m ; WX0 + lea r5d, [r5d+14-%2] ; shift = 14 - bitd + denom + movd m3, wx1m ; WX1 + movd m0, r5d ; shift +%if %1 <= 4 + punpcklwd m2, m1 + punpcklwd m3, m1 +%else + punpcklwd m2, m2 + punpcklwd m3, m3 +%endif + inc r5d + movd m5, r5d ; shift+1 + pshufd m2, m2, 0 + mov r5d, ox0m + pshufd m3, m3, 0 + add r5d, ox1m +%if %2 != 8 + shl r5d, %2-8 ; ox << (bitd - 8) +%endif + inc r5d + movd m4, r5d ; offset + pshufd m4, m4, 0 +%if UNIX64 +%define h heightd +%else + mov r5d, heightm +%define h r5d +%endif + pslld m4, m0 + +.loop: + SIMPLE_LOAD %1, 10, srcq, m0 + SIMPLE_LOAD %1, 10, src2q, m8 +%if %1 <= 4 + punpcklwd m0, m1 + punpcklwd m8, m1 + pmaddwd m0, m3 + pmaddwd m8, m2 + paddd m0, m4 + paddd m0, m8 + psrad m0, m5 +%else + pmulhw m6, m0, m3 + pmullw m0, m3 + pmulhw m7, m8, m2 + pmullw m8, m2 + punpckhwd m1, m0, m6 + punpcklwd m0, m6 + punpckhwd m9, m8, m7 + punpcklwd m8, m7 + paddd m0, m8 + paddd m1, m9 + paddd m0, m4 + paddd m1, m4 + psrad m0, m5 + psrad m1, m5 +%endif + packssdw m0, m1 +%if %2 == 8 + packuswb m0, m0 +%else + CLIPW m0, [pb_0], [max_pixels_%2] +%endif + PEL_%2STORE%1 dstq, m0, m1 + add dstq, dststrideq ; dst += dststride + add srcq, 2*MAX_PB_SIZE ; src += srcstride + add src2q, 2*MAX_PB_SIZE ; src2 += srcstride + dec h ; cmp height + jnz .loop ; height loop + RET +%endmacro + +INIT_XMM sse4 ; adds ff_ and _sse4 to function name + +WEIGHTING_FUNCS 2, 8 +WEIGHTING_FUNCS 4, 8 +WEIGHTING_FUNCS 6, 8 +WEIGHTING_FUNCS 8, 8 + +WEIGHTING_FUNCS 2, 10 +WEIGHTING_FUNCS 4, 10 +WEIGHTING_FUNCS 6, 10 +WEIGHTING_FUNCS 8, 10 + +WEIGHTING_FUNCS 2, 12 +WEIGHTING_FUNCS 4, 12 +WEIGHTING_FUNCS 6, 12 +WEIGHTING_FUNCS 8, 12 + +HEVC_PUT_HEVC_PEL_PIXELS 2, 8 +HEVC_PUT_HEVC_PEL_PIXELS 4, 8 +HEVC_PUT_HEVC_PEL_PIXELS 6, 8 +HEVC_PUT_HEVC_PEL_PIXELS 8, 8 +HEVC_PUT_HEVC_PEL_PIXELS 12, 8 +HEVC_PUT_HEVC_PEL_PIXELS 16, 8 + +HEVC_PUT_HEVC_PEL_PIXELS 2, 10 +HEVC_PUT_HEVC_PEL_PIXELS 4, 10 +HEVC_PUT_HEVC_PEL_PIXELS 6, 10 +HEVC_PUT_HEVC_PEL_PIXELS 8, 10 + +HEVC_PUT_HEVC_PEL_PIXELS 2, 12 +HEVC_PUT_HEVC_PEL_PIXELS 4, 12 +HEVC_PUT_HEVC_PEL_PIXELS 6, 12 +HEVC_PUT_HEVC_PEL_PIXELS 8, 12 + +HEVC_PUT_HEVC_EPEL 2, 8 +HEVC_PUT_HEVC_EPEL 4, 8 +HEVC_PUT_HEVC_EPEL 6, 8 +HEVC_PUT_HEVC_EPEL 8, 8 +HEVC_PUT_HEVC_EPEL 12, 8 +HEVC_PUT_HEVC_EPEL 16, 8 + + +HEVC_PUT_HEVC_EPEL 2, 10 +HEVC_PUT_HEVC_EPEL 4, 10 +HEVC_PUT_HEVC_EPEL 6, 10 +HEVC_PUT_HEVC_EPEL 8, 10 + +HEVC_PUT_HEVC_EPEL 2, 12 +HEVC_PUT_HEVC_EPEL 4, 12 +HEVC_PUT_HEVC_EPEL 6, 12 +HEVC_PUT_HEVC_EPEL 8, 12 + +HEVC_PUT_HEVC_EPEL_HV 2, 8 +HEVC_PUT_HEVC_EPEL_HV 4, 8 +HEVC_PUT_HEVC_EPEL_HV 6, 8 +HEVC_PUT_HEVC_EPEL_HV 8, 8 +HEVC_PUT_HEVC_EPEL_HV 16, 8 + +HEVC_PUT_HEVC_EPEL_HV 2, 10 +HEVC_PUT_HEVC_EPEL_HV 4, 10 +HEVC_PUT_HEVC_EPEL_HV 6, 10 +HEVC_PUT_HEVC_EPEL_HV 8, 10 + +HEVC_PUT_HEVC_EPEL_HV 2, 12 +HEVC_PUT_HEVC_EPEL_HV 4, 12 +HEVC_PUT_HEVC_EPEL_HV 6, 12 +HEVC_PUT_HEVC_EPEL_HV 8, 12 + +HEVC_PUT_HEVC_QPEL 4, 8 +HEVC_PUT_HEVC_QPEL 8, 8 +HEVC_PUT_HEVC_QPEL 12, 8 +HEVC_PUT_HEVC_QPEL 16, 8 + +HEVC_PUT_HEVC_QPEL 4, 10 +HEVC_PUT_HEVC_QPEL 8, 10 + +HEVC_PUT_HEVC_QPEL 4, 12 +HEVC_PUT_HEVC_QPEL 8, 12 + +HEVC_PUT_HEVC_QPEL_HV 2, 8 +HEVC_PUT_HEVC_QPEL_HV 4, 8 +HEVC_PUT_HEVC_QPEL_HV 6, 8 +HEVC_PUT_HEVC_QPEL_HV 8, 8 + +HEVC_PUT_HEVC_QPEL_HV 2, 10 +HEVC_PUT_HEVC_QPEL_HV 4, 10 +HEVC_PUT_HEVC_QPEL_HV 6, 10 +HEVC_PUT_HEVC_QPEL_HV 8, 10 + +HEVC_PUT_HEVC_QPEL_HV 2, 12 +HEVC_PUT_HEVC_QPEL_HV 4, 12 +HEVC_PUT_HEVC_QPEL_HV 6, 12 +HEVC_PUT_HEVC_QPEL_HV 8, 12 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 ; adds ff_ and _avx2 to function name & enables 256b registers : m0 for 256b, xm0 for 128b. cpuflag(avx2) = 1 / notcpuflag(avx) = 0 + +HEVC_PUT_HEVC_PEL_PIXELS 32, 8 +HEVC_PUT_HEVC_PEL_PIXELS 16, 10 + +HEVC_PUT_HEVC_EPEL 32, 8 +HEVC_PUT_HEVC_EPEL 16, 10 + +HEVC_PUT_HEVC_EPEL_HV 16, 10 +HEVC_PUT_HEVC_EPEL_HV 32, 8 + +HEVC_PUT_HEVC_QPEL 32, 8 + +HEVC_PUT_HEVC_QPEL 16, 10 + +HEVC_PUT_HEVC_QPEL_HV 16, 10 + +%endif ;AVX2 +%endif ; ARCH_X86_64 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_sao.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_sao.asm new file mode 100644 index 00000000..756adfee --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_sao.asm @@ -0,0 +1,340 @@ +;****************************************************************************** +;* SIMD optimized SAO functions for HEVC 8bit decoding +;* +;* Copyright (c) 2013 Pierre-Edouard LEPERE +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pb_edge_shuffle: times 2 db 1, 2, 0, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +pb_eo: db -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, 1, 1, -1, -1, 1 +cextern pb_1 +cextern pb_2 + +SECTION .text + +;****************************************************************************** +;SAO Band Filter +;****************************************************************************** + +%macro HEVC_SAO_BAND_FILTER_INIT 0 + and leftq, 31 + movd xm0, leftd + add leftq, 1 + and leftq, 31 + movd xm1, leftd + add leftq, 1 + and leftq, 31 + movd xm2, leftd + add leftq, 1 + and leftq, 31 + movd xm3, leftd + + SPLATW m0, xm0 + SPLATW m1, xm1 + SPLATW m2, xm2 + SPLATW m3, xm3 +%if mmsize > 16 + SPLATW m4, [offsetq + 2] + SPLATW m5, [offsetq + 4] + SPLATW m6, [offsetq + 6] + SPLATW m7, [offsetq + 8] +%else + movq m7, [offsetq + 2] + SPLATW m4, m7, 0 + SPLATW m5, m7, 1 + SPLATW m6, m7, 2 + SPLATW m7, m7, 3 +%endif + +%if ARCH_X86_64 + pxor m14, m14 + +%else ; ARCH_X86_32 + mova [rsp+mmsize*0], m0 + mova [rsp+mmsize*1], m1 + mova [rsp+mmsize*2], m2 + mova [rsp+mmsize*3], m3 + mova [rsp+mmsize*4], m4 + mova [rsp+mmsize*5], m5 + mova [rsp+mmsize*6], m6 + pxor m0, m0 + %assign MMSIZE mmsize + %define m14 m0 + %define m13 m1 + %define m9 m2 + %define m8 m3 +%endif ; ARCH +DEFINE_ARGS dst, src, dststride, srcstride, offset, height + mov heightd, r7m +%endmacro + +%macro HEVC_SAO_BAND_FILTER_COMPUTE 2 + psraw %1, %2, 3 +%if ARCH_X86_64 + pcmpeqw m10, %1, m0 + pcmpeqw m11, %1, m1 + pcmpeqw m12, %1, m2 + pcmpeqw %1, m3 + pand m10, m4 + pand m11, m5 + pand m12, m6 + pand %1, m7 + por m10, m11 + por m12, %1 + por m10, m12 + paddw %2, m10 +%else ; ARCH_X86_32 + pcmpeqw m4, %1, [rsp+MMSIZE*0] + pcmpeqw m5, %1, [rsp+MMSIZE*1] + pcmpeqw m6, %1, [rsp+MMSIZE*2] + pcmpeqw %1, [rsp+MMSIZE*3] + pand m4, [rsp+MMSIZE*4] + pand m5, [rsp+MMSIZE*5] + pand m6, [rsp+MMSIZE*6] + pand %1, m7 + por m4, m5 + por m6, %1 + por m4, m6 + paddw %2, m4 +%endif ; ARCH +%endmacro + +;void ff_hevc_sao_band_filter__8_(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, +; int16_t *sao_offset_val, int sao_left_class, int width, int height); +%macro HEVC_SAO_BAND_FILTER 2 +cglobal hevc_sao_band_filter_%1_8, 6, 6, 15, 7*mmsize*ARCH_X86_32, dst, src, dststride, srcstride, offset, left + HEVC_SAO_BAND_FILTER_INIT + +align 16 +.loop: +%if %1 == 8 + movq m8, [srcq] + punpcklbw m8, m14 + HEVC_SAO_BAND_FILTER_COMPUTE m9, m8 + packuswb m8, m14 + movq [dstq], m8 +%endif ; %1 == 8 + +%assign i 0 +%rep %2 + mova m13, [srcq + i] + punpcklbw m8, m13, m14 + HEVC_SAO_BAND_FILTER_COMPUTE m9, m8 + punpckhbw m13, m14 + HEVC_SAO_BAND_FILTER_COMPUTE m9, m13 + packuswb m8, m13 + mova [dstq + i], m8 +%assign i i+mmsize +%endrep + +%if %1 == 48 +INIT_XMM cpuname + + mova m13, [srcq + i] + punpcklbw m8, m13, m14 + HEVC_SAO_BAND_FILTER_COMPUTE m9, m8 + punpckhbw m13, m14 + HEVC_SAO_BAND_FILTER_COMPUTE m9, m13 + packuswb m8, m13 + mova [dstq + i], m8 +%if cpuflag(avx2) +INIT_YMM cpuname +%endif +%endif ; %1 == 48 + + add dstq, dststrideq ; dst += dststride + add srcq, srcstrideq ; src += srcstride + dec heightd ; cmp height + jnz .loop ; height loop + REP_RET +%endmacro + + +%macro HEVC_SAO_BAND_FILTER_FUNCS 0 +HEVC_SAO_BAND_FILTER 8, 0 +HEVC_SAO_BAND_FILTER 16, 1 +HEVC_SAO_BAND_FILTER 32, 2 +HEVC_SAO_BAND_FILTER 48, 2 +HEVC_SAO_BAND_FILTER 64, 4 +%endmacro + +INIT_XMM sse2 +HEVC_SAO_BAND_FILTER_FUNCS +INIT_XMM avx +HEVC_SAO_BAND_FILTER_FUNCS + +%if HAVE_AVX2_EXTERNAL +INIT_XMM avx2 +HEVC_SAO_BAND_FILTER 8, 0 +HEVC_SAO_BAND_FILTER 16, 1 +INIT_YMM avx2 +HEVC_SAO_BAND_FILTER 32, 1 +HEVC_SAO_BAND_FILTER 48, 1 +HEVC_SAO_BAND_FILTER 64, 2 +%endif + +;****************************************************************************** +;SAO Edge Filter +;****************************************************************************** + +%define MAX_PB_SIZE 64 +%define PADDING_SIZE 64 ; AV_INPUT_BUFFER_PADDING_SIZE +%define EDGE_SRCSTRIDE 2 * MAX_PB_SIZE + PADDING_SIZE + +%macro HEVC_SAO_EDGE_FILTER_INIT 0 +%if WIN64 + movsxd eoq, dword eom +%elif ARCH_X86_64 + movsxd eoq, eod +%else + mov eoq, r4m +%endif + lea tmp2q, [pb_eo] + movsx a_strideq, byte [tmp2q+eoq*4+1] + movsx b_strideq, byte [tmp2q+eoq*4+3] + imul a_strideq, EDGE_SRCSTRIDE + imul b_strideq, EDGE_SRCSTRIDE + movsx tmpq, byte [tmp2q+eoq*4] + add a_strideq, tmpq + movsx tmpq, byte [tmp2q+eoq*4+2] + add b_strideq, tmpq +%endmacro + +%macro HEVC_SAO_EDGE_FILTER_COMPUTE 1 + pminub m4, m1, m2 + pminub m5, m1, m3 + pcmpeqb m2, m4 + pcmpeqb m3, m5 + pcmpeqb m4, m1 + pcmpeqb m5, m1 + psubb m4, m2 + psubb m5, m3 + paddb m4, m6 + paddb m4, m5 + + pshufb m2, m0, m4 +%if %1 > 8 + punpckhbw m5, m7, m1 + punpckhbw m4, m2, m7 + punpcklbw m3, m7, m1 + punpcklbw m2, m7 + pmaddubsw m5, m4 + pmaddubsw m3, m2 + packuswb m3, m5 +%else + punpcklbw m3, m7, m1 + punpcklbw m2, m7 + pmaddubsw m3, m2 + packuswb m3, m3 +%endif +%endmacro + +;void ff_hevc_sao_edge_filter__8_(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, +; int eo, int width, int height); +%macro HEVC_SAO_EDGE_FILTER 2-3 +%if ARCH_X86_64 +cglobal hevc_sao_edge_filter_%1_8, 4, 9, 8, dst, src, dststride, offset, eo, a_stride, b_stride, height, tmp +%define tmp2q heightq + HEVC_SAO_EDGE_FILTER_INIT + mov heightd, r6m + +%else ; ARCH_X86_32 +cglobal hevc_sao_edge_filter_%1_8, 1, 6, 8, dst, src, dststride, a_stride, b_stride, height +%define eoq srcq +%define tmpq heightq +%define tmp2q dststrideq +%define offsetq heightq + HEVC_SAO_EDGE_FILTER_INIT + mov srcq, srcm + mov offsetq, r3m + mov dststrideq, dststridem +%endif ; ARCH + +%if mmsize > 16 + vbroadcasti128 m0, [offsetq] +%else + movu m0, [offsetq] +%endif + mova m1, [pb_edge_shuffle] + packsswb m0, m0 + mova m7, [pb_1] + pshufb m0, m1 + mova m6, [pb_2] +%if ARCH_X86_32 + mov heightd, r6m +%endif + +align 16 +.loop: + +%if %1 == 8 + movq m1, [srcq] + movq m2, [srcq + a_strideq] + movq m3, [srcq + b_strideq] + HEVC_SAO_EDGE_FILTER_COMPUTE %1 + movq [dstq], m3 +%endif + +%assign i 0 +%rep %2 + mova m1, [srcq + i] + movu m2, [srcq + a_strideq + i] + movu m3, [srcq + b_strideq + i] + HEVC_SAO_EDGE_FILTER_COMPUTE %1 + mov%3 [dstq + i], m3 +%assign i i+mmsize +%endrep + +%if %1 == 48 +INIT_XMM cpuname + + mova m1, [srcq + i] + movu m2, [srcq + a_strideq + i] + movu m3, [srcq + b_strideq + i] + HEVC_SAO_EDGE_FILTER_COMPUTE %1 + mova [dstq + i], m3 +%if cpuflag(avx2) +INIT_YMM cpuname +%endif +%endif + + add dstq, dststrideq + add srcq, EDGE_SRCSTRIDE + dec heightd + jg .loop + RET +%endmacro + +INIT_XMM ssse3 +HEVC_SAO_EDGE_FILTER 8, 0 +HEVC_SAO_EDGE_FILTER 16, 1, a +HEVC_SAO_EDGE_FILTER 32, 2, a +HEVC_SAO_EDGE_FILTER 48, 2, a +HEVC_SAO_EDGE_FILTER 64, 4, a + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +HEVC_SAO_EDGE_FILTER 32, 1, a +HEVC_SAO_EDGE_FILTER 48, 1, u +HEVC_SAO_EDGE_FILTER 64, 2, a +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_sao_10bit.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_sao_10bit.asm new file mode 100644 index 00000000..b30583dd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevc_sao_10bit.asm @@ -0,0 +1,370 @@ +;****************************************************************************** +;* SIMD optimized SAO functions for HEVC 10/12bit decoding +;* +;* Copyright (c) 2013 Pierre-Edouard LEPERE +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pw_m2: times 16 dw -2 +pw_mask10: times 16 dw 0x03FF +pw_mask12: times 16 dw 0x0FFF +pb_eo: db -1, 0, 1, 0, 0, -1, 0, 1, -1, -1, 1, 1, 1, -1, -1, 1 +cextern pw_m1 +cextern pw_1 +cextern pw_2 + +SECTION .text + +;****************************************************************************** +;SAO Band Filter +;****************************************************************************** + +%macro HEVC_SAO_BAND_FILTER_INIT 1 + and leftq, 31 + movd xm0, leftd + add leftq, 1 + and leftq, 31 + movd xm1, leftd + add leftq, 1 + and leftq, 31 + movd xm2, leftd + add leftq, 1 + and leftq, 31 + movd xm3, leftd + + SPLATW m0, xm0 + SPLATW m1, xm1 + SPLATW m2, xm2 + SPLATW m3, xm3 +%if mmsize > 16 + SPLATW m4, [offsetq + 2] + SPLATW m5, [offsetq + 4] + SPLATW m6, [offsetq + 6] + SPLATW m7, [offsetq + 8] +%else + movq m7, [offsetq + 2] + SPLATW m4, m7, 0 + SPLATW m5, m7, 1 + SPLATW m6, m7, 2 + SPLATW m7, m7, 3 +%endif + +%if ARCH_X86_64 + mova m13, [pw_mask %+ %1] + pxor m14, m14 + +%else ; ARCH_X86_32 + mova [rsp+mmsize*0], m0 + mova [rsp+mmsize*1], m1 + mova [rsp+mmsize*2], m2 + mova [rsp+mmsize*3], m3 + mova [rsp+mmsize*4], m4 + mova [rsp+mmsize*5], m5 + mova [rsp+mmsize*6], m6 + mova m1, [pw_mask %+ %1] + pxor m0, m0 + %define m14 m0 + %define m13 m1 + %define m9 m2 + %define m8 m3 +%endif ; ARCH +DEFINE_ARGS dst, src, dststride, srcstride, offset, height + mov heightd, r7m +%endmacro + +;void ff_hevc_sao_band_filter___(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, +; int16_t *sao_offset_val, int sao_left_class, int width, int height); +%macro HEVC_SAO_BAND_FILTER 3 +cglobal hevc_sao_band_filter_%2_%1, 6, 6, 15, 7*mmsize*ARCH_X86_32, dst, src, dststride, srcstride, offset, left + HEVC_SAO_BAND_FILTER_INIT %1 + +align 16 +.loop: + +%assign i 0 +%assign j 0 +%rep %3 +%assign k 8+(j&1) +%assign l 9-(j&1) + mova m %+ k, [srcq + i] + psraw m %+ l, m %+ k, %1-5 +%if ARCH_X86_64 + pcmpeqw m10, m %+ l, m0 + pcmpeqw m11, m %+ l, m1 + pcmpeqw m12, m %+ l, m2 + pcmpeqw m %+ l, m3 + pand m10, m4 + pand m11, m5 + pand m12, m6 + pand m %+ l, m7 + por m10, m11 + por m12, m %+ l + por m10, m12 + paddw m %+ k, m10 +%else ; ARCH_X86_32 + pcmpeqw m4, m %+ l, [rsp+mmsize*0] + pcmpeqw m5, m %+ l, [rsp+mmsize*1] + pcmpeqw m6, m %+ l, [rsp+mmsize*2] + pcmpeqw m %+ l, [rsp+mmsize*3] + pand m4, [rsp+mmsize*4] + pand m5, [rsp+mmsize*5] + pand m6, [rsp+mmsize*6] + pand m %+ l, m7 + por m4, m5 + por m6, m %+ l + por m4, m6 + paddw m %+ k, m4 +%endif ; ARCH + CLIPW m %+ k, m14, m13 + mova [dstq + i], m %+ k +%assign i i+mmsize +%assign j j+1 +%endrep + + add dstq, dststrideq + add srcq, srcstrideq + dec heightd + jg .loop + REP_RET +%endmacro + +%macro HEVC_SAO_BAND_FILTER_FUNCS 0 +HEVC_SAO_BAND_FILTER 10, 8, 1 +HEVC_SAO_BAND_FILTER 10, 16, 2 +HEVC_SAO_BAND_FILTER 10, 32, 4 +HEVC_SAO_BAND_FILTER 10, 48, 6 +HEVC_SAO_BAND_FILTER 10, 64, 8 + +HEVC_SAO_BAND_FILTER 12, 8, 1 +HEVC_SAO_BAND_FILTER 12, 16, 2 +HEVC_SAO_BAND_FILTER 12, 32, 4 +HEVC_SAO_BAND_FILTER 12, 48, 6 +HEVC_SAO_BAND_FILTER 12, 64, 8 +%endmacro + +INIT_XMM sse2 +HEVC_SAO_BAND_FILTER_FUNCS +INIT_XMM avx +HEVC_SAO_BAND_FILTER_FUNCS + +%if HAVE_AVX2_EXTERNAL +INIT_XMM avx2 +HEVC_SAO_BAND_FILTER 10, 8, 1 +INIT_YMM avx2 +HEVC_SAO_BAND_FILTER 10, 16, 1 +HEVC_SAO_BAND_FILTER 10, 32, 2 +HEVC_SAO_BAND_FILTER 10, 48, 3 +HEVC_SAO_BAND_FILTER 10, 64, 4 + +INIT_XMM avx2 +HEVC_SAO_BAND_FILTER 12, 8, 1 +INIT_YMM avx2 +HEVC_SAO_BAND_FILTER 12, 16, 1 +HEVC_SAO_BAND_FILTER 12, 32, 2 +HEVC_SAO_BAND_FILTER 12, 48, 3 +HEVC_SAO_BAND_FILTER 12, 64, 4 +%endif + +;****************************************************************************** +;SAO Edge Filter +;****************************************************************************** + +%define MAX_PB_SIZE 64 +%define PADDING_SIZE 64 ; AV_INPUT_BUFFER_PADDING_SIZE +%define EDGE_SRCSTRIDE 2 * MAX_PB_SIZE + PADDING_SIZE + +%macro PMINUW 4 +%if cpuflag(sse4) + pminuw %1, %2, %3 +%else + psubusw %4, %2, %3 + psubw %1, %2, %4 +%endif +%endmacro + +%macro HEVC_SAO_EDGE_FILTER_INIT 0 +%if WIN64 + movsxd eoq, dword eom +%elif ARCH_X86_64 + movsxd eoq, eod +%else + mov eoq, r4m +%endif + lea tmp2q, [pb_eo] + movsx a_strideq, byte [tmp2q+eoq*4+1] + movsx b_strideq, byte [tmp2q+eoq*4+3] + imul a_strideq, EDGE_SRCSTRIDE >> 1 + imul b_strideq, EDGE_SRCSTRIDE >> 1 + movsx tmpq, byte [tmp2q+eoq*4] + add a_strideq, tmpq + movsx tmpq, byte [tmp2q+eoq*4+2] + add b_strideq, tmpq +%endmacro + +;void ff_hevc_sao_edge_filter___(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, +; int eo, int width, int height); +%macro HEVC_SAO_EDGE_FILTER 3 +%if ARCH_X86_64 +cglobal hevc_sao_edge_filter_%2_%1, 4, 9, 16, dst, src, dststride, offset, eo, a_stride, b_stride, height, tmp +%define tmp2q heightq + HEVC_SAO_EDGE_FILTER_INIT + mov heightd, r6m + add a_strideq, a_strideq + add b_strideq, b_strideq + +%else ; ARCH_X86_32 +cglobal hevc_sao_edge_filter_%2_%1, 1, 6, 8, 5*mmsize, dst, src, dststride, a_stride, b_stride, height +%define eoq srcq +%define tmpq heightq +%define tmp2q dststrideq +%define offsetq heightq +%define m8 m1 +%define m9 m2 +%define m10 m3 +%define m11 m4 +%define m12 m5 + HEVC_SAO_EDGE_FILTER_INIT + mov srcq, srcm + mov offsetq, r3m + mov dststrideq, dststridem + add a_strideq, a_strideq + add b_strideq, b_strideq + +%endif ; ARCH + +%if mmsize > 16 + SPLATW m8, [offsetq+2] + SPLATW m9, [offsetq+4] + SPLATW m10, [offsetq+0] + SPLATW m11, [offsetq+6] + SPLATW m12, [offsetq+8] +%else + movq m10, [offsetq+0] + movd m12, [offsetq+6] + SPLATW m8, xm10, 1 + SPLATW m9, xm10, 2 + SPLATW m10, xm10, 0 + SPLATW m11, xm12, 0 + SPLATW m12, xm12, 1 +%endif + pxor m0, m0 +%if ARCH_X86_64 + mova m13, [pw_m1] + mova m14, [pw_1] + mova m15, [pw_2] +%else + mov heightd, r6m + mova [rsp+mmsize*0], m8 + mova [rsp+mmsize*1], m9 + mova [rsp+mmsize*2], m10 + mova [rsp+mmsize*3], m11 + mova [rsp+mmsize*4], m12 +%endif + +align 16 +.loop: + +%assign i 0 +%rep %3 + mova m1, [srcq + i] + movu m2, [srcq+a_strideq + i] + movu m3, [srcq+b_strideq + i] + PMINUW m4, m1, m2, m6 + PMINUW m5, m1, m3, m7 + pcmpeqw m2, m4 + pcmpeqw m3, m5 + pcmpeqw m4, m1 + pcmpeqw m5, m1 + psubw m4, m2 + psubw m5, m3 + + paddw m4, m5 + pcmpeqw m2, m4, [pw_m2] +%if ARCH_X86_64 + pcmpeqw m3, m4, m13 + pcmpeqw m5, m4, m0 + pcmpeqw m6, m4, m14 + pcmpeqw m7, m4, m15 + pand m2, m8 + pand m3, m9 + pand m5, m10 + pand m6, m11 + pand m7, m12 +%else + pcmpeqw m3, m4, [pw_m1] + pcmpeqw m5, m4, m0 + pcmpeqw m6, m4, [pw_1] + pcmpeqw m7, m4, [pw_2] + pand m2, [rsp+mmsize*0] + pand m3, [rsp+mmsize*1] + pand m5, [rsp+mmsize*2] + pand m6, [rsp+mmsize*3] + pand m7, [rsp+mmsize*4] +%endif + paddw m2, m3 + paddw m5, m6 + paddw m2, m7 + paddw m2, m1 + paddw m2, m5 + CLIPW m2, m0, [pw_mask %+ %1] + mova [dstq + i], m2 +%assign i i+mmsize +%endrep + + add dstq, dststrideq + add srcq, EDGE_SRCSTRIDE + dec heightd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +HEVC_SAO_EDGE_FILTER 10, 8, 1 +HEVC_SAO_EDGE_FILTER 10, 16, 2 +HEVC_SAO_EDGE_FILTER 10, 32, 4 +HEVC_SAO_EDGE_FILTER 10, 48, 6 +HEVC_SAO_EDGE_FILTER 10, 64, 8 + +HEVC_SAO_EDGE_FILTER 12, 8, 1 +HEVC_SAO_EDGE_FILTER 12, 16, 2 +HEVC_SAO_EDGE_FILTER 12, 32, 4 +HEVC_SAO_EDGE_FILTER 12, 48, 6 +HEVC_SAO_EDGE_FILTER 12, 64, 8 + +%if HAVE_AVX2_EXTERNAL +INIT_XMM avx2 +HEVC_SAO_EDGE_FILTER 10, 8, 1 +INIT_YMM avx2 +HEVC_SAO_EDGE_FILTER 10, 16, 1 +HEVC_SAO_EDGE_FILTER 10, 32, 2 +HEVC_SAO_EDGE_FILTER 10, 48, 3 +HEVC_SAO_EDGE_FILTER 10, 64, 4 + +INIT_XMM avx2 +HEVC_SAO_EDGE_FILTER 12, 8, 1 +INIT_YMM avx2 +HEVC_SAO_EDGE_FILTER 12, 16, 1 +HEVC_SAO_EDGE_FILTER 12, 32, 2 +HEVC_SAO_EDGE_FILTER 12, 48, 3 +HEVC_SAO_EDGE_FILTER 12, 64, 4 +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevcdsp.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevcdsp.h new file mode 100644 index 00000000..67be0a90 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevcdsp.h @@ -0,0 +1,259 @@ +/* + * HEVC video decoder + * + * Copyright (C) 2012 - 2013 Guillaume Martres + * Copyright (C) 2013 - 2014 Pierre-Edouard Lepere + * + * + * 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 + */ + +#ifndef AVCODEC_X86_HEVCDSP_H +#define AVCODEC_X86_HEVCDSP_H + +#include +#include + + +#define PEL_LINK(dst, idx1, idx2, idx3, name, D, opt) \ +dst[idx1][idx2][idx3] = ff_hevc_put_hevc_ ## name ## _ ## D ## _##opt; \ +dst ## _bi[idx1][idx2][idx3] = ff_hevc_put_hevc_bi_ ## name ## _ ## D ## _##opt; \ +dst ## _uni[idx1][idx2][idx3] = ff_hevc_put_hevc_uni_ ## name ## _ ## D ## _##opt; \ +dst ## _uni_w[idx1][idx2][idx3] = ff_hevc_put_hevc_uni_w_ ## name ## _ ## D ## _##opt; \ +dst ## _bi_w[idx1][idx2][idx3] = ff_hevc_put_hevc_bi_w_ ## name ## _ ## D ## _##opt + + +#define PEL_PROTOTYPE(name, D, opt) \ +void ff_hevc_put_hevc_ ## name ## _ ## D ## _##opt(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); \ +void ff_hevc_put_hevc_bi_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); \ +void ff_hevc_put_hevc_uni_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my, int width); \ +void ff_hevc_put_hevc_uni_w_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int height, int denom, int wx, int ox, intptr_t mx, intptr_t my, int width); \ +void ff_hevc_put_hevc_bi_w_ ## name ## _ ## D ## _##opt(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, int denom, int wx0, int wx1, int ox0, int ox1, intptr_t mx, intptr_t my, int width) + + +/////////////////////////////////////////////////////////////////////////////// +// MC functions +/////////////////////////////////////////////////////////////////////////////// + +#define EPEL_PROTOTYPES(fname, bitd, opt) \ + PEL_PROTOTYPE(fname##4, bitd, opt); \ + PEL_PROTOTYPE(fname##6, bitd, opt); \ + PEL_PROTOTYPE(fname##8, bitd, opt); \ + PEL_PROTOTYPE(fname##12, bitd, opt); \ + PEL_PROTOTYPE(fname##16, bitd, opt); \ + PEL_PROTOTYPE(fname##24, bitd, opt); \ + PEL_PROTOTYPE(fname##32, bitd, opt); \ + PEL_PROTOTYPE(fname##48, bitd, opt); \ + PEL_PROTOTYPE(fname##64, bitd, opt) + +#define QPEL_PROTOTYPES(fname, bitd, opt) \ + PEL_PROTOTYPE(fname##4, bitd, opt); \ + PEL_PROTOTYPE(fname##8, bitd, opt); \ + PEL_PROTOTYPE(fname##12, bitd, opt); \ + PEL_PROTOTYPE(fname##16, bitd, opt); \ + PEL_PROTOTYPE(fname##24, bitd, opt); \ + PEL_PROTOTYPE(fname##32, bitd, opt); \ + PEL_PROTOTYPE(fname##48, bitd, opt); \ + PEL_PROTOTYPE(fname##64, bitd, opt) + +#define WEIGHTING_PROTOTYPE(width, bitd, opt) \ +void ff_hevc_put_hevc_uni_w##width##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, int16_t *_src, int height, int denom, int _wx, int _ox); \ +void ff_hevc_put_hevc_bi_w##width##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, int16_t *_src, int16_t *_src2, int height, int denom, int _wx0, int _wx1, int _ox0, int _ox1) + +#define WEIGHTING_PROTOTYPES(bitd, opt) \ + WEIGHTING_PROTOTYPE(2, bitd, opt); \ + WEIGHTING_PROTOTYPE(4, bitd, opt); \ + WEIGHTING_PROTOTYPE(6, bitd, opt); \ + WEIGHTING_PROTOTYPE(8, bitd, opt); \ + WEIGHTING_PROTOTYPE(12, bitd, opt); \ + WEIGHTING_PROTOTYPE(16, bitd, opt); \ + WEIGHTING_PROTOTYPE(24, bitd, opt); \ + WEIGHTING_PROTOTYPE(32, bitd, opt); \ + WEIGHTING_PROTOTYPE(48, bitd, opt); \ + WEIGHTING_PROTOTYPE(64, bitd, opt) + + +/////////////////////////////////////////////////////////////////////////////// +// QPEL_PIXELS EPEL_PIXELS +/////////////////////////////////////////////////////////////////////////////// +EPEL_PROTOTYPES(pel_pixels , 8, sse4); +EPEL_PROTOTYPES(pel_pixels , 10, sse4); +EPEL_PROTOTYPES(pel_pixels , 12, sse4); + +void ff_hevc_put_hevc_pel_pixels16_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels24_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels32_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels48_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels64_8_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); + +void ff_hevc_put_hevc_pel_pixels16_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels24_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels32_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels48_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_pel_pixels64_10_avx2(int16_t *dst, uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); + + + +void ff_hevc_put_hevc_uni_pel_pixels32_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_uni_pel_pixels48_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_uni_pel_pixels64_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); +void ff_hevc_put_hevc_uni_pel_pixels96_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width); //used for 10bit +void ff_hevc_put_hevc_uni_pel_pixels128_8_avx2(uint8_t *dst, ptrdiff_t dststride,uint8_t *_src, ptrdiff_t _srcstride, int height, intptr_t mx, intptr_t my,int width);//used for 10bit + + +void ff_hevc_put_hevc_bi_pel_pixels16_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels24_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels32_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels48_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels64_8_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); + +void ff_hevc_put_hevc_bi_pel_pixels16_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels24_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels32_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels48_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); +void ff_hevc_put_hevc_bi_pel_pixels64_10_avx2(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride, int16_t *src2, int height, intptr_t mx, intptr_t my, int width); + +/////////////////////////////////////////////////////////////////////////////// +// EPEL +/////////////////////////////////////////////////////////////////////////////// +EPEL_PROTOTYPES(epel_h , 8, sse4); +EPEL_PROTOTYPES(epel_h , 10, sse4); +EPEL_PROTOTYPES(epel_h , 12, sse4); + +EPEL_PROTOTYPES(epel_v , 8, sse4); +EPEL_PROTOTYPES(epel_v , 10, sse4); +EPEL_PROTOTYPES(epel_v , 12, sse4); + +EPEL_PROTOTYPES(epel_hv , 8, sse4); +EPEL_PROTOTYPES(epel_hv , 10, sse4); +EPEL_PROTOTYPES(epel_hv , 12, sse4); + +PEL_PROTOTYPE(epel_h16, 8, avx2); +PEL_PROTOTYPE(epel_h24, 8, avx2); +PEL_PROTOTYPE(epel_h32, 8, avx2); +PEL_PROTOTYPE(epel_h48, 8, avx2); +PEL_PROTOTYPE(epel_h64, 8, avx2); + +PEL_PROTOTYPE(epel_h16,10, avx2); +PEL_PROTOTYPE(epel_h24,10, avx2); +PEL_PROTOTYPE(epel_h32,10, avx2); +PEL_PROTOTYPE(epel_h48,10, avx2); +PEL_PROTOTYPE(epel_h64,10, avx2); + +PEL_PROTOTYPE(epel_v16, 8, avx2); +PEL_PROTOTYPE(epel_v24, 8, avx2); +PEL_PROTOTYPE(epel_v32, 8, avx2); +PEL_PROTOTYPE(epel_v48, 8, avx2); +PEL_PROTOTYPE(epel_v64, 8, avx2); + +PEL_PROTOTYPE(epel_v16,10, avx2); +PEL_PROTOTYPE(epel_v24,10, avx2); +PEL_PROTOTYPE(epel_v32,10, avx2); +PEL_PROTOTYPE(epel_v48,10, avx2); +PEL_PROTOTYPE(epel_v64,10, avx2); + +PEL_PROTOTYPE(epel_hv16, 8, avx2); +PEL_PROTOTYPE(epel_hv24, 8, avx2); +PEL_PROTOTYPE(epel_hv32, 8, avx2); +PEL_PROTOTYPE(epel_hv48, 8, avx2); +PEL_PROTOTYPE(epel_hv64, 8, avx2); + +PEL_PROTOTYPE(epel_hv16,10, avx2); +PEL_PROTOTYPE(epel_hv24,10, avx2); +PEL_PROTOTYPE(epel_hv32,10, avx2); +PEL_PROTOTYPE(epel_hv48,10, avx2); +PEL_PROTOTYPE(epel_hv64,10, avx2); + +/////////////////////////////////////////////////////////////////////////////// +// QPEL +/////////////////////////////////////////////////////////////////////////////// +QPEL_PROTOTYPES(qpel_h , 8, sse4); +QPEL_PROTOTYPES(qpel_h , 10, sse4); +QPEL_PROTOTYPES(qpel_h , 12, sse4); + +QPEL_PROTOTYPES(qpel_v, 8, sse4); +QPEL_PROTOTYPES(qpel_v, 10, sse4); +QPEL_PROTOTYPES(qpel_v, 12, sse4); + +QPEL_PROTOTYPES(qpel_hv, 8, sse4); +QPEL_PROTOTYPES(qpel_hv, 10, sse4); +QPEL_PROTOTYPES(qpel_hv, 12, sse4); + +PEL_PROTOTYPE(qpel_h16, 8, avx2); +PEL_PROTOTYPE(qpel_h24, 8, avx2); +PEL_PROTOTYPE(qpel_h32, 8, avx2); +PEL_PROTOTYPE(qpel_h48, 8, avx2); +PEL_PROTOTYPE(qpel_h64, 8, avx2); + +PEL_PROTOTYPE(qpel_h16,10, avx2); +PEL_PROTOTYPE(qpel_h24,10, avx2); +PEL_PROTOTYPE(qpel_h32,10, avx2); +PEL_PROTOTYPE(qpel_h48,10, avx2); +PEL_PROTOTYPE(qpel_h64,10, avx2); + +PEL_PROTOTYPE(qpel_v16, 8, avx2); +PEL_PROTOTYPE(qpel_v24, 8, avx2); +PEL_PROTOTYPE(qpel_v32, 8, avx2); +PEL_PROTOTYPE(qpel_v48, 8, avx2); +PEL_PROTOTYPE(qpel_v64, 8, avx2); + +PEL_PROTOTYPE(qpel_v16,10, avx2); +PEL_PROTOTYPE(qpel_v24,10, avx2); +PEL_PROTOTYPE(qpel_v32,10, avx2); +PEL_PROTOTYPE(qpel_v48,10, avx2); +PEL_PROTOTYPE(qpel_v64,10, avx2); + +PEL_PROTOTYPE(qpel_hv16, 8, avx2); +PEL_PROTOTYPE(qpel_hv24, 8, avx2); +PEL_PROTOTYPE(qpel_hv32, 8, avx2); +PEL_PROTOTYPE(qpel_hv48, 8, avx2); +PEL_PROTOTYPE(qpel_hv64, 8, avx2); + +PEL_PROTOTYPE(qpel_hv16,10, avx2); +PEL_PROTOTYPE(qpel_hv24,10, avx2); +PEL_PROTOTYPE(qpel_hv32,10, avx2); +PEL_PROTOTYPE(qpel_hv48,10, avx2); +PEL_PROTOTYPE(qpel_hv64,10, avx2); + +WEIGHTING_PROTOTYPES(8, sse4); +WEIGHTING_PROTOTYPES(10, sse4); +WEIGHTING_PROTOTYPES(12, sse4); + +/////////////////////////////////////////////////////////////////////////////// +// TRANSFORM_ADD +/////////////////////////////////////////////////////////////////////////////// + +void ff_hevc_add_residual_4_8_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_8_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_8_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_8_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_8_avx(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_32_8_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_4_10_mmxext(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_8_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_16_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_10_sse2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +void ff_hevc_add_residual_16_10_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); +void ff_hevc_add_residual_32_10_avx2(uint8_t *dst, int16_t *res, ptrdiff_t stride); + +#endif // AVCODEC_X86_HEVCDSP_H diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevcdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevcdsp_init.c new file mode 100644 index 00000000..8a3fa274 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hevcdsp_init.c @@ -0,0 +1,1152 @@ +/* + * Copyright (c) 2013 Seppo Tomperi + * Copyright (c) 2013 - 2014 Pierre-Edouard Lepere + * + * 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.h" + +#include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/get_bits.h" /* required for hevcdsp.h GetBitContext */ +#include "libavcodec/hevcdsp.h" +#include "libavcodec/x86/hevcdsp.h" + +#define LFC_FUNC(DIR, DEPTH, OPT) \ +void ff_hevc_ ## DIR ## _loop_filter_chroma_ ## DEPTH ## _ ## OPT(uint8_t *pix, ptrdiff_t stride, int *tc, uint8_t *no_p, uint8_t *no_q); + +#define LFL_FUNC(DIR, DEPTH, OPT) \ +void ff_hevc_ ## DIR ## _loop_filter_luma_ ## DEPTH ## _ ## OPT(uint8_t *pix, ptrdiff_t stride, int beta, int *tc, uint8_t *no_p, uint8_t *no_q); + +#define LFC_FUNCS(type, depth, opt) \ + LFC_FUNC(h, depth, opt) \ + LFC_FUNC(v, depth, opt) + +#define LFL_FUNCS(type, depth, opt) \ + LFL_FUNC(h, depth, opt) \ + LFL_FUNC(v, depth, opt) + +LFC_FUNCS(uint8_t, 8, sse2) +LFC_FUNCS(uint8_t, 10, sse2) +LFC_FUNCS(uint8_t, 12, sse2) +LFC_FUNCS(uint8_t, 8, avx) +LFC_FUNCS(uint8_t, 10, avx) +LFC_FUNCS(uint8_t, 12, avx) +LFL_FUNCS(uint8_t, 8, sse2) +LFL_FUNCS(uint8_t, 10, sse2) +LFL_FUNCS(uint8_t, 12, sse2) +LFL_FUNCS(uint8_t, 8, ssse3) +LFL_FUNCS(uint8_t, 10, ssse3) +LFL_FUNCS(uint8_t, 12, ssse3) +LFL_FUNCS(uint8_t, 8, avx) +LFL_FUNCS(uint8_t, 10, avx) +LFL_FUNCS(uint8_t, 12, avx) + +#define IDCT_DC_FUNCS(W, opt) \ +void ff_hevc_idct_ ## W ## _dc_8_ ## opt(int16_t *coeffs); \ +void ff_hevc_idct_ ## W ## _dc_10_ ## opt(int16_t *coeffs); \ +void ff_hevc_idct_ ## W ## _dc_12_ ## opt(int16_t *coeffs) + +IDCT_DC_FUNCS(4x4, mmxext); +IDCT_DC_FUNCS(8x8, mmxext); +IDCT_DC_FUNCS(8x8, sse2); +IDCT_DC_FUNCS(16x16, sse2); +IDCT_DC_FUNCS(32x32, sse2); +IDCT_DC_FUNCS(16x16, avx2); +IDCT_DC_FUNCS(32x32, avx2); + +#define IDCT_FUNCS(opt) \ +void ff_hevc_idct_4x4_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_4x4_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_8x8_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_8x8_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_16x16_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_16x16_10_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_32x32_8_ ## opt(int16_t *coeffs, int col_limit); \ +void ff_hevc_idct_32x32_10_ ## opt(int16_t *coeffs, int col_limit); + +IDCT_FUNCS(sse2) +IDCT_FUNCS(avx) + +#define mc_rep_func(name, bitd, step, W, opt) \ +void ff_hevc_put_hevc_##name##W##_##bitd##_##opt(int16_t *_dst, \ + uint8_t *_src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + int i; \ + uint8_t *src; \ + int16_t *dst; \ + for (i = 0; i < W; i += step) { \ + src = _src + (i * ((bitd + 7) / 8)); \ + dst = _dst + i; \ + ff_hevc_put_hevc_##name##step##_##bitd##_##opt(dst, src, _srcstride, height, mx, my, width); \ + } \ +} +#define mc_rep_uni_func(name, bitd, step, W, opt) \ +void ff_hevc_put_hevc_uni_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, \ + uint8_t *_src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + int i; \ + uint8_t *src; \ + uint8_t *dst; \ + for (i = 0; i < W; i += step) { \ + src = _src + (i * ((bitd + 7) / 8)); \ + dst = _dst + (i * ((bitd + 7) / 8)); \ + ff_hevc_put_hevc_uni_##name##step##_##bitd##_##opt(dst, dststride, src, _srcstride, \ + height, mx, my, width); \ + } \ +} +#define mc_rep_bi_func(name, bitd, step, W, opt) \ +void ff_hevc_put_hevc_bi_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, uint8_t *_src, \ + ptrdiff_t _srcstride, int16_t* _src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + int i; \ + uint8_t *src; \ + uint8_t *dst; \ + int16_t *src2; \ + for (i = 0; i < W ; i += step) { \ + src = _src + (i * ((bitd + 7) / 8)); \ + dst = _dst + (i * ((bitd + 7) / 8)); \ + src2 = _src2 + i; \ + ff_hevc_put_hevc_bi_##name##step##_##bitd##_##opt(dst, dststride, src, _srcstride, src2, \ + height, mx, my, width); \ + } \ +} + +#define mc_rep_funcs(name, bitd, step, W, opt) \ + mc_rep_func(name, bitd, step, W, opt) \ + mc_rep_uni_func(name, bitd, step, W, opt) \ + mc_rep_bi_func(name, bitd, step, W, opt) + +#define mc_rep_func2(name, bitd, step1, step2, W, opt) \ +void ff_hevc_put_hevc_##name##W##_##bitd##_##opt(int16_t *dst, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_##name##step1##_##bitd##_##opt(dst, src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_##name##step2##_##bitd##_##opt(dst + step1, src + (step1 * ((bitd + 7) / 8)), \ + _srcstride, height, mx, my, width); \ +} +#define mc_rep_uni_func2(name, bitd, step1, step2, W, opt) \ +void ff_hevc_put_hevc_uni_##name##W##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_uni_##name##step1##_##bitd##_##opt(dst, dststride, src, _srcstride, height, mx, my, width);\ + ff_hevc_put_hevc_uni_##name##step2##_##bitd##_##opt(dst + (step1 * ((bitd + 7) / 8)), dststride, \ + src + (step1 * ((bitd + 7) / 8)), _srcstride, \ + height, mx, my, width); \ +} +#define mc_rep_bi_func2(name, bitd, step1, step2, W, opt) \ +void ff_hevc_put_hevc_bi_##name##W##_##bitd##_##opt(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t _srcstride, int16_t* src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_bi_##name##step1##_##bitd##_##opt(dst, dststride, src, _srcstride, src2, height, mx, my, width);\ + ff_hevc_put_hevc_bi_##name##step2##_##bitd##_##opt(dst + (step1 * ((bitd + 7) / 8)), dststride, \ + src + (step1 * ((bitd + 7) / 8)), _srcstride, \ + src2 + step1, height, mx, my, width); \ +} + +#define mc_rep_funcs2(name, bitd, step1, step2, W, opt) \ + mc_rep_func2(name, bitd, step1, step2, W, opt) \ + mc_rep_uni_func2(name, bitd, step1, step2, W, opt) \ + mc_rep_bi_func2(name, bitd, step1, step2, W, opt) + +#if ARCH_X86_64 && HAVE_SSE4_EXTERNAL + +#define mc_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +void ff_hevc_put_hevc_##name##width1##_10_##opt1(int16_t *dst, uint8_t *src, ptrdiff_t _srcstride, \ + int height, intptr_t mx, intptr_t my, int width) \ + \ +{ \ + ff_hevc_put_hevc_##name##width2##_10_##opt1(dst, src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_##name##width3##_10_##opt2(dst+ width2, src+ width4, _srcstride, height, mx, my, width); \ +} + +#define mc_bi_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +void ff_hevc_put_hevc_bi_##name##width1##_10_##opt1(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t _srcstride, int16_t *src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_bi_##name##width2##_10_##opt1(dst, dststride, src, _srcstride, src2, \ + height, mx, my, width); \ + ff_hevc_put_hevc_bi_##name##width3##_10_##opt2(dst+width4, dststride, src+width4, _srcstride, src2+width2,\ + height, mx, my, width); \ +} + +#define mc_uni_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +void ff_hevc_put_hevc_uni_##name##width1##_10_##opt1(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_uni_##name##width2##_10_##opt1(dst, dststride, src, _srcstride, \ + height, mx, my, width); \ + ff_hevc_put_hevc_uni_##name##width3##_10_##opt2(dst+width4, dststride, src+width4, _srcstride, \ + height, mx, my, width); \ +} + +#define mc_rep_mixs_10(name, width1, width2, width3, opt1, opt2, width4) \ +mc_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +mc_bi_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) \ +mc_uni_rep_mix_10(name, width1, width2, width3, opt1, opt2, width4) + +#define mc_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +void ff_hevc_put_hevc_##name##width1##_8_##opt1(int16_t *dst, uint8_t *src, ptrdiff_t _srcstride, \ + int height, intptr_t mx, intptr_t my, int width) \ + \ +{ \ + ff_hevc_put_hevc_##name##width2##_8_##opt1(dst, src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_##name##width3##_8_##opt2(dst+ width2, src+ width2, _srcstride, height, mx, my, width); \ +} + +#define mc_bi_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +void ff_hevc_put_hevc_bi_##name##width1##_8_##opt1(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t _srcstride, int16_t* src2, \ + int height, intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_bi_##name##width2##_8_##opt1(dst, dststride, src, _srcstride, \ + src2, height, mx, my, width); \ + ff_hevc_put_hevc_bi_##name##width3##_8_##opt2(dst+width2, dststride, src+width2, _srcstride, \ + src2+width2, height, mx, my, width); \ +} + +#define mc_uni_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +void ff_hevc_put_hevc_uni_##name##width1##_8_##opt1(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t _srcstride, int height, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + ff_hevc_put_hevc_uni_##name##width2##_8_##opt1(dst, dststride, src, _srcstride, \ + height, mx, my, width); \ + ff_hevc_put_hevc_uni_##name##width3##_8_##opt2(dst+width2, dststride, src+width2, _srcstride, \ + height, mx, my, width); \ +} + +#define mc_rep_mixs_8(name, width1, width2, width3, opt1, opt2) \ +mc_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +mc_bi_rep_mix_8(name, width1, width2, width3, opt1, opt2) \ +mc_uni_rep_mix_8(name, width1, width2, width3, opt1, opt2) + +#if HAVE_AVX2_EXTERNAL + +mc_rep_mixs_8(pel_pixels, 48, 32, 16, avx2, sse4) +mc_rep_mixs_8(epel_hv, 48, 32, 16, avx2, sse4) +mc_rep_mixs_8(epel_h , 48, 32, 16, avx2, sse4) +mc_rep_mixs_8(epel_v , 48, 32, 16, avx2, sse4) + +mc_rep_mix_10(pel_pixels, 24, 16, 8, avx2, sse4, 32) +mc_bi_rep_mix_10(pel_pixels,24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(epel_hv, 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(epel_h , 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(epel_v , 24, 16, 8, avx2, sse4, 32) + + +mc_rep_mixs_10(qpel_h , 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(qpel_v , 24, 16, 8, avx2, sse4, 32) +mc_rep_mixs_10(qpel_hv, 24, 16, 8, avx2, sse4, 32) + + +mc_rep_uni_func(pel_pixels, 8, 64, 128, avx2)//used for 10bit +mc_rep_uni_func(pel_pixels, 8, 32, 96, avx2) //used for 10bit + +mc_rep_funcs(pel_pixels, 8, 32, 64, avx2) + +mc_rep_func(pel_pixels, 10, 16, 32, avx2) +mc_rep_func(pel_pixels, 10, 16, 48, avx2) +mc_rep_func(pel_pixels, 10, 32, 64, avx2) + +mc_rep_bi_func(pel_pixels, 10, 16, 32, avx2) +mc_rep_bi_func(pel_pixels, 10, 16, 48, avx2) +mc_rep_bi_func(pel_pixels, 10, 32, 64, avx2) + +mc_rep_funcs(epel_h, 8, 32, 64, avx2) + +mc_rep_funcs(epel_v, 8, 32, 64, avx2) + +mc_rep_funcs(epel_h, 10, 16, 32, avx2) +mc_rep_funcs(epel_h, 10, 16, 48, avx2) +mc_rep_funcs(epel_h, 10, 32, 64, avx2) + +mc_rep_funcs(epel_v, 10, 16, 32, avx2) +mc_rep_funcs(epel_v, 10, 16, 48, avx2) +mc_rep_funcs(epel_v, 10, 32, 64, avx2) + + +mc_rep_funcs(epel_hv, 8, 32, 64, avx2) + +mc_rep_funcs(epel_hv, 10, 16, 32, avx2) +mc_rep_funcs(epel_hv, 10, 16, 48, avx2) +mc_rep_funcs(epel_hv, 10, 32, 64, avx2) + +mc_rep_funcs(qpel_h, 8, 32, 64, avx2) +mc_rep_mixs_8(qpel_h , 48, 32, 16, avx2, sse4) + +mc_rep_funcs(qpel_v, 8, 32, 64, avx2) +mc_rep_mixs_8(qpel_v, 48, 32, 16, avx2, sse4) + +mc_rep_funcs(qpel_h, 10, 16, 32, avx2) +mc_rep_funcs(qpel_h, 10, 16, 48, avx2) +mc_rep_funcs(qpel_h, 10, 32, 64, avx2) + +mc_rep_funcs(qpel_v, 10, 16, 32, avx2) +mc_rep_funcs(qpel_v, 10, 16, 48, avx2) +mc_rep_funcs(qpel_v, 10, 32, 64, avx2) + +mc_rep_funcs(qpel_hv, 10, 16, 32, avx2) +mc_rep_funcs(qpel_hv, 10, 16, 48, avx2) +mc_rep_funcs(qpel_hv, 10, 32, 64, avx2) + +#endif //AVX2 + +mc_rep_funcs(pel_pixels, 8, 16, 64, sse4) +mc_rep_funcs(pel_pixels, 8, 16, 48, sse4) +mc_rep_funcs(pel_pixels, 8, 16, 32, sse4) +mc_rep_funcs(pel_pixels, 8, 8, 24, sse4) +mc_rep_funcs(pel_pixels,10, 8, 64, sse4) +mc_rep_funcs(pel_pixels,10, 8, 48, sse4) +mc_rep_funcs(pel_pixels,10, 8, 32, sse4) +mc_rep_funcs(pel_pixels,10, 8, 24, sse4) +mc_rep_funcs(pel_pixels,10, 8, 16, sse4) +mc_rep_funcs(pel_pixels,10, 4, 12, sse4) +mc_rep_funcs(pel_pixels,12, 8, 64, sse4) +mc_rep_funcs(pel_pixels,12, 8, 48, sse4) +mc_rep_funcs(pel_pixels,12, 8, 32, sse4) +mc_rep_funcs(pel_pixels,12, 8, 24, sse4) +mc_rep_funcs(pel_pixels,12, 8, 16, sse4) +mc_rep_funcs(pel_pixels,12, 4, 12, sse4) + +mc_rep_funcs(epel_h, 8, 16, 64, sse4) +mc_rep_funcs(epel_h, 8, 16, 48, sse4) +mc_rep_funcs(epel_h, 8, 16, 32, sse4) +mc_rep_funcs(epel_h, 8, 8, 24, sse4) +mc_rep_funcs(epel_h,10, 8, 64, sse4) +mc_rep_funcs(epel_h,10, 8, 48, sse4) +mc_rep_funcs(epel_h,10, 8, 32, sse4) +mc_rep_funcs(epel_h,10, 8, 24, sse4) +mc_rep_funcs(epel_h,10, 8, 16, sse4) +mc_rep_funcs(epel_h,10, 4, 12, sse4) +mc_rep_funcs(epel_h,12, 8, 64, sse4) +mc_rep_funcs(epel_h,12, 8, 48, sse4) +mc_rep_funcs(epel_h,12, 8, 32, sse4) +mc_rep_funcs(epel_h,12, 8, 24, sse4) +mc_rep_funcs(epel_h,12, 8, 16, sse4) +mc_rep_funcs(epel_h,12, 4, 12, sse4) +mc_rep_funcs(epel_v, 8, 16, 64, sse4) +mc_rep_funcs(epel_v, 8, 16, 48, sse4) +mc_rep_funcs(epel_v, 8, 16, 32, sse4) +mc_rep_funcs(epel_v, 8, 8, 24, sse4) +mc_rep_funcs(epel_v,10, 8, 64, sse4) +mc_rep_funcs(epel_v,10, 8, 48, sse4) +mc_rep_funcs(epel_v,10, 8, 32, sse4) +mc_rep_funcs(epel_v,10, 8, 24, sse4) +mc_rep_funcs(epel_v,10, 8, 16, sse4) +mc_rep_funcs(epel_v,10, 4, 12, sse4) +mc_rep_funcs(epel_v,12, 8, 64, sse4) +mc_rep_funcs(epel_v,12, 8, 48, sse4) +mc_rep_funcs(epel_v,12, 8, 32, sse4) +mc_rep_funcs(epel_v,12, 8, 24, sse4) +mc_rep_funcs(epel_v,12, 8, 16, sse4) +mc_rep_funcs(epel_v,12, 4, 12, sse4) +mc_rep_funcs(epel_hv, 8, 16, 64, sse4) +mc_rep_funcs(epel_hv, 8, 16, 48, sse4) +mc_rep_funcs(epel_hv, 8, 16, 32, sse4) +mc_rep_funcs(epel_hv, 8, 8, 24, sse4) +mc_rep_funcs2(epel_hv,8, 8, 4, 12, sse4) +mc_rep_funcs(epel_hv,10, 8, 64, sse4) +mc_rep_funcs(epel_hv,10, 8, 48, sse4) +mc_rep_funcs(epel_hv,10, 8, 32, sse4) +mc_rep_funcs(epel_hv,10, 8, 24, sse4) +mc_rep_funcs(epel_hv,10, 8, 16, sse4) +mc_rep_funcs(epel_hv,10, 4, 12, sse4) +mc_rep_funcs(epel_hv,12, 8, 64, sse4) +mc_rep_funcs(epel_hv,12, 8, 48, sse4) +mc_rep_funcs(epel_hv,12, 8, 32, sse4) +mc_rep_funcs(epel_hv,12, 8, 24, sse4) +mc_rep_funcs(epel_hv,12, 8, 16, sse4) +mc_rep_funcs(epel_hv,12, 4, 12, sse4) + +mc_rep_funcs(qpel_h, 8, 16, 64, sse4) +mc_rep_funcs(qpel_h, 8, 16, 48, sse4) +mc_rep_funcs(qpel_h, 8, 16, 32, sse4) +mc_rep_funcs(qpel_h, 8, 8, 24, sse4) +mc_rep_funcs(qpel_h,10, 8, 64, sse4) +mc_rep_funcs(qpel_h,10, 8, 48, sse4) +mc_rep_funcs(qpel_h,10, 8, 32, sse4) +mc_rep_funcs(qpel_h,10, 8, 24, sse4) +mc_rep_funcs(qpel_h,10, 8, 16, sse4) +mc_rep_funcs(qpel_h,10, 4, 12, sse4) +mc_rep_funcs(qpel_h,12, 8, 64, sse4) +mc_rep_funcs(qpel_h,12, 8, 48, sse4) +mc_rep_funcs(qpel_h,12, 8, 32, sse4) +mc_rep_funcs(qpel_h,12, 8, 24, sse4) +mc_rep_funcs(qpel_h,12, 8, 16, sse4) +mc_rep_funcs(qpel_h,12, 4, 12, sse4) +mc_rep_funcs(qpel_v, 8, 16, 64, sse4) +mc_rep_funcs(qpel_v, 8, 16, 48, sse4) +mc_rep_funcs(qpel_v, 8, 16, 32, sse4) +mc_rep_funcs(qpel_v, 8, 8, 24, sse4) +mc_rep_funcs(qpel_v,10, 8, 64, sse4) +mc_rep_funcs(qpel_v,10, 8, 48, sse4) +mc_rep_funcs(qpel_v,10, 8, 32, sse4) +mc_rep_funcs(qpel_v,10, 8, 24, sse4) +mc_rep_funcs(qpel_v,10, 8, 16, sse4) +mc_rep_funcs(qpel_v,10, 4, 12, sse4) +mc_rep_funcs(qpel_v,12, 8, 64, sse4) +mc_rep_funcs(qpel_v,12, 8, 48, sse4) +mc_rep_funcs(qpel_v,12, 8, 32, sse4) +mc_rep_funcs(qpel_v,12, 8, 24, sse4) +mc_rep_funcs(qpel_v,12, 8, 16, sse4) +mc_rep_funcs(qpel_v,12, 4, 12, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 64, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 48, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 32, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 24, sse4) +mc_rep_funcs(qpel_hv, 8, 8, 16, sse4) +mc_rep_funcs2(qpel_hv,8, 8, 4, 12, sse4) +mc_rep_funcs(qpel_hv,10, 8, 64, sse4) +mc_rep_funcs(qpel_hv,10, 8, 48, sse4) +mc_rep_funcs(qpel_hv,10, 8, 32, sse4) +mc_rep_funcs(qpel_hv,10, 8, 24, sse4) +mc_rep_funcs(qpel_hv,10, 8, 16, sse4) +mc_rep_funcs(qpel_hv,10, 4, 12, sse4) +mc_rep_funcs(qpel_hv,12, 8, 64, sse4) +mc_rep_funcs(qpel_hv,12, 8, 48, sse4) +mc_rep_funcs(qpel_hv,12, 8, 32, sse4) +mc_rep_funcs(qpel_hv,12, 8, 24, sse4) +mc_rep_funcs(qpel_hv,12, 8, 16, sse4) +mc_rep_funcs(qpel_hv,12, 4, 12, sse4) + +#define mc_rep_uni_w(bitd, step, W, opt) \ +void ff_hevc_put_hevc_uni_w##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, int16_t *_src, \ + int height, int denom, int _wx, int _ox) \ +{ \ + int i; \ + int16_t *src; \ + uint8_t *dst; \ + for (i = 0; i < W; i += step) { \ + src= _src + i; \ + dst= _dst + (i * ((bitd + 7) / 8)); \ + ff_hevc_put_hevc_uni_w##step##_##bitd##_##opt(dst, dststride, src, \ + height, denom, _wx, _ox); \ + } \ +} + +mc_rep_uni_w(8, 6, 12, sse4) +mc_rep_uni_w(8, 8, 16, sse4) +mc_rep_uni_w(8, 8, 24, sse4) +mc_rep_uni_w(8, 8, 32, sse4) +mc_rep_uni_w(8, 8, 48, sse4) +mc_rep_uni_w(8, 8, 64, sse4) + +mc_rep_uni_w(10, 6, 12, sse4) +mc_rep_uni_w(10, 8, 16, sse4) +mc_rep_uni_w(10, 8, 24, sse4) +mc_rep_uni_w(10, 8, 32, sse4) +mc_rep_uni_w(10, 8, 48, sse4) +mc_rep_uni_w(10, 8, 64, sse4) + +mc_rep_uni_w(12, 6, 12, sse4) +mc_rep_uni_w(12, 8, 16, sse4) +mc_rep_uni_w(12, 8, 24, sse4) +mc_rep_uni_w(12, 8, 32, sse4) +mc_rep_uni_w(12, 8, 48, sse4) +mc_rep_uni_w(12, 8, 64, sse4) + +#define mc_rep_bi_w(bitd, step, W, opt) \ +void ff_hevc_put_hevc_bi_w##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t dststride, int16_t *_src, \ + int16_t *_src2, int height, \ + int denom, int _wx0, int _wx1, int _ox0, int _ox1) \ +{ \ + int i; \ + int16_t *src; \ + int16_t *src2; \ + uint8_t *dst; \ + for (i = 0; i < W; i += step) { \ + src = _src + i; \ + src2 = _src2 + i; \ + dst = _dst + (i * ((bitd + 7) / 8)); \ + ff_hevc_put_hevc_bi_w##step##_##bitd##_##opt(dst, dststride, src, src2, \ + height, denom, _wx0, _wx1, _ox0, _ox1); \ + } \ +} + +mc_rep_bi_w(8, 6, 12, sse4) +mc_rep_bi_w(8, 8, 16, sse4) +mc_rep_bi_w(8, 8, 24, sse4) +mc_rep_bi_w(8, 8, 32, sse4) +mc_rep_bi_w(8, 8, 48, sse4) +mc_rep_bi_w(8, 8, 64, sse4) + +mc_rep_bi_w(10, 6, 12, sse4) +mc_rep_bi_w(10, 8, 16, sse4) +mc_rep_bi_w(10, 8, 24, sse4) +mc_rep_bi_w(10, 8, 32, sse4) +mc_rep_bi_w(10, 8, 48, sse4) +mc_rep_bi_w(10, 8, 64, sse4) + +mc_rep_bi_w(12, 6, 12, sse4) +mc_rep_bi_w(12, 8, 16, sse4) +mc_rep_bi_w(12, 8, 24, sse4) +mc_rep_bi_w(12, 8, 32, sse4) +mc_rep_bi_w(12, 8, 48, sse4) +mc_rep_bi_w(12, 8, 64, sse4) + +#define mc_uni_w_func(name, bitd, W, opt) \ +void ff_hevc_put_hevc_uni_w_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t _dststride, \ + uint8_t *_src, ptrdiff_t _srcstride, \ + int height, int denom, \ + int _wx, int _ox, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + LOCAL_ALIGNED_16(int16_t, temp, [71 * MAX_PB_SIZE]); \ + ff_hevc_put_hevc_##name##W##_##bitd##_##opt(temp, _src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_uni_w##W##_##bitd##_##opt(_dst, _dststride, temp, height, denom, _wx, _ox);\ +} + +#define mc_uni_w_funcs(name, bitd, opt) \ + mc_uni_w_func(name, bitd, 4, opt) \ + mc_uni_w_func(name, bitd, 8, opt) \ + mc_uni_w_func(name, bitd, 12, opt) \ + mc_uni_w_func(name, bitd, 16, opt) \ + mc_uni_w_func(name, bitd, 24, opt) \ + mc_uni_w_func(name, bitd, 32, opt) \ + mc_uni_w_func(name, bitd, 48, opt) \ + mc_uni_w_func(name, bitd, 64, opt) + +mc_uni_w_funcs(pel_pixels, 8, sse4) +mc_uni_w_func(pel_pixels, 8, 6, sse4) +mc_uni_w_funcs(epel_h, 8, sse4) +mc_uni_w_func(epel_h, 8, 6, sse4) +mc_uni_w_funcs(epel_v, 8, sse4) +mc_uni_w_func(epel_v, 8, 6, sse4) +mc_uni_w_funcs(epel_hv, 8, sse4) +mc_uni_w_func(epel_hv, 8, 6, sse4) +mc_uni_w_funcs(qpel_h, 8, sse4) +mc_uni_w_funcs(qpel_v, 8, sse4) +mc_uni_w_funcs(qpel_hv, 8, sse4) + +mc_uni_w_funcs(pel_pixels, 10, sse4) +mc_uni_w_func(pel_pixels, 10, 6, sse4) +mc_uni_w_funcs(epel_h, 10, sse4) +mc_uni_w_func(epel_h, 10, 6, sse4) +mc_uni_w_funcs(epel_v, 10, sse4) +mc_uni_w_func(epel_v, 10, 6, sse4) +mc_uni_w_funcs(epel_hv, 10, sse4) +mc_uni_w_func(epel_hv, 10, 6, sse4) +mc_uni_w_funcs(qpel_h, 10, sse4) +mc_uni_w_funcs(qpel_v, 10, sse4) +mc_uni_w_funcs(qpel_hv, 10, sse4) + +mc_uni_w_funcs(pel_pixels, 12, sse4) +mc_uni_w_func(pel_pixels, 12, 6, sse4) +mc_uni_w_funcs(epel_h, 12, sse4) +mc_uni_w_func(epel_h, 12, 6, sse4) +mc_uni_w_funcs(epel_v, 12, sse4) +mc_uni_w_func(epel_v, 12, 6, sse4) +mc_uni_w_funcs(epel_hv, 12, sse4) +mc_uni_w_func(epel_hv, 12, 6, sse4) +mc_uni_w_funcs(qpel_h, 12, sse4) +mc_uni_w_funcs(qpel_v, 12, sse4) +mc_uni_w_funcs(qpel_hv, 12, sse4) + +#define mc_bi_w_func(name, bitd, W, opt) \ +void ff_hevc_put_hevc_bi_w_##name##W##_##bitd##_##opt(uint8_t *_dst, ptrdiff_t _dststride, \ + uint8_t *_src, ptrdiff_t _srcstride, \ + int16_t *_src2, \ + int height, int denom, \ + int _wx0, int _wx1, int _ox0, int _ox1, \ + intptr_t mx, intptr_t my, int width) \ +{ \ + LOCAL_ALIGNED_16(int16_t, temp, [71 * MAX_PB_SIZE]); \ + ff_hevc_put_hevc_##name##W##_##bitd##_##opt(temp, _src, _srcstride, height, mx, my, width); \ + ff_hevc_put_hevc_bi_w##W##_##bitd##_##opt(_dst, _dststride, temp, _src2, \ + height, denom, _wx0, _wx1, _ox0, _ox1); \ +} + +#define mc_bi_w_funcs(name, bitd, opt) \ + mc_bi_w_func(name, bitd, 4, opt) \ + mc_bi_w_func(name, bitd, 8, opt) \ + mc_bi_w_func(name, bitd, 12, opt) \ + mc_bi_w_func(name, bitd, 16, opt) \ + mc_bi_w_func(name, bitd, 24, opt) \ + mc_bi_w_func(name, bitd, 32, opt) \ + mc_bi_w_func(name, bitd, 48, opt) \ + mc_bi_w_func(name, bitd, 64, opt) + +mc_bi_w_funcs(pel_pixels, 8, sse4) +mc_bi_w_func(pel_pixels, 8, 6, sse4) +mc_bi_w_funcs(epel_h, 8, sse4) +mc_bi_w_func(epel_h, 8, 6, sse4) +mc_bi_w_funcs(epel_v, 8, sse4) +mc_bi_w_func(epel_v, 8, 6, sse4) +mc_bi_w_funcs(epel_hv, 8, sse4) +mc_bi_w_func(epel_hv, 8, 6, sse4) +mc_bi_w_funcs(qpel_h, 8, sse4) +mc_bi_w_funcs(qpel_v, 8, sse4) +mc_bi_w_funcs(qpel_hv, 8, sse4) + +mc_bi_w_funcs(pel_pixels, 10, sse4) +mc_bi_w_func(pel_pixels, 10, 6, sse4) +mc_bi_w_funcs(epel_h, 10, sse4) +mc_bi_w_func(epel_h, 10, 6, sse4) +mc_bi_w_funcs(epel_v, 10, sse4) +mc_bi_w_func(epel_v, 10, 6, sse4) +mc_bi_w_funcs(epel_hv, 10, sse4) +mc_bi_w_func(epel_hv, 10, 6, sse4) +mc_bi_w_funcs(qpel_h, 10, sse4) +mc_bi_w_funcs(qpel_v, 10, sse4) +mc_bi_w_funcs(qpel_hv, 10, sse4) + +mc_bi_w_funcs(pel_pixels, 12, sse4) +mc_bi_w_func(pel_pixels, 12, 6, sse4) +mc_bi_w_funcs(epel_h, 12, sse4) +mc_bi_w_func(epel_h, 12, 6, sse4) +mc_bi_w_funcs(epel_v, 12, sse4) +mc_bi_w_func(epel_v, 12, 6, sse4) +mc_bi_w_funcs(epel_hv, 12, sse4) +mc_bi_w_func(epel_hv, 12, 6, sse4) +mc_bi_w_funcs(qpel_h, 12, sse4) +mc_bi_w_funcs(qpel_v, 12, sse4) +mc_bi_w_funcs(qpel_hv, 12, sse4) +#endif //ARCH_X86_64 && HAVE_SSE4_EXTERNAL + +#define SAO_BAND_FILTER_FUNCS(bitd, opt) \ +void ff_hevc_sao_band_filter_8_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_16_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_32_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_48_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); \ +void ff_hevc_sao_band_filter_64_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t _stride_dst, ptrdiff_t _stride_src, \ + int16_t *sao_offset_val, int sao_left_class, int width, int height); + +SAO_BAND_FILTER_FUNCS(8, sse2) +SAO_BAND_FILTER_FUNCS(10, sse2) +SAO_BAND_FILTER_FUNCS(12, sse2) +SAO_BAND_FILTER_FUNCS(8, avx) +SAO_BAND_FILTER_FUNCS(10, avx) +SAO_BAND_FILTER_FUNCS(12, avx) +SAO_BAND_FILTER_FUNCS(8, avx2) +SAO_BAND_FILTER_FUNCS(10, avx2) +SAO_BAND_FILTER_FUNCS(12, avx2) + +#define SAO_BAND_INIT(bitd, opt) do { \ + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_##bitd##_##opt; \ + c->sao_band_filter[1] = ff_hevc_sao_band_filter_16_##bitd##_##opt; \ + c->sao_band_filter[2] = ff_hevc_sao_band_filter_32_##bitd##_##opt; \ + c->sao_band_filter[3] = ff_hevc_sao_band_filter_48_##bitd##_##opt; \ + c->sao_band_filter[4] = ff_hevc_sao_band_filter_64_##bitd##_##opt; \ +} while (0) + +#define SAO_EDGE_FILTER_FUNCS(bitd, opt) \ +void ff_hevc_sao_edge_filter_8_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_16_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_32_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_48_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ +void ff_hevc_sao_edge_filter_64_##bitd##_##opt(uint8_t *_dst, uint8_t *_src, ptrdiff_t stride_dst, int16_t *sao_offset_val, \ + int eo, int width, int height); \ + +SAO_EDGE_FILTER_FUNCS(8, ssse3) +SAO_EDGE_FILTER_FUNCS(8, avx2) +SAO_EDGE_FILTER_FUNCS(10, sse2) +SAO_EDGE_FILTER_FUNCS(10, avx2) +SAO_EDGE_FILTER_FUNCS(12, sse2) +SAO_EDGE_FILTER_FUNCS(12, avx2) + +#define SAO_EDGE_INIT(bitd, opt) do { \ + c->sao_edge_filter[0] = ff_hevc_sao_edge_filter_8_##bitd##_##opt; \ + c->sao_edge_filter[1] = ff_hevc_sao_edge_filter_16_##bitd##_##opt; \ + c->sao_edge_filter[2] = ff_hevc_sao_edge_filter_32_##bitd##_##opt; \ + c->sao_edge_filter[3] = ff_hevc_sao_edge_filter_48_##bitd##_##opt; \ + c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_64_##bitd##_##opt; \ +} while (0) + +#define EPEL_LINKS(pointer, my, mx, fname, bitd, opt ) \ + PEL_LINK(pointer, 1, my , mx , fname##4 , bitd, opt ); \ + PEL_LINK(pointer, 2, my , mx , fname##6 , bitd, opt ); \ + PEL_LINK(pointer, 3, my , mx , fname##8 , bitd, opt ); \ + PEL_LINK(pointer, 4, my , mx , fname##12, bitd, opt ); \ + PEL_LINK(pointer, 5, my , mx , fname##16, bitd, opt ); \ + PEL_LINK(pointer, 6, my , mx , fname##24, bitd, opt ); \ + PEL_LINK(pointer, 7, my , mx , fname##32, bitd, opt ); \ + PEL_LINK(pointer, 8, my , mx , fname##48, bitd, opt ); \ + PEL_LINK(pointer, 9, my , mx , fname##64, bitd, opt ) +#define QPEL_LINKS(pointer, my, mx, fname, bitd, opt) \ + PEL_LINK(pointer, 1, my , mx , fname##4 , bitd, opt ); \ + PEL_LINK(pointer, 3, my , mx , fname##8 , bitd, opt ); \ + PEL_LINK(pointer, 4, my , mx , fname##12, bitd, opt ); \ + PEL_LINK(pointer, 5, my , mx , fname##16, bitd, opt ); \ + PEL_LINK(pointer, 6, my , mx , fname##24, bitd, opt ); \ + PEL_LINK(pointer, 7, my , mx , fname##32, bitd, opt ); \ + PEL_LINK(pointer, 8, my , mx , fname##48, bitd, opt ); \ + PEL_LINK(pointer, 9, my , mx , fname##64, bitd, opt ) + +void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (bit_depth == 8) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_dc[0] = ff_hevc_idct_4x4_dc_8_mmxext; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_mmxext; + + c->add_residual[0] = ff_hevc_add_residual_4_8_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_8_sse2; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_8_sse2; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_sse2; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_sse2; + + c->idct[2] = ff_hevc_idct_16x16_8_sse2; + c->idct[3] = ff_hevc_idct_32x32_8_sse2; + } + SAO_BAND_INIT(8, sse2); + + c->idct_dc[1] = ff_hevc_idct_8x8_dc_8_sse2; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_sse2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_sse2; + + c->idct[0] = ff_hevc_idct_4x4_8_sse2; + c->idct[1] = ff_hevc_idct_8x8_8_sse2; + + c->add_residual[1] = ff_hevc_add_residual_8_8_sse2; + c->add_residual[2] = ff_hevc_add_residual_16_8_sse2; + c->add_residual[3] = ff_hevc_add_residual_32_8_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + if(ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_ssse3; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_ssse3; + } + SAO_EDGE_INIT(8, ssse3); + } + if (EXTERNAL_SSE4(cpu_flags) && ARCH_X86_64) { + + EPEL_LINKS(c->put_hevc_epel, 0, 0, pel_pixels, 8, sse4); + EPEL_LINKS(c->put_hevc_epel, 0, 1, epel_h, 8, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 0, epel_v, 8, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 1, epel_hv, 8, sse4); + + QPEL_LINKS(c->put_hevc_qpel, 0, 0, pel_pixels, 8, sse4); + QPEL_LINKS(c->put_hevc_qpel, 0, 1, qpel_h, 8, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 0, qpel_v, 8, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 1, qpel_hv, 8, sse4); + } + if (EXTERNAL_AVX(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_8_avx; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_8_avx; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_8_avx; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_8_avx; + + c->idct[2] = ff_hevc_idct_16x16_8_avx; + c->idct[3] = ff_hevc_idct_32x32_8_avx; + } + SAO_BAND_INIT(8, avx); + + c->idct[0] = ff_hevc_idct_4x4_8_avx; + c->idct[1] = ff_hevc_idct_8x8_8_avx; + + c->add_residual[1] = ff_hevc_add_residual_8_8_avx; + c->add_residual[2] = ff_hevc_add_residual_16_8_avx; + c->add_residual[3] = ff_hevc_add_residual_32_8_avx; + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_8_avx2; + c->sao_band_filter[1] = ff_hevc_sao_band_filter_16_8_avx2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->idct_dc[2] = ff_hevc_idct_16x16_dc_8_avx2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_8_avx2; + if (ARCH_X86_64) { + c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_avx2; + c->put_hevc_epel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_avx2; + c->put_hevc_epel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_avx2; + + c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_8_avx2; + c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_8_avx2; + c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_8_avx2; + + c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_epel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_epel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + + c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + + c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_avx2; + c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_avx2; + c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_avx2; + + c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_8_avx2; + c->put_hevc_epel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_8_avx2; + c->put_hevc_epel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_8_avx2; + + c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_8_avx2; + c->put_hevc_epel[8][0][1] = ff_hevc_put_hevc_epel_h48_8_avx2; + c->put_hevc_epel[9][0][1] = ff_hevc_put_hevc_epel_h64_8_avx2; + + c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_8_avx2; + c->put_hevc_epel_uni[8][0][1] = ff_hevc_put_hevc_uni_epel_h48_8_avx2; + c->put_hevc_epel_uni[9][0][1] = ff_hevc_put_hevc_uni_epel_h64_8_avx2; + + c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_8_avx2; + c->put_hevc_epel_bi[8][0][1] = ff_hevc_put_hevc_bi_epel_h48_8_avx2; + c->put_hevc_epel_bi[9][0][1] = ff_hevc_put_hevc_bi_epel_h64_8_avx2; + + c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_8_avx2; + c->put_hevc_epel[8][1][0] = ff_hevc_put_hevc_epel_v48_8_avx2; + c->put_hevc_epel[9][1][0] = ff_hevc_put_hevc_epel_v64_8_avx2; + + c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_8_avx2; + c->put_hevc_epel_uni[8][1][0] = ff_hevc_put_hevc_uni_epel_v48_8_avx2; + c->put_hevc_epel_uni[9][1][0] = ff_hevc_put_hevc_uni_epel_v64_8_avx2; + + c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_8_avx2; + c->put_hevc_epel_bi[8][1][0] = ff_hevc_put_hevc_bi_epel_v48_8_avx2; + c->put_hevc_epel_bi[9][1][0] = ff_hevc_put_hevc_bi_epel_v64_8_avx2; + + c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_8_avx2; + c->put_hevc_epel[8][1][1] = ff_hevc_put_hevc_epel_hv48_8_avx2; + c->put_hevc_epel[9][1][1] = ff_hevc_put_hevc_epel_hv64_8_avx2; + + c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_8_avx2; + c->put_hevc_epel_uni[8][1][1] = ff_hevc_put_hevc_uni_epel_hv48_8_avx2; + c->put_hevc_epel_uni[9][1][1] = ff_hevc_put_hevc_uni_epel_hv64_8_avx2; + + c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_8_avx2; + c->put_hevc_epel_bi[8][1][1] = ff_hevc_put_hevc_bi_epel_hv48_8_avx2; + c->put_hevc_epel_bi[9][1][1] = ff_hevc_put_hevc_bi_epel_hv64_8_avx2; + + c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_8_avx2; + c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_8_avx2; + c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_8_avx2; + + c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_8_avx2; + c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_8_avx2; + c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_8_avx2; + + c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_8_avx2; + c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_8_avx2; + c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_8_avx2; + + c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_8_avx2; + c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_8_avx2; + c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_8_avx2; + + c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_8_avx2; + c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_8_avx2; + c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_8_avx2; + + c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_8_avx2; + c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_8_avx2; + c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_8_avx2; + } + SAO_BAND_INIT(8, avx2); + + c->sao_edge_filter[2] = ff_hevc_sao_edge_filter_32_8_avx2; + c->sao_edge_filter[3] = ff_hevc_sao_edge_filter_48_8_avx2; + c->sao_edge_filter[4] = ff_hevc_sao_edge_filter_64_8_avx2; + + c->add_residual[3] = ff_hevc_add_residual_32_8_avx2; + } + } else if (bit_depth == 10) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->add_residual[0] = ff_hevc_add_residual_4_10_mmxext; + c->idct_dc[0] = ff_hevc_idct_4x4_dc_10_mmxext; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_10_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_10_sse2; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_10_sse2; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_sse2; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_sse2; + + c->idct[2] = ff_hevc_idct_16x16_10_sse2; + c->idct[3] = ff_hevc_idct_32x32_10_sse2; + } + SAO_BAND_INIT(10, sse2); + SAO_EDGE_INIT(10, sse2); + + c->idct_dc[1] = ff_hevc_idct_8x8_dc_10_sse2; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_sse2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_sse2; + + c->idct[0] = ff_hevc_idct_4x4_10_sse2; + c->idct[1] = ff_hevc_idct_8x8_10_sse2; + + c->add_residual[1] = ff_hevc_add_residual_8_10_sse2; + c->add_residual[2] = ff_hevc_add_residual_16_10_sse2; + c->add_residual[3] = ff_hevc_add_residual_32_10_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_ssse3; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_ssse3; + } + if (EXTERNAL_SSE4(cpu_flags) && ARCH_X86_64) { + EPEL_LINKS(c->put_hevc_epel, 0, 0, pel_pixels, 10, sse4); + EPEL_LINKS(c->put_hevc_epel, 0, 1, epel_h, 10, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 0, epel_v, 10, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 1, epel_hv, 10, sse4); + + QPEL_LINKS(c->put_hevc_qpel, 0, 0, pel_pixels, 10, sse4); + QPEL_LINKS(c->put_hevc_qpel, 0, 1, qpel_h, 10, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 0, qpel_v, 10, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 1, qpel_hv, 10, sse4); + } + if (EXTERNAL_AVX(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_10_avx; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_10_avx; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_10_avx; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_10_avx; + + c->idct[2] = ff_hevc_idct_16x16_10_avx; + c->idct[3] = ff_hevc_idct_32x32_10_avx; + } + + c->idct[0] = ff_hevc_idct_4x4_10_avx; + c->idct[1] = ff_hevc_idct_8x8_10_avx; + + SAO_BAND_INIT(10, avx); + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_10_avx2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->idct_dc[2] = ff_hevc_idct_16x16_dc_10_avx2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_10_avx2; + if (ARCH_X86_64) { + c->put_hevc_epel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_10_avx2; + c->put_hevc_epel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_10_avx2; + c->put_hevc_epel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_10_avx2; + c->put_hevc_epel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_10_avx2; + c->put_hevc_epel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_10_avx2; + + c->put_hevc_qpel[5][0][0] = ff_hevc_put_hevc_pel_pixels16_10_avx2; + c->put_hevc_qpel[6][0][0] = ff_hevc_put_hevc_pel_pixels24_10_avx2; + c->put_hevc_qpel[7][0][0] = ff_hevc_put_hevc_pel_pixels32_10_avx2; + c->put_hevc_qpel[8][0][0] = ff_hevc_put_hevc_pel_pixels48_10_avx2; + c->put_hevc_qpel[9][0][0] = ff_hevc_put_hevc_pel_pixels64_10_avx2; + + c->put_hevc_epel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_epel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_epel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + c->put_hevc_epel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels96_8_avx2; + c->put_hevc_epel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels128_8_avx2; + + c->put_hevc_qpel_uni[5][0][0] = ff_hevc_put_hevc_uni_pel_pixels32_8_avx2; + c->put_hevc_qpel_uni[6][0][0] = ff_hevc_put_hevc_uni_pel_pixels48_8_avx2; + c->put_hevc_qpel_uni[7][0][0] = ff_hevc_put_hevc_uni_pel_pixels64_8_avx2; + c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_hevc_uni_pel_pixels96_8_avx2; + c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_hevc_uni_pel_pixels128_8_avx2; + + c->put_hevc_epel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_10_avx2; + c->put_hevc_epel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_10_avx2; + c->put_hevc_epel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_10_avx2; + c->put_hevc_epel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_10_avx2; + c->put_hevc_epel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_10_avx2; + c->put_hevc_qpel_bi[5][0][0] = ff_hevc_put_hevc_bi_pel_pixels16_10_avx2; + c->put_hevc_qpel_bi[6][0][0] = ff_hevc_put_hevc_bi_pel_pixels24_10_avx2; + c->put_hevc_qpel_bi[7][0][0] = ff_hevc_put_hevc_bi_pel_pixels32_10_avx2; + c->put_hevc_qpel_bi[8][0][0] = ff_hevc_put_hevc_bi_pel_pixels48_10_avx2; + c->put_hevc_qpel_bi[9][0][0] = ff_hevc_put_hevc_bi_pel_pixels64_10_avx2; + + c->put_hevc_epel[5][0][1] = ff_hevc_put_hevc_epel_h16_10_avx2; + c->put_hevc_epel[6][0][1] = ff_hevc_put_hevc_epel_h24_10_avx2; + c->put_hevc_epel[7][0][1] = ff_hevc_put_hevc_epel_h32_10_avx2; + c->put_hevc_epel[8][0][1] = ff_hevc_put_hevc_epel_h48_10_avx2; + c->put_hevc_epel[9][0][1] = ff_hevc_put_hevc_epel_h64_10_avx2; + + c->put_hevc_epel_uni[5][0][1] = ff_hevc_put_hevc_uni_epel_h16_10_avx2; + c->put_hevc_epel_uni[6][0][1] = ff_hevc_put_hevc_uni_epel_h24_10_avx2; + c->put_hevc_epel_uni[7][0][1] = ff_hevc_put_hevc_uni_epel_h32_10_avx2; + c->put_hevc_epel_uni[8][0][1] = ff_hevc_put_hevc_uni_epel_h48_10_avx2; + c->put_hevc_epel_uni[9][0][1] = ff_hevc_put_hevc_uni_epel_h64_10_avx2; + + c->put_hevc_epel_bi[5][0][1] = ff_hevc_put_hevc_bi_epel_h16_10_avx2; + c->put_hevc_epel_bi[6][0][1] = ff_hevc_put_hevc_bi_epel_h24_10_avx2; + c->put_hevc_epel_bi[7][0][1] = ff_hevc_put_hevc_bi_epel_h32_10_avx2; + c->put_hevc_epel_bi[8][0][1] = ff_hevc_put_hevc_bi_epel_h48_10_avx2; + c->put_hevc_epel_bi[9][0][1] = ff_hevc_put_hevc_bi_epel_h64_10_avx2; + + c->put_hevc_epel[5][1][0] = ff_hevc_put_hevc_epel_v16_10_avx2; + c->put_hevc_epel[6][1][0] = ff_hevc_put_hevc_epel_v24_10_avx2; + c->put_hevc_epel[7][1][0] = ff_hevc_put_hevc_epel_v32_10_avx2; + c->put_hevc_epel[8][1][0] = ff_hevc_put_hevc_epel_v48_10_avx2; + c->put_hevc_epel[9][1][0] = ff_hevc_put_hevc_epel_v64_10_avx2; + + c->put_hevc_epel_uni[5][1][0] = ff_hevc_put_hevc_uni_epel_v16_10_avx2; + c->put_hevc_epel_uni[6][1][0] = ff_hevc_put_hevc_uni_epel_v24_10_avx2; + c->put_hevc_epel_uni[7][1][0] = ff_hevc_put_hevc_uni_epel_v32_10_avx2; + c->put_hevc_epel_uni[8][1][0] = ff_hevc_put_hevc_uni_epel_v48_10_avx2; + c->put_hevc_epel_uni[9][1][0] = ff_hevc_put_hevc_uni_epel_v64_10_avx2; + + c->put_hevc_epel_bi[5][1][0] = ff_hevc_put_hevc_bi_epel_v16_10_avx2; + c->put_hevc_epel_bi[6][1][0] = ff_hevc_put_hevc_bi_epel_v24_10_avx2; + c->put_hevc_epel_bi[7][1][0] = ff_hevc_put_hevc_bi_epel_v32_10_avx2; + c->put_hevc_epel_bi[8][1][0] = ff_hevc_put_hevc_bi_epel_v48_10_avx2; + c->put_hevc_epel_bi[9][1][0] = ff_hevc_put_hevc_bi_epel_v64_10_avx2; + + c->put_hevc_epel[5][1][1] = ff_hevc_put_hevc_epel_hv16_10_avx2; + c->put_hevc_epel[6][1][1] = ff_hevc_put_hevc_epel_hv24_10_avx2; + c->put_hevc_epel[7][1][1] = ff_hevc_put_hevc_epel_hv32_10_avx2; + c->put_hevc_epel[8][1][1] = ff_hevc_put_hevc_epel_hv48_10_avx2; + c->put_hevc_epel[9][1][1] = ff_hevc_put_hevc_epel_hv64_10_avx2; + + c->put_hevc_epel_uni[5][1][1] = ff_hevc_put_hevc_uni_epel_hv16_10_avx2; + c->put_hevc_epel_uni[6][1][1] = ff_hevc_put_hevc_uni_epel_hv24_10_avx2; + c->put_hevc_epel_uni[7][1][1] = ff_hevc_put_hevc_uni_epel_hv32_10_avx2; + c->put_hevc_epel_uni[8][1][1] = ff_hevc_put_hevc_uni_epel_hv48_10_avx2; + c->put_hevc_epel_uni[9][1][1] = ff_hevc_put_hevc_uni_epel_hv64_10_avx2; + + c->put_hevc_epel_bi[5][1][1] = ff_hevc_put_hevc_bi_epel_hv16_10_avx2; + c->put_hevc_epel_bi[6][1][1] = ff_hevc_put_hevc_bi_epel_hv24_10_avx2; + c->put_hevc_epel_bi[7][1][1] = ff_hevc_put_hevc_bi_epel_hv32_10_avx2; + c->put_hevc_epel_bi[8][1][1] = ff_hevc_put_hevc_bi_epel_hv48_10_avx2; + c->put_hevc_epel_bi[9][1][1] = ff_hevc_put_hevc_bi_epel_hv64_10_avx2; + + c->put_hevc_qpel[5][0][1] = ff_hevc_put_hevc_qpel_h16_10_avx2; + c->put_hevc_qpel[6][0][1] = ff_hevc_put_hevc_qpel_h24_10_avx2; + c->put_hevc_qpel[7][0][1] = ff_hevc_put_hevc_qpel_h32_10_avx2; + c->put_hevc_qpel[8][0][1] = ff_hevc_put_hevc_qpel_h48_10_avx2; + c->put_hevc_qpel[9][0][1] = ff_hevc_put_hevc_qpel_h64_10_avx2; + + c->put_hevc_qpel_uni[5][0][1] = ff_hevc_put_hevc_uni_qpel_h16_10_avx2; + c->put_hevc_qpel_uni[6][0][1] = ff_hevc_put_hevc_uni_qpel_h24_10_avx2; + c->put_hevc_qpel_uni[7][0][1] = ff_hevc_put_hevc_uni_qpel_h32_10_avx2; + c->put_hevc_qpel_uni[8][0][1] = ff_hevc_put_hevc_uni_qpel_h48_10_avx2; + c->put_hevc_qpel_uni[9][0][1] = ff_hevc_put_hevc_uni_qpel_h64_10_avx2; + + c->put_hevc_qpel_bi[5][0][1] = ff_hevc_put_hevc_bi_qpel_h16_10_avx2; + c->put_hevc_qpel_bi[6][0][1] = ff_hevc_put_hevc_bi_qpel_h24_10_avx2; + c->put_hevc_qpel_bi[7][0][1] = ff_hevc_put_hevc_bi_qpel_h32_10_avx2; + c->put_hevc_qpel_bi[8][0][1] = ff_hevc_put_hevc_bi_qpel_h48_10_avx2; + c->put_hevc_qpel_bi[9][0][1] = ff_hevc_put_hevc_bi_qpel_h64_10_avx2; + + c->put_hevc_qpel[5][1][0] = ff_hevc_put_hevc_qpel_v16_10_avx2; + c->put_hevc_qpel[6][1][0] = ff_hevc_put_hevc_qpel_v24_10_avx2; + c->put_hevc_qpel[7][1][0] = ff_hevc_put_hevc_qpel_v32_10_avx2; + c->put_hevc_qpel[8][1][0] = ff_hevc_put_hevc_qpel_v48_10_avx2; + c->put_hevc_qpel[9][1][0] = ff_hevc_put_hevc_qpel_v64_10_avx2; + + c->put_hevc_qpel_uni[5][1][0] = ff_hevc_put_hevc_uni_qpel_v16_10_avx2; + c->put_hevc_qpel_uni[6][1][0] = ff_hevc_put_hevc_uni_qpel_v24_10_avx2; + c->put_hevc_qpel_uni[7][1][0] = ff_hevc_put_hevc_uni_qpel_v32_10_avx2; + c->put_hevc_qpel_uni[8][1][0] = ff_hevc_put_hevc_uni_qpel_v48_10_avx2; + c->put_hevc_qpel_uni[9][1][0] = ff_hevc_put_hevc_uni_qpel_v64_10_avx2; + + c->put_hevc_qpel_bi[5][1][0] = ff_hevc_put_hevc_bi_qpel_v16_10_avx2; + c->put_hevc_qpel_bi[6][1][0] = ff_hevc_put_hevc_bi_qpel_v24_10_avx2; + c->put_hevc_qpel_bi[7][1][0] = ff_hevc_put_hevc_bi_qpel_v32_10_avx2; + c->put_hevc_qpel_bi[8][1][0] = ff_hevc_put_hevc_bi_qpel_v48_10_avx2; + c->put_hevc_qpel_bi[9][1][0] = ff_hevc_put_hevc_bi_qpel_v64_10_avx2; + + c->put_hevc_qpel[5][1][1] = ff_hevc_put_hevc_qpel_hv16_10_avx2; + c->put_hevc_qpel[6][1][1] = ff_hevc_put_hevc_qpel_hv24_10_avx2; + c->put_hevc_qpel[7][1][1] = ff_hevc_put_hevc_qpel_hv32_10_avx2; + c->put_hevc_qpel[8][1][1] = ff_hevc_put_hevc_qpel_hv48_10_avx2; + c->put_hevc_qpel[9][1][1] = ff_hevc_put_hevc_qpel_hv64_10_avx2; + + c->put_hevc_qpel_uni[5][1][1] = ff_hevc_put_hevc_uni_qpel_hv16_10_avx2; + c->put_hevc_qpel_uni[6][1][1] = ff_hevc_put_hevc_uni_qpel_hv24_10_avx2; + c->put_hevc_qpel_uni[7][1][1] = ff_hevc_put_hevc_uni_qpel_hv32_10_avx2; + c->put_hevc_qpel_uni[8][1][1] = ff_hevc_put_hevc_uni_qpel_hv48_10_avx2; + c->put_hevc_qpel_uni[9][1][1] = ff_hevc_put_hevc_uni_qpel_hv64_10_avx2; + + c->put_hevc_qpel_bi[5][1][1] = ff_hevc_put_hevc_bi_qpel_hv16_10_avx2; + c->put_hevc_qpel_bi[6][1][1] = ff_hevc_put_hevc_bi_qpel_hv24_10_avx2; + c->put_hevc_qpel_bi[7][1][1] = ff_hevc_put_hevc_bi_qpel_hv32_10_avx2; + c->put_hevc_qpel_bi[8][1][1] = ff_hevc_put_hevc_bi_qpel_hv48_10_avx2; + c->put_hevc_qpel_bi[9][1][1] = ff_hevc_put_hevc_bi_qpel_hv64_10_avx2; + } + SAO_BAND_INIT(10, avx2); + SAO_EDGE_INIT(10, avx2); + + c->add_residual[2] = ff_hevc_add_residual_16_10_avx2; + c->add_residual[3] = ff_hevc_add_residual_32_10_avx2; + } + } else if (bit_depth == 12) { + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_dc[0] = ff_hevc_idct_4x4_dc_12_mmxext; + c->idct_dc[1] = ff_hevc_idct_8x8_dc_12_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_12_sse2; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_12_sse2; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_sse2; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_12_sse2; + } + SAO_BAND_INIT(12, sse2); + SAO_EDGE_INIT(12, sse2); + + c->idct_dc[1] = ff_hevc_idct_8x8_dc_12_sse2; + c->idct_dc[2] = ff_hevc_idct_16x16_dc_12_sse2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_12_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags) && ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_ssse3; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_12_ssse3; + } + if (EXTERNAL_SSE4(cpu_flags) && ARCH_X86_64) { + EPEL_LINKS(c->put_hevc_epel, 0, 0, pel_pixels, 12, sse4); + EPEL_LINKS(c->put_hevc_epel, 0, 1, epel_h, 12, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 0, epel_v, 12, sse4); + EPEL_LINKS(c->put_hevc_epel, 1, 1, epel_hv, 12, sse4); + + QPEL_LINKS(c->put_hevc_qpel, 0, 0, pel_pixels, 12, sse4); + QPEL_LINKS(c->put_hevc_qpel, 0, 1, qpel_h, 12, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 0, qpel_v, 12, sse4); + QPEL_LINKS(c->put_hevc_qpel, 1, 1, qpel_hv, 12, sse4); + } + if (EXTERNAL_AVX(cpu_flags)) { + c->hevc_v_loop_filter_chroma = ff_hevc_v_loop_filter_chroma_12_avx; + c->hevc_h_loop_filter_chroma = ff_hevc_h_loop_filter_chroma_12_avx; + if (ARCH_X86_64) { + c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_12_avx; + c->hevc_h_loop_filter_luma = ff_hevc_h_loop_filter_luma_12_avx; + } + SAO_BAND_INIT(12, avx); + } + if (EXTERNAL_AVX2(cpu_flags)) { + c->sao_band_filter[0] = ff_hevc_sao_band_filter_8_12_avx2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->idct_dc[2] = ff_hevc_idct_16x16_dc_12_avx2; + c->idct_dc[3] = ff_hevc_idct_32x32_dc_12_avx2; + + SAO_BAND_INIT(12, avx2); + SAO_EDGE_INIT(12, avx2); + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp.asm new file mode 100644 index 00000000..ce5d7a4e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp.asm @@ -0,0 +1,591 @@ +;****************************************************************************** +;* +;* Copyright (c) 2000-2001 Fabrice Bellard +;* Copyright (c) Nick Kurshev +;* Copyright (c) 2002 Michael Niedermayer +;* Copyright (c) 2002 Zdenek Kabelac +;* Copyright (c) 2013 Daniel Kang +;* +;* SIMD-optimized halfpel functions +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +cextern pb_1 +cextern pw_2 +pb_interleave16: db 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 +pb_interleave8: db 0, 4, 1, 5, 2, 6, 3, 7 + +cextern pw_8192 + +SECTION .text + +; void ff_put_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_PIXELS8_X2 0 +%if cpuflag(sse2) +cglobal put_pixels16_x2, 4,5,4 +%else +cglobal put_pixels8_x2, 4,5 +%endif + lea r4, [r2*2] +.loop: + movu m0, [r1+1] + movu m1, [r1+r2+1] +%if cpuflag(sse2) + movu m2, [r1] + movu m3, [r1+r2] + pavgb m0, m2 + pavgb m1, m3 +%else + PAVGB m0, [r1] + PAVGB m1, [r1+r2] +%endif + mova [r0], m0 + mova [r0+r2], m1 + add r1, r4 + add r0, r4 + movu m0, [r1+1] + movu m1, [r1+r2+1] +%if cpuflag(sse2) + movu m2, [r1] + movu m3, [r1+r2] + pavgb m0, m2 + pavgb m1, m3 +%else + PAVGB m0, [r1] + PAVGB m1, [r1+r2] +%endif + add r1, r4 + mova [r0], m0 + mova [r0+r2], m1 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_PIXELS8_X2 +INIT_MMX 3dnow +PUT_PIXELS8_X2 + + +; void ff_put_pixels16_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_PIXELS_16 0 +cglobal put_pixels16_x2, 4,5 + lea r4, [r2*2] +.loop: + mova m0, [r1] + mova m1, [r1+r2] + mova m2, [r1+8] + mova m3, [r1+r2+8] + PAVGB m0, [r1+1] + PAVGB m1, [r1+r2+1] + PAVGB m2, [r1+9] + PAVGB m3, [r1+r2+9] + mova [r0], m0 + mova [r0+r2], m1 + mova [r0+8], m2 + mova [r0+r2+8], m3 + add r1, r4 + add r0, r4 + mova m0, [r1] + mova m1, [r1+r2] + mova m2, [r1+8] + mova m3, [r1+r2+8] + PAVGB m0, [r1+1] + PAVGB m1, [r1+r2+1] + PAVGB m2, [r1+9] + PAVGB m3, [r1+r2+9] + add r1, r4 + mova [r0], m0 + mova [r0+r2], m1 + mova [r0+8], m2 + mova [r0+r2+8], m3 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_PIXELS_16 +INIT_MMX 3dnow +PUT_PIXELS_16 +; The 8_X2 macro can easily be used here +INIT_XMM sse2 +PUT_PIXELS8_X2 + + +; void ff_put_no_rnd_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_NO_RND_PIXELS8_X2 0 +cglobal put_no_rnd_pixels8_x2, 4,5 + mova m6, [pb_1] + lea r4, [r2*2] +.loop: + mova m0, [r1] + mova m2, [r1+r2] + mova m1, [r1+1] + mova m3, [r1+r2+1] + add r1, r4 + psubusb m0, m6 + psubusb m2, m6 + PAVGB m0, m1 + PAVGB m2, m3 + mova [r0], m0 + mova [r0+r2], m2 + mova m0, [r1] + mova m1, [r1+1] + mova m2, [r1+r2] + mova m3, [r1+r2+1] + add r0, r4 + add r1, r4 + psubusb m0, m6 + psubusb m2, m6 + PAVGB m0, m1 + PAVGB m2, m3 + mova [r0], m0 + mova [r0+r2], m2 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_NO_RND_PIXELS8_X2 +INIT_MMX 3dnow +PUT_NO_RND_PIXELS8_X2 + + +; void ff_put_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_PIXELS8_Y2 0 +%if cpuflag(sse2) +cglobal put_pixels16_y2, 4,5,3 +%else +cglobal put_pixels8_y2, 4,5 +%endif + lea r4, [r2*2] + movu m0, [r1] + sub r0, r2 +.loop: + movu m1, [r1+r2] + movu m2, [r1+r4] + add r1, r4 + PAVGB m0, m1 + PAVGB m1, m2 + mova [r0+r2], m0 + mova [r0+r4], m1 + movu m1, [r1+r2] + movu m0, [r1+r4] + add r0, r4 + add r1, r4 + PAVGB m2, m1 + PAVGB m1, m0 + mova [r0+r2], m2 + mova [r0+r4], m1 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_PIXELS8_Y2 +INIT_MMX 3dnow +PUT_PIXELS8_Y2 +; actually, put_pixels16_y2_sse2 +INIT_XMM sse2 +PUT_PIXELS8_Y2 + + +; void ff_put_no_rnd_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_NO_RND_PIXELS8_Y2 0 +cglobal put_no_rnd_pixels8_y2, 4,5 + mova m6, [pb_1] + lea r4, [r2+r2] + mova m0, [r1] + sub r0, r2 +.loop: + mova m1, [r1+r2] + mova m2, [r1+r4] + add r1, r4 + psubusb m1, m6 + PAVGB m0, m1 + PAVGB m1, m2 + mova [r0+r2], m0 + mova [r0+r4], m1 + mova m1, [r1+r2] + mova m0, [r1+r4] + add r0, r4 + add r1, r4 + psubusb m1, m6 + PAVGB m2, m1 + PAVGB m1, m0 + mova [r0+r2], m2 + mova [r0+r4], m1 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_NO_RND_PIXELS8_Y2 +INIT_MMX 3dnow +PUT_NO_RND_PIXELS8_Y2 + + +; void ff_avg_pixels8(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro AVG_PIXELS8 0 +cglobal avg_pixels8, 4,5 + lea r4, [r2*2] +.loop: + mova m0, [r0] + mova m1, [r0+r2] + PAVGB m0, [r1] + PAVGB m1, [r1+r2] + mova [r0], m0 + mova [r0+r2], m1 + add r1, r4 + add r0, r4 + mova m0, [r0] + mova m1, [r0+r2] + PAVGB m0, [r1] + PAVGB m1, [r1+r2] + add r1, r4 + mova [r0], m0 + mova [r0+r2], m1 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX 3dnow +AVG_PIXELS8 + + +; void ff_avg_pixels8_x2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro AVG_PIXELS8_X2 0 +%if cpuflag(sse2) +cglobal avg_pixels16_x2, 4,5,4 +%else +cglobal avg_pixels8_x2, 4,5 +%endif + lea r4, [r2*2] +%if notcpuflag(mmxext) + pcmpeqd m5, m5 + paddb m5, m5 +%endif +.loop: + movu m0, [r1] + movu m2, [r1+r2] +%if cpuflag(sse2) + movu m1, [r1+1] + movu m3, [r1+r2+1] + pavgb m0, m1 + pavgb m2, m3 +%else + PAVGB m0, [r1+1], m3, m5 + PAVGB m2, [r1+r2+1], m4, m5 +%endif + PAVGB m0, [r0], m3, m5 + PAVGB m2, [r0+r2], m4, m5 + add r1, r4 + mova [r0], m0 + mova [r0+r2], m2 + movu m0, [r1] + movu m2, [r1+r2] +%if cpuflag(sse2) + movu m1, [r1+1] + movu m3, [r1+r2+1] + pavgb m0, m1 + pavgb m2, m3 +%else + PAVGB m0, [r1+1], m3, m5 + PAVGB m2, [r1+r2+1], m4, m5 +%endif + add r0, r4 + add r1, r4 + PAVGB m0, [r0], m3, m5 + PAVGB m2, [r0+r2], m4, m5 + mova [r0], m0 + mova [r0+r2], m2 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmx +AVG_PIXELS8_X2 +INIT_MMX mmxext +AVG_PIXELS8_X2 +INIT_MMX 3dnow +AVG_PIXELS8_X2 +; actually avg_pixels16_x2 +INIT_XMM sse2 +AVG_PIXELS8_X2 + + +; void ff_avg_pixels8_y2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro AVG_PIXELS8_Y2 0 +%if cpuflag(sse2) +cglobal avg_pixels16_y2, 4,5,3 +%else +cglobal avg_pixels8_y2, 4,5 +%endif + lea r4, [r2*2] + movu m0, [r1] + sub r0, r2 +.loop: + movu m1, [r1+r2] + movu m2, [r1+r4] + add r1, r4 + PAVGB m0, m1 + PAVGB m1, m2 + PAVGB m0, [r0+r2] + PAVGB m1, [r0+r4] + mova [r0+r2], m0 + mova [r0+r4], m1 + movu m1, [r1+r2] + movu m0, [r1+r4] + PAVGB m2, m1 + PAVGB m1, m0 + add r0, r4 + add r1, r4 + PAVGB m2, [r0+r2] + PAVGB m1, [r0+r4] + mova [r0+r2], m2 + mova [r0+r4], m1 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +AVG_PIXELS8_Y2 +INIT_MMX 3dnow +AVG_PIXELS8_Y2 +; actually avg_pixels16_y2 +INIT_XMM sse2 +AVG_PIXELS8_Y2 + + +; void ff_avg_pixels8_xy2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +; Note this is not correctly rounded, and is therefore used for +; not-bitexact output +%macro AVG_APPROX_PIXELS8_XY2 0 +cglobal avg_approx_pixels8_xy2, 4,5 + mova m6, [pb_1] + lea r4, [r2*2] + mova m0, [r1] + PAVGB m0, [r1+1] +.loop: + mova m2, [r1+r4] + mova m1, [r1+r2] + psubusb m2, m6 + PAVGB m1, [r1+r2+1] + PAVGB m2, [r1+r4+1] + add r1, r4 + PAVGB m0, m1 + PAVGB m1, m2 + PAVGB m0, [r0] + PAVGB m1, [r0+r2] + mova [r0], m0 + mova [r0+r2], m1 + mova m1, [r1+r2] + mova m0, [r1+r4] + PAVGB m1, [r1+r2+1] + PAVGB m0, [r1+r4+1] + add r0, r4 + add r1, r4 + PAVGB m2, m1 + PAVGB m1, m0 + PAVGB m2, [r0] + PAVGB m1, [r0+r2] + mova [r0], m2 + mova [r0+r2], m1 + add r0, r4 + sub r3d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +AVG_APPROX_PIXELS8_XY2 +INIT_MMX 3dnow +AVG_APPROX_PIXELS8_XY2 + + +; void ff_avg_pixels16_xy2(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro SET_PIXELS_XY2 1 +%if cpuflag(sse2) +cglobal %1_pixels16_xy2, 4,5,8 +%else +cglobal %1_pixels8_xy2, 4,5 +%endif + pxor m7, m7 + mova m6, [pw_2] + movu m0, [r1] + movu m4, [r1+1] + mova m1, m0 + mova m5, m4 + punpcklbw m0, m7 + punpcklbw m4, m7 + punpckhbw m1, m7 + punpckhbw m5, m7 + paddusw m4, m0 + paddusw m5, m1 + xor r4, r4 + add r1, r2 +.loop: + movu m0, [r1+r4] + movu m2, [r1+r4+1] + mova m1, m0 + mova m3, m2 + punpcklbw m0, m7 + punpcklbw m2, m7 + punpckhbw m1, m7 + punpckhbw m3, m7 + paddusw m0, m2 + paddusw m1, m3 + paddusw m4, m6 + paddusw m5, m6 + paddusw m4, m0 + paddusw m5, m1 + psrlw m4, 2 + psrlw m5, 2 +%ifidn %1, avg + mova m3, [r0+r4] + packuswb m4, m5 + PAVGB m4, m3 +%else + packuswb m4, m5 +%endif + mova [r0+r4], m4 + add r4, r2 + + movu m2, [r1+r4] + movu m4, [r1+r4+1] + mova m3, m2 + mova m5, m4 + punpcklbw m2, m7 + punpcklbw m4, m7 + punpckhbw m3, m7 + punpckhbw m5, m7 + paddusw m4, m2 + paddusw m5, m3 + paddusw m0, m6 + paddusw m1, m6 + paddusw m0, m4 + paddusw m1, m5 + psrlw m0, 2 + psrlw m1, 2 +%ifidn %1, avg + mova m3, [r0+r4] + packuswb m0, m1 + PAVGB m0, m3 +%else + packuswb m0, m1 +%endif + mova [r0+r4], m0 + add r4, r2 + sub r3d, 2 + jnz .loop + REP_RET +%endmacro + +INIT_MMX mmxext +SET_PIXELS_XY2 avg +INIT_MMX 3dnow +SET_PIXELS_XY2 avg +INIT_XMM sse2 +SET_PIXELS_XY2 put +SET_PIXELS_XY2 avg + +%macro SSSE3_PIXELS_XY2 1-2 +%if %0 == 2 ; sse2 +cglobal %1_pixels16_xy2, 4,5,%2 + mova m4, [pb_interleave16] +%else +cglobal %1_pixels8_xy2, 4,5 + mova m4, [pb_interleave8] +%endif + mova m5, [pb_1] + movu m0, [r1] + movu m1, [r1+1] + pmaddubsw m0, m5 + pmaddubsw m1, m5 + xor r4, r4 + add r1, r2 +.loop: + movu m2, [r1+r4] + movu m3, [r1+r4+1] + pmaddubsw m2, m5 + pmaddubsw m3, m5 + paddusw m0, m2 + paddusw m1, m3 + pmulhrsw m0, [pw_8192] + pmulhrsw m1, [pw_8192] +%ifidn %1, avg + mova m6, [r0+r4] + packuswb m0, m1 + pshufb m0, m4 + pavgb m0, m6 +%else + packuswb m0, m1 + pshufb m0, m4 +%endif + mova [r0+r4], m0 + add r4, r2 + + movu m0, [r1+r4] + movu m1, [r1+r4+1] + pmaddubsw m0, m5 + pmaddubsw m1, m5 + paddusw m2, m0 + paddusw m3, m1 + pmulhrsw m2, [pw_8192] + pmulhrsw m3, [pw_8192] +%ifidn %1, avg + mova m6, [r0+r4] + packuswb m2, m3 + pshufb m2, m4 + pavgb m2, m6 +%else + packuswb m2, m3 + pshufb m2, m4 +%endif + mova [r0+r4], m2 + add r4, r2 + sub r3d, 2 + jnz .loop + REP_RET +%endmacro + +INIT_MMX ssse3 +SSSE3_PIXELS_XY2 put +SSSE3_PIXELS_XY2 avg +INIT_XMM ssse3 +SSSE3_PIXELS_XY2 put, 6 +SSSE3_PIXELS_XY2 avg, 7 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp.h new file mode 100644 index 00000000..bf97029b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp.h @@ -0,0 +1,57 @@ +/* + * 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 + */ + +#ifndef AVCODEC_X86_HPELDSP_H +#define AVCODEC_X86_HPELDSP_H + +#include +#include + +#include "libavcodec/hpeldsp.h" + +void ff_avg_pixels8_x2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_avg_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_avg_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_xy2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_put_pixels8_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_mmx(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_xy2_ssse3(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +void ff_hpeldsp_vp3_init_x86(HpelDSPContext *c, int cpu_flags, int flags); + +#endif /* AVCODEC_X86_HPELDSP_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_init.c new file mode 100644 index 00000000..d89928ce --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_init.c @@ -0,0 +1,313 @@ +/* + * SIMD-optimized halfpel functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * 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 + * + * MMX optimization by Nick Kurshev + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/hpeldsp.h" +#include "libavcodec/pixels.h" +#include "fpel.h" +#include "hpeldsp.h" + +void ff_put_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_x2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_x2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels16_y2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels16_y2_sse2(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_x2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_x2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_y2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_y2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_approx_pixels8_xy2_mmxext(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_avg_approx_pixels8_xy2_3dnow(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h); + +#define avg_pixels8_mmx ff_avg_pixels8_mmx +#define avg_pixels8_x2_mmx ff_avg_pixels8_x2_mmx +#define avg_pixels16_mmx ff_avg_pixels16_mmx +#define avg_pixels8_xy2_mmx ff_avg_pixels8_xy2_mmx +#define avg_pixels16_xy2_mmx ff_avg_pixels16_xy2_mmx +#define put_pixels8_mmx ff_put_pixels8_mmx +#define put_pixels16_mmx ff_put_pixels16_mmx +#define put_pixels8_xy2_mmx ff_put_pixels8_xy2_mmx +#define put_pixels16_xy2_mmx ff_put_pixels16_xy2_mmx +#define avg_no_rnd_pixels16_mmx ff_avg_pixels16_mmx +#define put_no_rnd_pixels8_mmx ff_put_pixels8_mmx +#define put_no_rnd_pixels16_mmx ff_put_pixels16_mmx + +#if HAVE_INLINE_ASM + +/***********************************/ +/* MMX no rounding */ +#define DEF(x, y) x ## _no_rnd_ ## y ## _mmx +#define SET_RND MOVQ_WONE +#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX_NO_RND(a, b, c, d, e, f) +#define PAVGB(a, b, c, e) PAVGB_MMX_NO_RND(a, b, c, e) +#define STATIC static + +#include "rnd_template.c" +#include "hpeldsp_rnd_template.c" + +#undef DEF +#undef SET_RND +#undef PAVGBP +#undef PAVGB +#undef STATIC + +#if HAVE_MMX +CALL_2X_PIXELS(avg_no_rnd_pixels16_y2_mmx, avg_no_rnd_pixels8_y2_mmx, 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_y2_mmx, put_no_rnd_pixels8_y2_mmx, 8) + +CALL_2X_PIXELS(avg_no_rnd_pixels16_xy2_mmx, avg_no_rnd_pixels8_xy2_mmx, 8) +CALL_2X_PIXELS(put_no_rnd_pixels16_xy2_mmx, put_no_rnd_pixels8_xy2_mmx, 8) +#endif + +/***********************************/ +/* MMX rounding */ + +#define DEF(x, y) x ## _ ## y ## _mmx +#define SET_RND MOVQ_WTWO +#define PAVGBP(a, b, c, d, e, f) PAVGBP_MMX(a, b, c, d, e, f) +#define PAVGB(a, b, c, e) PAVGB_MMX(a, b, c, e) + +#include "hpeldsp_rnd_template.c" + +#undef DEF +#define DEF(x, y) ff_ ## x ## _ ## y ## _mmx +#define STATIC + +#include "rnd_template.c" + +#undef DEF +#undef SET_RND +#undef PAVGBP +#undef PAVGB + +#if HAVE_MMX +CALL_2X_PIXELS(avg_pixels16_y2_mmx, avg_pixels8_y2_mmx, 8) +CALL_2X_PIXELS(put_pixels16_y2_mmx, put_pixels8_y2_mmx, 8) + +CALL_2X_PIXELS_EXPORT(ff_avg_pixels16_xy2_mmx, ff_avg_pixels8_xy2_mmx, 8) +CALL_2X_PIXELS_EXPORT(ff_put_pixels16_xy2_mmx, ff_put_pixels8_xy2_mmx, 8) +#endif + +#endif /* HAVE_INLINE_ASM */ + + +#if HAVE_X86ASM + +#define HPELDSP_AVG_PIXELS16(CPUEXT) \ + CALL_2X_PIXELS(put_no_rnd_pixels16_x2 ## CPUEXT, ff_put_no_rnd_pixels8_x2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(put_pixels16_y2 ## CPUEXT, ff_put_pixels8_y2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(put_no_rnd_pixels16_y2 ## CPUEXT, ff_put_no_rnd_pixels8_y2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16 ## CPUEXT, ff_avg_pixels8 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16_x2 ## CPUEXT, ff_avg_pixels8_x2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16_y2 ## CPUEXT, ff_avg_pixels8_y2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_pixels16_xy2 ## CPUEXT, ff_avg_pixels8_xy2 ## CPUEXT, 8) \ + CALL_2X_PIXELS(avg_approx_pixels16_xy2## CPUEXT, ff_avg_approx_pixels8_xy2## CPUEXT, 8) + +HPELDSP_AVG_PIXELS16(_3dnow) +HPELDSP_AVG_PIXELS16(_mmxext) + +#endif /* HAVE_X86ASM */ + +#define SET_HPEL_FUNCS_EXT(PFX, IDX, SIZE, CPU) \ + if (HAVE_MMX_EXTERNAL) \ + c->PFX ## _pixels_tab IDX [0] = PFX ## _pixels ## SIZE ## _ ## CPU; + +#if HAVE_MMX_INLINE +#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ + do { \ + SET_HPEL_FUNCS_EXT(PFX, IDX, SIZE, CPU) \ + c->PFX ## _pixels_tab IDX [1] = PFX ## _pixels ## SIZE ## _x2_ ## CPU; \ + c->PFX ## _pixels_tab IDX [2] = PFX ## _pixels ## SIZE ## _y2_ ## CPU; \ + c->PFX ## _pixels_tab IDX [3] = PFX ## _pixels ## SIZE ## _xy2_ ## CPU; \ + } while (0) +#else +#define SET_HPEL_FUNCS(PFX, IDX, SIZE, CPU) \ + do { \ + SET_HPEL_FUNCS_EXT(PFX, IDX, SIZE, CPU) \ + } while (0) +#endif + +static void hpeldsp_init_mmx(HpelDSPContext *c, int flags) +{ + SET_HPEL_FUNCS(put, [0], 16, mmx); + SET_HPEL_FUNCS(put_no_rnd, [0], 16, mmx); + SET_HPEL_FUNCS(avg, [0], 16, mmx); + SET_HPEL_FUNCS(avg_no_rnd, , 16, mmx); + SET_HPEL_FUNCS(put, [1], 8, mmx); + SET_HPEL_FUNCS(put_no_rnd, [1], 8, mmx); + if (HAVE_MMX_EXTERNAL) { + c->avg_pixels_tab[1][0] = ff_avg_pixels8_mmx; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_mmx; + } +#if HAVE_MMX_INLINE + c->avg_pixels_tab[1][2] = avg_pixels8_y2_mmx; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmx; +#endif +} + +static void hpeldsp_init_mmxext(HpelDSPContext *c, int flags) +{ +#if HAVE_MMXEXT_EXTERNAL + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_mmxext; + c->put_pixels_tab[0][2] = put_pixels16_y2_mmxext; + + c->avg_pixels_tab[0][0] = avg_pixels16_mmxext; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_mmxext; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_mmxext; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_mmxext; + + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_mmxext; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_mmxext; + + c->avg_pixels_tab[1][0] = ff_avg_pixels8_mmxext; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_mmxext; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_mmxext; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_mmxext; + + if (!(flags & AV_CODEC_FLAG_BITEXACT)) { + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_mmxext; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_mmxext; + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_mmxext; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_mmxext; + + c->avg_pixels_tab[0][3] = avg_approx_pixels16_xy2_mmxext; + c->avg_pixels_tab[1][3] = ff_avg_approx_pixels8_xy2_mmxext; + } +#endif /* HAVE_MMXEXT_EXTERNAL */ +} + +static void hpeldsp_init_3dnow(HpelDSPContext *c, int flags) +{ +#if HAVE_AMD3DNOW_EXTERNAL + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_3dnow; + c->put_pixels_tab[0][2] = put_pixels16_y2_3dnow; + + c->avg_pixels_tab[0][0] = avg_pixels16_3dnow; + c->avg_pixels_tab[0][1] = avg_pixels16_x2_3dnow; + c->avg_pixels_tab[0][2] = avg_pixels16_y2_3dnow; + c->avg_pixels_tab[0][3] = avg_pixels16_xy2_3dnow; + + c->put_pixels_tab[1][1] = ff_put_pixels8_x2_3dnow; + c->put_pixels_tab[1][2] = ff_put_pixels8_y2_3dnow; + + c->avg_pixels_tab[1][0] = ff_avg_pixels8_3dnow; + c->avg_pixels_tab[1][1] = ff_avg_pixels8_x2_3dnow; + c->avg_pixels_tab[1][2] = ff_avg_pixels8_y2_3dnow; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_3dnow; + + if (!(flags & AV_CODEC_FLAG_BITEXACT)){ + c->put_no_rnd_pixels_tab[0][1] = put_no_rnd_pixels16_x2_3dnow; + c->put_no_rnd_pixels_tab[0][2] = put_no_rnd_pixels16_y2_3dnow; + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_3dnow; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_3dnow; + + c->avg_pixels_tab[0][3] = avg_approx_pixels16_xy2_3dnow; + c->avg_pixels_tab[1][3] = ff_avg_approx_pixels8_xy2_3dnow; + } +#endif /* HAVE_AMD3DNOW_EXTERNAL */ +} + +static void hpeldsp_init_sse2_fast(HpelDSPContext *c, int flags) +{ +#if HAVE_SSE2_EXTERNAL + c->put_pixels_tab[0][0] = ff_put_pixels16_sse2; + c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_sse2; + c->put_pixels_tab[0][1] = ff_put_pixels16_x2_sse2; + c->put_pixels_tab[0][2] = ff_put_pixels16_y2_sse2; + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_sse2; + c->avg_pixels_tab[0][0] = ff_avg_pixels16_sse2; + c->avg_pixels_tab[0][1] = ff_avg_pixels16_x2_sse2; + c->avg_pixels_tab[0][2] = ff_avg_pixels16_y2_sse2; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_sse2; +#endif /* HAVE_SSE2_EXTERNAL */ +} + +static void hpeldsp_init_ssse3(HpelDSPContext *c, int flags) +{ +#if HAVE_SSSE3_EXTERNAL + c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_ssse3; + c->avg_pixels_tab[0][3] = ff_avg_pixels16_xy2_ssse3; + c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_ssse3; + c->avg_pixels_tab[1][3] = ff_avg_pixels8_xy2_ssse3; +#endif +} + +av_cold void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags) +{ + int cpu_flags = av_get_cpu_flags(); + + if (INLINE_MMX(cpu_flags)) + hpeldsp_init_mmx(c, flags); + + if (EXTERNAL_AMD3DNOW(cpu_flags)) + hpeldsp_init_3dnow(c, flags); + + if (EXTERNAL_MMXEXT(cpu_flags)) + hpeldsp_init_mmxext(c, flags); + + if (EXTERNAL_SSE2_FAST(cpu_flags)) + hpeldsp_init_sse2_fast(c, flags); + + if (EXTERNAL_SSSE3(cpu_flags)) + hpeldsp_init_ssse3(c, flags); + + if (CONFIG_VP3_DECODER) + ff_hpeldsp_vp3_init_x86(c, cpu_flags, flags); +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_rnd_template.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_rnd_template.c new file mode 100644 index 00000000..2bff2d27 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_rnd_template.c @@ -0,0 +1,202 @@ +/* + * SIMD-optimized halfpel functions are compiled twice for rnd/no_rnd + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * mostly rewritten by Michael Niedermayer + * and improved by Zdenek Kabelac + * + * 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 +#include + +// put_pixels +av_unused static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +av_unused static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%1, %3), %%mm2 \n\t" + "movq 1(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%1, %3), %%mm2 \n\t" + "movq 9(%1, %3), %%mm3 \n\t" + PAVGBP(%%mm0, %%mm1, %%mm4, %%mm2, %%mm3, %%mm5) + "movq %%mm4, 8(%2) \n\t" + "movq %%mm5, 8(%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +av_unused static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"),%%mm2\n\t" + PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"),%%mm0\n\t" + PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq %%mm4, (%2) \n\t" + "movq %%mm5, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +av_unused static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm1 \n\t" + "movq (%2), %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq 8(%1), %%mm0 \n\t" + "movq 9(%1), %%mm1 \n\t" + "movq 8(%2), %%mm3 \n\t" + PAVGB(%%mm0, %%mm1, %%mm2, %%mm6) + PAVGB_MMX(%%mm3, %%mm2, %%mm0, %%mm6) + "movq %%mm0, 8(%2) \n\t" + "add %3, %1 \n\t" + "add %3, %2 \n\t" + "subl $1, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :"memory"); +} + +av_unused static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +{ + MOVQ_BFE(mm6); + __asm__ volatile( + "lea (%3, %3), %%"FF_REG_a" \n\t" + "movq (%1), %%mm0 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" + PAVGBP(%%mm1, %%mm0, %%mm4, %%mm2, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm0, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm0, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + + "movq (%1, %3), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + PAVGBP(%%mm1, %%mm2, %%mm4, %%mm0, %%mm1, %%mm5) + "movq (%2), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm2, %%mm6) + "movq (%2, %3), %%mm3 \n\t" + PAVGB_MMX(%%mm3, %%mm5, %%mm1, %%mm6) + "movq %%mm2, (%2) \n\t" + "movq %%mm1, (%2, %3) \n\t" + "add %%"FF_REG_a", %1 \n\t" + "add %%"FF_REG_a", %2 \n\t" + + "subl $4, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels), "+D"(block) + :"r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_vp3.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_vp3.asm new file mode 100644 index 00000000..cba96d06 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_vp3.asm @@ -0,0 +1,111 @@ +;****************************************************************************** +;* SIMD-optimized halfpel functions for VP3 +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +; void ff_put_no_rnd_pixels8_x2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_NO_RND_PIXELS8_X2_EXACT 0 +cglobal put_no_rnd_pixels8_x2_exact, 4,5 + lea r4, [r2*3] + pcmpeqb m6, m6 +.loop: + mova m0, [r1] + mova m2, [r1+r2] + mova m1, [r1+1] + mova m3, [r1+r2+1] + pxor m0, m6 + pxor m2, m6 + pxor m1, m6 + pxor m3, m6 + PAVGB m0, m1 + PAVGB m2, m3 + pxor m0, m6 + pxor m2, m6 + mova [r0], m0 + mova [r0+r2], m2 + mova m0, [r1+r2*2] + mova m1, [r1+r2*2+1] + mova m2, [r1+r4] + mova m3, [r1+r4+1] + pxor m0, m6 + pxor m1, m6 + pxor m2, m6 + pxor m3, m6 + PAVGB m0, m1 + PAVGB m2, m3 + pxor m0, m6 + pxor m2, m6 + mova [r0+r2*2], m0 + mova [r0+r4], m2 + lea r1, [r1+r2*4] + lea r0, [r0+r2*4] + sub r3d, 4 + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_NO_RND_PIXELS8_X2_EXACT +INIT_MMX 3dnow +PUT_NO_RND_PIXELS8_X2_EXACT + + +; void ff_put_no_rnd_pixels8_y2_exact(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h) +%macro PUT_NO_RND_PIXELS8_Y2_EXACT 0 +cglobal put_no_rnd_pixels8_y2_exact, 4,5 + lea r4, [r2*3] + mova m0, [r1] + pcmpeqb m6, m6 + add r1, r2 + pxor m0, m6 +.loop: + mova m1, [r1] + mova m2, [r1+r2] + pxor m1, m6 + pxor m2, m6 + PAVGB m0, m1 + PAVGB m1, m2 + pxor m0, m6 + pxor m1, m6 + mova [r0], m0 + mova [r0+r2], m1 + mova m1, [r1+r2*2] + mova m0, [r1+r4] + pxor m1, m6 + pxor m0, m6 + PAVGB m2, m1 + PAVGB m1, m0 + pxor m2, m6 + pxor m1, m6 + mova [r0+r2*2], m2 + mova [r0+r4], m1 + lea r1, [r1+r2*4] + lea r0, [r0+r2*4] + sub r3d, 4 + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_NO_RND_PIXELS8_Y2_EXACT +INIT_MMX 3dnow +PUT_NO_RND_PIXELS8_Y2_EXACT diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_vp3_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_vp3_init.c new file mode 100644 index 00000000..5979f412 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/hpeldsp_vp3_init.c @@ -0,0 +1,56 @@ +/* + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" + +#include "libavcodec/avcodec.h" +#include "libavcodec/hpeldsp.h" + +#include "hpeldsp.h" + +void ff_put_no_rnd_pixels8_x2_exact_mmxext(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_x2_exact_3dnow(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_exact_mmxext(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); +void ff_put_no_rnd_pixels8_y2_exact_3dnow(uint8_t *block, + const uint8_t *pixels, + ptrdiff_t line_size, int h); + +av_cold void ff_hpeldsp_vp3_init_x86(HpelDSPContext *c, int cpu_flags, int flags) +{ + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + if (flags & AV_CODEC_FLAG_BITEXACT) { + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_3dnow; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_3dnow; + } + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + if (flags & AV_CODEC_FLAG_BITEXACT) { + c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_exact_mmxext; + c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_exact_mmxext; + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp.asm new file mode 100644 index 00000000..a1231f1b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp.asm @@ -0,0 +1,164 @@ +;****************************************************************************** +;* SIMD-optimized HuffYUV functions +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2014 Christophe Gisquet +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%include "libavcodec/x86/huffyuvdsp_template.asm" + +;------------------------------------------------------------------------------ +; void (*add_int16)(uint16_t *dst, const uint16_t *src, unsigned mask, int w); +;------------------------------------------------------------------------------ + +%macro ADD_INT16 0 +cglobal add_int16, 4,4,5, dst, src, mask, w, tmp +%if mmsize > 8 + test srcq, mmsize-1 + jnz .unaligned + test dstq, mmsize-1 + jnz .unaligned +%endif + INT16_LOOP a, add +%if mmsize > 8 +.unaligned: + INT16_LOOP u, add +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +ADD_INT16 +%endif + +INIT_XMM sse2 +ADD_INT16 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +ADD_INT16 +%endif + +; void add_hfyu_left_pred_bgr32(uint8_t *dst, const uint8_t *src, +; intptr_t w, uint8_t *left) +%macro LEFT_BGR32 0 +cglobal add_hfyu_left_pred_bgr32, 4,4,3, dst, src, w, left + shl wq, 2 + movd m0, [leftq] + lea dstq, [dstq + wq] + lea srcq, [srcq + wq] + LSHIFT m0, mmsize-4 + neg wq +.loop: + movu m1, [srcq+wq] + mova m2, m1 +%if mmsize == 8 + punpckhdq m0, m0 +%endif + LSHIFT m1, 4 + paddb m1, m2 +%if mmsize == 16 + pshufd m0, m0, q3333 + mova m2, m1 + LSHIFT m1, 8 + paddb m1, m2 +%endif + paddb m0, m1 + movu [dstq+wq], m0 + add wq, mmsize + jl .loop + movd m0, [dstq-4] + movd [leftq], m0 + REP_RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +LEFT_BGR32 +%endif +INIT_XMM sse2 +LEFT_BGR32 + +; void add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int mask, int w, int *left, int *left_top) +INIT_MMX mmxext +cglobal add_hfyu_median_pred_int16, 7,7,0, dst, top, diff, mask, w, left, left_top + add wd, wd + movd mm6, maskd + SPLATW mm6, mm6 + movq mm0, [topq] + movq mm2, mm0 + movd mm4, [left_topq] + psllq mm2, 16 + movq mm1, mm0 + por mm4, mm2 + movd mm3, [leftq] + psubw mm0, mm4 ; t-tl + add dstq, wq + add topq, wq + add diffq, wq + neg wq + jmp .skip +.loop: + movq mm4, [topq+wq] + movq mm0, mm4 + psllq mm4, 16 + por mm4, mm1 + movq mm1, mm0 ; t + psubw mm0, mm4 ; t-tl +.skip: + movq mm2, [diffq+wq] +%assign i 0 +%rep 4 + movq mm4, mm0 + paddw mm4, mm3 ; t-tl+l + pand mm4, mm6 + movq mm5, mm3 + pmaxsw mm3, mm1 + pminsw mm5, mm1 + pminsw mm3, mm4 + pmaxsw mm3, mm5 ; median + paddw mm3, mm2 ; +residual + pand mm3, mm6 +%if i==0 + movq mm7, mm3 + psllq mm7, 48 +%else + movq mm4, mm3 + psrlq mm7, 16 + psllq mm4, 48 + por mm7, mm4 +%endif +%if i<3 + psrlq mm0, 16 + psrlq mm1, 16 + psrlq mm2, 16 +%endif +%assign i i+1 +%endrep + movq [dstq+wq], mm7 + add wq, 8 + jl .loop + movzx r2d, word [dstq-2] + mov [leftq], r2d + movzx r2d, word [topq-2] + mov [left_topq], r2d + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp_init.c new file mode 100644 index 00000000..eb10de38 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp_init.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2009 Loren Merritt + * + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/pixdesc.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/huffyuvdsp.h" + +void ff_add_int16_mmx(uint16_t *dst, const uint16_t *src, unsigned mask, int w); +void ff_add_int16_sse2(uint16_t *dst, const uint16_t *src, unsigned mask, int w); +void ff_add_int16_avx2(uint16_t *dst, const uint16_t *src, unsigned mask, int w); + +void ff_add_hfyu_left_pred_bgr32_mmx(uint8_t *dst, const uint8_t *src, + intptr_t w, uint8_t *left); +void ff_add_hfyu_left_pred_bgr32_sse2(uint8_t *dst, const uint8_t *src, + intptr_t w, uint8_t *left); +void ff_add_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *top, const uint16_t *diff, unsigned mask, int w, int *left, int *left_top); + +av_cold void ff_huffyuvdsp_init_x86(HuffYUVDSPContext *c, enum AVPixelFormat pix_fmt) +{ + int cpu_flags = av_get_cpu_flags(); + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(pix_fmt); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_mmx; + c->add_int16 = ff_add_int16_mmx; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && pix_desc && pix_desc->comp[0].depth<16) { + c->add_hfyu_median_pred_int16 = ff_add_hfyu_median_pred_int16_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->add_int16 = ff_add_int16_sse2; + c->add_hfyu_left_pred_bgr32 = ff_add_hfyu_left_pred_bgr32_sse2; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->add_int16 = ff_add_int16_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp_template.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp_template.asm new file mode 100644 index 00000000..89721f4e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvdsp_template.asm @@ -0,0 +1,76 @@ +;****************************************************************************** +;* SIMD-optimized HuffYUV functions +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2014 Christophe Gisquet +;* +;* 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 +;****************************************************************************** + +%macro INT16_LOOP 2 ; %1 = a/u (aligned/unaligned), %2 = add/sub + movd xm4, maskd + SPLATW m4, xm4 + add wd, wd + test wq, 2*mmsize - 1 + jz %%.tomainloop + push tmpq +%%.wordloop: + sub wq, 2 +%ifidn %2, add + mov tmpw, [srcq+wq] + add tmpw, [dstq+wq] +%else + mov tmpw, [src1q+wq] + sub tmpw, [src2q+wq] +%endif + and tmpw, maskw + mov [dstq+wq], tmpw + test wq, 2*mmsize - 1 + jnz %%.wordloop + pop tmpq +%%.tomainloop: +%ifidn %2, add + add srcq, wq +%else + add src1q, wq + add src2q, wq +%endif + add dstq, wq + neg wq + jz %%.end +%%.loop: +%ifidn %2, add + mov%1 m0, [srcq+wq] + mov%1 m1, [dstq+wq] + mov%1 m2, [srcq+wq+mmsize] + mov%1 m3, [dstq+wq+mmsize] +%else + mov%1 m0, [src1q+wq] + mov%1 m1, [src2q+wq] + mov%1 m2, [src1q+wq+mmsize] + mov%1 m3, [src2q+wq+mmsize] +%endif + p%2w m0, m1 + p%2w m2, m3 + pand m0, m4 + pand m2, m4 + mov%1 [dstq+wq] , m0 + mov%1 [dstq+wq+mmsize], m2 + add wq, 2*mmsize + jl %%.loop +%%.end: + RET +%endmacro diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvencdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvencdsp.asm new file mode 100644 index 00000000..d994fd0f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvencdsp.asm @@ -0,0 +1,105 @@ +;************************************************************************ +;* SIMD-optimized HuffYUV encoding functions +;* Copyright (c) 2000, 2001 Fabrice Bellard +;* Copyright (c) 2002-2004 Michael Niedermayer +;* +;* MMX optimization by Nick Kurshev +;* Conversion to NASM format by Tiancheng "Timothy" Gu +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION .text + +%include "libavcodec/x86/huffyuvdsp_template.asm" + +;------------------------------------------------------------------------------ +; void ff_diff_int16(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, +; unsigned mask, int w); +;------------------------------------------------------------------------------ + +%macro DIFF_INT16 0 +cglobal diff_int16, 5,5,5, dst, src1, src2, mask, w, tmp +%if mmsize > 8 + test src1q, mmsize-1 + jnz .unaligned + test src2q, mmsize-1 + jnz .unaligned + test dstq, mmsize-1 + jnz .unaligned +%endif + INT16_LOOP a, sub +%if mmsize > 8 +.unaligned: + INT16_LOOP u, sub +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +DIFF_INT16 +%endif + +INIT_XMM sse2 +DIFF_INT16 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +DIFF_INT16 +%endif + +INIT_MMX mmxext +cglobal sub_hfyu_median_pred_int16, 7,7,0, dst, src1, src2, mask, w, left, left_top + add wd, wd + movd mm7, maskd + SPLATW mm7, mm7 + movq mm0, [src1q] + movq mm2, [src2q] + psllq mm0, 16 + psllq mm2, 16 + movd mm6, [left_topq] + por mm0, mm6 + movd mm6, [leftq] + por mm2, mm6 + xor maskq, maskq +.loop: + movq mm1, [src1q + maskq] + movq mm3, [src2q + maskq] + movq mm4, mm2 + psubw mm2, mm0 + paddw mm2, mm1 + pand mm2, mm7 + movq mm5, mm4 + pmaxsw mm4, mm1 + pminsw mm1, mm5 + pminsw mm4, mm2 + pmaxsw mm4, mm1 + psubw mm3, mm4 + pand mm3, mm7 + movq [dstq + maskq], mm3 + add maskq, 8 + movq mm0, [src1q + maskq - 2] + movq mm2, [src2q + maskq - 2] + cmp maskq, wq + jb .loop + movzx maskd, word [src1q + wq - 2] + mov [left_topq], maskd + movzx maskd, word [src2q + wq - 2] + mov [leftq], maskd + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvencdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvencdsp_init.c new file mode 100644 index 00000000..6c6e068c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/huffyuvencdsp_init.c @@ -0,0 +1,60 @@ +/* + * SIMD-optimized HuffYUV encoding functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/pixdesc.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/huffyuvencdsp.h" + +void ff_diff_int16_mmx (uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w); +void ff_diff_int16_sse2(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w); +void ff_diff_int16_avx2(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w); +void ff_sub_hfyu_median_pred_int16_mmxext(uint16_t *dst, const uint16_t *src1, const uint16_t *src2, + unsigned mask, int w, int *left, int *left_top); + +av_cold void ff_huffyuvencdsp_init_x86(HuffYUVEncDSPContext *c, AVCodecContext *avctx) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->diff_int16 = ff_diff_int16_mmx; + } + + if (EXTERNAL_MMXEXT(cpu_flags) && pix_desc && pix_desc->comp[0].depth<16) { + c->sub_hfyu_median_pred_int16 = ff_sub_hfyu_median_pred_int16_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->diff_int16 = ff_diff_int16_sse2; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->diff_int16 = ff_diff_int16_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp.asm new file mode 100644 index 00000000..089425a9 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp.asm @@ -0,0 +1,183 @@ +;****************************************************************************** +;* SIMD-optimized IDCT-related routines +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2003-2013 Michael Niedermayer +;* Copyright (c) 2013 Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pb_80 + +SECTION .text + +;-------------------------------------------------------------------------- +;void ff_put_signed_pixels_clamped(const int16_t *block, uint8_t *pixels, +; ptrdiff_t line_size) +;-------------------------------------------------------------------------- + +%macro PUT_SIGNED_PIXELS_CLAMPED_HALF 1 + mova m1, [blockq+mmsize*0+%1] + mova m2, [blockq+mmsize*2+%1] +%if mmsize == 8 + mova m3, [blockq+mmsize*4+%1] + mova m4, [blockq+mmsize*6+%1] +%endif + packsswb m1, [blockq+mmsize*1+%1] + packsswb m2, [blockq+mmsize*3+%1] +%if mmsize == 8 + packsswb m3, [blockq+mmsize*5+%1] + packsswb m4, [blockq+mmsize*7+%1] +%endif + paddb m1, m0 + paddb m2, m0 +%if mmsize == 8 + paddb m3, m0 + paddb m4, m0 + movq [pixelsq+lsizeq*0], m1 + movq [pixelsq+lsizeq*1], m2 + movq [pixelsq+lsizeq*2], m3 + movq [pixelsq+lsize3q ], m4 +%else + movq [pixelsq+lsizeq*0], m1 + movhps [pixelsq+lsizeq*1], m1 + movq [pixelsq+lsizeq*2], m2 + movhps [pixelsq+lsize3q ], m2 +%endif +%endmacro + +%macro PUT_SIGNED_PIXELS_CLAMPED 1 +cglobal put_signed_pixels_clamped, 3, 4, %1, block, pixels, lsize, lsize3 + mova m0, [pb_80] + lea lsize3q, [lsizeq*3] + PUT_SIGNED_PIXELS_CLAMPED_HALF 0 + lea pixelsq, [pixelsq+lsizeq*4] + PUT_SIGNED_PIXELS_CLAMPED_HALF 64 + RET +%endmacro + +INIT_MMX mmx +PUT_SIGNED_PIXELS_CLAMPED 0 +INIT_XMM sse2 +PUT_SIGNED_PIXELS_CLAMPED 3 + +;-------------------------------------------------------------------------- +; void ff_put_pixels_clamped(const int16_t *block, uint8_t *pixels, +; ptrdiff_t line_size); +;-------------------------------------------------------------------------- +; %1 = block offset +%macro PUT_PIXELS_CLAMPED_HALF 1 + mova m0, [blockq+mmsize*0+%1] + mova m1, [blockq+mmsize*2+%1] +%if mmsize == 8 + mova m2, [blockq+mmsize*4+%1] + mova m3, [blockq+mmsize*6+%1] +%endif + packuswb m0, [blockq+mmsize*1+%1] + packuswb m1, [blockq+mmsize*3+%1] +%if mmsize == 8 + packuswb m2, [blockq+mmsize*5+%1] + packuswb m3, [blockq+mmsize*7+%1] + movq [pixelsq], m0 + movq [lsizeq+pixelsq], m1 + movq [2*lsizeq+pixelsq], m2 + movq [lsize3q+pixelsq], m3 +%else + movq [pixelsq], m0 + movhps [lsizeq+pixelsq], m0 + movq [2*lsizeq+pixelsq], m1 + movhps [lsize3q+pixelsq], m1 +%endif +%endmacro + +%macro PUT_PIXELS_CLAMPED 0 +cglobal put_pixels_clamped, 3, 4, 2, block, pixels, lsize, lsize3 + lea lsize3q, [lsizeq*3] + PUT_PIXELS_CLAMPED_HALF 0 + lea pixelsq, [pixelsq+lsizeq*4] + PUT_PIXELS_CLAMPED_HALF 64 + RET +%endmacro + +INIT_MMX mmx +PUT_PIXELS_CLAMPED +INIT_XMM sse2 +PUT_PIXELS_CLAMPED + +;-------------------------------------------------------------------------- +; void ff_add_pixels_clamped(const int16_t *block, uint8_t *pixels, +; ptrdiff_t line_size); +;-------------------------------------------------------------------------- +; %1 = block offset +%macro ADD_PIXELS_CLAMPED 1 + mova m0, [blockq+mmsize*0+%1] + mova m1, [blockq+mmsize*1+%1] +%if mmsize == 8 + mova m5, [blockq+mmsize*2+%1] + mova m6, [blockq+mmsize*3+%1] +%endif + movq m2, [pixelsq] + movq m3, [pixelsq+lsizeq] +%if mmsize == 8 + mova m7, m2 + punpcklbw m2, m4 + punpckhbw m7, m4 + paddsw m0, m2 + paddsw m1, m7 + mova m7, m3 + punpcklbw m3, m4 + punpckhbw m7, m4 + paddsw m5, m3 + paddsw m6, m7 +%else + punpcklbw m2, m4 + punpcklbw m3, m4 + paddsw m0, m2 + paddsw m1, m3 +%endif + packuswb m0, m1 +%if mmsize == 8 + packuswb m5, m6 + movq [pixelsq], m0 + movq [pixelsq+lsizeq], m5 +%else + movq [pixelsq], m0 + movhps [pixelsq+lsizeq], m0 +%endif +%endmacro + +%macro ADD_PIXELS_CLAMPED 0 +cglobal add_pixels_clamped, 3, 3, 5, block, pixels, lsize + pxor m4, m4 + ADD_PIXELS_CLAMPED 0 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 32 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 64 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 96 + RET +%endmacro + +INIT_MMX mmx +ADD_PIXELS_CLAMPED +INIT_XMM sse2 +ADD_PIXELS_CLAMPED diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp.h new file mode 100644 index 00000000..0d0bdb5f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp.h @@ -0,0 +1,39 @@ +/* + * 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 + */ + +#ifndef AVCODEC_X86_IDCTDSP_H +#define AVCODEC_X86_IDCTDSP_H + +#include +#include + +void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_add_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); +void ff_put_signed_pixels_clamped_sse2(const int16_t *block, uint8_t *pixels, + ptrdiff_t line_size); + + +#endif /* AVCODEC_X86_IDCTDSP_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp_init.c new file mode 100644 index 00000000..9103b92c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/idctdsp_init.c @@ -0,0 +1,162 @@ +/* + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/idctdsp.h" +#include "idctdsp.h" +#include "simple_idct.h" + +/* Input permutation for the simple_idct_mmx */ +static const uint8_t simple_mmx_permutation[64] = { + 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, + 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, + 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, + 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, + 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, + 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, + 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, + 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F, +}; + +static const uint8_t idct_sse2_row_perm[8] = { 0, 4, 1, 5, 2, 6, 3, 7 }; + +av_cold int ff_init_scantable_permutation_x86(uint8_t *idct_permutation, + enum idct_permutation_type perm_type) +{ + int i; + + switch (perm_type) { + case FF_IDCT_PERM_SIMPLE: + for (i = 0; i < 64; i++) + idct_permutation[i] = simple_mmx_permutation[i]; + return 1; + case FF_IDCT_PERM_SSE2: + for (i = 0; i < 64; i++) + idct_permutation[i] = (i & 0x38) | idct_sse2_row_perm[i & 7]; + return 1; + } + + return 0; +} + +av_cold void ff_idctdsp_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx; + c->put_pixels_clamped = ff_put_pixels_clamped_mmx; + c->add_pixels_clamped = ff_add_pixels_clamped_mmx; + + if (!high_bit_depth && + avctx->lowres == 0 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX)) { + c->idct_put = ff_simple_idct_put_mmx; + c->idct_add = ff_simple_idct_add_mmx; + c->idct = ff_simple_idct_mmx; + c->perm_type = FF_IDCT_PERM_SIMPLE; + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_sse2; + c->put_pixels_clamped = ff_put_pixels_clamped_sse2; + c->add_pixels_clamped = ff_add_pixels_clamped_sse2; + + if (!high_bit_depth && + avctx->lowres == 0 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX)) { + c->idct_put = ff_simple_idct_put_sse2; + c->idct_add = ff_simple_idct_add_sse2; + c->perm_type = FF_IDCT_PERM_SIMPLE; + } + + if (ARCH_X86_64 && + !high_bit_depth && + avctx->lowres == 0 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX || + avctx->idct_algo == FF_IDCT_SIMPLE)) { + c->idct = ff_simple_idct8_sse2; + c->idct_put = ff_simple_idct8_put_sse2; + c->idct_add = ff_simple_idct8_add_sse2; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + } + + if (ARCH_X86_64 && avctx->lowres == 0) { + if (EXTERNAL_AVX(cpu_flags) && + !high_bit_depth && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX || + avctx->idct_algo == FF_IDCT_SIMPLE)) { + c->idct = ff_simple_idct8_avx; + c->idct_put = ff_simple_idct8_put_avx; + c->idct_add = ff_simple_idct8_add_avx; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + + if (avctx->bits_per_raw_sample == 10 && + avctx->codec_id != AV_CODEC_ID_MPEG4 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEAUTO || + avctx->idct_algo == FF_IDCT_SIMPLE)) { + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_simple_idct10_put_sse2; + c->idct_add = NULL; + c->idct = ff_simple_idct10_sse2; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + + } + if (EXTERNAL_AVX(cpu_flags)) { + c->idct_put = ff_simple_idct10_put_avx; + c->idct_add = NULL; + c->idct = ff_simple_idct10_avx; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + } + + if (avctx->bits_per_raw_sample == 12 && + (avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_SIMPLEMMX)) { + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_simple_idct12_put_sse2; + c->idct_add = NULL; + c->idct = ff_simple_idct12_sse2; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + if (EXTERNAL_AVX(cpu_flags)) { + c->idct_put = ff_simple_idct12_put_avx; + c->idct_add = NULL; + c->idct = ff_simple_idct12_avx; + c->perm_type = FF_IDCT_PERM_TRANSPOSE; + } + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/imdct36.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/imdct36.asm new file mode 100644 index 00000000..b386ab95 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/imdct36.asm @@ -0,0 +1,741 @@ +;****************************************************************************** +;* 36 point SSE-optimized IMDCT transform +;* Copyright (c) 2011 Vitor Sessak +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +ps_mask: dd 0, ~0, ~0, ~0 +ps_mask2: dd 0, ~0, 0, ~0 +ps_mask3: dd 0, 0, 0, ~0 +ps_mask4: dd 0, ~0, 0, 0 + +ps_val1: dd -0.5, -0.5, -0.8660254038, -0.8660254038 +ps_val2: dd 1.0, 1.0, 0.8660254038, 0.8660254038 +ps_val3: dd 0.1736481777, 0.1736481777, 0.3420201433, 0.3420201433 +ps_val4: dd -0.7660444431, -0.7660444431, 0.8660254038, 0.8660254038 +ps_val5: dd -0.9396926208, -0.9396926208, -0.9848077530, -0.9848077530 +ps_val6: dd 0.5, 0.5, -0.6427876097, -0.6427876097 +ps_val7: dd 1.0, 1.0, -0.6427876097, -0.6427876097 + +ps_p1p1m1m1: dd 0, 0, 0x80000000, 0x80000000 +ps_p1m1p1m1: dd 0, 0x80000000, 0, 0x80000000 + +ps_cosh: dd 1.0, 0.50190991877167369479, 1.0, 5.73685662283492756461 + dd 1.0, 0.51763809020504152469, 1.0, 1.93185165257813657349 + dd 1.0, 0.55168895948124587824, -1.0, -1.18310079157624925896 + dd 1.0, 0.61038729438072803416, -1.0, -0.87172339781054900991 + dd 1.0, 0.70710678118654752439, 0.0, 0.0 + +ps_cosh_sse3: dd 1.0, -0.50190991877167369479, 1.0, -5.73685662283492756461 + dd 1.0, -0.51763809020504152469, 1.0, -1.93185165257813657349 + dd 1.0, -0.55168895948124587824, -1.0, 1.18310079157624925896 + dd 1.0, -0.61038729438072803416, -1.0, 0.87172339781054900991 + dd 1.0, -0.70710678118654752439, 0.0, 0.0 + +costabs: times 4 dd 0.98480773 + times 4 dd 0.93969262 + times 4 dd 0.86602539 + times 4 dd -0.76604444 + times 4 dd -0.64278764 + times 4 dd 0.50000000 + times 4 dd -0.50000000 + times 4 dd -0.34202015 + times 4 dd -0.17364818 + times 4 dd 0.50190992 + times 4 dd 0.51763808 + times 4 dd 0.55168896 + times 4 dd 0.61038726 + times 4 dd 0.70710677 + times 4 dd 0.87172341 + times 4 dd 1.18310082 + times 4 dd 1.93185163 + times 4 dd 5.73685646 + +%define SBLIMIT 32 +SECTION .text + +%macro PSHUFD 3 +%if cpuflag(sse2) && notcpuflag(avx) + pshufd %1, %2, %3 +%else + shufps %1, %2, %2, %3 +%endif +%endmacro + +; input %2={x1,x2,x3,x4}, %3={y1,y2,y3,y4} +; output %1={x3,x4,y1,y2} +%macro BUILDINVHIGHLOW 3 +%if cpuflag(avx) + shufps %1, %2, %3, 0x4e +%else + movlhps %1, %3 + movhlps %1, %2 +%endif +%endmacro + +; input %2={x1,x2,x3,x4}, %3={y1,y2,y3,y4} +; output %1={x4,y1,y2,y3} +%macro ROTLEFT 3 +%if cpuflag(ssse3) + palignr %1, %3, %2, 12 +%else + BUILDINVHIGHLOW %1, %2, %3 + shufps %1, %1, %3, 0x99 +%endif +%endmacro + +%macro INVERTHL 2 +%if cpuflag(sse2) + PSHUFD %1, %2, 0x4e +%else + movhlps %1, %2 + movlhps %1, %2 +%endif +%endmacro + +%macro BUTTERF 3 + INVERTHL %2, %1 + xorps %1, [ps_p1p1m1m1] + addps %1, %2 +%if cpuflag(sse3) + mulps %1, %1, [ps_cosh_sse3 + %3] + PSHUFD %2, %1, 0xb1 + addsubps %1, %1, %2 +%else + mulps %1, [ps_cosh + %3] + PSHUFD %2, %1, 0xb1 + xorps %1, [ps_p1m1p1m1] + addps %1, %2 +%endif +%endmacro + +%macro BUTTERF2 3 +%if cpuflag(sse3) + mulps %1, %1, [ps_cosh_sse3 + %3] + PSHUFD %2, %1, 0xe1 + addsubps %1, %1, %2 +%else + mulps %1, [ps_cosh + %3] + PSHUFD %2, %1, 0xe1 + xorps %1, [ps_p1m1p1m1] + addps %1, %2 +%endif +%endmacro + +%macro STORE 4 +%if cpuflag(sse4) + movss [%3 ], %1 + extractps dword [%3 + %4], %1, 1 + extractps dword [%3 + 2*%4], %1, 2 + extractps dword [%3 + 3*%4], %1, 3 +%else + movhlps %2, %1 + movss [%3 ], %1 + movss [%3 + 2*%4], %2 + shufps %1, %1, 0xb1 + movss [%3 + %4], %1 + movhlps %2, %1 + movss [%3 + 3*%4], %2 +%endif +%endmacro + +%macro LOAD 4 + movlps %1, [%3 ] + movhps %1, [%3 + %4] + movlps %2, [%3 + 2*%4] + movhps %2, [%3 + 3*%4] + shufps %1, %2, 0x88 +%endmacro + +%macro LOADA64 2 +%if cpuflag(avx) + movu %1, [%2] +%else + movlps %1, [%2] + movhps %1, [%2 + 8] +%endif +%endmacro + +%macro DEFINE_IMDCT 0 +cglobal imdct36_float, 4,4,9, out, buf, in, win + + ; for(i=17;i>=1;i--) in[i] += in[i-1]; + LOADA64 m0, inq + LOADA64 m1, inq + 16 + + ROTLEFT m5, m0, m1 + + PSHUFD m6, m0, 0x93 + andps m6, m6, [ps_mask] + addps m0, m0, m6 + + LOADA64 m2, inq + 32 + + ROTLEFT m7, m1, m2 + + addps m1, m1, m5 + LOADA64 m3, inq + 48 + + ROTLEFT m5, m2, m3 + + xorps m4, m4, m4 + movlps m4, [inq+64] + BUILDINVHIGHLOW m6, m3, m4 + shufps m6, m6, m4, 0xa9 + + addps m4, m4, m6 + addps m2, m2, m7 + addps m3, m3, m5 + + ; for(i=17;i>=3;i-=2) in[i] += in[i-2]; + movlhps m5, m5, m0 + andps m5, m5, [ps_mask3] + + BUILDINVHIGHLOW m7, m0, m1 + andps m7, m7, [ps_mask2] + + addps m0, m0, m5 + + BUILDINVHIGHLOW m6, m1, m2 + andps m6, m6, [ps_mask2] + + addps m1, m1, m7 + + BUILDINVHIGHLOW m7, m2, m3 + andps m7, m7, [ps_mask2] + + addps m2, m2, m6 + + movhlps m6, m6, m3 + andps m6, m6, [ps_mask4] + + addps m3, m3, m7 + addps m4, m4, m6 + + ; Populate tmp[] + movlhps m6, m1, m5 ; zero out high values + subps m6, m6, m4 + + subps m5, m0, m3 + +%if ARCH_X86_64 + SWAP m5, m8 +%endif + + mulps m7, m2, [ps_val1] + +%if ARCH_X86_64 + mulps m5, m8, [ps_val2] +%else + mulps m5, m5, [ps_val2] +%endif + addps m7, m7, m5 + + mulps m5, m6, [ps_val1] + subps m7, m7, m5 + +%if ARCH_X86_64 + SWAP m5, m8 +%else + subps m5, m0, m3 +%endif + + subps m5, m5, m6 + addps m5, m5, m2 + + shufps m6, m4, m3, 0xe4 + subps m6, m6, m2 + mulps m6, m6, [ps_val3] + + addps m4, m4, m1 + mulps m4, m4, [ps_val4] + + shufps m1, m1, m0, 0xe4 + addps m1, m1, m2 + mulps m1, m1, [ps_val5] + + mulps m3, m3, [ps_val6] + mulps m0, m0, [ps_val7] + addps m0, m0, m3 + + xorps m2, m1, [ps_p1p1m1m1] + subps m2, m2, m4 + addps m2, m2, m0 + + addps m3, m4, m0 + subps m3, m3, m6 + xorps m3, m3, [ps_p1p1m1m1] + + shufps m0, m0, m4, 0xe4 + subps m0, m0, m1 + addps m0, m0, m6 + + BUILDINVHIGHLOW m4, m2, m3 + shufps m3, m3, m2, 0x4e + + ; we have tmp = {SwAPLH(m0), SwAPLH(m7), m3, m4, m5} + + BUTTERF m0, m1, 0 + BUTTERF m7, m2, 16 + BUTTERF m3, m6, 32 + BUTTERF m4, m1, 48 + BUTTERF2 m5, m1, 64 + + ; permutates: + ; m0 0 1 2 3 => 2 6 10 14 m1 + ; m7 4 5 6 7 => 3 7 11 15 m2 + ; m3 8 9 10 11 => 17 13 9 5 m3 + ; m4 12 13 14 15 => 16 12 8 4 m5 + ; m5 16 17 xx xx => 0 1 xx xx m0 + + unpckhps m1, m0, m7 + unpckhps m6, m3, m4 + movhlps m2, m6, m1 + movlhps m1, m1, m6 + + unpcklps m5, m5, m4 + unpcklps m3, m3, m7 + movhlps m4, m3, m5 + movlhps m5, m5, m3 + SWAP m4, m3 + ; permutation done + + PSHUFD m6, m2, 0xb1 + movss m4, [bufq + 4*68] + movss m7, [bufq + 4*64] + unpcklps m7, m7, m4 + mulps m6, m6, [winq + 16*4] + addps m6, m6, m7 + movss [outq + 64*SBLIMIT], m6 + shufps m6, m6, m6, 0xb1 + movss [outq + 68*SBLIMIT], m6 + + mulps m6, m3, [winq + 4*4] + LOAD m4, m7, bufq + 4*16, 16 + addps m6, m6, m4 + STORE m6, m7, outq + 16*SBLIMIT, 4*SBLIMIT + + shufps m4, m0, m3, 0xb5 + mulps m4, m4, [winq + 8*4] + LOAD m7, m6, bufq + 4*32, 16 + addps m4, m4, m7 + STORE m4, m6, outq + 32*SBLIMIT, 4*SBLIMIT + + shufps m3, m3, m2, 0xb1 + mulps m3, m3, [winq + 12*4] + LOAD m7, m6, bufq + 4*48, 16 + addps m3, m3, m7 + STORE m3, m7, outq + 48*SBLIMIT, 4*SBLIMIT + + mulps m2, m2, [winq] + LOAD m6, m7, bufq, 16 + addps m2, m2, m6 + STORE m2, m7, outq, 4*SBLIMIT + + mulps m4, m1, [winq + 20*4] + STORE m4, m7, bufq, 16 + + mulps m3, m5, [winq + 24*4] + STORE m3, m7, bufq + 4*16, 16 + + shufps m0, m0, m5, 0xb0 + mulps m0, m0, [winq + 28*4] + STORE m0, m7, bufq + 4*32, 16 + + shufps m5, m5, m1, 0xb1 + mulps m5, m5, [winq + 32*4] + STORE m5, m7, bufq + 4*48, 16 + + shufps m1, m1, m1, 0xb1 + mulps m1, m1, [winq + 36*4] + movss [bufq + 4*64], m1 + shufps m1, m1, 0xb1 + movss [bufq + 4*68], m1 + RET +%endmacro + +%if ARCH_X86_32 +INIT_XMM sse +DEFINE_IMDCT +%endif + +INIT_XMM sse2 +DEFINE_IMDCT + +INIT_XMM sse3 +DEFINE_IMDCT + +INIT_XMM ssse3 +DEFINE_IMDCT + +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEFINE_IMDCT +%endif + +INIT_XMM sse + +%if ARCH_X86_64 +%define SPILL SWAP +%define UNSPILL SWAP +%define SPILLED(x) m %+ x +%else +%define SPILLED(x) [tmpq+(x-8)*16 + 32*4] +%macro SPILL 2 ; xmm#, mempos + movaps SPILLED(%2), m%1 +%endmacro +%macro UNSPILL 2 + movaps m%1, SPILLED(%2) +%endmacro +%endif + +%macro DEFINE_FOUR_IMDCT 0 +cglobal four_imdct36_float, 5,5,16, out, buf, in, win, tmp + movlps m0, [inq+64] + movhps m0, [inq+64 + 72] + movlps m3, [inq+64 + 2*72] + movhps m3, [inq+64 + 3*72] + + shufps m5, m0, m3, 0xdd + shufps m0, m0, m3, 0x88 + + mova m1, [inq+48] + movu m6, [inq+48 + 72] + mova m7, [inq+48 + 2*72] + movu m3, [inq+48 + 3*72] + + TRANSPOSE4x4PS 1, 6, 7, 3, 4 + + addps m4, m6, m7 + mova [tmpq+4*28], m4 + + addps m7, m3 + addps m6, m1 + addps m3, m0 + addps m0, m5 + addps m0, m7 + addps m7, m6 + mova [tmpq+4*12], m7 + SPILL 3, 12 + + mova m4, [inq+32] + movu m5, [inq+32 + 72] + mova m2, [inq+32 + 2*72] + movu m7, [inq+32 + 3*72] + + TRANSPOSE4x4PS 4, 5, 2, 7, 3 + + addps m1, m7 + SPILL 1, 11 + + addps m3, m5, m2 + SPILL 3, 13 + + addps m7, m2 + addps m5, m4 + addps m6, m7 + mova [tmpq], m6 + addps m7, m5 + mova [tmpq+4*16], m7 + + mova m2, [inq+16] + movu m7, [inq+16 + 72] + mova m1, [inq+16 + 2*72] + movu m6, [inq+16 + 3*72] + + TRANSPOSE4x4PS 2, 7, 1, 6, 3 + + addps m4, m6 + addps m6, m1 + addps m1, m7 + addps m7, m2 + addps m5, m6 + SPILL 5, 15 + addps m6, m7 + mulps m6, [costabs + 16*2] + mova [tmpq+4*8], m6 + SPILL 1, 10 + SPILL 0, 14 + + mova m1, [inq] + movu m6, [inq + 72] + mova m3, [inq + 2*72] + movu m5, [inq + 3*72] + + TRANSPOSE4x4PS 1, 6, 3, 5, 0 + + addps m2, m5 + addps m5, m3 + addps m7, m5 + addps m3, m6 + addps m6, m1 + SPILL 7, 8 + addps m5, m6 + SPILL 6, 9 + addps m6, m4, SPILLED(12) + subps m6, m2 + UNSPILL 7, 11 + SPILL 5, 11 + subps m5, m1, m7 + mulps m7, [costabs + 16*5] + addps m7, m1 + mulps m0, m6, [costabs + 16*6] + addps m0, m5 + mova [tmpq+4*24], m0 + addps m6, m5 + mova [tmpq+4*4], m6 + addps m6, m4, m2 + mulps m6, [costabs + 16*1] + subps m4, SPILLED(12) + mulps m4, [costabs + 16*8] + addps m2, SPILLED(12) + mulps m2, [costabs + 16*3] + subps m5, m7, m6 + subps m5, m2 + addps m6, m7 + addps m6, m4 + addps m7, m2 + subps m7, m4 + mova [tmpq+4*20], m7 + mova m2, [tmpq+4*28] + mova [tmpq+4*28], m5 + UNSPILL 7, 13 + subps m5, m7, m2 + mulps m5, [costabs + 16*7] + UNSPILL 1, 10 + mulps m1, [costabs + 16*2] + addps m4, m3, m2 + mulps m4, [costabs + 16*4] + addps m2, m7 + addps m7, m3 + mulps m7, [costabs] + subps m3, m2 + mulps m3, [costabs + 16*2] + addps m2, m7, m5 + addps m2, m1 + SPILL 2, 10 + addps m7, m4 + subps m7, m1 + SPILL 7, 12 + subps m5, m4 + subps m5, m1 + UNSPILL 0, 14 + SPILL 5, 13 + addps m1, m0, SPILLED(15) + subps m1, SPILLED(8) + mova m4, [costabs + 16*5] + mulps m4, [tmpq] + UNSPILL 2, 9 + addps m4, m2 + subps m2, [tmpq] + mulps m5, m1, [costabs + 16*6] + addps m5, m2 + SPILL 5, 9 + addps m2, m1 + SPILL 2, 14 + UNSPILL 5, 15 + subps m7, m5, m0 + addps m5, SPILLED(8) + mulps m5, [costabs + 16*1] + mulps m7, [costabs + 16*8] + addps m0, SPILLED(8) + mulps m0, [costabs + 16*3] + subps m2, m4, m5 + subps m2, m0 + SPILL 2, 15 + addps m5, m4 + addps m5, m7 + addps m4, m0 + subps m4, m7 + SPILL 4, 8 + mova m7, [tmpq+4*16] + mova m2, [tmpq+4*12] + addps m0, m7, m2 + subps m0, SPILLED(11) + mulps m0, [costabs + 16*2] + addps m4, m7, SPILLED(11) + mulps m4, [costabs] + subps m7, m2 + mulps m7, [costabs + 16*7] + addps m2, SPILLED(11) + mulps m2, [costabs + 16*4] + addps m1, m7, [tmpq+4*8] + addps m1, m4 + addps m4, m2 + subps m4, [tmpq+4*8] + SPILL 4, 11 + subps m7, m2 + subps m7, [tmpq+4*8] + addps m4, m6, SPILLED(10) + subps m6, SPILLED(10) + addps m2, m5, m1 + mulps m2, [costabs + 16*9] + subps m5, m1 + mulps m5, [costabs + 16*17] + subps m1, m4, m2 + addps m4, m2 + mulps m2, m1, [winq+4*36] + addps m2, [bufq+4*36] + mova [outq+1152], m2 + mulps m1, [winq+4*32] + addps m1, [bufq+4*32] + mova [outq+1024], m1 + mulps m1, m4, [winq+4*116] + mova [bufq+4*36], m1 + mulps m4, [winq+4*112] + mova [bufq+4*32], m4 + addps m2, m6, m5 + subps m6, m5 + mulps m1, m6, [winq+4*68] + addps m1, [bufq+4*68] + mova [outq+2176], m1 + mulps m6, [winq] + addps m6, [bufq] + mova [outq], m6 + mulps m1, m2, [winq+4*148] + mova [bufq+4*68], m1 + mulps m2, [winq+4*80] + mova [bufq], m2 + addps m5, m3, [tmpq+4*24] + mova m2, [tmpq+4*24] + subps m2, m3 + mova m1, SPILLED(9) + subps m1, m0 + mulps m1, [costabs + 16*10] + addps m0, SPILLED(9) + mulps m0, [costabs + 16*16] + addps m6, m5, m1 + subps m5, m1 + mulps m3, m5, [winq+4*40] + addps m3, [bufq+4*40] + mova [outq+1280], m3 + mulps m5, [winq+4*28] + addps m5, [bufq+4*28] + mova [outq+896], m5 + mulps m1, m6, [winq+4*120] + mova [bufq+4*40], m1 + mulps m6, [winq+4*108] + mova [bufq+4*28], m6 + addps m1, m2, m0 + subps m2, m0 + mulps m5, m2, [winq+4*64] + addps m5, [bufq+4*64] + mova [outq+2048], m5 + mulps m2, [winq+4*4] + addps m2, [bufq+4*4] + mova [outq+128], m2 + mulps m0, m1, [winq+4*144] + mova [bufq+4*64], m0 + mulps m1, [winq+4*84] + mova [bufq+4*4], m1 + mova m1, [tmpq+4*28] + mova m5, m1 + addps m1, SPILLED(13) + subps m5, SPILLED(13) + UNSPILL 3, 15 + addps m2, m7, m3 + mulps m2, [costabs + 16*11] + subps m3, m7 + mulps m3, [costabs + 16*15] + addps m0, m2, m1 + subps m1, m2 + SWAP m0, m2 + mulps m6, m1, [winq+4*44] + addps m6, [bufq+4*44] + mova [outq+1408], m6 + mulps m1, [winq+4*24] + addps m1, [bufq+4*24] + mova [outq+768], m1 + mulps m0, m2, [winq+4*124] + mova [bufq+4*44], m0 + mulps m2, [winq+4*104] + mova [bufq+4*24], m2 + addps m0, m5, m3 + subps m5, m3 + mulps m1, m5, [winq+4*60] + addps m1, [bufq+4*60] + mova [outq+1920], m1 + mulps m5, [winq+4*8] + addps m5, [bufq+4*8] + mova [outq+256], m5 + mulps m1, m0, [winq+4*140] + mova [bufq+4*60], m1 + mulps m0, [winq+4*88] + mova [bufq+4*8], m0 + mova m1, [tmpq+4*20] + addps m1, SPILLED(12) + mova m2, [tmpq+4*20] + subps m2, SPILLED(12) + UNSPILL 7, 8 + subps m0, m7, SPILLED(11) + addps m7, SPILLED(11) + mulps m4, m7, [costabs + 16*12] + mulps m0, [costabs + 16*14] + addps m5, m1, m4 + subps m1, m4 + mulps m7, m1, [winq+4*48] + addps m7, [bufq+4*48] + mova [outq+1536], m7 + mulps m1, [winq+4*20] + addps m1, [bufq+4*20] + mova [outq+640], m1 + mulps m1, m5, [winq+4*128] + mova [bufq+4*48], m1 + mulps m5, [winq+4*100] + mova [bufq+4*20], m5 + addps m6, m2, m0 + subps m2, m0 + mulps m1, m2, [winq+4*56] + addps m1, [bufq+4*56] + mova [outq+1792], m1 + mulps m2, [winq+4*12] + addps m2, [bufq+4*12] + mova [outq+384], m2 + mulps m0, m6, [winq+4*136] + mova [bufq+4*56], m0 + mulps m6, [winq+4*92] + mova [bufq+4*12], m6 + UNSPILL 0, 14 + mulps m0, [costabs + 16*13] + mova m3, [tmpq+4*4] + addps m2, m0, m3 + subps m3, m0 + mulps m0, m3, [winq+4*52] + addps m0, [bufq+4*52] + mova [outq+1664], m0 + mulps m3, [winq+4*16] + addps m3, [bufq+4*16] + mova [outq+512], m3 + mulps m0, m2, [winq+4*132] + mova [bufq+4*52], m0 + mulps m2, [winq+4*96] + mova [bufq+4*16], m2 + RET +%endmacro + +INIT_XMM sse +DEFINE_FOUR_IMDCT + +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +DEFINE_FOUR_IMDCT +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/inline_asm.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/inline_asm.h new file mode 100644 index 00000000..01987467 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/inline_asm.h @@ -0,0 +1,100 @@ +/* + * inline assembly helper macros + * + * 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 + */ + +#ifndef AVCODEC_X86_INLINE_ASM_H +#define AVCODEC_X86_INLINE_ASM_H + +#include "constants.h" + +#define MOVQ_WONE(regd) \ + __asm__ volatile ( \ + "pcmpeqd %%" #regd ", %%" #regd " \n\t" \ + "psrlw $15, %%" #regd ::) + +#define JUMPALIGN() __asm__ volatile (".p2align 3"::) +#define MOVQ_ZERO(regd) __asm__ volatile ("pxor %%"#regd", %%"#regd ::) + +#define MOVQ_BFE(regd) \ + __asm__ volatile ( \ + "pcmpeqd %%"#regd", %%"#regd" \n\t" \ + "paddb %%"#regd", %%"#regd" \n\t" ::) + +#ifndef PIC +#define MOVQ_WTWO(regd) __asm__ volatile ("movq %0, %%"#regd" \n\t" :: "m"(ff_pw_2)) +#else +// for shared library it's better to use this way for accessing constants +// pcmpeqd -> -1 +#define MOVQ_WTWO(regd) \ + __asm__ volatile ( \ + "pcmpeqd %%"#regd", %%"#regd" \n\t" \ + "psrlw $15, %%"#regd" \n\t" \ + "psllw $1, %%"#regd" \n\t"::) + +#endif + +// using regr as temporary and for the output result +// first argument is unmodified and second is trashed +// regfe is supposed to contain 0xfefefefefefefefe +#define PAVGB_MMX_NO_RND(rega, regb, regr, regfe) \ + "movq "#rega", "#regr" \n\t" \ + "pand "#regb", "#regr" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pand "#regfe", "#regb" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "paddb "#regb", "#regr" \n\t" + +#define PAVGB_MMX(rega, regb, regr, regfe) \ + "movq "#rega", "#regr" \n\t" \ + "por "#regb", "#regr" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pand "#regfe", "#regb" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "psubb "#regb", "#regr" \n\t" + +// mm6 is supposed to contain 0xfefefefefefefefe +#define PAVGBP_MMX_NO_RND(rega, regb, regr, regc, regd, regp) \ + "movq "#rega", "#regr" \n\t" \ + "movq "#regc", "#regp" \n\t" \ + "pand "#regb", "#regr" \n\t" \ + "pand "#regd", "#regp" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pxor "#regc", "#regd" \n\t" \ + "pand %%mm6, "#regb" \n\t" \ + "pand %%mm6, "#regd" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "psrlq $1, "#regd" \n\t" \ + "paddb "#regb", "#regr" \n\t" \ + "paddb "#regd", "#regp" \n\t" + +#define PAVGBP_MMX(rega, regb, regr, regc, regd, regp) \ + "movq "#rega", "#regr" \n\t" \ + "movq "#regc", "#regp" \n\t" \ + "por "#regb", "#regr" \n\t" \ + "por "#regd", "#regp" \n\t" \ + "pxor "#rega", "#regb" \n\t" \ + "pxor "#regc", "#regd" \n\t" \ + "pand %%mm6, "#regb" \n\t" \ + "pand %%mm6, "#regd" \n\t" \ + "psrlq $1, "#regd" \n\t" \ + "psrlq $1, "#regb" \n\t" \ + "psubb "#regb", "#regr" \n\t" \ + "psubb "#regd", "#regp" \n\t" + +#endif /* AVCODEC_X86_INLINE_ASM_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/jpeg2000dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/jpeg2000dsp.asm new file mode 100644 index 00000000..61dfdd4f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/jpeg2000dsp.asm @@ -0,0 +1,164 @@ +;****************************************************************************** +;* SIMD-optimized JPEG2000 DSP functions +;* Copyright (c) 2014 Nicolas Bertrand +;* Copyright (c) 2015 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pf_ict0: times 8 dd 1.402 +pf_ict1: times 8 dd 0.34413 +pf_ict2: times 8 dd 0.71414 +pf_ict3: times 8 dd 1.772 + +SECTION .text + +;*********************************************************************** +; ff_ict_float_(float *src0, float *src1, float *src2, int csize) +;*********************************************************************** +%macro ICT_FLOAT 1 +cglobal ict_float, 4, 4, %1, src0, src1, src2, csize + shl csized, 2 + add src0q, csizeq + add src1q, csizeq + add src2q, csizeq + neg csizeq + movaps m6, [pf_ict0] + movaps m7, [pf_ict1] + %define ICT0 m6 + %define ICT1 m7 + +%if ARCH_X86_64 + movaps m8, [pf_ict2] + %define ICT2 m8 +%if cpuflag(avx) + movaps m3, [pf_ict3] + %define ICT3 m3 +%else + movaps m9, [pf_ict3] + %define ICT3 m9 +%endif + +%else ; ARCH_X86_32 + %define ICT2 [pf_ict2] +%if cpuflag(avx) + movaps m3, [pf_ict3] + %define ICT3 m3 +%else + %define ICT3 [pf_ict3] +%endif + +%endif ; ARCH + +align 16 +.loop: + movaps m0, [src0q+csizeq] + movaps m1, [src1q+csizeq] + movaps m2, [src2q+csizeq] + +%if cpuflag(fma4) || cpuflag(fma3) +%if cpuflag(fma4) + fnmaddps m5, m1, ICT1, m0 + fmaddps m4, m2, ICT0, m0 +%else ; fma3 + movaps m5, m1 + movaps m4, m2 + fnmaddps m5, m5, ICT1, m0 + fmaddps m4, m4, ICT0, m0 +%endif + fmaddps m0, m1, ICT3, m0 + fnmaddps m5, m2, ICT2, m5 +%else ; non FMA +%if cpuflag(avx) + mulps m5, m1, ICT1 + mulps m4, m2, ICT0 + mulps m1, m1, ICT3 + mulps m2, m2, ICT2 + subps m5, m0, m5 +%else ; sse + movaps m3, m1 + movaps m4, m2 + movaps m5, m0 + mulps m3, ICT1 + mulps m4, ICT0 + mulps m1, ICT3 + mulps m2, ICT2 + subps m5, m3 +%endif + addps m4, m4, m0 + addps m0, m0, m1 + subps m5, m5, m2 +%endif + + movaps [src0q+csizeq], m4 + movaps [src2q+csizeq], m0 + movaps [src1q+csizeq], m5 + add csizeq, mmsize + jl .loop + REP_RET +%endmacro + +INIT_XMM sse +ICT_FLOAT 10 +INIT_YMM avx +ICT_FLOAT 9 +%if HAVE_FMA4_EXTERNAL +INIT_XMM fma4 +ICT_FLOAT 9 +%endif +INIT_YMM fma3 +ICT_FLOAT 9 + +;*************************************************************************** +; ff_rct_int_(int32_t *src0, int32_t *src1, int32_t *src2, int csize) +;*************************************************************************** +%macro RCT_INT 0 +cglobal rct_int, 4, 4, 4, src0, src1, src2, csize + shl csized, 2 + add src0q, csizeq + add src1q, csizeq + add src2q, csizeq + neg csizeq + +align 16 +.loop: + mova m1, [src1q+csizeq] + mova m2, [src2q+csizeq] + mova m0, [src0q+csizeq] + paddd m3, m1, m2 + psrad m3, 2 + psubd m0, m3 + paddd m1, m0 + paddd m2, m0 + mova [src1q+csizeq], m0 + mova [src2q+csizeq], m1 + mova [src0q+csizeq], m2 + add csizeq, mmsize + jl .loop + REP_RET +%endmacro + +INIT_XMM sse2 +RCT_INT +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +RCT_INT +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/jpeg2000dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/jpeg2000dsp_init.c new file mode 100644 index 00000000..7310a1d0 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/jpeg2000dsp_init.c @@ -0,0 +1,60 @@ +/* + * SIMD optimized JPEG 2000 DSP functions + * Copyright (c) 2015 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/jpeg2000dsp.h" + +void ff_ict_float_sse(void *src0, void *src1, void *src2, int csize); +void ff_ict_float_avx(void *src0, void *src1, void *src2, int csize); +void ff_ict_float_fma3(void *src0, void *src1, void *src2, int csize); +void ff_ict_float_fma4(void *src0, void *src1, void *src2, int csize); +void ff_rct_int_sse2 (void *src0, void *src1, void *src2, int csize); +void ff_rct_int_avx2 (void *src0, void *src1, void *src2, int csize); + +av_cold void ff_jpeg2000dsp_init_x86(Jpeg2000DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->mct_decode[FF_DWT53] = ff_rct_int_sse2; + } + + if (EXTERNAL_AVX_FAST(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_avx; + } + + if (EXTERNAL_FMA4(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_fma4; + } + + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + c->mct_decode[FF_DWT97] = ff_ict_float_fma3; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->mct_decode[FF_DWT53] = ff_rct_int_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_audiodsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_audiodsp.asm new file mode 100644 index 00000000..063d7b41 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_audiodsp.asm @@ -0,0 +1,190 @@ +;****************************************************************************** +;* Copyright (c) 2008 Loren Merritt +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro SCALARPRODUCT 0 +; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, +; int order, int mul) +cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul + shl orderq, 1 + movd m7, mulm +%if mmsize == 16 + pshuflw m7, m7, 0 + punpcklqdq m7, m7 +%else + pshufw m7, m7, 0 +%endif + pxor m6, m6 + add v1q, orderq + add v2q, orderq + add v3q, orderq + neg orderq +.loop: + movu m0, [v2q + orderq] + movu m1, [v2q + orderq + mmsize] + mova m4, [v1q + orderq] + mova m5, [v1q + orderq + mmsize] + movu m2, [v3q + orderq] + movu m3, [v3q + orderq + mmsize] + pmaddwd m0, m4 + pmaddwd m1, m5 + pmullw m2, m7 + pmullw m3, m7 + paddd m6, m0 + paddd m6, m1 + paddw m2, m4 + paddw m3, m5 + mova [v1q + orderq], m2 + mova [v1q + orderq + mmsize], m3 + add orderq, mmsize*2 + jl .loop + HADDD m6, m0 + movd eax, m6 + RET +%endmacro + +INIT_MMX mmxext +SCALARPRODUCT +INIT_XMM sse2 +SCALARPRODUCT + +INIT_XMM sse4 +; int ff_scalarproduct_and_madd_int32(int16_t *v1, int32_t *v2, int16_t *v3, +; int order, int mul) +cglobal scalarproduct_and_madd_int32, 4,4,8, v1, v2, v3, order, mul + shl orderq, 1 + movd m7, mulm + SPLATW m7, m7 + pxor m6, m6 + add v1q, orderq + lea v2q, [v2q + 2*orderq] + add v3q, orderq + neg orderq +.loop: + mova m3, [v1q + orderq] + movu m0, [v2q + 2*orderq] + pmovsxwd m4, m3 + movu m1, [v2q + 2*orderq + mmsize] + movhlps m5, m3 + movu m2, [v3q + orderq] + pmovsxwd m5, m5 + pmullw m2, m7 + pmulld m0, m4 + pmulld m1, m5 + paddw m2, m3 + paddd m6, m0 + paddd m6, m1 + mova [v1q + orderq], m2 + add orderq, 16 + jl .loop + HADDD m6, m0 + movd eax, m6 + RET + +%macro SCALARPRODUCT_LOOP 1 +align 16 +.loop%1: + sub orderq, mmsize*2 +%if %1 + mova m1, m4 + mova m4, [v2q + orderq] + mova m0, [v2q + orderq + mmsize] + palignr m1, m0, %1 + palignr m0, m4, %1 + mova m3, m5 + mova m5, [v3q + orderq] + mova m2, [v3q + orderq + mmsize] + palignr m3, m2, %1 + palignr m2, m5, %1 +%else + mova m0, [v2q + orderq] + mova m1, [v2q + orderq + mmsize] + mova m2, [v3q + orderq] + mova m3, [v3q + orderq + mmsize] +%endif + %define t0 [v1q + orderq] + %define t1 [v1q + orderq + mmsize] +%if ARCH_X86_64 + mova m8, t0 + mova m9, t1 + %define t0 m8 + %define t1 m9 +%endif + pmaddwd m0, t0 + pmaddwd m1, t1 + pmullw m2, m7 + pmullw m3, m7 + paddw m2, t0 + paddw m3, t1 + paddd m6, m0 + paddd m6, m1 + mova [v1q + orderq], m2 + mova [v1q + orderq + mmsize], m3 + jg .loop%1 +%if %1 + jmp .end +%endif +%endmacro + +; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, +; int order, int mul) +INIT_XMM ssse3 +cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul + shl orderq, 1 + movd m7, mulm + pshuflw m7, m7, 0 + punpcklqdq m7, m7 + pxor m6, m6 + mov r4d, v2d + and r4d, 15 + and v2q, ~15 + and v3q, ~15 + mova m4, [v2q + orderq] + mova m5, [v3q + orderq] + ; linear is faster than branch tree or jump table, because the branches taken are cyclic (i.e. predictable) + cmp r4d, 0 + je .loop0 + cmp r4d, 2 + je .loop2 + cmp r4d, 4 + je .loop4 + cmp r4d, 6 + je .loop6 + cmp r4d, 8 + je .loop8 + cmp r4d, 10 + je .loop10 + cmp r4d, 12 + je .loop12 +SCALARPRODUCT_LOOP 14 +SCALARPRODUCT_LOOP 12 +SCALARPRODUCT_LOOP 10 +SCALARPRODUCT_LOOP 8 +SCALARPRODUCT_LOOP 6 +SCALARPRODUCT_LOOP 4 +SCALARPRODUCT_LOOP 2 +SCALARPRODUCT_LOOP 0 +.end: + HADDD m6, m0 + movd eax, m6 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_audiodsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_audiodsp_init.c new file mode 100644 index 00000000..f74c7e43 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_audiodsp_init.c @@ -0,0 +1,56 @@ +/* + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lossless_audiodsp.h" + +int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul); +int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul); +int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul); + +int32_t ff_scalarproduct_and_madd_int32_sse4(int16_t *v1, const int32_t *v2, + const int16_t *v3, + int order, int mul); + +av_cold void ff_llauddsp_init_x86(LLAudDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMXEXT(cpu_flags)) + c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext; + + if (EXTERNAL_SSE2(cpu_flags)) + c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2; + + if (EXTERNAL_SSSE3(cpu_flags) && + !(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit + c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3; + + if (EXTERNAL_SSE4(cpu_flags)) + c->scalarproduct_and_madd_int32 = ff_scalarproduct_and_madd_int32_sse4; +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videodsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videodsp.asm new file mode 100644 index 00000000..0a1b7091 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videodsp.asm @@ -0,0 +1,406 @@ +;****************************************************************************** +;* SIMD lossless video DSP utils +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2014 Michael Niedermayer +;* Copyright (c) 2017 Jokyo Images +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pb_15 +pb_zzzzzzzz77777777: times 8 db -1 +pb_7: times 8 db 7 +pb_ef: times 8 db 14,15 +pb_67: times 8 db 6, 7 +pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11 +pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13 +pb_zzzz2323zzzzabab: db -1,-1,-1,-1, 2, 3, 2, 3,-1,-1,-1,-1,10,11,10,11 +pb_zzzzzzzz67676767: db -1,-1,-1,-1,-1,-1,-1,-1, 6, 7, 6, 7, 6, 7, 6, 7 + +SECTION .text + +;------------------------------------------------------------------------------ +; void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top, +; const uint8_t *diff, int w, +; int *left, int *left_top) +;------------------------------------------------------------------------------ +%macro MEDIAN_PRED 0 +cglobal add_median_pred, 6,6,8, dst, top, diff, w, left, left_top + movu m0, [topq] + mova m2, m0 + movd m4, [left_topq] + LSHIFT m2, 1 + mova m1, m0 + por m4, m2 + movd m3, [leftq] + psubb m0, m4 ; t-tl + add dstq, wq + add topq, wq + add diffq, wq + neg wq + jmp .skip +.loop: + movu m4, [topq+wq] + mova m0, m4 + LSHIFT m4, 1 + por m4, m1 + mova m1, m0 ; t + psubb m0, m4 ; t-tl +.skip: + movu m2, [diffq+wq] +%assign i 0 +%rep mmsize + mova m4, m0 + paddb m4, m3 ; t-tl+l + mova m5, m3 + pmaxub m3, m1 + pminub m5, m1 + pminub m3, m4 + pmaxub m3, m5 ; median + paddb m3, m2 ; +residual +%if i==0 + mova m7, m3 + LSHIFT m7, mmsize-1 +%else + mova m6, m3 + RSHIFT m7, 1 + LSHIFT m6, mmsize-1 + por m7, m6 +%endif +%if i= 16 + pshufb m2, m1, m6 + paddb m1, m2 +%endif + paddb xm0, xm1 +%if %1 + mova [dstq+wq], xm0 +%else + movq [dstq+wq], xm0 + movhps [dstq+wq+8], xm0 +%endif + +%if mmsize == 32 + vextracti128 xm2, m1, 1 ; get second lane of the ymm + pshufb xm0, xm5 ; set alls val to last val of the first lane + paddb xm0, xm2 +;store val +%if %1 + mova [dstq+wq+16], xm0 +%else; + movq [dstq+wq+16], xm0 + movhps [dstq+wq+16+8], xm0 +%endif +%endif + add wq, mmsize + jl %%.loop +%if mmsize == 32 + movzx eax, byte [dstq - 1] +%else; + mov eax, mmsize-1 + sub eax, wd + movd m1, eax + pshufb m0, m1 + movd eax, m0 +%endif + RET +%endmacro + +;------------------------------------------------------------------------------ +; int ff_add_left_pred(uint8_t *dst, const uint8_t *src, int w, int left) +;------------------------------------------------------------------------------ +INIT_MMX ssse3 +cglobal add_left_pred, 3,3,7, dst, src, w, left +.skip_prologue: + mova m5, [pb_7] + mova m4, [pb_zzzz3333zzzzbbbb] + mova m3, [pb_zz11zz55zz99zzdd] + movd m0, leftm + psllq m0, 56 + ADD_LEFT_LOOP 1, 1 + +%macro ADD_LEFT_PRED_UNALIGNED 0 +cglobal add_left_pred_unaligned, 3,3,7, dst, src, w, left + mova xm5, [pb_15] + VBROADCASTI128 m6, [pb_zzzzzzzz77777777] + VBROADCASTI128 m4, [pb_zzzz3333zzzzbbbb] + VBROADCASTI128 m3, [pb_zz11zz55zz99zzdd] + movd xm0, leftm + pslldq xm0, 15 + test srcq, mmsize - 1 + jnz .src_unaligned + test dstq, mmsize - 1 + jnz .dst_unaligned + ADD_LEFT_LOOP 1, 1 +.dst_unaligned: + ADD_LEFT_LOOP 0, 1 +.src_unaligned: + ADD_LEFT_LOOP 0, 0 +%endmacro + +INIT_XMM ssse3 +ADD_LEFT_PRED_UNALIGNED + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +ADD_LEFT_PRED_UNALIGNED +%endif + +;------------------------------------------------------------------------------ +; void ff_add_bytes(uint8_t *dst, uint8_t *src, ptrdiff_t w); +;------------------------------------------------------------------------------ +%macro ADD_BYTES 0 +cglobal add_bytes, 3,4,2, dst, src, w, size + mov sizeq, wq + and sizeq, -2*mmsize + jz .2 + add dstq, sizeq + add srcq, sizeq + neg sizeq +.1: + mova m0, [srcq + sizeq] + mova m1, [srcq + sizeq + mmsize] + paddb m0, [dstq + sizeq] + paddb m1, [dstq + sizeq + mmsize] + mova [dstq + sizeq], m0 + mova [dstq + sizeq + mmsize], m1 + add sizeq, 2*mmsize + jl .1 +.2: + and wq, 2*mmsize-1 + jz .end + add dstq, wq + add srcq, wq + neg wq +.3: + mov sizeb, [srcq + wq] + add [dstq + wq], sizeb + inc wq + jl .3 +.end: + REP_RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +ADD_BYTES +%endif +INIT_XMM sse2 +ADD_BYTES + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +ADD_BYTES +%endif + +%macro ADD_HFYU_LEFT_LOOP_INT16 2 ; %1 = dst alignment (a/u), %2 = src alignment (a/u) + add wd, wd + add srcq, wq + add dstq, wq + neg wq +%%.loop: + mov%2 m1, [srcq+wq] + mova m2, m1 + pslld m1, 16 + paddw m1, m2 + mova m2, m1 + + pshufb m1, m3 + paddw m1, m2 + pshufb m0, m5 +%if mmsize == 16 + mova m2, m1 + pshufb m1, m4 + paddw m1, m2 +%endif + paddw m0, m1 + pand m0, m7 +%ifidn %1, a + mova [dstq+wq], m0 +%else + movq [dstq+wq], m0 + movhps [dstq+wq+8], m0 +%endif + add wq, mmsize + jl %%.loop + mov eax, mmsize-1 + sub eax, wd + mov wd, eax + shl wd, 8 + lea eax, [wd+eax-1] + movd m1, eax + pshufb m0, m1 + movd eax, m0 + RET +%endmacro + +;--------------------------------------------------------------------------------------------- +; int add_left_pred_int16(uint16_t *dst, const uint16_t *src, unsigned mask, int w, int left) +;--------------------------------------------------------------------------------------------- +INIT_MMX ssse3 +cglobal add_left_pred_int16, 4,4,8, dst, src, mask, w, left +.skip_prologue: + mova m5, [pb_67] + mova m3, [pb_zzzz2323zzzzabab] + movd m0, leftm + psllq m0, 48 + movd m7, maskm + SPLATW m7 ,m7 + ADD_HFYU_LEFT_LOOP_INT16 a, a + +INIT_XMM ssse3 +cglobal add_left_pred_int16_unaligned, 4,4,8, dst, src, mask, w, left + mova m5, [pb_ef] + mova m4, [pb_zzzzzzzz67676767] + mova m3, [pb_zzzz2323zzzzabab] + movd m0, leftm + pslldq m0, 14 + movd m7, maskm + SPLATW m7 ,m7 + test srcq, 15 + jnz .src_unaligned + test dstq, 15 + jnz .dst_unaligned + ADD_HFYU_LEFT_LOOP_INT16 a, a +.dst_unaligned: + ADD_HFYU_LEFT_LOOP_INT16 u, a +.src_unaligned: + ADD_HFYU_LEFT_LOOP_INT16 u, u + + +;--------------------------------------------------------------------------------------------- +; void add_gradient_pred(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width) +;--------------------------------------------------------------------------------------------- +%macro ADD_GRADIENT_PRED 0 +cglobal add_gradient_pred, 3,4,5, src, stride, width, tmp + mova xm0, [pb_15] + +;load src - 1 in xm1 + movd xm1, [srcq-1] +%if cpuflag(avx2) + vpbroadcastb xm1, xm1 +%else + pxor xm2, xm2 + pshufb xm1, xm2 +%endif + + add srcq, widthq + neg widthq + neg strideq + +.loop: + lea tmpq, [srcq + strideq] + mova m2, [tmpq + widthq] ; A = src[x-stride] + movu m3, [tmpq + widthq - 1] ; B = src[x - (stride + 1)] + mova m4, [srcq + widthq] ; current val (src[x]) + + psubb m2, m3; A - B + +; prefix sum A-B + pslldq m3, m2, 1 + paddb m2, m3 + pslldq m3, m2, 2 + paddb m2, m3 + pslldq m3, m2, 4 + paddb m2, m3 + pslldq m3, m2, 8 + paddb m2, m3 + +; prefix sum current val + pslldq m3, m4, 1 + paddb m4, m3 + pslldq m3, m4, 2 + paddb m4, m3 + pslldq m3, m4, 4 + paddb m4, m3 + pslldq m3, m4, 8 + paddb m4, m3 + +; last sum + paddb m2, m4 ; current + (A - B) + + paddb xm1, xm2 ; += C + mova [srcq + widthq], xm1 ; store + + pshufb xm1, xm0 ; put last val in all val of xm1 + +%if mmsize == 32 + vextracti128 xm2, m2, 1 ; get second lane of the ymm + paddb xm1, xm2; += C + + mova [srcq + widthq + 16], xm1 ; store + pshufb xm1, xm0 ; put last val in all val of m1 +%endif + + add widthq, mmsize + jl .loop + RET + +%endmacro + +INIT_XMM ssse3 +ADD_GRADIENT_PRED + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +ADD_GRADIENT_PRED +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videodsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videodsp_init.c new file mode 100644 index 00000000..6d71f14e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videodsp_init.c @@ -0,0 +1,128 @@ +/* + * Lossless video DSP utils + * + * 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.h" +#include "libavutil/x86/asm.h" +#include "../lossless_videodsp.h" +#include "libavutil/x86/cpu.h" + +void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t w); +void ff_add_bytes_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t w); +void ff_add_bytes_avx2(uint8_t *dst, uint8_t *src, ptrdiff_t w); + +void ff_add_median_pred_mmxext(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, ptrdiff_t w, + int *left, int *left_top); +void ff_add_median_pred_sse2(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, ptrdiff_t w, + int *left, int *left_top); + +int ff_add_left_pred_ssse3(uint8_t *dst, const uint8_t *src, + ptrdiff_t w, int left); +int ff_add_left_pred_unaligned_ssse3(uint8_t *dst, const uint8_t *src, + ptrdiff_t w, int left); +int ff_add_left_pred_unaligned_avx2(uint8_t *dst, const uint8_t *src, + ptrdiff_t w, int left); + +int ff_add_left_pred_int16_ssse3(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); +int ff_add_left_pred_int16_unaligned_ssse3(uint16_t *dst, const uint16_t *src, unsigned mask, ptrdiff_t w, unsigned acc); + +void ff_add_gradient_pred_ssse3(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width); +void ff_add_gradient_pred_avx2(uint8_t *src, const ptrdiff_t stride, const ptrdiff_t width); + +#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32 +static void add_median_pred_cmov(uint8_t *dst, const uint8_t *top, + const uint8_t *diff, ptrdiff_t w, + int *left, int *left_top) +{ + x86_reg w2 = -w; + x86_reg x; + int l = *left & 0xff; + int tl = *left_top & 0xff; + int t; + __asm__ volatile ( + "mov %7, %3 \n" + "1: \n" + "movzbl (%3, %4), %2 \n" + "mov %2, %k3 \n" + "sub %b1, %b3 \n" + "add %b0, %b3 \n" + "mov %2, %1 \n" + "cmp %0, %2 \n" + "cmovg %0, %2 \n" + "cmovg %1, %0 \n" + "cmp %k3, %0 \n" + "cmovg %k3, %0 \n" + "mov %7, %3 \n" + "cmp %2, %0 \n" + "cmovl %2, %0 \n" + "add (%6, %4), %b0 \n" + "mov %b0, (%5, %4) \n" + "inc %4 \n" + "jl 1b \n" + : "+&q"(l), "+&q"(tl), "=&r"(t), "=&q"(x), "+&r"(w2) + : "r"(dst + w), "r"(diff + w), "rm"(top + w) + ); + *left = l; + *left_top = tl; +} +#endif + +void ff_llviddsp_init_x86(LLVidDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#if HAVE_INLINE_ASM && HAVE_7REGS && ARCH_X86_32 + if (cpu_flags & AV_CPU_FLAG_CMOV) + c->add_median_pred = add_median_pred_cmov; +#endif + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->add_bytes = ff_add_bytes_mmx; + } + + if (ARCH_X86_32 && EXTERNAL_MMXEXT(cpu_flags)) { + /* slower than cmov version on AMD */ + if (!(cpu_flags & AV_CPU_FLAG_3DNOW)) + c->add_median_pred = ff_add_median_pred_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->add_bytes = ff_add_bytes_sse2; + c->add_median_pred = ff_add_median_pred_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->add_left_pred = ff_add_left_pred_ssse3; + c->add_left_pred_int16 = ff_add_left_pred_int16_ssse3; + c->add_gradient_pred = ff_add_gradient_pred_ssse3; + } + + if (EXTERNAL_SSSE3_FAST(cpu_flags)) { + c->add_left_pred = ff_add_left_pred_unaligned_ssse3; + c->add_left_pred_int16 = ff_add_left_pred_int16_unaligned_ssse3; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->add_bytes = ff_add_bytes_avx2; + c->add_left_pred = ff_add_left_pred_unaligned_avx2; + c->add_gradient_pred = ff_add_gradient_pred_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videoencdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videoencdsp.asm new file mode 100644 index 00000000..fb1204f0 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videoencdsp.asm @@ -0,0 +1,194 @@ +;************************************************************************ +;* SIMD-optimized lossless video encoding functions +;* Copyright (c) 2000, 2001 Fabrice Bellard +;* Copyright (c) 2002-2004 Michael Niedermayer +;* +;* MMX optimization by Nick Kurshev +;* Conversion to NASM format by Tiancheng "Timothy" Gu +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +cextern pb_80 + +SECTION .text + +; void ff_diff_bytes(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, +; intptr_t w); +%macro DIFF_BYTES_PROLOGUE 0 +%if ARCH_X86_32 +cglobal diff_bytes, 3,5,2, dst, src1, src2 +%define wq r4q + DECLARE_REG_TMP 3 + mov wq, r3mp +%else +cglobal diff_bytes, 4,5,2, dst, src1, src2, w + DECLARE_REG_TMP 4 +%endif ; ARCH_X86_32 +%define i t0q +%endmacro + +; labels to jump to if w < regsize and w < 0 +%macro DIFF_BYTES_LOOP_PREP 2 + mov i, wq + and i, -2 * regsize + js %2 + jz %1 + add dstq, i + add src1q, i + add src2q, i + neg i +%endmacro + +; mov type used for src1q, dstq, first reg, second reg +%macro DIFF_BYTES_LOOP_CORE 4 +%if mmsize != 16 + mov%1 %3, [src1q + i] + mov%1 %4, [src1q + i + regsize] + psubb %3, [src2q + i] + psubb %4, [src2q + i + regsize] + mov%2 [dstq + i], %3 + mov%2 [regsize + dstq + i], %4 +%else + ; SSE enforces alignment of psubb operand + mov%1 %3, [src1q + i] + movu %4, [src2q + i] + psubb %3, %4 + mov%2 [dstq + i], %3 + mov%1 %3, [src1q + i + regsize] + movu %4, [src2q + i + regsize] + psubb %3, %4 + mov%2 [regsize + dstq + i], %3 +%endif +%endmacro + +%macro DIFF_BYTES_BODY 2 ; mov type used for src1q, for dstq + %define regsize mmsize +.loop_%1%2: + DIFF_BYTES_LOOP_CORE %1, %2, m0, m1 + add i, 2 * regsize + jl .loop_%1%2 +.skip_main_%1%2: + and wq, 2 * regsize - 1 + jz .end_%1%2 +%if mmsize > 16 + ; fall back to narrower xmm + %define regsize (mmsize / 2) + DIFF_BYTES_LOOP_PREP .setup_loop_gpr_aa, .end_aa +.loop2_%1%2: + DIFF_BYTES_LOOP_CORE %1, %2, xm0, xm1 + add i, 2 * regsize + jl .loop2_%1%2 +.setup_loop_gpr_%1%2: + and wq, 2 * regsize - 1 + jz .end_%1%2 +%endif + add dstq, wq + add src1q, wq + add src2q, wq + neg wq +.loop_gpr_%1%2: + mov t0b, [src1q + wq] + sub t0b, [src2q + wq] + mov [dstq + wq], t0b + inc wq + jl .loop_gpr_%1%2 +.end_%1%2: + REP_RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +DIFF_BYTES_PROLOGUE + %define regsize mmsize + DIFF_BYTES_LOOP_PREP .skip_main_aa, .end_aa + DIFF_BYTES_BODY a, a +%undef i +%endif + +INIT_XMM sse2 +DIFF_BYTES_PROLOGUE + %define regsize mmsize + DIFF_BYTES_LOOP_PREP .skip_main_aa, .end_aa + test dstq, regsize - 1 + jnz .loop_uu + test src1q, regsize - 1 + jnz .loop_ua + DIFF_BYTES_BODY a, a + DIFF_BYTES_BODY u, a + DIFF_BYTES_BODY u, u +%undef i + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +DIFF_BYTES_PROLOGUE + %define regsize mmsize + ; Directly using unaligned SSE2 version is marginally faster than + ; branching based on arguments. + DIFF_BYTES_LOOP_PREP .skip_main_uu, .end_uu + test dstq, regsize - 1 + jnz .loop_uu + test src1q, regsize - 1 + jnz .loop_ua + DIFF_BYTES_BODY a, a + DIFF_BYTES_BODY u, a + DIFF_BYTES_BODY u, u +%undef i +%endif + + +;-------------------------------------------------------------------------------------------------- +;void sub_left_predict(uint8_t *dst, uint8_t *src, ptrdiff_t stride, ptrdiff_t width, int height) +;-------------------------------------------------------------------------------------------------- + +INIT_XMM avx +cglobal sub_left_predict, 5,6,5, dst, src, stride, width, height, x + mova m1, [pb_80] ; prev initial + add dstq, widthq + add srcq, widthq + lea xd, [widthq-1] + neg widthq + and xd, 15 + pinsrb m4, m1, xd, 15 + mov xq, widthq + + .loop: + movu m0, [srcq + widthq] + palignr m2, m0, m1, 15 + movu m1, [srcq + widthq + 16] + palignr m3, m1, m0, 15 + psubb m2, m0, m2 + psubb m3, m1, m3 + movu [dstq + widthq], m2 + movu [dstq + widthq + 16], m3 + add widthq, 2 * 16 + jl .loop + + add srcq, strideq + sub dstq, xq ; dst + width + test xd, 16 + jz .mod32 + mova m1, m0 + +.mod32: + pshufb m1, m4 + mov widthq, xq + dec heightd + jg .loop + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videoencdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videoencdsp_init.c new file mode 100644 index 00000000..40407add --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lossless_videoencdsp_init.c @@ -0,0 +1,111 @@ +/* + * SIMD-optimized lossless video encoding functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lossless_videoencdsp.h" +#include "libavcodec/mathops.h" + +void ff_diff_bytes_mmx(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + intptr_t w); +void ff_diff_bytes_sse2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + intptr_t w); +void ff_diff_bytes_avx2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, + intptr_t w); + +void ff_sub_left_predict_avx(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, ptrdiff_t width, int height); + +#if HAVE_INLINE_ASM + +static void sub_median_pred_mmxext(uint8_t *dst, const uint8_t *src1, + const uint8_t *src2, intptr_t w, + int *left, int *left_top) +{ + x86_reg i = 0; + uint8_t l, lt; + + __asm__ volatile ( + "movq (%1, %0), %%mm0 \n\t" // LT + "psllq $8, %%mm0 \n\t" + "1: \n\t" + "movq (%1, %0), %%mm1 \n\t" // T + "movq -1(%2, %0), %%mm2 \n\t" // L + "movq (%2, %0), %%mm3 \n\t" // X + "movq %%mm2, %%mm4 \n\t" // L + "psubb %%mm0, %%mm2 \n\t" + "paddb %%mm1, %%mm2 \n\t" // L + T - LT + "movq %%mm4, %%mm5 \n\t" // L + "pmaxub %%mm1, %%mm4 \n\t" // max(T, L) + "pminub %%mm5, %%mm1 \n\t" // min(T, L) + "pminub %%mm2, %%mm4 \n\t" + "pmaxub %%mm1, %%mm4 \n\t" + "psubb %%mm4, %%mm3 \n\t" // dst - pred + "movq %%mm3, (%3, %0) \n\t" + "add $8, %0 \n\t" + "movq -1(%1, %0), %%mm0 \n\t" // LT + "cmp %4, %0 \n\t" + " jb 1b \n\t" + : "+r" (i) + : "r" (src1), "r" (src2), "r" (dst), "r" ((x86_reg) w)); + + l = *left; + lt = *left_top; + + dst[0] = src2[0] - mid_pred(l, src1[0], (l + src1[0] - lt) & 0xFF); + + *left_top = src1[w - 1]; + *left = src2[w - 1]; +} + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_llvidencdsp_init_x86(LLVidEncDSPContext *c) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) { + c->diff_bytes = ff_diff_bytes_mmx; + } + +#if HAVE_INLINE_ASM + if (INLINE_MMXEXT(cpu_flags)) { + c->sub_median_pred = sub_median_pred_mmxext; + } +#endif /* HAVE_INLINE_ASM */ + + if (EXTERNAL_SSE2(cpu_flags)) { + c->diff_bytes = ff_diff_bytes_sse2; + } + + if (EXTERNAL_AVX(cpu_flags)) { + c->sub_left_predict = ff_sub_left_predict_avx; + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->diff_bytes = ff_diff_bytes_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lpc.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lpc.c new file mode 100644 index 00000000..6c72e21b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/lpc.c @@ -0,0 +1,162 @@ +/* + * SIMD-optimized LPC functions + * Copyright (c) 2007 Loren Merritt + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/lpc.h" + +DECLARE_ASM_CONST(16, double, pd_1)[2] = { 1.0, 1.0 }; +DECLARE_ASM_CONST(16, double, pd_2)[2] = { 2.0, 2.0 }; + +#if HAVE_SSE2_INLINE + +static void lpc_apply_welch_window_sse2(const int32_t *data, int len, + double *w_data) +{ + double c = 2.0 / (len-1.0); + int n2 = len>>1; + x86_reg i = -n2*sizeof(int32_t); + x86_reg j = n2*sizeof(int32_t); + __asm__ volatile( + "movsd %4, %%xmm7 \n\t" + "movapd "MANGLE(pd_1)", %%xmm6 \n\t" + "movapd "MANGLE(pd_2)", %%xmm5 \n\t" + "movlhps %%xmm7, %%xmm7 \n\t" + "subpd %%xmm5, %%xmm7 \n\t" + "addsd %%xmm6, %%xmm7 \n\t" + "test $1, %5 \n\t" + "jz 2f \n\t" +#define WELCH(MOVPD, offset)\ + "1: \n\t"\ + "movapd %%xmm7, %%xmm1 \n\t"\ + "mulpd %%xmm1, %%xmm1 \n\t"\ + "movapd %%xmm6, %%xmm0 \n\t"\ + "subpd %%xmm1, %%xmm0 \n\t"\ + "pshufd $0x4e, %%xmm0, %%xmm1 \n\t"\ + "cvtpi2pd (%3,%0), %%xmm2 \n\t"\ + "cvtpi2pd "#offset"*4(%3,%1), %%xmm3 \n\t"\ + "mulpd %%xmm0, %%xmm2 \n\t"\ + "mulpd %%xmm1, %%xmm3 \n\t"\ + "movapd %%xmm2, (%2,%0,2) \n\t"\ + MOVPD" %%xmm3, "#offset"*8(%2,%1,2) \n\t"\ + "subpd %%xmm5, %%xmm7 \n\t"\ + "sub $8, %1 \n\t"\ + "add $8, %0 \n\t"\ + "jl 1b \n\t"\ + + WELCH("movupd", -1) + "jmp 3f \n\t" + "2: \n\t" + WELCH("movapd", -2) + "3: \n\t" + :"+&r"(i), "+&r"(j) + :"r"(w_data+n2), "r"(data+n2), "m"(c), "r"(len) + NAMED_CONSTRAINTS_ARRAY_ADD(pd_1,pd_2) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm5", "%xmm6", "%xmm7") + ); +#undef WELCH +} + +static void lpc_compute_autocorr_sse2(const double *data, int len, int lag, + double *autoc) +{ + int j; + + if((x86_reg)data & 15) + data++; + + for(j=0; jlpc_apply_welch_window = lpc_apply_welch_window_sse2; + c->lpc_compute_autocorr = lpc_compute_autocorr_sse2; + } +#endif /* HAVE_SSE2_INLINE */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mathops.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mathops.h new file mode 100644 index 00000000..6298f5ed --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mathops.h @@ -0,0 +1,133 @@ +/* + * simple math operations + * Copyright (c) 2006 Michael Niedermayer et al + * + * 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 + */ + +#ifndef AVCODEC_X86_MATHOPS_H +#define AVCODEC_X86_MATHOPS_H + +#include "config.h" + +#include "libavutil/common.h" +#include "libavutil/x86/asm.h" + +#if HAVE_INLINE_ASM + +#if ARCH_X86_32 + +#define MULL MULL +static av_always_inline av_const int MULL(int a, int b, unsigned shift) +{ + int rt, dummy; + __asm__ ( + "imull %3 \n\t" + "shrdl %4, %%edx, %%eax \n\t" + :"=a"(rt), "=d"(dummy) + :"a"(a), "rm"(b), "ci"((uint8_t)shift) + ); + return rt; +} + +#define MULH MULH +static av_always_inline av_const int MULH(int a, int b) +{ + int rt, dummy; + __asm__ ( + "imull %3" + :"=d"(rt), "=a"(dummy) + :"a"(a), "rm"(b) + ); + return rt; +} + +#define MUL64 MUL64 +static av_always_inline av_const int64_t MUL64(int a, int b) +{ + int64_t rt; + __asm__ ( + "imull %2" + :"=A"(rt) + :"a"(a), "rm"(b) + ); + return rt; +} + +#endif /* ARCH_X86_32 */ + +#if HAVE_I686 +/* median of 3 */ +#define mid_pred mid_pred +static inline av_const int mid_pred(int a, int b, int c) +{ + int i=b; + __asm__ ( + "cmp %2, %1 \n\t" + "cmovg %1, %0 \n\t" + "cmovg %2, %1 \n\t" + "cmp %3, %1 \n\t" + "cmovl %3, %1 \n\t" + "cmp %1, %0 \n\t" + "cmovg %1, %0 \n\t" + :"+&r"(i), "+&r"(a) + :"r"(b), "r"(c) + ); + return i; +} + +#if HAVE_6REGS +#define COPY3_IF_LT(x, y, a, b, c, d)\ +__asm__ volatile(\ + "cmpl %0, %3 \n\t"\ + "cmovl %3, %0 \n\t"\ + "cmovl %4, %1 \n\t"\ + "cmovl %5, %2 \n\t"\ + : "+&r" (x), "+&r" (a), "+r" (c)\ + : "r" (y), "r" (b), "r" (d)\ +); +#endif /* HAVE_6REGS */ + +#endif /* HAVE_I686 */ + +#define MASK_ABS(mask, level) \ + __asm__ ("cdq \n\t" \ + "xorl %1, %0 \n\t" \ + "subl %1, %0 \n\t" \ + : "+a"(level), "=&d"(mask)) + +// avoid +32 for shift optimization (gcc should do that ...) +#define NEG_SSR32 NEG_SSR32 +static inline int32_t NEG_SSR32( int32_t a, int8_t s){ + __asm__ ("sarl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} + +#define NEG_USR32 NEG_USR32 +static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ + __asm__ ("shrl %1, %0\n\t" + : "+r" (a) + : "ic" ((uint8_t)(-s)) + ); + return a; +} + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVCODEC_X86_MATHOPS_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mdct15.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mdct15.asm new file mode 100644 index 00000000..2a2cdbd2 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mdct15.asm @@ -0,0 +1,221 @@ +;****************************************************************************** +;* SIMD optimized non-power-of-two MDCT functions +;* +;* Copyright (C) 2017 Rostislav Pehlivanov +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +perm_neg: dd 2, 5, 3, 4, 6, 1, 7, 0 +perm_pos: dd 0, 7, 1, 6, 4, 3, 5, 2 +sign_adjust_r: times 4 dd 0x80000000, 0x00000000 + +sign_adjust_5: dd 0x00000000, 0x80000000, 0x80000000, 0x00000000 + +SECTION .text + +%if ARCH_X86_64 + +;***************************************************************************************** +;void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); +;***************************************************************************************** +%macro FFT5 3 ; %1 - in_offset, %2 - dst1 (64bit used), %3 - dst2 + VBROADCASTSD m0, [inq + %1] ; in[ 0].re, in[ 0].im, in[ 0].re, in[ 0].im + movsd xm1, [inq + 1*16 + 8 + %1] ; in[ 3].re, in[ 3].im, 0, 0 + movsd xm4, [inq + 6*16 + 0 + %1] ; in[12].re, in[12].im, 0, 0 + movhps xm1, [inq + 3*16 + 0 + %1] ; in[ 3].re, in[ 3].im, in[ 6].re, in[ 6].im + movhps xm4, [inq + 4*16 + 8 + %1] ; in[12].re, in[12].im, in[ 9].re, in[ 9].im + + subps xm2, xm1, xm4 ; t[2].im, t[2].re, t[3].im, t[3].re + addps xm1, xm4 ; t[0].re, t[0].im, t[1].re, t[1].im + + movhlps %2, xm1 ; t[0].re, t[1].re, t[0].im, t[1].im + addps %2, xm1 + addps %2, xm0 ; DC[0].re, DC[0].im, junk... + movlhps %2, %2 ; DC[0].re, DC[0].im, DC[0].re, DC[0].im + + shufps xm3, xm1, xm2, q0110 ; t[0].re, t[0].im, t[2].re, t[2].im + shufps xm1, xm2, q2332 ; t[1].re, t[1].im, t[3].re, t[3].im + + mulps xm%3, xm1, xm5 + mulps xm4, xm3, xm6 + mulps xm1, xm6 + + xorps xm1, xm7 + mulps xm3, xm5 + addsubps xm3, xm1 ; t[0].re, t[0].im, t[2].re, t[2].im + subps xm%3, xm4 ; t[4].re, t[4].im, t[5].re, t[5].im + + movhlps xm2, xm%3, xm3 ; t[2].re, t[2].im, t[5].re, t[5].im + movlhps xm3, xm%3 ; t[0].re, t[0].im, t[4].re, t[4].im + + xorps xm2, xm7 + addps xm%3, xm2, xm3 + subps xm3, xm2 + + shufps xm3, xm3, q1032 + vinsertf128 m%3, m%3, xm3, 1 ; All ACs (tmp[1] through to tmp[4]) + addps m%3, m%3, m0 ; Finally offset with DCs +%endmacro + +%macro BUTTERFLIES_DC 1 ; %1 - exptab_offset + mulps xm0, xm9, [exptabq + %1 + 16*0] + mulps xm1, xm10, [exptabq + %1 + 16*1] + + haddps xm0, xm1 + movhlps xm1, xm0 ; t[0].re, t[1].re, t[0].im, t[1].im + + addps xm0, xm1 + addps xm0, xm8 + + movsd [outq], xm0 +%endmacro + +%macro BUTTERFLIES_AC 1 ; %1 - exptab_offset + mulps m0, m12, [exptabq + 64*0 + 0*mmsize + %1] + mulps m1, m12, [exptabq + 64*0 + 1*mmsize + %1] + mulps m2, m13, [exptabq + 64*1 + 0*mmsize + %1] + mulps m3, m13, [exptabq + 64*1 + 1*mmsize + %1] + + addps m0, m0, m2 + addps m1, m1, m3 + addps m0, m0, m11 + + shufps m1, m1, m1, q2301 + addps m0, m0, m1 + + vextractf128 xm1, m0, 1 + + movlps [outq + strideq*1], xm0 + movhps [outq + strideq*2], xm0 + movlps [outq + stride3q], xm1 + movhps [outq + strideq*4], xm1 +%endmacro + +INIT_YMM avx +cglobal fft15, 4, 5, 14, out, in, exptab, stride, stride5 + shl strideq, 3 + + movaps xm5, [exptabq + 480 + 16*0] + movaps xm6, [exptabq + 480 + 16*1] + movaps xm7, [sign_adjust_5] + + FFT5 0, xm8, 11 + FFT5 8, xm9, 12 + FFT5 16, xm10, 13 + +%define stride3q inq + lea stride3q, [strideq + strideq*2] + lea stride5q, [strideq + strideq*4] + + BUTTERFLIES_DC (8*6 + 4*0)*2*4 + BUTTERFLIES_AC (8*0 + 0*0)*2*4 + + add outq, stride5q + BUTTERFLIES_DC (8*6 + 4*1)*2*4 + BUTTERFLIES_AC (8*2 + 0*0)*2*4 + + add outq, stride5q + BUTTERFLIES_DC (8*6 + 4*2)*2*4 + BUTTERFLIES_AC (8*4 + 0*0)*2*4 + + RET + +%endif ; ARCH_X86_64 + +;******************************************************************************************************* +;void ff_mdct15_postreindex(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +;******************************************************************************************************* +%macro LUT_LOAD_4D 3 + mov r4d, [lutq + %3q*4 + 0] + movsd xmm%1, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 4] + movhps xmm%1, [inq + r4q*8] +%if cpuflag(avx2) + mov r4d, [lutq + %3q*4 + 8] + movsd %2, [inq + r4q*8] + mov r4d, [lutq + %3q*4 + 12] + movhps %2, [inq + r4q*8] + vinsertf128 %1, %1, %2, 1 +%endif +%endmacro + +%macro POSTROTATE_FN 1 +cglobal mdct15_postreindex, 5, 7, 8 + cpuflag(avx2)*2, out, in, exp, lut, len8, offset_p, offset_n + + xor offset_nq, offset_nq + lea offset_pq, [len8q*2 - %1] + + movaps m7, [sign_adjust_r] + +%if cpuflag(avx2) + movaps m8, [perm_pos] + movaps m9, [perm_neg] +%endif + +.loop: + movups m0, [expq + offset_pq*8] ; exp[p0].re, exp[p0].im, exp[p1].re, exp[p1].im, exp[p2].re, exp[p2].im, exp[p3].re, exp[p3].im + movups m1, [expq + offset_nq*8] ; exp[n3].re, exp[n3].im, exp[n2].re, exp[n2].im, exp[n1].re, exp[n1].im, exp[n0].re, exp[n0].im + + LUT_LOAD_4D m3, xm4, offset_p ; in[p0].re, in[p0].im, in[p1].re, in[p1].im, in[p2].re, in[p2].im, in[p3].re, in[p3].im + LUT_LOAD_4D m4, xm5, offset_n ; in[n3].re, in[n3].im, in[n2].re, in[n2].im, in[n1].re, in[n1].im, in[n0].re, in[n0].im + + mulps m5, m3, m0 ; in[p].reim * exp[p].reim + mulps m6, m4, m1 ; in[n].reim * exp[n].reim + + xorps m5, m7 ; in[p].re *= -1, in[p].im *= 1 + xorps m6, m7 ; in[n].re *= -1, in[n].im *= 1 + + shufps m3, m3, m3, q2301 ; in[p].imre + shufps m4, m4, m4, q2301 ; in[n].imre + + mulps m3, m0 ; in[p].imre * exp[p].reim + mulps m4, m1 ; in[n].imre * exp[n].reim + + haddps m3, m6 ; out[n0].im, out[n1].im, out[n3].re, out[n2].re, out[n2].im, out[n3].im, out[n1].re, out[n0].re + haddps m5, m4 ; out[p0].re, out[p1].re, out[p3].im, out[p2].im, out[p2].re, out[p3].re, out[p1].im, out[p0].im + +%if cpuflag(avx2) + vpermps m3, m9, m3 ; out[n3].im, out[n3].re, out[n2].im, out[n2].re, out[n1].im, out[n1].re, out[n0].im, out[n0].re + vpermps m5, m8, m5 ; out[p0].re, out[p0].im, out[p1].re, out[p1].im, out[p2].re, out[p2].im, out[p3].re, out[p3].im +%else + shufps m3, m3, m3, q0312 + shufps m5, m5, m5, q2130 +%endif + + movups [outq + offset_nq*8], m3 + movups [outq + offset_pq*8], m5 + + sub offset_pq, %1 + add offset_nq, %1 + cmp offset_nq, offset_pq + jle .loop + + REP_RET +%endmacro + +INIT_XMM sse3 +POSTROTATE_FN 2 + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +POSTROTATE_FN 4 +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mdct15_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mdct15_init.c new file mode 100644 index 00000000..444801d9 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mdct15_init.c @@ -0,0 +1,99 @@ +/* + * SIMD optimized non-power-of-two MDCT functions + * + * Copyright (C) 2017 Rostislav Pehlivanov + * + * 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.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/mdct15.h" + +void ff_mdct15_postreindex_sse3(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); +void ff_mdct15_postreindex_avx2(FFTComplex *out, FFTComplex *in, FFTComplex *exp, int *lut, ptrdiff_t len8); + +void ff_fft15_avx(FFTComplex *out, FFTComplex *in, FFTComplex *exptab, ptrdiff_t stride); + +static void perm_twiddles(MDCT15Context *s) +{ + int k; + FFTComplex tmp[30]; + + /* 5-point FFT twiddles */ + s->exptab[60].re = s->exptab[60].im = s->exptab[19].re; + s->exptab[61].re = s->exptab[61].im = s->exptab[19].im; + s->exptab[62].re = s->exptab[62].im = s->exptab[20].re; + s->exptab[63].re = s->exptab[63].im = s->exptab[20].im; + + /* 15-point FFT twiddles */ + for (k = 0; k < 5; k++) { + tmp[6*k + 0] = s->exptab[k + 0]; + tmp[6*k + 2] = s->exptab[k + 5]; + tmp[6*k + 4] = s->exptab[k + 10]; + + tmp[6*k + 1] = s->exptab[2 * (k + 0)]; + tmp[6*k + 3] = s->exptab[2 * (k + 5)]; + tmp[6*k + 5] = s->exptab[2 * k + 5 ]; + } + + for (k = 0; k < 6; k++) { + FFTComplex ac_exp[] = { + { tmp[6*1 + k].re, tmp[6*1 + k].re }, + { tmp[6*2 + k].re, tmp[6*2 + k].re }, + { tmp[6*3 + k].re, tmp[6*3 + k].re }, + { tmp[6*4 + k].re, tmp[6*4 + k].re }, + { tmp[6*1 + k].im, -tmp[6*1 + k].im }, + { tmp[6*2 + k].im, -tmp[6*2 + k].im }, + { tmp[6*3 + k].im, -tmp[6*3 + k].im }, + { tmp[6*4 + k].im, -tmp[6*4 + k].im }, + }; + memcpy(s->exptab + 8*k, ac_exp, 8*sizeof(FFTComplex)); + } + + /* Specialcase when k = 0 */ + for (k = 0; k < 3; k++) { + FFTComplex dc_exp[] = { + { tmp[2*k + 0].re, -tmp[2*k + 0].im }, + { tmp[2*k + 0].im, tmp[2*k + 0].re }, + { tmp[2*k + 1].re, -tmp[2*k + 1].im }, + { tmp[2*k + 1].im, tmp[2*k + 1].re }, + }; + memcpy(s->exptab + 8*6 + 4*k, dc_exp, 4*sizeof(FFTComplex)); + } +} + +av_cold void ff_mdct15_init_x86(MDCT15Context *s) +{ + int adjust_twiddles = 0; + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE3(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_sse3; + + if (ARCH_X86_64 && EXTERNAL_AVX(cpu_flags)) { + s->fft15 = ff_fft15_avx; + adjust_twiddles = 1; + } + + if (ARCH_X86_64 && EXTERNAL_AVX2_FAST(cpu_flags)) + s->postreindex = ff_mdct15_postreindex_avx2; + + if (adjust_twiddles) + perm_twiddles(s); +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/me_cmp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/me_cmp.asm new file mode 100644 index 00000000..ad06d485 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/me_cmp.asm @@ -0,0 +1,934 @@ +;***************************************************************************** +;* SIMD-optimized motion compensation estimation +;***************************************************************************** +;* Copyright (c) 2000, 2001 Fabrice Bellard +;* Copyright (c) 2002-2004 Michael Niedermayer +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pb_1 +cextern pb_80 + +SECTION .text + +%macro DIFF_PIXELS_1 4 + movh %1, %3 + movh %2, %4 + punpcklbw %2, %1 + punpcklbw %1, %1 + psubw %1, %2 +%endmacro + +; %1=uint8_t *pix1, %2=uint8_t *pix2, %3=static offset, %4=stride, %5=stride*3 +; %6=temporary storage location +; this macro requires $mmsize stack space (aligned) on %6 (except on SSE+x86-64) +%macro DIFF_PIXELS_8 6 + DIFF_PIXELS_1 m0, m7, [%1 +%3], [%2 +%3] + DIFF_PIXELS_1 m1, m7, [%1+%4 +%3], [%2+%4 +%3] + DIFF_PIXELS_1 m2, m7, [%1+%4*2+%3], [%2+%4*2+%3] + add %1, %5 + add %2, %5 + DIFF_PIXELS_1 m3, m7, [%1 +%3], [%2 +%3] + DIFF_PIXELS_1 m4, m7, [%1+%4 +%3], [%2+%4 +%3] + DIFF_PIXELS_1 m5, m7, [%1+%4*2+%3], [%2+%4*2+%3] + DIFF_PIXELS_1 m6, m7, [%1+%5 +%3], [%2+%5 +%3] +%ifdef m8 + DIFF_PIXELS_1 m7, m8, [%1+%4*4+%3], [%2+%4*4+%3] +%else + mova [%6], m0 + DIFF_PIXELS_1 m7, m0, [%1+%4*4+%3], [%2+%4*4+%3] + mova m0, [%6] +%endif + sub %1, %5 + sub %2, %5 +%endmacro + +%macro HADAMARD8 0 + SUMSUB_BADC w, 0, 1, 2, 3 + SUMSUB_BADC w, 4, 5, 6, 7 + SUMSUB_BADC w, 0, 2, 1, 3 + SUMSUB_BADC w, 4, 6, 5, 7 + SUMSUB_BADC w, 0, 4, 1, 5 + SUMSUB_BADC w, 2, 6, 3, 7 +%endmacro + +%macro ABS1_SUM 3 + ABS1 %1, %2 + paddusw %3, %1 +%endmacro + +%macro ABS2_SUM 6 + ABS2 %1, %2, %3, %4 + paddusw %5, %1 + paddusw %6, %2 +%endmacro + +%macro ABS_SUM_8x8_64 1 + ABS2 m0, m1, m8, m9 + ABS2_SUM m2, m3, m8, m9, m0, m1 + ABS2_SUM m4, m5, m8, m9, m0, m1 + ABS2_SUM m6, m7, m8, m9, m0, m1 + paddusw m0, m1 +%endmacro + +%macro ABS_SUM_8x8_32 1 + mova [%1], m7 + ABS1 m0, m7 + ABS1 m1, m7 + ABS1_SUM m2, m7, m0 + ABS1_SUM m3, m7, m1 + ABS1_SUM m4, m7, m0 + ABS1_SUM m5, m7, m1 + ABS1_SUM m6, m7, m0 + mova m2, [%1] + ABS1_SUM m2, m7, m1 + paddusw m0, m1 +%endmacro + +; FIXME: HSUM saturates at 64k, while an 8x8 hadamard or dct block can get up to +; about 100k on extreme inputs. But that's very unlikely to occur in natural video, +; and it's even more unlikely to not have any alternative mvs/modes with lower cost. +%macro HSUM 3 +%if cpuflag(sse2) + movhlps %2, %1 + paddusw %1, %2 + pshuflw %2, %1, 0xE + paddusw %1, %2 + pshuflw %2, %1, 0x1 + paddusw %1, %2 + movd %3, %1 +%elif cpuflag(mmxext) + pshufw %2, %1, 0xE + paddusw %1, %2 + pshufw %2, %1, 0x1 + paddusw %1, %2 + movd %3, %1 +%elif cpuflag(mmx) + mova %2, %1 + psrlq %1, 32 + paddusw %1, %2 + mova %2, %1 + psrlq %1, 16 + paddusw %1, %2 + movd %3, %1 +%endif +%endmacro + +%macro STORE4 5 + mova [%1+mmsize*0], %2 + mova [%1+mmsize*1], %3 + mova [%1+mmsize*2], %4 + mova [%1+mmsize*3], %5 +%endmacro + +%macro LOAD4 5 + mova %2, [%1+mmsize*0] + mova %3, [%1+mmsize*1] + mova %4, [%1+mmsize*2] + mova %5, [%1+mmsize*3] +%endmacro + +%macro hadamard8_16_wrapper 2 +cglobal hadamard8_diff, 4, 4, %1 +%ifndef m8 + %assign pad %2*mmsize-(4+stack_offset&(mmsize-1)) + SUB rsp, pad +%endif + call hadamard8x8_diff %+ SUFFIX +%ifndef m8 + ADD rsp, pad +%endif + RET + +cglobal hadamard8_diff16, 5, 6, %1 +%ifndef m8 + %assign pad %2*mmsize-(4+stack_offset&(mmsize-1)) + SUB rsp, pad +%endif + + call hadamard8x8_diff %+ SUFFIX + mov r5d, eax + + add r1, 8 + add r2, 8 + call hadamard8x8_diff %+ SUFFIX + add r5d, eax + + cmp r4d, 16 + jne .done + + lea r1, [r1+r3*8-8] + lea r2, [r2+r3*8-8] + call hadamard8x8_diff %+ SUFFIX + add r5d, eax + + add r1, 8 + add r2, 8 + call hadamard8x8_diff %+ SUFFIX + add r5d, eax + +.done: + mov eax, r5d +%ifndef m8 + ADD rsp, pad +%endif + RET +%endmacro + +%macro HADAMARD8_DIFF 0-1 +%if cpuflag(sse2) +hadamard8x8_diff %+ SUFFIX: + lea r0, [r3*3] + DIFF_PIXELS_8 r1, r2, 0, r3, r0, rsp+gprsize + HADAMARD8 +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [rsp+gprsize], [rsp+mmsize+gprsize] +%endif + HADAMARD8 + ABS_SUM_8x8 rsp+gprsize + HSUM m0, m1, eax + and eax, 0xFFFF + ret + +hadamard8_16_wrapper %1, 3 +%elif cpuflag(mmx) +ALIGN 16 +; int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, +; uint8_t *src2, ptrdiff_t stride, int h) +; r0 = void *s = unused, int h = unused (always 8) +; note how r1, r2 and r3 are not clobbered in this function, so 16x16 +; can simply call this 2x2x (and that's why we access rsp+gprsize +; everywhere, which is rsp of calling func +hadamard8x8_diff %+ SUFFIX: + lea r0, [r3*3] + + ; first 4x8 pixels + DIFF_PIXELS_8 r1, r2, 0, r3, r0, rsp+gprsize+0x60 + HADAMARD8 + mova [rsp+gprsize+0x60], m7 + TRANSPOSE4x4W 0, 1, 2, 3, 7 + STORE4 rsp+gprsize, m0, m1, m2, m3 + mova m7, [rsp+gprsize+0x60] + TRANSPOSE4x4W 4, 5, 6, 7, 0 + STORE4 rsp+gprsize+0x40, m4, m5, m6, m7 + + ; second 4x8 pixels + DIFF_PIXELS_8 r1, r2, 4, r3, r0, rsp+gprsize+0x60 + HADAMARD8 + mova [rsp+gprsize+0x60], m7 + TRANSPOSE4x4W 0, 1, 2, 3, 7 + STORE4 rsp+gprsize+0x20, m0, m1, m2, m3 + mova m7, [rsp+gprsize+0x60] + TRANSPOSE4x4W 4, 5, 6, 7, 0 + + LOAD4 rsp+gprsize+0x40, m0, m1, m2, m3 + HADAMARD8 + ABS_SUM_8x8_32 rsp+gprsize+0x60 + mova [rsp+gprsize+0x60], m0 + + LOAD4 rsp+gprsize , m0, m1, m2, m3 + LOAD4 rsp+gprsize+0x20, m4, m5, m6, m7 + HADAMARD8 + ABS_SUM_8x8_32 rsp+gprsize + paddusw m0, [rsp+gprsize+0x60] + + HSUM m0, m1, eax + and rax, 0xFFFF + ret + +hadamard8_16_wrapper 0, 14 +%endif +%endmacro + +INIT_MMX mmx +HADAMARD8_DIFF + +INIT_MMX mmxext +HADAMARD8_DIFF + +INIT_XMM sse2 +%if ARCH_X86_64 +%define ABS_SUM_8x8 ABS_SUM_8x8_64 +%else +%define ABS_SUM_8x8 ABS_SUM_8x8_32 +%endif +HADAMARD8_DIFF 10 + +INIT_XMM ssse3 +%define ABS_SUM_8x8 ABS_SUM_8x8_64 +HADAMARD8_DIFF 9 + +; int ff_sse*_*(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, +; ptrdiff_t line_size, int h) + +%macro SUM_SQUARED_ERRORS 1 +cglobal sse%1, 5,5,8, v, pix1, pix2, lsize, h +%if %1 == mmsize + shr hd, 1 +%endif + pxor m0, m0 ; mm0 = 0 + pxor m7, m7 ; mm7 holds the sum + +.next2lines: ; FIXME why are these unaligned movs? pix1[] is aligned + movu m1, [pix1q] ; m1 = pix1[0][0-15], [0-7] for mmx + movu m2, [pix2q] ; m2 = pix2[0][0-15], [0-7] for mmx +%if %1 == mmsize + movu m3, [pix1q+lsizeq] ; m3 = pix1[1][0-15], [0-7] for mmx + movu m4, [pix2q+lsizeq] ; m4 = pix2[1][0-15], [0-7] for mmx +%else ; %1 / 2 == mmsize; mmx only + mova m3, [pix1q+8] ; m3 = pix1[0][8-15] + mova m4, [pix2q+8] ; m4 = pix2[0][8-15] +%endif + + ; todo: mm1-mm2, mm3-mm4 + ; algo: subtract mm1 from mm2 with saturation and vice versa + ; OR the result to get the absolute difference + mova m5, m1 + mova m6, m3 + psubusb m1, m2 + psubusb m3, m4 + psubusb m2, m5 + psubusb m4, m6 + + por m2, m1 + por m4, m3 + + ; now convert to 16-bit vectors so we can square them + mova m1, m2 + mova m3, m4 + + punpckhbw m2, m0 + punpckhbw m4, m0 + punpcklbw m1, m0 ; mm1 not spread over (mm1,mm2) + punpcklbw m3, m0 ; mm4 not spread over (mm3,mm4) + + pmaddwd m2, m2 + pmaddwd m4, m4 + pmaddwd m1, m1 + pmaddwd m3, m3 + + paddd m1, m2 + paddd m3, m4 + paddd m7, m1 + paddd m7, m3 + +%if %1 == mmsize + lea pix1q, [pix1q + 2*lsizeq] + lea pix2q, [pix2q + 2*lsizeq] +%else + add pix1q, lsizeq + add pix2q, lsizeq +%endif + dec hd + jnz .next2lines + + HADDD m7, m1 + movd eax, m7 ; return value + RET +%endmacro + +INIT_MMX mmx +SUM_SQUARED_ERRORS 8 + +INIT_MMX mmx +SUM_SQUARED_ERRORS 16 + +INIT_XMM sse2 +SUM_SQUARED_ERRORS 16 + +;----------------------------------------------- +;int ff_sum_abs_dctelem(int16_t *block) +;----------------------------------------------- +; %1 = number of xmm registers used +; %2 = number of inline loops + +%macro SUM_ABS_DCTELEM 2 +cglobal sum_abs_dctelem, 1, 1, %1, block + pxor m0, m0 + pxor m1, m1 +%assign %%i 0 +%rep %2 + mova m2, [blockq+mmsize*(0+%%i)] + mova m3, [blockq+mmsize*(1+%%i)] + mova m4, [blockq+mmsize*(2+%%i)] + mova m5, [blockq+mmsize*(3+%%i)] + ABS1_SUM m2, m6, m0 + ABS1_SUM m3, m6, m1 + ABS1_SUM m4, m6, m0 + ABS1_SUM m5, m6, m1 +%assign %%i %%i+4 +%endrep + paddusw m0, m1 + HSUM m0, m1, eax + and eax, 0xFFFF + RET +%endmacro + +INIT_MMX mmx +SUM_ABS_DCTELEM 0, 4 +INIT_MMX mmxext +SUM_ABS_DCTELEM 0, 4 +INIT_XMM sse2 +SUM_ABS_DCTELEM 7, 2 +INIT_XMM ssse3 +SUM_ABS_DCTELEM 6, 2 + +;------------------------------------------------------------------------------ +; int ff_hf_noise*_mmx(uint8_t *pix1, ptrdiff_t lsize, int h) +;------------------------------------------------------------------------------ +; %1 = 8/16. %2-5=m# +%macro HF_NOISE_PART1 5 + mova m%2, [pix1q] +%if %1 == 8 + mova m%3, m%2 + psllq m%2, 8 + psrlq m%3, 8 + psrlq m%2, 8 +%else + mova m%3, [pix1q+1] +%endif + mova m%4, m%2 + mova m%5, m%3 + punpcklbw m%2, m7 + punpcklbw m%3, m7 + punpckhbw m%4, m7 + punpckhbw m%5, m7 + psubw m%2, m%3 + psubw m%4, m%5 +%endmacro + +; %1-2 = m# +%macro HF_NOISE_PART2 4 + psubw m%1, m%3 + psubw m%2, m%4 + pxor m3, m3 + pxor m1, m1 + pcmpgtw m3, m%1 + pcmpgtw m1, m%2 + pxor m%1, m3 + pxor m%2, m1 + psubw m%1, m3 + psubw m%2, m1 + paddw m%2, m%1 + paddw m6, m%2 +%endmacro + +; %1 = 8/16 +%macro HF_NOISE 1 +cglobal hf_noise%1, 3,3,0, pix1, lsize, h + sub hd, 2 + pxor m7, m7 + pxor m6, m6 + HF_NOISE_PART1 %1, 0, 1, 2, 3 + add pix1q, lsizeq + HF_NOISE_PART1 %1, 4, 1, 5, 3 + HF_NOISE_PART2 0, 2, 4, 5 + add pix1q, lsizeq +.loop: + HF_NOISE_PART1 %1, 0, 1, 2, 3 + HF_NOISE_PART2 4, 5, 0, 2 + add pix1q, lsizeq + HF_NOISE_PART1 %1, 4, 1, 5, 3 + HF_NOISE_PART2 0, 2, 4, 5 + add pix1q, lsizeq + sub hd, 2 + jne .loop + + mova m0, m6 + punpcklwd m0, m7 + punpckhwd m6, m7 + paddd m6, m0 + mova m0, m6 + psrlq m6, 32 + paddd m0, m6 + movd eax, m0 ; eax = result of hf_noise8; + REP_RET ; return eax; +%endmacro + +INIT_MMX mmx +HF_NOISE 8 +HF_NOISE 16 + +;--------------------------------------------------------------------------------------- +;int ff_sad_(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h); +;--------------------------------------------------------------------------------------- +;%1 = 8/16 +%macro SAD 1 +cglobal sad%1, 5, 5, 3, v, pix1, pix2, stride, h + movu m2, [pix2q] + movu m1, [pix2q+strideq] + psadbw m2, [pix1q] + psadbw m1, [pix1q+strideq] + paddw m2, m1 +%if %1 != mmsize + movu m0, [pix2q+8] + movu m1, [pix2q+strideq+8] + psadbw m0, [pix1q+8] + psadbw m1, [pix1q+strideq+8] + paddw m2, m0 + paddw m2, m1 +%endif + sub hd, 2 + +align 16 +.loop: + lea pix1q, [pix1q+strideq*2] + lea pix2q, [pix2q+strideq*2] + movu m0, [pix2q] + movu m1, [pix2q+strideq] + psadbw m0, [pix1q] + psadbw m1, [pix1q+strideq] + paddw m2, m0 + paddw m2, m1 +%if %1 != mmsize + movu m0, [pix2q+8] + movu m1, [pix2q+strideq+8] + psadbw m0, [pix1q+8] + psadbw m1, [pix1q+strideq+8] + paddw m2, m0 + paddw m2, m1 +%endif + sub hd, 2 + jg .loop +%if mmsize == 16 + movhlps m0, m2 + paddw m2, m0 +%endif + movd eax, m2 + RET +%endmacro + +INIT_MMX mmxext +SAD 8 +SAD 16 +INIT_XMM sse2 +SAD 16 + +;------------------------------------------------------------------------------------------ +;int ff_sad_x2_(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h); +;------------------------------------------------------------------------------------------ +;%1 = 8/16 +%macro SAD_X2 1 +cglobal sad%1_x2, 5, 5, 5, v, pix1, pix2, stride, h + movu m0, [pix2q] + movu m2, [pix2q+strideq] +%if mmsize == 16 + movu m3, [pix2q+1] + movu m4, [pix2q+strideq+1] + pavgb m0, m3 + pavgb m2, m4 +%else + pavgb m0, [pix2q+1] + pavgb m2, [pix2q+strideq+1] +%endif + psadbw m0, [pix1q] + psadbw m2, [pix1q+strideq] + paddw m0, m2 +%if %1 != mmsize + movu m1, [pix2q+8] + movu m2, [pix2q+strideq+8] + pavgb m1, [pix2q+9] + pavgb m2, [pix2q+strideq+9] + psadbw m1, [pix1q+8] + psadbw m2, [pix1q+strideq+8] + paddw m0, m1 + paddw m0, m2 +%endif + sub hd, 2 + +align 16 +.loop: + lea pix1q, [pix1q+2*strideq] + lea pix2q, [pix2q+2*strideq] + movu m1, [pix2q] + movu m2, [pix2q+strideq] +%if mmsize == 16 + movu m3, [pix2q+1] + movu m4, [pix2q+strideq+1] + pavgb m1, m3 + pavgb m2, m4 +%else + pavgb m1, [pix2q+1] + pavgb m2, [pix2q+strideq+1] +%endif + psadbw m1, [pix1q] + psadbw m2, [pix1q+strideq] + paddw m0, m1 + paddw m0, m2 +%if %1 != mmsize + movu m1, [pix2q+8] + movu m2, [pix2q+strideq+8] + pavgb m1, [pix2q+9] + pavgb m2, [pix2q+strideq+9] + psadbw m1, [pix1q+8] + psadbw m2, [pix1q+strideq+8] + paddw m0, m1 + paddw m0, m2 +%endif + sub hd, 2 + jg .loop +%if mmsize == 16 + movhlps m1, m0 + paddw m0, m1 +%endif + movd eax, m0 + RET +%endmacro + +INIT_MMX mmxext +SAD_X2 8 +SAD_X2 16 +INIT_XMM sse2 +SAD_X2 16 + +;------------------------------------------------------------------------------------------ +;int ff_sad_y2_(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h); +;------------------------------------------------------------------------------------------ +;%1 = 8/16 +%macro SAD_Y2 1 +cglobal sad%1_y2, 5, 5, 4, v, pix1, pix2, stride, h + movu m1, [pix2q] + movu m0, [pix2q+strideq] + movu m3, [pix2q+2*strideq] + pavgb m1, m0 + pavgb m0, m3 + psadbw m1, [pix1q] + psadbw m0, [pix1q+strideq] + paddw m0, m1 + mova m1, m3 +%if %1 != mmsize + movu m4, [pix2q+8] + movu m5, [pix2q+strideq+8] + movu m6, [pix2q+2*strideq+8] + pavgb m4, m5 + pavgb m5, m6 + psadbw m4, [pix1q+8] + psadbw m5, [pix1q+strideq+8] + paddw m0, m4 + paddw m0, m5 + mova m4, m6 +%endif + add pix2q, strideq + sub hd, 2 + +align 16 +.loop: + lea pix1q, [pix1q+2*strideq] + lea pix2q, [pix2q+2*strideq] + movu m2, [pix2q] + movu m3, [pix2q+strideq] + pavgb m1, m2 + pavgb m2, m3 + psadbw m1, [pix1q] + psadbw m2, [pix1q+strideq] + paddw m0, m1 + paddw m0, m2 + mova m1, m3 +%if %1 != mmsize + movu m5, [pix2q+8] + movu m6, [pix2q+strideq+8] + pavgb m4, m5 + pavgb m5, m6 + psadbw m4, [pix1q+8] + psadbw m5, [pix1q+strideq+8] + paddw m0, m4 + paddw m0, m5 + mova m4, m6 +%endif + sub hd, 2 + jg .loop +%if mmsize == 16 + movhlps m1, m0 + paddw m0, m1 +%endif + movd eax, m0 + RET +%endmacro + +INIT_MMX mmxext +SAD_Y2 8 +SAD_Y2 16 +INIT_XMM sse2 +SAD_Y2 16 + +;------------------------------------------------------------------------------------------- +;int ff_sad_approx_xy2_(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, ptrdiff_t stride, int h); +;------------------------------------------------------------------------------------------- +;%1 = 8/16 +%macro SAD_APPROX_XY2 1 +cglobal sad%1_approx_xy2, 5, 5, 7, v, pix1, pix2, stride, h + mova m4, [pb_1] + movu m1, [pix2q] + movu m0, [pix2q+strideq] + movu m3, [pix2q+2*strideq] +%if mmsize == 16 + movu m5, [pix2q+1] + movu m6, [pix2q+strideq+1] + movu m2, [pix2q+2*strideq+1] + pavgb m1, m5 + pavgb m0, m6 + pavgb m3, m2 +%else + pavgb m1, [pix2q+1] + pavgb m0, [pix2q+strideq+1] + pavgb m3, [pix2q+2*strideq+1] +%endif + psubusb m0, m4 + pavgb m1, m0 + pavgb m0, m3 + psadbw m1, [pix1q] + psadbw m0, [pix1q+strideq] + paddw m0, m1 + mova m1, m3 +%if %1 != mmsize + movu m5, [pix2q+8] + movu m6, [pix2q+strideq+8] + movu m7, [pix2q+2*strideq+8] + pavgb m5, [pix2q+1+8] + pavgb m6, [pix2q+strideq+1+8] + pavgb m7, [pix2q+2*strideq+1+8] + psubusb m6, m4 + pavgb m5, m6 + pavgb m6, m7 + psadbw m5, [pix1q+8] + psadbw m6, [pix1q+strideq+8] + paddw m0, m5 + paddw m0, m6 + mova m5, m7 +%endif + add pix2q, strideq + sub hd, 2 + +align 16 +.loop: + lea pix1q, [pix1q+2*strideq] + lea pix2q, [pix2q+2*strideq] + movu m2, [pix2q] + movu m3, [pix2q+strideq] +%if mmsize == 16 + movu m5, [pix2q+1] + movu m6, [pix2q+strideq+1] + pavgb m2, m5 + pavgb m3, m6 +%else + pavgb m2, [pix2q+1] + pavgb m3, [pix2q+strideq+1] +%endif + psubusb m2, m4 + pavgb m1, m2 + pavgb m2, m3 + psadbw m1, [pix1q] + psadbw m2, [pix1q+strideq] + paddw m0, m1 + paddw m0, m2 + mova m1, m3 +%if %1 != mmsize + movu m6, [pix2q+8] + movu m7, [pix2q+strideq+8] + pavgb m6, [pix2q+8+1] + pavgb m7, [pix2q+strideq+8+1] + psubusb m6, m4 + pavgb m5, m6 + pavgb m6, m7 + psadbw m5, [pix1q+8] + psadbw m6, [pix1q+strideq+8] + paddw m0, m5 + paddw m0, m6 + mova m5, m7 +%endif + sub hd, 2 + jg .loop +%if mmsize == 16 + movhlps m1, m0 + paddw m0, m1 +%endif + movd eax, m0 + RET +%endmacro + +INIT_MMX mmxext +SAD_APPROX_XY2 8 +SAD_APPROX_XY2 16 +INIT_XMM sse2 +SAD_APPROX_XY2 16 + +;-------------------------------------------------------------------- +;int ff_vsad_intra(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, +; ptrdiff_t line_size, int h); +;-------------------------------------------------------------------- +; %1 = 8/16 +%macro VSAD_INTRA 1 +cglobal vsad_intra%1, 5, 5, 3, v, pix1, pix2, lsize, h + mova m0, [pix1q] +%if %1 == mmsize + mova m2, [pix1q+lsizeq] + psadbw m0, m2 +%else + mova m2, [pix1q+lsizeq] + mova m3, [pix1q+8] + mova m4, [pix1q+lsizeq+8] + psadbw m0, m2 + psadbw m3, m4 + paddw m0, m3 +%endif + sub hd, 2 + +.loop: + lea pix1q, [pix1q + 2*lsizeq] +%if %1 == mmsize + mova m1, [pix1q] + psadbw m2, m1 + paddw m0, m2 + mova m2, [pix1q+lsizeq] + psadbw m1, m2 + paddw m0, m1 +%else + mova m1, [pix1q] + mova m3, [pix1q+8] + psadbw m2, m1 + psadbw m4, m3 + paddw m0, m2 + paddw m0, m4 + mova m2, [pix1q+lsizeq] + mova m4, [pix1q+lsizeq+8] + psadbw m1, m2 + psadbw m3, m4 + paddw m0, m1 + paddw m0, m3 +%endif + sub hd, 2 + jg .loop + +%if mmsize == 16 + pshufd m1, m0, 0xe + paddd m0, m1 +%endif + movd eax, m0 + RET +%endmacro + +INIT_MMX mmxext +VSAD_INTRA 8 +VSAD_INTRA 16 +INIT_XMM sse2 +VSAD_INTRA 16 + +;--------------------------------------------------------------------- +;int ff_vsad_approx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, +; ptrdiff_t line_size, int h); +;--------------------------------------------------------------------- +; %1 = 8/16 +%macro VSAD_APPROX 1 +cglobal vsad%1_approx, 5, 5, 5, v, pix1, pix2, lsize, h + mova m1, [pb_80] + mova m0, [pix1q] +%if %1 == mmsize ; vsad8_mmxext, vsad16_sse2 + mova m4, [pix1q+lsizeq] +%if mmsize == 16 + movu m3, [pix2q] + movu m2, [pix2q+lsizeq] + psubb m0, m3 + psubb m4, m2 +%else + psubb m0, [pix2q] + psubb m4, [pix2q+lsizeq] +%endif + pxor m0, m1 + pxor m4, m1 + psadbw m0, m4 +%else ; vsad16_mmxext + mova m3, [pix1q+8] + psubb m0, [pix2q] + psubb m3, [pix2q+8] + pxor m0, m1 + pxor m3, m1 + mova m4, [pix1q+lsizeq] + mova m5, [pix1q+lsizeq+8] + psubb m4, [pix2q+lsizeq] + psubb m5, [pix2q+lsizeq+8] + pxor m4, m1 + pxor m5, m1 + psadbw m0, m4 + psadbw m3, m5 + paddw m0, m3 +%endif + sub hd, 2 + +.loop: + lea pix1q, [pix1q + 2*lsizeq] + lea pix2q, [pix2q + 2*lsizeq] + mova m2, [pix1q] +%if %1 == mmsize ; vsad8_mmxext, vsad16_sse2 +%if mmsize == 16 + movu m3, [pix2q] + psubb m2, m3 +%else + psubb m2, [pix2q] +%endif + pxor m2, m1 + psadbw m4, m2 + paddw m0, m4 + mova m4, [pix1q+lsizeq] + movu m3, [pix2q+lsizeq] + psubb m4, m3 + pxor m4, m1 + psadbw m2, m4 + paddw m0, m2 +%else ; vsad16_mmxext + mova m3, [pix1q+8] + psubb m2, [pix2q] + psubb m3, [pix2q+8] + pxor m2, m1 + pxor m3, m1 + psadbw m4, m2 + psadbw m5, m3 + paddw m0, m4 + paddw m0, m5 + mova m4, [pix1q+lsizeq] + mova m5, [pix1q+lsizeq+8] + psubb m4, [pix2q+lsizeq] + psubb m5, [pix2q+lsizeq+8] + pxor m4, m1 + pxor m5, m1 + psadbw m2, m4 + psadbw m3, m5 + paddw m0, m2 + paddw m0, m3 +%endif + sub hd, 2 + jg .loop + +%if mmsize == 16 + pshufd m1, m0, 0xe + paddd m0, m1 +%endif + movd eax, m0 + RET +%endmacro + +INIT_MMX mmxext +VSAD_APPROX 8 +VSAD_APPROX 16 +INIT_XMM sse2 +VSAD_APPROX 16 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/me_cmp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/me_cmp_init.c new file mode 100644 index 00000000..701eb1ab --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/me_cmp_init.c @@ -0,0 +1,652 @@ +/* + * SIMD-optimized motion estimation + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/me_cmp.h" +#include "libavcodec/mpegvideo.h" + +int ff_sum_abs_dctelem_mmx(int16_t *block); +int ff_sum_abs_dctelem_mmxext(int16_t *block); +int ff_sum_abs_dctelem_sse2(int16_t *block); +int ff_sum_abs_dctelem_ssse3(int16_t *block); +int ff_sse8_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sse16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sse16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_hf_noise8_mmx(uint8_t *pix1, ptrdiff_t stride, int h); +int ff_hf_noise16_mmx(uint8_t *pix1, ptrdiff_t stride, int h); +int ff_sad8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad8_x2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_x2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_x2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad8_y2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_y2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_y2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad8_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_approx_xy2_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_sad16_approx_xy2_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad_intra8_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad_intra16_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad_intra16_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad8_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad16_approx_mmxext(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); +int ff_vsad16_approx_sse2(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h); + +#define hadamard_func(cpu) \ + int ff_hadamard8_diff_ ## cpu(MpegEncContext *s, uint8_t *src1, \ + uint8_t *src2, ptrdiff_t stride, int h); \ + int ff_hadamard8_diff16_ ## cpu(MpegEncContext *s, uint8_t *src1, \ + uint8_t *src2, ptrdiff_t stride, int h); + +hadamard_func(mmx) +hadamard_func(mmxext) +hadamard_func(sse2) +hadamard_func(ssse3) + +#if HAVE_X86ASM +static int nsse16_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int score1, score2; + + if (c) + score1 = c->mecc.sse[0](c, pix1, pix2, stride, h); + else + score1 = ff_sse16_mmx(c, pix1, pix2, stride, h); + score2 = ff_hf_noise16_mmx(pix1, stride, h) + ff_hf_noise8_mmx(pix1+8, stride, h) + - ff_hf_noise16_mmx(pix2, stride, h) - ff_hf_noise8_mmx(pix2+8, stride, h); + + if (c) + return score1 + FFABS(score2) * c->avctx->nsse_weight; + else + return score1 + FFABS(score2) * 8; +} + +static int nsse8_mmx(MpegEncContext *c, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int score1 = ff_sse8_mmx(c, pix1, pix2, stride, h); + int score2 = ff_hf_noise8_mmx(pix1, stride, h) - + ff_hf_noise8_mmx(pix2, stride, h); + + if (c) + return score1 + FFABS(score2) * c->avctx->nsse_weight; + else + return score1 + FFABS(score2) * 8; +} + +#endif /* HAVE_X86ASM */ + +#if HAVE_INLINE_ASM + +static int vsad_intra16_mmx(MpegEncContext *v, uint8_t *pix, uint8_t *dummy, + ptrdiff_t stride, int h) +{ + int tmp; + + av_assert2((((int) pix) & 7) == 0); + av_assert2((stride & 7) == 0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), %%mm2\n" \ + "movq 8(%0), %%mm3\n" \ + "add %2,%0\n" \ + "movq %%mm2, " #out0 "\n" \ + "movq %%mm3, " #out1 "\n" \ + "psubusb " #in0 ", %%mm2\n" \ + "psubusb " #in1 ", %%mm3\n" \ + "psubusb " #out0 ", " #in0 "\n" \ + "psubusb " #out1 ", " #in1 "\n" \ + "por %%mm2, " #in0 "\n" \ + "por %%mm3, " #in1 "\n" \ + "movq " #in0 ", %%mm2\n" \ + "movq " #in1 ", %%mm3\n" \ + "punpcklbw %%mm7, " #in0 "\n" \ + "punpcklbw %%mm7, " #in1 "\n" \ + "punpckhbw %%mm7, %%mm2\n" \ + "punpckhbw %%mm7, %%mm3\n" \ + "paddw " #in1 ", " #in0 "\n" \ + "paddw %%mm3, %%mm2\n" \ + "paddw %%mm2, " #in0 "\n" \ + "paddw " #in0 ", %%mm6\n" + + + __asm__ volatile ( + "movl %3, %%ecx\n" + "pxor %%mm6, %%mm6\n" + "pxor %%mm7, %%mm7\n" + "movq (%0), %%mm0\n" + "movq 8(%0), %%mm1\n" + "add %2, %0\n" + "jmp 2f\n" + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + "2:\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6, %%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6, %%mm0\n" + "movq %%mm0, %%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6, %%mm0\n" + "movd %%mm0, %1\n" + : "+r" (pix), "=r" (tmp) + : "r" (stride), "m" (h) + : "%ecx"); + + return tmp & 0xFFFF; +} +#undef SUM + +static int vsad16_mmx(MpegEncContext *v, uint8_t *pix1, uint8_t *pix2, + ptrdiff_t stride, int h) +{ + int tmp; + + av_assert2((((int) pix1) & 7) == 0); + av_assert2((((int) pix2) & 7) == 0); + av_assert2((stride & 7) == 0); + +#define SUM(in0, in1, out0, out1) \ + "movq (%0), %%mm2\n" \ + "movq (%1), " #out0 "\n" \ + "movq 8(%0), %%mm3\n" \ + "movq 8(%1), " #out1 "\n" \ + "add %3, %0\n" \ + "add %3, %1\n" \ + "psubb " #out0 ", %%mm2\n" \ + "psubb " #out1 ", %%mm3\n" \ + "pxor %%mm7, %%mm2\n" \ + "pxor %%mm7, %%mm3\n" \ + "movq %%mm2, " #out0 "\n" \ + "movq %%mm3, " #out1 "\n" \ + "psubusb " #in0 ", %%mm2\n" \ + "psubusb " #in1 ", %%mm3\n" \ + "psubusb " #out0 ", " #in0 "\n" \ + "psubusb " #out1 ", " #in1 "\n" \ + "por %%mm2, " #in0 "\n" \ + "por %%mm3, " #in1 "\n" \ + "movq " #in0 ", %%mm2\n" \ + "movq " #in1 ", %%mm3\n" \ + "punpcklbw %%mm7, " #in0 "\n" \ + "punpcklbw %%mm7, " #in1 "\n" \ + "punpckhbw %%mm7, %%mm2\n" \ + "punpckhbw %%mm7, %%mm3\n" \ + "paddw " #in1 ", " #in0 "\n" \ + "paddw %%mm3, %%mm2\n" \ + "paddw %%mm2, " #in0 "\n" \ + "paddw " #in0 ", %%mm6\n" + + + __asm__ volatile ( + "movl %4, %%ecx\n" + "pxor %%mm6, %%mm6\n" + "pcmpeqw %%mm7, %%mm7\n" + "psllw $15, %%mm7\n" + "packsswb %%mm7, %%mm7\n" + "movq (%0), %%mm0\n" + "movq (%1), %%mm2\n" + "movq 8(%0), %%mm1\n" + "movq 8(%1), %%mm3\n" + "add %3, %0\n" + "add %3, %1\n" + "psubb %%mm2, %%mm0\n" + "psubb %%mm3, %%mm1\n" + "pxor %%mm7, %%mm0\n" + "pxor %%mm7, %%mm1\n" + "jmp 2f\n" + "1:\n" + + SUM(%%mm4, %%mm5, %%mm0, %%mm1) + "2:\n" + SUM(%%mm0, %%mm1, %%mm4, %%mm5) + + "subl $2, %%ecx\n" + "jnz 1b\n" + + "movq %%mm6, %%mm0\n" + "psrlq $32, %%mm6\n" + "paddw %%mm6, %%mm0\n" + "movq %%mm0, %%mm6\n" + "psrlq $16, %%mm0\n" + "paddw %%mm6, %%mm0\n" + "movd %%mm0, %2\n" + : "+r" (pix1), "+r" (pix2), "=r" (tmp) + : "r" (stride), "m" (h) + : "%ecx"); + + return tmp & 0x7FFF; +} +#undef SUM + +DECLARE_ASM_CONST(8, uint64_t, round_tab)[3] = { + 0x0000000000000000ULL, + 0x0001000100010001ULL, + 0x0002000200020002ULL, +}; + +static inline void sad8_1_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + x86_reg len = -stride * h; + __asm__ volatile ( + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm2 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm4 \n\t" + "add %3, %%"FF_REG_a" \n\t" + "psubusb %%mm0, %%mm2 \n\t" + "psubusb %%mm4, %%mm0 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm1 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm5 \n\t" + "psubusb %%mm1, %%mm3 \n\t" + "psubusb %%mm5, %%mm1 \n\t" + "por %%mm2, %%mm0 \n\t" + "por %%mm1, %%mm3 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm3, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm3, %%mm2 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %3, %%"FF_REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk2 - len), "r" (stride)); +} + +static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + x86_reg len = -stride * h; + __asm__ volatile ( + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm1 \n\t" + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm0, %%mm1 \n\t" + "paddw %%mm2, %%mm3 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm4 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm2 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "paddw %%mm5, %%mm3 \n\t" + "psrlw $1, %%mm1 \n\t" + "psrlw $1, %%mm3 \n\t" + "packuswb %%mm3, %%mm1 \n\t" + "psubusb %%mm1, %%mm4 \n\t" + "psubusb %%mm2, %%mm1 \n\t" + "por %%mm4, %%mm1 \n\t" + "movq %%mm1, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "add %4, %%"FF_REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1a - len), "r" (blk1b - len), "r" (blk2 - len), + "r" (stride)); +} + +static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + x86_reg len = -stride * h; + __asm__ volatile ( + "movq (%1, %%"FF_REG_a"), %%mm0\n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2\n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm3, %%mm1 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%2, %%"FF_REG_a"), %%mm2\n\t" + "movq 1(%2, %%"FF_REG_a"), %%mm4\n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddw %%mm4, %%mm2 \n\t" + "paddw %%mm5, %%mm3 \n\t" + "movq %5, %%mm5 \n\t" + "paddw %%mm2, %%mm0 \n\t" + "paddw %%mm3, %%mm1 \n\t" + "paddw %%mm5, %%mm0 \n\t" + "paddw %%mm5, %%mm1 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm4 \n\t" + "movq (%3, %%"FF_REG_a"), %%mm5 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "psubusb %%mm0, %%mm4 \n\t" + "psubusb %%mm5, %%mm0 \n\t" + "por %%mm4, %%mm0 \n\t" + "movq %%mm0, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpckhbw %%mm7, %%mm4 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "paddw %%mm4, %%mm6 \n\t" + "movq %%mm2, %%mm0 \n\t" + "movq %%mm3, %%mm1 \n\t" + "add %4, %%"FF_REG_a" \n\t" + " js 1b \n\t" + : "+a" (len) + : "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len), + "r" (stride), "m" (round_tab[2])); +} + +static inline int sum_mmx(void) +{ + int ret; + __asm__ volatile ( + "movq %%mm6, %%mm0 \n\t" + "psrlq $32, %%mm6 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "movq %%mm6, %%mm0 \n\t" + "psrlq $16, %%mm6 \n\t" + "paddw %%mm0, %%mm6 \n\t" + "movd %%mm6, %0 \n\t" + : "=r" (ret)); + return ret & 0xFFFF; +} + +static inline void sad8_x2a_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + sad8_2_mmx(blk1, blk1 + 1, blk2, stride, h); +} + +static inline void sad8_y2a_mmx(uint8_t *blk1, uint8_t *blk2, + ptrdiff_t stride, int h) +{ + sad8_2_mmx(blk1, blk1 + stride, blk2, stride, h); +} + +#define PIX_SAD(suf) \ +static int sad8_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + :); \ + \ + sad8_1_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad8_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_x2a_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad8_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_y2a_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad8_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + av_assert2(h == 8); \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + ::); \ + \ + sad8_4_ ## suf(blk1, blk2, stride, 8); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + :); \ + \ + sad8_1_ ## suf(blk1, blk2, stride, h); \ + sad8_1_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_x2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_x2a_ ## suf(blk1, blk2, stride, h); \ + sad8_x2a_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_y2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + "movq %0, %%mm5 \n\t" \ + :: "m" (round_tab[1])); \ + \ + sad8_y2a_ ## suf(blk1, blk2, stride, h); \ + sad8_y2a_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + \ +static int sad16_xy2_ ## suf(MpegEncContext *v, uint8_t *blk2, \ + uint8_t *blk1, ptrdiff_t stride, int h) \ +{ \ + __asm__ volatile ( \ + "pxor %%mm7, %%mm7 \n\t" \ + "pxor %%mm6, %%mm6 \n\t" \ + ::); \ + \ + sad8_4_ ## suf(blk1, blk2, stride, h); \ + sad8_4_ ## suf(blk1 + 8, blk2 + 8, stride, h); \ + \ + return sum_ ## suf(); \ +} \ + +PIX_SAD(mmx) + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_me_cmp_init_x86(MECmpContext *c, AVCodecContext *avctx) +{ + int cpu_flags = av_get_cpu_flags(); + +#if HAVE_INLINE_ASM + if (INLINE_MMX(cpu_flags)) { + c->pix_abs[0][0] = sad16_mmx; + c->pix_abs[0][1] = sad16_x2_mmx; + c->pix_abs[0][2] = sad16_y2_mmx; + c->pix_abs[0][3] = sad16_xy2_mmx; + c->pix_abs[1][0] = sad8_mmx; + c->pix_abs[1][1] = sad8_x2_mmx; + c->pix_abs[1][2] = sad8_y2_mmx; + c->pix_abs[1][3] = sad8_xy2_mmx; + + c->sad[0] = sad16_mmx; + c->sad[1] = sad8_mmx; + + c->vsad[4] = vsad_intra16_mmx; + + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->vsad[0] = vsad16_mmx; + } + } + +#endif /* HAVE_INLINE_ASM */ + + if (EXTERNAL_MMX(cpu_flags)) { + c->hadamard8_diff[0] = ff_hadamard8_diff16_mmx; + c->hadamard8_diff[1] = ff_hadamard8_diff_mmx; + c->sum_abs_dctelem = ff_sum_abs_dctelem_mmx; + c->sse[0] = ff_sse16_mmx; + c->sse[1] = ff_sse8_mmx; +#if HAVE_X86ASM + c->nsse[0] = nsse16_mmx; + c->nsse[1] = nsse8_mmx; +#endif + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->hadamard8_diff[0] = ff_hadamard8_diff16_mmxext; + c->hadamard8_diff[1] = ff_hadamard8_diff_mmxext; + c->sum_abs_dctelem = ff_sum_abs_dctelem_mmxext; + + c->sad[0] = ff_sad16_mmxext; + c->sad[1] = ff_sad8_mmxext; + + c->pix_abs[0][0] = ff_sad16_mmxext; + c->pix_abs[0][1] = ff_sad16_x2_mmxext; + c->pix_abs[0][2] = ff_sad16_y2_mmxext; + c->pix_abs[1][0] = ff_sad8_mmxext; + c->pix_abs[1][1] = ff_sad8_x2_mmxext; + c->pix_abs[1][2] = ff_sad8_y2_mmxext; + + c->vsad[4] = ff_vsad_intra16_mmxext; + c->vsad[5] = ff_vsad_intra8_mmxext; + + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->pix_abs[0][3] = ff_sad16_approx_xy2_mmxext; + c->pix_abs[1][3] = ff_sad8_approx_xy2_mmxext; + + c->vsad[0] = ff_vsad16_approx_mmxext; + c->vsad[1] = ff_vsad8_approx_mmxext; + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->sse[0] = ff_sse16_sse2; + c->sum_abs_dctelem = ff_sum_abs_dctelem_sse2; + +#if HAVE_ALIGNED_STACK + c->hadamard8_diff[0] = ff_hadamard8_diff16_sse2; + c->hadamard8_diff[1] = ff_hadamard8_diff_sse2; +#endif + if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW) && avctx->codec_id != AV_CODEC_ID_SNOW) { + c->sad[0] = ff_sad16_sse2; + c->pix_abs[0][0] = ff_sad16_sse2; + c->pix_abs[0][1] = ff_sad16_x2_sse2; + c->pix_abs[0][2] = ff_sad16_y2_sse2; + + c->vsad[4] = ff_vsad_intra16_sse2; + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->pix_abs[0][3] = ff_sad16_approx_xy2_sse2; + c->vsad[0] = ff_vsad16_approx_sse2; + } + } + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->sum_abs_dctelem = ff_sum_abs_dctelem_ssse3; +#if HAVE_ALIGNED_STACK + c->hadamard8_diff[0] = ff_hadamard8_diff16_ssse3; + c->hadamard8_diff[1] = ff_hadamard8_diff_ssse3; +#endif + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mlpdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mlpdsp.asm new file mode 100644 index 00000000..3dc641e8 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mlpdsp.asm @@ -0,0 +1,196 @@ +;****************************************************************************** +;* SIMD-optimized MLP DSP functions +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%if ARCH_X86_64 + +%macro SHLX 2 +%if cpuflag(bmi2) + shlx %1, %1, %2q +%else + shl %1, %2b +%endif +%endmacro + +%macro REMATRIX 0 + movdqa m0, [samplesq] + movdqa m1, [coeffsq ] + pshufd m2, m0, q2301 + pshufd m3, m1, q2301 + pmuldq m0, m1 + pmuldq m3, m2 + paddq m0, m3 +%if notcpuflag(avx2) + movdqa m1, [samplesq + 16] + movdqa m2, [coeffsq + 16] + pshufd m3, m1, q2301 + pshufd m4, m2, q2301 + pmuldq m1, m2 + pmuldq m4, m3 + paddq m0, m1 + paddq m0, m4 +%else + vextracti128 xm1, m0, 1 + paddq xm0, xm1 +%endif +%endmacro + +%macro LOOP_END 0 + pshufd xm1, xm0, q0032 + paddq xm0, xm1 + movq accumq, xm0 + movzx blsbsd, byte [blsbs_ptrq] ; load *bypassed_lsbs + sar accumq, 14 ; accum >>= 14 + and accumd, maskd ; accum &= mask + add accumd, blsbsd ; accum += *bypassed_lsbs + mov [samplesq + dest_chq], accumd ; samples[dest_ch] = accum + add blsbs_ptrq, 8 ; bypassed_lsbs += MAX_CHANNELS; + add samplesq, 32 ; samples += MAX_CHANNELS; + cmp blsbs_ptrq, cntq +%endmacro + +%macro LOOP_SHIFT_END 0 + pshufd xm1, xm0, q0032 + paddq xm0, xm1 + movq accumq, xm0 + and indexd, auspd ; index &= access_unit_size_pow2; + movsx noiseq, byte [noise_bufferq + indexq] ; load noise_buffer[index] + add indexd, index2d ; index += index2 + SHLX noiseq, mns ; noise_buffer[index] <<= matrix_noise_shift + add accumq, noiseq ; accum += noise_buffer[index] + movzx noised, byte [blsbs_ptrq] ; load *bypassed_lsbs (reuse tmp noise register) + sar accumq, 14 ; accum >>= 14 + and accumd, maskd ; accum &= mask + add accumd, noised ; accum += *bypassed_lsbs + mov [samplesq + dest_chq], accumd ; samples[dest_ch] = accum + add blsbs_ptrq, 8 ; bypassed_lsbs += MAX_CHANNELS; + add samplesq, 32 ; samples += MAX_CHANNELS; + cmp blsbs_ptrq, cntq +%endmacro + +;void ff_mlp_rematrix_channel(int32_t *samples, const int32_t *coeffs, +; const uint8_t *bypassed_lsbs, const int8_t *noise_buffer, +; int index, unsigned int dest_ch, uint16_t blockpos, +; unsigned int maxchan, int matrix_noise_shift, +; int access_unit_size_pow2, int32_t mask) +%macro MLP_REMATRIX_CHANNEL 0 +cglobal mlp_rematrix_channel, 0, 13, 5, samples, coeffs, blsbs_ptr, blsbs, \ + index, dest_ch, blockpos, maxchan, mns, \ + accum, mask, cnt + mov mnsd, mnsm ; load matrix_noise_shift + movzx blockposq, word blockposm ; load and zero extend blockpos (16bit) + mov maxchand, maxchanm ; load maxchan + mov maskd, maskm ; load mask +%if WIN64 + mov dest_chd, dest_chm ; load dest_chd (not needed on UNIX64) +%endif + shl dest_chd, 2 + lea cntq, [blsbs_ptrq + blockposq*8] + test mnsd, mnsd ; is matrix_noise_shift != 0? + jne .shift ; jump if true + cmp maxchand, 4 ; is maxchan < 4? + jl .loop4 ; jump if true + +align 16 +.loop8: + ; Process 5 or more channels + REMATRIX + LOOP_END + jne .loop8 + RET + +align 16 +.loop4: + ; Process up to 4 channels + movdqa xm0, [samplesq] + movdqa xm1, [coeffsq ] + pshufd xm2, xm0, q2301 + pshufd xm3, xm1, q2301 + pmuldq xm0, xm1 + pmuldq xm3, xm2 + paddq xm0, xm3 + LOOP_END + jne .loop4 + RET + +.shift: +%if WIN64 + mov indexd, indexm ; load index (not needed on UNIX64) +%endif + mov r9d, r9m ; load access_unit_size_pow2 +%if cpuflag(bmi2) + ; bmi2 has shift functions that accept any gpr, not just cl, so keep things in place. + DEFINE_ARGS samples, coeffs, blsbs_ptr, noise_buffer, \ + index, dest_ch, accum, index2, mns, \ + ausp, mask, cnt, noise + add mnsd, 7 ; matrix_noise_shift += 7 +%else ; sse4 + mov r6, rcx ; move rcx elsewhere so we can use cl for matrix_noise_shift +%if WIN64 + ; r0 = rcx + DEFINE_ARGS mns, coeffs, blsbs_ptr, noise_buffer, index, dest_ch, samples, \ + index2, accum, ausp, mask, cnt, noise +%else ; UNIX64 + ; r3 = rcx + DEFINE_ARGS samples, coeffs, blsbs_ptr, mns, index, dest_ch, noise_buffer, \ + index2, accum, ausp, mask, cnt, noise +%endif + lea mnsd, [r8 + 7] ; rcx = matrix_noise_shift + 7 +%endif ; cpuflag + sub auspd, 1 ; access_unit_size_pow2 -= 1 + cmp r7d, 4 ; is maxchan < 4? + lea index2q, [indexq*2 + 1] ; index2 = 2 * index + 1; + jl .loop4_shift ; jump if maxchan < 4 + +align 16 +.loop8_shift: + ; Process 5 or more channels + REMATRIX + LOOP_SHIFT_END + jne .loop8_shift + RET + +align 16 +.loop4_shift: + ; Process up to 4 channels + movdqa xm0, [samplesq] + movdqa xm1, [coeffsq ] + pshufd xm2, xm0, q2301 + pshufd xm3, xm1, q2301 + pmuldq xm0, xm1 + pmuldq xm3, xm2 + paddq xm0, xm3 + LOOP_SHIFT_END + jne .loop4_shift + RET +%endmacro + +INIT_XMM sse4 +MLP_REMATRIX_CHANNEL +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2, bmi2 +MLP_REMATRIX_CHANNEL +%endif + +%endif ; ARCH_X86_64 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mlpdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mlpdsp_init.c new file mode 100644 index 00000000..cb90ca24 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mlpdsp_init.c @@ -0,0 +1,204 @@ +/* + * MLP DSP functions x86-optimized + * Copyright (c) 2009 Ramiro Polla + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/mlpdsp.h" +#include "libavcodec/mlp.h" + +#define REMATRIX_CHANNEL_FUNC(opt) \ +void ff_mlp_rematrix_channel_##opt(int32_t *samples, \ + const int32_t *coeffs, \ + const uint8_t *bypassed_lsbs, \ + const int8_t *noise_buffer, \ + int index, \ + unsigned int dest_ch, \ + uint16_t blockpos, \ + unsigned int maxchan, \ + int matrix_noise_shift, \ + int access_unit_size_pow2, \ + int32_t mask); + +REMATRIX_CHANNEL_FUNC(sse4) +REMATRIX_CHANNEL_FUNC(avx2_bmi2) + +#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS + +extern char ff_mlp_firorder_8; +extern char ff_mlp_firorder_7; +extern char ff_mlp_firorder_6; +extern char ff_mlp_firorder_5; +extern char ff_mlp_firorder_4; +extern char ff_mlp_firorder_3; +extern char ff_mlp_firorder_2; +extern char ff_mlp_firorder_1; +extern char ff_mlp_firorder_0; + +extern char ff_mlp_iirorder_4; +extern char ff_mlp_iirorder_3; +extern char ff_mlp_iirorder_2; +extern char ff_mlp_iirorder_1; +extern char ff_mlp_iirorder_0; + +static const void * const firtable[9] = { &ff_mlp_firorder_0, &ff_mlp_firorder_1, + &ff_mlp_firorder_2, &ff_mlp_firorder_3, + &ff_mlp_firorder_4, &ff_mlp_firorder_5, + &ff_mlp_firorder_6, &ff_mlp_firorder_7, + &ff_mlp_firorder_8 }; +static const void * const iirtable[5] = { &ff_mlp_iirorder_0, &ff_mlp_iirorder_1, + &ff_mlp_iirorder_2, &ff_mlp_iirorder_3, + &ff_mlp_iirorder_4 }; + +#if ARCH_X86_64 + +#define MLPMUL(label, offset, offs, offc) \ + LABEL_MANGLE(label)": \n\t" \ + "movslq "offset"+"offs"(%0), %%rax\n\t" \ + "movslq "offset"+"offc"(%1), %%rdx\n\t" \ + "imul %%rdx, %%rax\n\t" \ + "add %%rax, %%rsi\n\t" + +#define FIRMULREG(label, offset, firc)\ + LABEL_MANGLE(label)": \n\t" \ + "movslq "#offset"(%0), %%rax\n\t" \ + "imul %"#firc", %%rax\n\t" \ + "add %%rax, %%rsi\n\t" + +#define CLEAR_ACCUM \ + "xor %%rsi, %%rsi\n\t" + +#define SHIFT_ACCUM \ + "shr %%cl, %%rsi\n\t" + +#define ACCUM "%%rdx" +#define RESULT "%%rsi" +#define RESULT32 "%%esi" + +#else /* if ARCH_X86_32 */ + +#define MLPMUL(label, offset, offs, offc) \ + LABEL_MANGLE(label)": \n\t" \ + "mov "offset"+"offs"(%0), %%eax\n\t" \ + "imull "offset"+"offc"(%1) \n\t" \ + "add %%eax , %%esi\n\t" \ + "adc %%edx , %%ecx\n\t" + +#define FIRMULREG(label, offset, firc) \ + MLPMUL(label, #offset, "0", "0") + +#define CLEAR_ACCUM \ + "xor %%esi, %%esi\n\t" \ + "xor %%ecx, %%ecx\n\t" + +#define SHIFT_ACCUM \ + "mov %%ecx, %%edx\n\t" \ + "mov %%esi, %%eax\n\t" \ + "movzbl %7 , %%ecx\n\t" \ + "shrd %%cl, %%edx, %%eax\n\t" \ + +#define ACCUM "%%edx" +#define RESULT "%%eax" +#define RESULT32 "%%eax" + +#endif /* !ARCH_X86_64 */ + +#define BINC AV_STRINGIFY(4* MAX_CHANNELS) +#define IOFFS AV_STRINGIFY(4*(MAX_FIR_ORDER + MAX_BLOCKSIZE)) +#define IOFFC AV_STRINGIFY(4* MAX_FIR_ORDER) + +#define FIRMUL(label, offset) MLPMUL(label, #offset, "0", "0") +#define IIRMUL(label, offset) MLPMUL(label, #offset, IOFFS, IOFFC) + +static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, + int firorder, int iirorder, + unsigned int filter_shift, int32_t mask, + int blocksize, int32_t *sample_buffer) +{ + const void *firjump = firtable[firorder]; + const void *iirjump = iirtable[iirorder]; + + blocksize = -blocksize; + + __asm__ volatile( + "1: \n\t" + CLEAR_ACCUM + "jmp *%5 \n\t" + FIRMUL (ff_mlp_firorder_8, 0x1c ) + FIRMUL (ff_mlp_firorder_7, 0x18 ) + FIRMUL (ff_mlp_firorder_6, 0x14 ) + FIRMUL (ff_mlp_firorder_5, 0x10 ) + FIRMUL (ff_mlp_firorder_4, 0x0c ) + FIRMUL (ff_mlp_firorder_3, 0x08 ) + FIRMUL (ff_mlp_firorder_2, 0x04 ) + FIRMULREG(ff_mlp_firorder_1, 0x00, 8) + LABEL_MANGLE(ff_mlp_firorder_0)":\n\t" + "jmp *%6 \n\t" + IIRMUL (ff_mlp_iirorder_4, 0x0c ) + IIRMUL (ff_mlp_iirorder_3, 0x08 ) + IIRMUL (ff_mlp_iirorder_2, 0x04 ) + IIRMUL (ff_mlp_iirorder_1, 0x00 ) + LABEL_MANGLE(ff_mlp_iirorder_0)":\n\t" + SHIFT_ACCUM + "mov "RESULT" ,"ACCUM" \n\t" + "add (%2) ,"RESULT" \n\t" + "and %4 ,"RESULT" \n\t" + "sub $4 , %0 \n\t" + "mov "RESULT32", (%0) \n\t" + "mov "RESULT32", (%2) \n\t" + "add $"BINC" , %2 \n\t" + "sub "ACCUM" ,"RESULT" \n\t" + "mov "RESULT32","IOFFS"(%0) \n\t" + "incl %3 \n\t" + "js 1b \n\t" + : /* 0*/"+r"(state), + /* 1*/"+r"(coeff), + /* 2*/"+r"(sample_buffer), +#if ARCH_X86_64 + /* 3*/"+r"(blocksize) + : /* 4*/"r"((x86_reg)mask), /* 5*/"r"(firjump), + /* 6*/"r"(iirjump) , /* 7*/"c"(filter_shift) + , /* 8*/"r"((int64_t)coeff[0]) + : "rax", "rdx", "rsi" +#else /* ARCH_X86_32 */ + /* 3*/"+m"(blocksize) + : /* 4*/"m"( mask), /* 5*/"m"(firjump), + /* 6*/"m"(iirjump) , /* 7*/"m"(filter_shift) + : "eax", "edx", "esi", "ecx" +#endif /* !ARCH_X86_64 */ + ); +} + +#endif /* HAVE_7REGS && HAVE_INLINE_ASM */ + +av_cold void ff_mlpdsp_init_x86(MLPDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); +#if HAVE_7REGS && HAVE_INLINE_ASM && HAVE_INLINE_ASM_NONLOCAL_LABELS + if (INLINE_MMX(cpu_flags)) + c->mlp_filter_channel = mlp_filter_channel_x86; +#endif + if (ARCH_X86_64 && EXTERNAL_SSE4(cpu_flags)) + c->mlp_rematrix_channel = ff_mlp_rematrix_channel_sse4; + if (ARCH_X86_64 && EXTERNAL_AVX2_FAST(cpu_flags) && cpu_flags & AV_CPU_FLAG_BMI2) + c->mlp_rematrix_channel = ff_mlp_rematrix_channel_avx2_bmi2; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegaudiodsp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegaudiodsp.c new file mode 100644 index 00000000..50692f29 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegaudiodsp.c @@ -0,0 +1,293 @@ +/* + * SIMD-optimized MP3 decoding functions + * Copyright (c) 2010 Vitor Sessak + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/internal.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/mpegaudiodsp.h" + +#define DECL(CPU)\ +static void imdct36_blocks_ ## CPU(float *out, float *buf, float *in, int count, int switch_point, int block_type);\ +void ff_imdct36_float_ ## CPU(float *out, float *buf, float *in, float *win); + +#if HAVE_X86ASM +#if ARCH_X86_32 +DECL(sse) +#endif +DECL(sse2) +DECL(sse3) +DECL(ssse3) +DECL(avx) +#endif /* HAVE_X86ASM */ + +void ff_four_imdct36_float_sse(float *out, float *buf, float *in, float *win, + float *tmpbuf); +void ff_four_imdct36_float_avx(float *out, float *buf, float *in, float *win, + float *tmpbuf); + +DECLARE_ALIGNED(16, static float, mdct_win_sse)[2][4][4*40]; + +#if HAVE_6REGS && HAVE_SSE_INLINE + +#define MACS(rt, ra, rb) rt+=(ra)*(rb) +#define MLSS(rt, ra, rb) rt-=(ra)*(rb) + +#define SUM8(op, sum, w, p) \ +{ \ + op(sum, (w)[0 * 64], (p)[0 * 64]); \ + op(sum, (w)[1 * 64], (p)[1 * 64]); \ + op(sum, (w)[2 * 64], (p)[2 * 64]); \ + op(sum, (w)[3 * 64], (p)[3 * 64]); \ + op(sum, (w)[4 * 64], (p)[4 * 64]); \ + op(sum, (w)[5 * 64], (p)[5 * 64]); \ + op(sum, (w)[6 * 64], (p)[6 * 64]); \ + op(sum, (w)[7 * 64], (p)[7 * 64]); \ +} + +static void apply_window(const float *buf, const float *win1, + const float *win2, float *sum1, float *sum2, int len) +{ + x86_reg count = - 4*len; + const float *win1a = win1+len; + const float *win2a = win2+len; + const float *bufa = buf+len; + float *sum1a = sum1+len; + float *sum2a = sum2+len; + + +#define MULT(a, b) \ + "movaps " #a "(%1,%0), %%xmm1 \n\t" \ + "movaps " #a "(%3,%0), %%xmm2 \n\t" \ + "mulps %%xmm2, %%xmm1 \n\t" \ + "subps %%xmm1, %%xmm0 \n\t" \ + "mulps " #b "(%2,%0), %%xmm2 \n\t" \ + "subps %%xmm2, %%xmm4 \n\t" \ + + __asm__ volatile( + "1: \n\t" + "xorps %%xmm0, %%xmm0 \n\t" + "xorps %%xmm4, %%xmm4 \n\t" + + MULT( 0, 0) + MULT( 256, 64) + MULT( 512, 128) + MULT( 768, 192) + MULT(1024, 256) + MULT(1280, 320) + MULT(1536, 384) + MULT(1792, 448) + + "movaps %%xmm0, (%4,%0) \n\t" + "movaps %%xmm4, (%5,%0) \n\t" + "add $16, %0 \n\t" + "jl 1b \n\t" + :"+&r"(count) + :"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a) + ); + +#undef MULT +} + +static void apply_window_mp3(float *in, float *win, int *unused, float *out, + ptrdiff_t incr) +{ + LOCAL_ALIGNED_16(float, suma, [17]); + LOCAL_ALIGNED_16(float, sumb, [17]); + LOCAL_ALIGNED_16(float, sumc, [17]); + LOCAL_ALIGNED_16(float, sumd, [17]); + + float sum; + + /* copy to avoid wrap */ + __asm__ volatile( + "movaps 0(%0), %%xmm0 \n\t" \ + "movaps 16(%0), %%xmm1 \n\t" \ + "movaps 32(%0), %%xmm2 \n\t" \ + "movaps 48(%0), %%xmm3 \n\t" \ + "movaps %%xmm0, 0(%1) \n\t" \ + "movaps %%xmm1, 16(%1) \n\t" \ + "movaps %%xmm2, 32(%1) \n\t" \ + "movaps %%xmm3, 48(%1) \n\t" \ + "movaps 64(%0), %%xmm0 \n\t" \ + "movaps 80(%0), %%xmm1 \n\t" \ + "movaps 96(%0), %%xmm2 \n\t" \ + "movaps 112(%0), %%xmm3 \n\t" \ + "movaps %%xmm0, 64(%1) \n\t" \ + "movaps %%xmm1, 80(%1) \n\t" \ + "movaps %%xmm2, 96(%1) \n\t" \ + "movaps %%xmm3, 112(%1) \n\t" + ::"r"(in), "r"(in+512) + :"memory" + ); + + apply_window(in + 16, win , win + 512, suma, sumc, 16); + apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16); + + SUM8(MACS, suma[0], win + 32, in + 48); + + sumc[ 0] = 0; + sumb[16] = 0; + sumd[16] = 0; + +#define SUMS(suma, sumb, sumc, sumd, out1, out2) \ + "movups " #sumd "(%4), %%xmm0 \n\t" \ + "shufps $0x1b, %%xmm0, %%xmm0 \n\t" \ + "subps " #suma "(%1), %%xmm0 \n\t" \ + "movaps %%xmm0," #out1 "(%0) \n\t" \ +\ + "movups " #sumc "(%3), %%xmm0 \n\t" \ + "shufps $0x1b, %%xmm0, %%xmm0 \n\t" \ + "addps " #sumb "(%2), %%xmm0 \n\t" \ + "movaps %%xmm0," #out2 "(%0) \n\t" + + if (incr == 1) { + __asm__ volatile( + SUMS( 0, 48, 4, 52, 0, 112) + SUMS(16, 32, 20, 36, 16, 96) + SUMS(32, 16, 36, 20, 32, 80) + SUMS(48, 0, 52, 4, 48, 64) + + :"+&r"(out) + :"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0]) + :"memory" + ); + out += 16*incr; + } else { + int j; + float *out2 = out + 32 * incr; + out[0 ] = -suma[ 0]; + out += incr; + out2 -= incr; + for(j=1;j<16;j++) { + *out = -suma[ j] + sumd[16-j]; + *out2 = sumb[16-j] + sumc[ j]; + out += incr; + out2 -= incr; + } + } + + sum = 0; + SUM8(MLSS, sum, win + 16 + 32, in + 32); + *out = sum; +} + +#endif /* HAVE_6REGS && HAVE_SSE_INLINE */ + +#if HAVE_X86ASM +#define DECL_IMDCT_BLOCKS(CPU1, CPU2) \ +static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ + int count, int switch_point, int block_type) \ +{ \ + int align_end = count - (count & 3); \ + int j; \ + for (j = 0; j < align_end; j+= 4) { \ + LOCAL_ALIGNED_16(float, tmpbuf, [1024]); \ + float *win = mdct_win_sse[switch_point && j < 4][block_type]; \ + /* apply window & overlap with previous buffer */ \ + \ + /* select window */ \ + ff_four_imdct36_float_ ## CPU2(out, buf, in, win, tmpbuf); \ + in += 4*18; \ + buf += 4*18; \ + out += 4; \ + } \ + for (; j < count; j++) { \ + /* apply window & overlap with previous buffer */ \ + \ + /* select window */ \ + int win_idx = (switch_point && j < 2) ? 0 : block_type; \ + float *win = ff_mdct_win_float[win_idx + (4 & -(j & 1))]; \ + \ + ff_imdct36_float_ ## CPU1(out, buf, in, win); \ + \ + in += 18; \ + buf++; \ + out++; \ + } \ +} + +#if HAVE_SSE +#if ARCH_X86_32 +DECL_IMDCT_BLOCKS(sse,sse) +#endif +DECL_IMDCT_BLOCKS(sse2,sse) +DECL_IMDCT_BLOCKS(sse3,sse) +DECL_IMDCT_BLOCKS(ssse3,sse) +#endif +#if HAVE_AVX_EXTERNAL +DECL_IMDCT_BLOCKS(avx,avx) +#endif +#endif /* HAVE_X86ASM */ + +av_cold void ff_mpadsp_init_x86_tabs(void) +{ + int i, j; + for (j = 0; j < 4; j++) { + for (i = 0; i < 40; i ++) { + mdct_win_sse[0][j][4*i ] = ff_mdct_win_float[j ][i]; + mdct_win_sse[0][j][4*i + 1] = ff_mdct_win_float[j + 4][i]; + mdct_win_sse[0][j][4*i + 2] = ff_mdct_win_float[j ][i]; + mdct_win_sse[0][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; + mdct_win_sse[1][j][4*i ] = ff_mdct_win_float[0 ][i]; + mdct_win_sse[1][j][4*i + 1] = ff_mdct_win_float[4 ][i]; + mdct_win_sse[1][j][4*i + 2] = ff_mdct_win_float[j ][i]; + mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i]; + } + } +} + +av_cold void ff_mpadsp_init_x86(MPADSPContext *s) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + +#if HAVE_6REGS && HAVE_SSE_INLINE + if (INLINE_SSE(cpu_flags)) { + s->apply_window_float = apply_window_mp3; + } +#endif /* HAVE_SSE_INLINE */ + +#if HAVE_X86ASM +#if HAVE_SSE +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_sse; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_sse2; + } + if (EXTERNAL_SSE3(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_sse3; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_ssse3; + } +#endif +#if HAVE_AVX_EXTERNAL + if (EXTERNAL_AVX(cpu_flags)) { + s->imdct36_blocks_float = imdct36_blocks_avx; + } +#endif +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideo.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideo.c new file mode 100644 index 00000000..73967caf --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideo.c @@ -0,0 +1,469 @@ +/* + * Optimized for ia32 CPUs by Nick Kurshev + * H.263, MPEG-1, MPEG-2 dequantizer & draw_edges by Michael Niedermayer + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/mpegvideo.h" +#include "libavcodec/mpegvideodata.h" + +#if HAVE_MMX_INLINE + +static void dct_unquantize_h263_intra_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg level, qmul, qadd, nCoeffs; + + qmul = qscale << 1; + + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); + + if (!s->h263_aic) { + if (n < 4) + level = block[0] * s->y_dc_scale; + else + level = block[0] * s->c_dc_scale; + qadd = (qscale - 1) | 1; + }else{ + qadd = 0; + level= block[0]; + } + if(s->ac_pred) + nCoeffs=63; + else + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + +__asm__ volatile( + "movd %1, %%mm6 \n\t" //qmul + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "movd %2, %%mm5 \n\t" //qadd + "pxor %%mm7, %%mm7 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "psubw %%mm5, %%mm7 \n\t" + "pxor %%mm4, %%mm4 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %3), %%mm0 \n\t" + "movq 8(%0, %3), %%mm1 \n\t" + + "pmullw %%mm6, %%mm0 \n\t" + "pmullw %%mm6, %%mm1 \n\t" + + "movq (%0, %3), %%mm2 \n\t" + "movq 8(%0, %3), %%mm3 \n\t" + + "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + + "paddw %%mm7, %%mm0 \n\t" + "paddw %%mm7, %%mm1 \n\t" + + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + + "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 + + "pandn %%mm2, %%mm0 \n\t" + "pandn %%mm3, %%mm1 \n\t" + + "movq %%mm0, (%0, %3) \n\t" + "movq %%mm1, 8(%0, %3) \n\t" + + "add $16, %3 \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "rm"(qmul), "rm" (qadd), "r" (2*(-nCoeffs)) + : "memory" + ); + block[0]= level; +} + + +static void dct_unquantize_h263_inter_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg qmul, qadd, nCoeffs; + + qmul = qscale << 1; + qadd = (qscale - 1) | 1; + + av_assert2(s->block_last_index[n]>=0 || s->h263_aic); + + nCoeffs= s->inter_scantable.raster_end[ s->block_last_index[n] ]; + +__asm__ volatile( + "movd %1, %%mm6 \n\t" //qmul + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "movd %2, %%mm5 \n\t" //qadd + "pxor %%mm7, %%mm7 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "packssdw %%mm5, %%mm5 \n\t" + "psubw %%mm5, %%mm7 \n\t" + "pxor %%mm4, %%mm4 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %3), %%mm0 \n\t" + "movq 8(%0, %3), %%mm1 \n\t" + + "pmullw %%mm6, %%mm0 \n\t" + "pmullw %%mm6, %%mm1 \n\t" + + "movq (%0, %3), %%mm2 \n\t" + "movq 8(%0, %3), %%mm3 \n\t" + + "pcmpgtw %%mm4, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm4, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + + "paddw %%mm7, %%mm0 \n\t" + "paddw %%mm7, %%mm1 \n\t" + + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + + "pcmpeqw %%mm7, %%mm0 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw %%mm7, %%mm1 \n\t" // block[i] == 0 ? -1 : 0 + + "pandn %%mm2, %%mm0 \n\t" + "pandn %%mm3, %%mm1 \n\t" + + "movq %%mm0, (%0, %3) \n\t" + "movq %%mm1, 8(%0, %3) \n\t" + + "add $16, %3 \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "rm"(qmul), "rm" (qadd), "r" (2*(-nCoeffs)) + : "memory" + ); +} + +static void dct_unquantize_mpeg1_intra_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + int block0; + + av_assert2(s->block_last_index[n]>=0); + + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1; + + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + /* XXX: only MPEG-1 */ + quant_matrix = s->intra_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $3, %%mm0 \n\t" + "psraw $3, %%mm1 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm1 \n\t" + "por %%mm7, %%mm0 \n\t" + "por %%mm7, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "js 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "g" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); + block[0]= block0; +} + +static void dct_unquantize_mpeg1_inter_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + + av_assert2(s->block_last_index[n]>=0); + + nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]+1; + + quant_matrix = s->inter_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2 + "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2 + "paddw %%mm7, %%mm0 \n\t" // abs(block[i])*2 + 1 + "paddw %%mm7, %%mm1 \n\t" // abs(block[i])*2 + 1 + "pmullw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q + "pmullw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $4, %%mm0 \n\t" + "psraw $4, %%mm1 \n\t" + "psubw %%mm7, %%mm0 \n\t" + "psubw %%mm7, %%mm1 \n\t" + "por %%mm7, %%mm0 \n\t" + "por %%mm7, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "js 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "g" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); +} + +static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + int block0; + + av_assert2(s->block_last_index[n]>=0); + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; //FIXME + else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + quant_matrix = s->intra_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlw $15, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psraw $4, %%mm0 \n\t" + "psraw $4, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "jng 1b \n\t" + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "g" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); + block[0]= block0; + //Note, we do not do mismatch control for intra as errors cannot accumulate +} + +static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s, + int16_t *block, int n, int qscale) +{ + x86_reg nCoeffs; + const uint16_t *quant_matrix; + + av_assert2(s->block_last_index[n]>=0); + + if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale]; + else qscale <<= 1; + + if(s->alternate_scan) nCoeffs= 63; //FIXME + else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ]; + + quant_matrix = s->inter_matrix; +__asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "psrlq $48, %%mm7 \n\t" + "movd %2, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "packssdw %%mm6, %%mm6 \n\t" + "mov %3, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%0, %%"FF_REG_a"), %%mm0 \n\t" + "movq 8(%0, %%"FF_REG_a"), %%mm1\n\t" + "movq (%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq 8(%1, %%"FF_REG_a"), %%mm5\n\t" + "pmullw %%mm6, %%mm4 \n\t" // q=qscale*quant_matrix[i] + "pmullw %%mm6, %%mm5 \n\t" // q=qscale*quant_matrix[i] + "pxor %%mm2, %%mm2 \n\t" + "pxor %%mm3, %%mm3 \n\t" + "pcmpgtw %%mm0, %%mm2 \n\t" // block[i] < 0 ? -1 : 0 + "pcmpgtw %%mm1, %%mm3 \n\t" // block[i] < 0 ? -1 : 0 + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" // abs(block[i]) + "psubw %%mm3, %%mm1 \n\t" // abs(block[i]) + "paddw %%mm0, %%mm0 \n\t" // abs(block[i])*2 + "paddw %%mm1, %%mm1 \n\t" // abs(block[i])*2 + "pmullw %%mm4, %%mm0 \n\t" // abs(block[i])*2*q + "pmullw %%mm5, %%mm1 \n\t" // abs(block[i])*2*q + "paddw %%mm4, %%mm0 \n\t" // (abs(block[i])*2 + 1)*q + "paddw %%mm5, %%mm1 \n\t" // (abs(block[i])*2 + 1)*q + "pxor %%mm4, %%mm4 \n\t" + "pxor %%mm5, %%mm5 \n\t" // FIXME slow + "pcmpeqw (%0, %%"FF_REG_a"), %%mm4 \n\t" // block[i] == 0 ? -1 : 0 + "pcmpeqw 8(%0, %%"FF_REG_a"), %%mm5\n\t" // block[i] == 0 ? -1 : 0 + "psrlw $5, %%mm0 \n\t" + "psrlw $5, %%mm1 \n\t" + "pxor %%mm2, %%mm0 \n\t" + "pxor %%mm3, %%mm1 \n\t" + "psubw %%mm2, %%mm0 \n\t" + "psubw %%mm3, %%mm1 \n\t" + "pandn %%mm0, %%mm4 \n\t" + "pandn %%mm1, %%mm5 \n\t" + "pxor %%mm4, %%mm7 \n\t" + "pxor %%mm5, %%mm7 \n\t" + "movq %%mm4, (%0, %%"FF_REG_a") \n\t" + "movq %%mm5, 8(%0, %%"FF_REG_a")\n\t" + + "add $16, %%"FF_REG_a" \n\t" + "jng 1b \n\t" + "movd 124(%0, %3), %%mm0 \n\t" + "movq %%mm7, %%mm6 \n\t" + "psrlq $32, %%mm7 \n\t" + "pxor %%mm6, %%mm7 \n\t" + "movq %%mm7, %%mm6 \n\t" + "psrlq $16, %%mm7 \n\t" + "pxor %%mm6, %%mm7 \n\t" + "pslld $31, %%mm7 \n\t" + "psrlq $15, %%mm7 \n\t" + "pxor %%mm7, %%mm0 \n\t" + "movd %%mm0, 124(%0, %3) \n\t" + + ::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "rm" (qscale), "r" (-2*nCoeffs) + : "%"FF_REG_a, "memory" + ); +} + +#endif /* HAVE_MMX_INLINE */ + +av_cold void ff_mpv_common_init_x86(MpegEncContext *s) +{ +#if HAVE_MMX_INLINE + int cpu_flags = av_get_cpu_flags(); + + if (INLINE_MMX(cpu_flags)) { + s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_mmx; + s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_mmx; + s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_mmx; + s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_mmx; + if (!(s->avctx->flags & AV_CODEC_FLAG_BITEXACT)) + s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_mmx; + s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_mmx; + } +#endif /* HAVE_MMX_INLINE */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideodsp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideodsp.c new file mode 100644 index 00000000..6009b64e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideodsp.c @@ -0,0 +1,161 @@ +/* + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/mpegvideodsp.h" +#include "libavcodec/videodsp.h" + +#if HAVE_INLINE_ASM + +static void gmc_mmx(uint8_t *dst, uint8_t *src, + int stride, int h, int ox, int oy, + int dxx, int dxy, int dyx, int dyy, + int shift, int r, int width, int height) +{ + const int w = 8; + const int ix = ox >> (16 + shift); + const int iy = oy >> (16 + shift); + const int oxs = ox >> 4; + const int oys = oy >> 4; + const int dxxs = dxx >> 4; + const int dxys = dxy >> 4; + const int dyxs = dyx >> 4; + const int dyys = dyy >> 4; + const uint16_t r4[4] = { r, r, r, r }; + const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys }; + const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys }; + const uint64_t shift2 = 2 * shift; +#define MAX_STRIDE 4096U +#define MAX_H 8U + uint8_t edge_buf[(MAX_H + 1) * MAX_STRIDE]; + int x, y; + + const int dxw = (dxx - (1 << (16 + shift))) * (w - 1); + const int dyh = (dyy - (1 << (16 + shift))) * (h - 1); + const int dxh = dxy * (h - 1); + const int dyw = dyx * (w - 1); + int need_emu = (unsigned) ix >= width - w || width < w || + (unsigned) iy >= height - h || height< h + ; + + if ( // non-constant fullpel offset (3% of blocks) + ((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) | + (oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift) || + // uses more than 16 bits of subpel mv (only at huge resolution) + (dxx | dxy | dyx | dyy) & 15 || + (need_emu && (h > MAX_H || stride > MAX_STRIDE))) { + // FIXME could still use mmx for some of the rows + ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, + shift, r, width, height); + return; + } + + src += ix + iy * stride; + if (need_emu) { + ff_emulated_edge_mc_8(edge_buf, src, stride, stride, w + 1, h + 1, ix, iy, width, height); + src = edge_buf; + } + + __asm__ volatile ( + "movd %0, %%mm6 \n\t" + "pxor %%mm7, %%mm7 \n\t" + "punpcklwd %%mm6, %%mm6 \n\t" + "punpcklwd %%mm6, %%mm6 \n\t" + :: "r" (1 << shift)); + + for (x = 0; x < w; x += 4) { + uint16_t dx4[4] = { oxs - dxys + dxxs * (x + 0), + oxs - dxys + dxxs * (x + 1), + oxs - dxys + dxxs * (x + 2), + oxs - dxys + dxxs * (x + 3) }; + uint16_t dy4[4] = { oys - dyys + dyxs * (x + 0), + oys - dyys + dyxs * (x + 1), + oys - dyys + dyxs * (x + 2), + oys - dyys + dyxs * (x + 3) }; + + for (y = 0; y < h; y++) { + __asm__ volatile ( + "movq %0, %%mm4 \n\t" + "movq %1, %%mm5 \n\t" + "paddw %2, %%mm4 \n\t" + "paddw %3, %%mm5 \n\t" + "movq %%mm4, %0 \n\t" + "movq %%mm5, %1 \n\t" + "psrlw $12, %%mm4 \n\t" + "psrlw $12, %%mm5 \n\t" + : "+m" (*dx4), "+m" (*dy4) + : "m" (*dxy4), "m" (*dyy4)); + + __asm__ volatile ( + "movq %%mm6, %%mm2 \n\t" + "movq %%mm6, %%mm1 \n\t" + "psubw %%mm4, %%mm2 \n\t" + "psubw %%mm5, %%mm1 \n\t" + "movq %%mm2, %%mm0 \n\t" + "movq %%mm4, %%mm3 \n\t" + "pmullw %%mm1, %%mm0 \n\t" // (s - dx) * (s - dy) + "pmullw %%mm5, %%mm3 \n\t" // dx * dy + "pmullw %%mm5, %%mm2 \n\t" // (s - dx) * dy + "pmullw %%mm4, %%mm1 \n\t" // dx * (s - dy) + + "movd %4, %%mm5 \n\t" + "movd %3, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "pmullw %%mm5, %%mm3 \n\t" // src[1, 1] * dx * dy + "pmullw %%mm4, %%mm2 \n\t" // src[0, 1] * (s - dx) * dy + + "movd %2, %%mm5 \n\t" + "movd %1, %%mm4 \n\t" + "punpcklbw %%mm7, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "pmullw %%mm5, %%mm1 \n\t" // src[1, 0] * dx * (s - dy) + "pmullw %%mm4, %%mm0 \n\t" // src[0, 0] * (s - dx) * (s - dy) + "paddw %5, %%mm1 \n\t" + "paddw %%mm3, %%mm2 \n\t" + "paddw %%mm1, %%mm0 \n\t" + "paddw %%mm2, %%mm0 \n\t" + + "psrlw %6, %%mm0 \n\t" + "packuswb %%mm0, %%mm0 \n\t" + "movd %%mm0, %0 \n\t" + + : "=m" (dst[x + y * stride]) + : "m" (src[0]), "m" (src[1]), + "m" (src[stride]), "m" (src[stride + 1]), + "m" (*r4), "m" (shift2)); + src += stride; + } + src += 4 - h * stride; + } +} + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_mpegvideodsp_init_x86(MpegVideoDSPContext *c) +{ +#if HAVE_INLINE_ASM + int cpu_flags = av_get_cpu_flags(); + + if (INLINE_MMX(cpu_flags)) + c->gmc = gmc_mmx; +#endif /* HAVE_INLINE_ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc.c new file mode 100644 index 00000000..4bad6a87 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc.c @@ -0,0 +1,245 @@ +/* + * The simplest mpeg encoder (well, it was the simplest!) + * Copyright (c) 2000,2001 Fabrice Bellard + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/dct.h" +#include "libavcodec/mpegvideo.h" + +/* not permutated inverse zigzag_direct + 1 for MMX quantizer */ +DECLARE_ALIGNED(16, static const uint16_t, inv_zigzag_direct16)[64] = { + 1, 2, 6, 7, 15, 16, 28, 29, + 3, 5, 8, 14, 17, 27, 30, 43, + 4, 9, 13, 18, 26, 31, 42, 44, + 10, 12, 19, 25, 32, 41, 45, 54, + 11, 20, 24, 33, 40, 46, 53, 55, + 21, 23, 34, 39, 47, 52, 56, 61, + 22, 35, 38, 48, 51, 57, 60, 62, + 36, 37, 49, 50, 58, 59, 63, 64, +}; + +#if HAVE_6REGS + +#if HAVE_MMX_INLINE +#define COMPILE_TEMPLATE_MMXEXT 0 +#define COMPILE_TEMPLATE_SSE2 0 +#define COMPILE_TEMPLATE_SSSE3 0 +#define RENAME(a) a ## _mmx +#define RENAME_FDCT(a) a ## _mmx +#include "mpegvideoenc_template.c" +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_MMXEXT_INLINE +#undef COMPILE_TEMPLATE_SSSE3 +#undef COMPILE_TEMPLATE_SSE2 +#undef COMPILE_TEMPLATE_MMXEXT +#define COMPILE_TEMPLATE_MMXEXT 1 +#define COMPILE_TEMPLATE_SSE2 0 +#define COMPILE_TEMPLATE_SSSE3 0 +#undef RENAME +#undef RENAME_FDCT +#define RENAME(a) a ## _mmxext +#define RENAME_FDCT(a) a ## _mmxext +#include "mpegvideoenc_template.c" +#endif /* HAVE_MMXEXT_INLINE */ + +#if HAVE_SSE2_INLINE +#undef COMPILE_TEMPLATE_MMXEXT +#undef COMPILE_TEMPLATE_SSE2 +#undef COMPILE_TEMPLATE_SSSE3 +#define COMPILE_TEMPLATE_MMXEXT 0 +#define COMPILE_TEMPLATE_SSE2 1 +#define COMPILE_TEMPLATE_SSSE3 0 +#undef RENAME +#undef RENAME_FDCT +#define RENAME(a) a ## _sse2 +#define RENAME_FDCT(a) a ## _sse2 +#include "mpegvideoenc_template.c" +#endif /* HAVE_SSE2_INLINE */ + +#if HAVE_SSSE3_INLINE +#undef COMPILE_TEMPLATE_MMXEXT +#undef COMPILE_TEMPLATE_SSE2 +#undef COMPILE_TEMPLATE_SSSE3 +#define COMPILE_TEMPLATE_MMXEXT 0 +#define COMPILE_TEMPLATE_SSE2 1 +#define COMPILE_TEMPLATE_SSSE3 1 +#undef RENAME +#undef RENAME_FDCT +#define RENAME(a) a ## _ssse3 +#define RENAME_FDCT(a) a ## _sse2 +#include "mpegvideoenc_template.c" +#endif /* HAVE_SSSE3_INLINE */ + +#endif /* HAVE_6REGS */ + +#if HAVE_INLINE_ASM +#if HAVE_MMX_INLINE +static void denoise_dct_mmx(MpegEncContext *s, int16_t *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + __asm__ volatile( + "pxor %%mm7, %%mm7 \n\t" + "1: \n\t" + "pxor %%mm0, %%mm0 \n\t" + "pxor %%mm1, %%mm1 \n\t" + "movq (%0), %%mm2 \n\t" + "movq 8(%0), %%mm3 \n\t" + "pcmpgtw %%mm2, %%mm0 \n\t" + "pcmpgtw %%mm3, %%mm1 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, %%mm4 \n\t" + "movq %%mm3, %%mm5 \n\t" + "psubusw (%2), %%mm2 \n\t" + "psubusw 8(%2), %%mm3 \n\t" + "pxor %%mm0, %%mm2 \n\t" + "pxor %%mm1, %%mm3 \n\t" + "psubw %%mm0, %%mm2 \n\t" + "psubw %%mm1, %%mm3 \n\t" + "movq %%mm2, (%0) \n\t" + "movq %%mm3, 8(%0) \n\t" + "movq %%mm4, %%mm2 \n\t" + "movq %%mm5, %%mm3 \n\t" + "punpcklwd %%mm7, %%mm4 \n\t" + "punpckhwd %%mm7, %%mm2 \n\t" + "punpcklwd %%mm7, %%mm5 \n\t" + "punpckhwd %%mm7, %%mm3 \n\t" + "paddd (%1), %%mm4 \n\t" + "paddd 8(%1), %%mm2 \n\t" + "paddd 16(%1), %%mm5 \n\t" + "paddd 24(%1), %%mm3 \n\t" + "movq %%mm4, (%1) \n\t" + "movq %%mm2, 8(%1) \n\t" + "movq %%mm5, 16(%1) \n\t" + "movq %%mm3, 24(%1) \n\t" + "add $16, %0 \n\t" + "add $32, %1 \n\t" + "add $16, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + ); +} +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_SSE2_INLINE +static void denoise_dct_sse2(MpegEncContext *s, int16_t *block){ + const int intra= s->mb_intra; + int *sum= s->dct_error_sum[intra]; + uint16_t *offset= s->dct_offset[intra]; + + s->dct_count[intra]++; + + __asm__ volatile( + "pxor %%xmm7, %%xmm7 \n\t" + "1: \n\t" + "pxor %%xmm0, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm1 \n\t" + "movdqa (%0), %%xmm2 \n\t" + "movdqa 16(%0), %%xmm3 \n\t" + "pcmpgtw %%xmm2, %%xmm0 \n\t" + "pcmpgtw %%xmm3, %%xmm1 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, %%xmm4 \n\t" + "movdqa %%xmm3, %%xmm5 \n\t" + "psubusw (%2), %%xmm2 \n\t" + "psubusw 16(%2), %%xmm3 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm3 \n\t" + "psubw %%xmm0, %%xmm2 \n\t" + "psubw %%xmm1, %%xmm3 \n\t" + "movdqa %%xmm2, (%0) \n\t" + "movdqa %%xmm3, 16(%0) \n\t" + "movdqa %%xmm4, %%xmm6 \n\t" + "movdqa %%xmm5, %%xmm0 \n\t" + "punpcklwd %%xmm7, %%xmm4 \n\t" + "punpckhwd %%xmm7, %%xmm6 \n\t" + "punpcklwd %%xmm7, %%xmm5 \n\t" + "punpckhwd %%xmm7, %%xmm0 \n\t" + "paddd (%1), %%xmm4 \n\t" + "paddd 16(%1), %%xmm6 \n\t" + "paddd 32(%1), %%xmm5 \n\t" + "paddd 48(%1), %%xmm0 \n\t" + "movdqa %%xmm4, (%1) \n\t" + "movdqa %%xmm6, 16(%1) \n\t" + "movdqa %%xmm5, 32(%1) \n\t" + "movdqa %%xmm0, 48(%1) \n\t" + "add $32, %0 \n\t" + "add $64, %1 \n\t" + "add $32, %2 \n\t" + "cmp %3, %0 \n\t" + " jb 1b \n\t" + : "+r" (block), "+r" (sum), "+r" (offset) + : "r"(block+64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); +} +#endif /* HAVE_SSE2_INLINE */ +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_dct_encode_init_x86(MpegEncContext *s) +{ + const int dct_algo = s->avctx->dct_algo; + + if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) { +#if HAVE_MMX_INLINE + int cpu_flags = av_get_cpu_flags(); + if (INLINE_MMX(cpu_flags)) { +#if HAVE_6REGS + s->dct_quantize = dct_quantize_mmx; +#endif + s->denoise_dct = denoise_dct_mmx; + } +#endif +#if HAVE_6REGS && HAVE_MMXEXT_INLINE + if (INLINE_MMXEXT(cpu_flags)) + s->dct_quantize = dct_quantize_mmxext; +#endif +#if HAVE_SSE2_INLINE + if (INLINE_SSE2(cpu_flags)) { +#if HAVE_6REGS + s->dct_quantize = dct_quantize_sse2; +#endif + s->denoise_dct = denoise_dct_sse2; + } +#endif +#if HAVE_6REGS && HAVE_SSSE3_INLINE + if (INLINE_SSSE3(cpu_flags)) + s->dct_quantize = dct_quantize_ssse3; +#endif + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc_qns_template.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc_qns_template.c new file mode 100644 index 00000000..882d4862 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc_qns_template.c @@ -0,0 +1,109 @@ +/* + * QNS functions are compiled 3 times for MMX/3DNOW/SSSE3 + * Copyright (c) 2004 Michael Niedermayer + * + * MMX optimization by Michael Niedermayer + * 3DNow! and SSSE3 optimization by Zuxy Meng + * + * 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 + +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/x86/asm.h" + +#include "inline_asm.h" + +#define MAX_ABS (512 >> (SCALE_OFFSET>0 ? SCALE_OFFSET : 0)) + +static int DEF(try_8x8basis)(int16_t rem[64], int16_t weight[64], int16_t basis[64], int scale) +{ + x86_reg i=0; + + av_assert2(FFABS(scale) < MAX_ABS); + scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; + + SET_RND(mm6); + __asm__ volatile( + "pxor %%mm7, %%mm7 \n\t" + "movd %4, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) + "paddw (%2, %0), %%mm0 \n\t" + "paddw 8(%2, %0), %%mm1 \n\t" + "psraw $6, %%mm0 \n\t" + "psraw $6, %%mm1 \n\t" + "pmullw (%3, %0), %%mm0 \n\t" + "pmullw 8(%3, %0), %%mm1 \n\t" + "pmaddwd %%mm0, %%mm0 \n\t" + "pmaddwd %%mm1, %%mm1 \n\t" + "paddd %%mm1, %%mm0 \n\t" + "psrld $4, %%mm0 \n\t" + "paddd %%mm0, %%mm7 \n\t" + "add $16, %0 \n\t" + "cmp $128, %0 \n\t" //FIXME optimize & bench + " jb 1b \n\t" + PHADDD(%%mm7, %%mm6) + "psrld $2, %%mm7 \n\t" + "movd %%mm7, %0 \n\t" + + : "+r" (i) + : "r"(basis), "r"(rem), "r"(weight), "g"(scale) + ); + return i; +} + +static void DEF(add_8x8basis)(int16_t rem[64], int16_t basis[64], int scale) +{ + x86_reg i=0; + + if(FFABS(scale) < MAX_ABS){ + scale<<= 16 + SCALE_OFFSET - BASIS_SHIFT + RECON_SHIFT; + SET_RND(mm6); + __asm__ volatile( + "movd %3, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + "punpcklwd %%mm5, %%mm5 \n\t" + ".p2align 4 \n\t" + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq 8(%1, %0), %%mm1 \n\t" + PMULHRW(%%mm0, %%mm1, %%mm5, %%mm6) + "paddw (%2, %0), %%mm0 \n\t" + "paddw 8(%2, %0), %%mm1 \n\t" + "movq %%mm0, (%2, %0) \n\t" + "movq %%mm1, 8(%2, %0) \n\t" + "add $16, %0 \n\t" + "cmp $128, %0 \n\t" // FIXME optimize & bench + " jb 1b \n\t" + + : "+r" (i) + : "r"(basis), "r"(rem), "g"(scale) + ); + }else{ + for(i=0; i<8*8; i++){ + rem[i] += (basis[i]*scale + (1<<(BASIS_SHIFT - RECON_SHIFT-1)))>>(BASIS_SHIFT - RECON_SHIFT); + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc_template.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc_template.c new file mode 100644 index 00000000..b32b1b03 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoenc_template.c @@ -0,0 +1,424 @@ +/* + * MPEG video MMX templates + * + * Copyright (c) 2002 Michael Niedermayer + * + * 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 + +#include "libavutil/internal.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavcodec/mpegutils.h" +#include "libavcodec/mpegvideo.h" +#include "fdct.h" + +#undef MMREG_WIDTH +#undef MM +#undef MOVQ +#undef SPREADW +#undef PMAXW +#undef PMAX +#undef SAVE_SIGN +#undef RESTORE_SIGN + +#if COMPILE_TEMPLATE_SSE2 +#define MMREG_WIDTH "16" +#define MM "%%xmm" +#define MOVQ "movdqa" +#define SPREADW(a) \ + "pshuflw $0, "a", "a" \n\t"\ + "punpcklwd "a", "a" \n\t" +#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" +#define PMAX(a,b) \ + "movhlps "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshuflw $0x0E, "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshuflw $0x01, "a", "b" \n\t"\ + PMAXW(b, a) +#else +#define MMREG_WIDTH "8" +#define MM "%%mm" +#define MOVQ "movq" +#if COMPILE_TEMPLATE_MMXEXT +#define SPREADW(a) "pshufw $0, "a", "a" \n\t" +#define PMAXW(a,b) "pmaxsw "a", "b" \n\t" +#define PMAX(a,b) \ + "pshufw $0x0E, "a", "b" \n\t"\ + PMAXW(b, a)\ + "pshufw $0x01, "a", "b" \n\t"\ + PMAXW(b, a) +#else +#define SPREADW(a) \ + "punpcklwd "a", "a" \n\t"\ + "punpcklwd "a", "a" \n\t" +#define PMAXW(a,b) \ + "psubusw "a", "b" \n\t"\ + "paddw "a", "b" \n\t" +#define PMAX(a,b) \ + "movq "a", "b" \n\t"\ + "psrlq $32, "a" \n\t"\ + PMAXW(b, a)\ + "movq "a", "b" \n\t"\ + "psrlq $16, "a" \n\t"\ + PMAXW(b, a) + +#endif +#endif + +#if COMPILE_TEMPLATE_SSSE3 +#define SAVE_SIGN(a,b) \ + "movdqa "b", "a" \n\t"\ + "pabsw "b", "b" \n\t" +#define RESTORE_SIGN(a,b) \ + "psignw "a", "b" \n\t" +#else +#define SAVE_SIGN(a,b) \ + "pxor "a", "a" \n\t"\ + "pcmpgtw "b", "a" \n\t" /* block[i] <= 0 ? 0xFF : 0x00 */\ + "pxor "a", "b" \n\t"\ + "psubw "a", "b" \n\t" /* ABS(block[i]) */ +#define RESTORE_SIGN(a,b) \ + "pxor "a", "b" \n\t"\ + "psubw "a", "b" \n\t" // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) +#endif + +static int RENAME(dct_quantize)(MpegEncContext *s, + int16_t *block, int n, + int qscale, int *overflow) +{ + x86_reg last_non_zero_p1; + int level=0, q; //=0 is because gcc says uninitialized ... + const uint16_t *qmat, *bias; + LOCAL_ALIGNED_16(int16_t, temp_block, [64]); + + av_assert2((7&(int)(&temp_block[0])) == 0); //did gcc align it correctly? + + //s->fdct (block); + RENAME_FDCT(ff_fdct)(block); // cannot be anything else ... + + if(s->dct_error_sum) + s->denoise_dct(s, block); + + if (s->mb_intra) { + int dummy; + if (n < 4){ + q = s->y_dc_scale; + bias = s->q_intra_matrix16[qscale][1]; + qmat = s->q_intra_matrix16[qscale][0]; + }else{ + q = s->c_dc_scale; + bias = s->q_chroma_intra_matrix16[qscale][1]; + qmat = s->q_chroma_intra_matrix16[qscale][0]; + } + /* note: block[0] is assumed to be positive */ + if (!s->h263_aic) { + __asm__ volatile ( + "mul %%ecx \n\t" + : "=d" (level), "=a"(dummy) + : "a" ((block[0]>>2) + q), "c" (ff_inverse[q<<1]) + ); + } else + /* For AIC we skip quant/dequant of INTRADC */ + level = (block[0] + 4)>>3; + + block[0]=0; //avoid fake overflow +// temp_block[0] = (block[0] + (q >> 1)) / q; + last_non_zero_p1 = 1; + } else { + last_non_zero_p1 = 0; + bias = s->q_inter_matrix16[qscale][1]; + qmat = s->q_inter_matrix16[qscale][0]; + } + + if((s->out_format == FMT_H263 || s->out_format == FMT_H261) && s->mpeg_quant==0){ + + __asm__ volatile( + "movd %%"FF_REG_a", "MM"3 \n\t" // last_non_zero_p1 + SPREADW(MM"3") + "pxor "MM"7, "MM"7 \n\t" // 0 + "pxor "MM"4, "MM"4 \n\t" // 0 + MOVQ" (%2), "MM"5 \n\t" // qmat[0] + "pxor "MM"6, "MM"6 \n\t" + "psubw (%3), "MM"6 \n\t" // -bias[0] + "mov $-128, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + MOVQ" (%1, %%"FF_REG_a"), "MM"0 \n\t" // block[i] + SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) + "psubusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] + "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16 + "por "MM"0, "MM"4 \n\t" + RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + MOVQ" "MM"0, (%5, %%"FF_REG_a") \n\t" + "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 + MOVQ" (%4, %%"FF_REG_a"), "MM"1 \n\t" + MOVQ" "MM"7, (%1, %%"FF_REG_a") \n\t" // 0 + "pandn "MM"1, "MM"0 \n\t" + PMAXW(MM"0", MM"3") + "add $"MMREG_WIDTH", %%"FF_REG_a" \n\t" + " js 1b \n\t" + PMAX(MM"3", MM"0") + "movd "MM"3, %%"FF_REG_a" \n\t" + "movzbl %%al, %%eax \n\t" // last_non_zero_p1 + : "+a" (last_non_zero_p1) + : "r" (block+64), "r" (qmat), "r" (bias), + "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); + }else{ // FMT_H263 + __asm__ volatile( + "movd %%"FF_REG_a", "MM"3 \n\t" // last_non_zero_p1 + SPREADW(MM"3") + "pxor "MM"7, "MM"7 \n\t" // 0 + "pxor "MM"4, "MM"4 \n\t" // 0 + "mov $-128, %%"FF_REG_a" \n\t" + ".p2align 4 \n\t" + "1: \n\t" + MOVQ" (%1, %%"FF_REG_a"), "MM"0 \n\t" // block[i] + SAVE_SIGN(MM"1", MM"0") // ABS(block[i]) + MOVQ" (%3, %%"FF_REG_a"), "MM"6 \n\t" // bias[0] + "paddusw "MM"6, "MM"0 \n\t" // ABS(block[i]) + bias[0] + MOVQ" (%2, %%"FF_REG_a"), "MM"5 \n\t" // qmat[i] + "pmulhw "MM"5, "MM"0 \n\t" // (ABS(block[i])*qmat[0] + bias[0]*qmat[0])>>16 + "por "MM"0, "MM"4 \n\t" + RESTORE_SIGN(MM"1", MM"0") // out=((ABS(block[i])*qmat[0] - bias[0]*qmat[0])>>16)*sign(block[i]) + MOVQ" "MM"0, (%5, %%"FF_REG_a") \n\t" + "pcmpeqw "MM"7, "MM"0 \n\t" // out==0 ? 0xFF : 0x00 + MOVQ" (%4, %%"FF_REG_a"), "MM"1 \n\t" + MOVQ" "MM"7, (%1, %%"FF_REG_a") \n\t" // 0 + "pandn "MM"1, "MM"0 \n\t" + PMAXW(MM"0", MM"3") + "add $"MMREG_WIDTH", %%"FF_REG_a" \n\t" + " js 1b \n\t" + PMAX(MM"3", MM"0") + "movd "MM"3, %%"FF_REG_a" \n\t" + "movzbl %%al, %%eax \n\t" // last_non_zero_p1 + : "+a" (last_non_zero_p1) + : "r" (block+64), "r" (qmat+64), "r" (bias+64), + "r" (inv_zigzag_direct16 + 64), "r" (temp_block + 64) + XMM_CLOBBERS_ONLY("%xmm0", "%xmm1", "%xmm2", "%xmm3", + "%xmm4", "%xmm5", "%xmm6", "%xmm7") + ); + } + __asm__ volatile( + "movd %1, "MM"1 \n\t" // max_qcoeff + SPREADW(MM"1") + "psubusw "MM"1, "MM"4 \n\t" + "packuswb "MM"4, "MM"4 \n\t" +#if COMPILE_TEMPLATE_SSE2 + "packsswb "MM"4, "MM"4 \n\t" +#endif + "movd "MM"4, %0 \n\t" // *overflow + : "=g" (*overflow) + : "g" (s->max_qcoeff) + ); + + if(s->mb_intra) block[0]= level; + else block[0]= temp_block[0]; + + if (s->idsp.perm_type == FF_IDCT_PERM_SIMPLE) { + if(last_non_zero_p1 <= 1) goto end; + block[0x08] = temp_block[0x01]; block[0x10] = temp_block[0x08]; + block[0x20] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x18] = temp_block[0x09]; block[0x04] = temp_block[0x02]; + block[0x09] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x14] = temp_block[0x0A]; block[0x28] = temp_block[0x11]; + block[0x12] = temp_block[0x18]; block[0x02] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x1A] = temp_block[0x19]; block[0x24] = temp_block[0x12]; + block[0x19] = temp_block[0x0B]; block[0x01] = temp_block[0x04]; + block[0x0C] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x11] = temp_block[0x0C]; block[0x29] = temp_block[0x13]; + block[0x16] = temp_block[0x1A]; block[0x0A] = temp_block[0x21]; + block[0x30] = temp_block[0x28]; block[0x22] = temp_block[0x30]; + block[0x38] = temp_block[0x29]; block[0x06] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x21] = temp_block[0x14]; + block[0x1C] = temp_block[0x0D]; block[0x05] = temp_block[0x06]; + block[0x0D] = temp_block[0x07]; block[0x15] = temp_block[0x0E]; + block[0x2C] = temp_block[0x15]; block[0x13] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x0B] = temp_block[0x23]; block[0x34] = temp_block[0x2A]; + block[0x2A] = temp_block[0x31]; block[0x32] = temp_block[0x38]; + block[0x3A] = temp_block[0x39]; block[0x26] = temp_block[0x32]; + block[0x39] = temp_block[0x2B]; block[0x03] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1E] = temp_block[0x1D]; block[0x25] = temp_block[0x16]; + block[0x1D] = temp_block[0x0F]; block[0x2D] = temp_block[0x17]; + block[0x17] = temp_block[0x1E]; block[0x0E] = temp_block[0x25]; + block[0x31] = temp_block[0x2C]; block[0x2B] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x36] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B]; + block[0x23] = temp_block[0x34]; block[0x3C] = temp_block[0x2D]; + block[0x07] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x0F] = temp_block[0x27]; block[0x35] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x2E] = temp_block[0x35]; block[0x33] = temp_block[0x3C]; + block[0x3E] = temp_block[0x3D]; block[0x27] = temp_block[0x36]; + block[0x3D] = temp_block[0x2F]; block[0x2F] = temp_block[0x37]; + block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + }else if(s->idsp.perm_type == FF_IDCT_PERM_LIBMPEG2){ + if(last_non_zero_p1 <= 1) goto end; + block[0x04] = temp_block[0x01]; + block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x0C] = temp_block[0x09]; block[0x01] = temp_block[0x02]; + block[0x05] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x09] = temp_block[0x0A]; block[0x14] = temp_block[0x11]; + block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x1C] = temp_block[0x19]; + block[0x11] = temp_block[0x12]; block[0x0D] = temp_block[0x0B]; + block[0x02] = temp_block[0x04]; block[0x06] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x0A] = temp_block[0x0C]; block[0x15] = temp_block[0x13]; + block[0x19] = temp_block[0x1A]; block[0x24] = temp_block[0x21]; + block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30]; + block[0x2C] = temp_block[0x29]; block[0x21] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1D] = temp_block[0x1B]; block[0x12] = temp_block[0x14]; + block[0x0E] = temp_block[0x0D]; block[0x03] = temp_block[0x06]; + block[0x07] = temp_block[0x07]; block[0x0B] = temp_block[0x0E]; + block[0x16] = temp_block[0x15]; block[0x1A] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x25] = temp_block[0x23]; block[0x29] = temp_block[0x2A]; + block[0x34] = temp_block[0x31]; block[0x38] = temp_block[0x38]; + block[0x3C] = temp_block[0x39]; block[0x31] = temp_block[0x32]; + block[0x2D] = temp_block[0x2B]; block[0x22] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1E] = temp_block[0x1D]; block[0x13] = temp_block[0x16]; + block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17]; + block[0x1B] = temp_block[0x1E]; block[0x26] = temp_block[0x25]; + block[0x2A] = temp_block[0x2C]; block[0x35] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x39] = temp_block[0x3A]; block[0x3D] = temp_block[0x3B]; + block[0x32] = temp_block[0x34]; block[0x2E] = temp_block[0x2D]; + block[0x23] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x27] = temp_block[0x27]; block[0x2B] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x36] = temp_block[0x35]; block[0x3A] = temp_block[0x3C]; + block[0x3E] = temp_block[0x3D]; block[0x33] = temp_block[0x36]; + block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37]; + block[0x3B] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } else if (s->idsp.perm_type == FF_IDCT_PERM_NONE) { + if(last_non_zero_p1 <= 1) goto end; + block[0x01] = temp_block[0x01]; + block[0x08] = temp_block[0x08]; block[0x10] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x09] = temp_block[0x09]; block[0x02] = temp_block[0x02]; + block[0x03] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x0A] = temp_block[0x0A]; block[0x11] = temp_block[0x11]; + block[0x18] = temp_block[0x18]; block[0x20] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x19] = temp_block[0x19]; + block[0x12] = temp_block[0x12]; block[0x0B] = temp_block[0x0B]; + block[0x04] = temp_block[0x04]; block[0x05] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x0C] = temp_block[0x0C]; block[0x13] = temp_block[0x13]; + block[0x1A] = temp_block[0x1A]; block[0x21] = temp_block[0x21]; + block[0x28] = temp_block[0x28]; block[0x30] = temp_block[0x30]; + block[0x29] = temp_block[0x29]; block[0x22] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x14] = temp_block[0x14]; + block[0x0D] = temp_block[0x0D]; block[0x06] = temp_block[0x06]; + block[0x07] = temp_block[0x07]; block[0x0E] = temp_block[0x0E]; + block[0x15] = temp_block[0x15]; block[0x1C] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x23] = temp_block[0x23]; block[0x2A] = temp_block[0x2A]; + block[0x31] = temp_block[0x31]; block[0x38] = temp_block[0x38]; + block[0x39] = temp_block[0x39]; block[0x32] = temp_block[0x32]; + block[0x2B] = temp_block[0x2B]; block[0x24] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x1D] = temp_block[0x1D]; block[0x16] = temp_block[0x16]; + block[0x0F] = temp_block[0x0F]; block[0x17] = temp_block[0x17]; + block[0x1E] = temp_block[0x1E]; block[0x25] = temp_block[0x25]; + block[0x2C] = temp_block[0x2C]; block[0x33] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x3A] = temp_block[0x3A]; block[0x3B] = temp_block[0x3B]; + block[0x34] = temp_block[0x34]; block[0x2D] = temp_block[0x2D]; + block[0x26] = temp_block[0x26]; block[0x1F] = temp_block[0x1F]; + block[0x27] = temp_block[0x27]; block[0x2E] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x35] = temp_block[0x35]; block[0x3C] = temp_block[0x3C]; + block[0x3D] = temp_block[0x3D]; block[0x36] = temp_block[0x36]; + block[0x2F] = temp_block[0x2F]; block[0x37] = temp_block[0x37]; + block[0x3E] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } else if (s->idsp.perm_type == FF_IDCT_PERM_TRANSPOSE) { + if(last_non_zero_p1 <= 1) goto end; + block[0x08] = temp_block[0x01]; + block[0x01] = temp_block[0x08]; block[0x02] = temp_block[0x10]; + if(last_non_zero_p1 <= 4) goto end; + block[0x09] = temp_block[0x09]; block[0x10] = temp_block[0x02]; + block[0x18] = temp_block[0x03]; + if(last_non_zero_p1 <= 7) goto end; + block[0x11] = temp_block[0x0A]; block[0x0A] = temp_block[0x11]; + block[0x03] = temp_block[0x18]; block[0x04] = temp_block[0x20]; + if(last_non_zero_p1 <= 11) goto end; + block[0x0B] = temp_block[0x19]; + block[0x12] = temp_block[0x12]; block[0x19] = temp_block[0x0B]; + block[0x20] = temp_block[0x04]; block[0x28] = temp_block[0x05]; + if(last_non_zero_p1 <= 16) goto end; + block[0x21] = temp_block[0x0C]; block[0x1A] = temp_block[0x13]; + block[0x13] = temp_block[0x1A]; block[0x0C] = temp_block[0x21]; + block[0x05] = temp_block[0x28]; block[0x06] = temp_block[0x30]; + block[0x0D] = temp_block[0x29]; block[0x14] = temp_block[0x22]; + if(last_non_zero_p1 <= 24) goto end; + block[0x1B] = temp_block[0x1B]; block[0x22] = temp_block[0x14]; + block[0x29] = temp_block[0x0D]; block[0x30] = temp_block[0x06]; + block[0x38] = temp_block[0x07]; block[0x31] = temp_block[0x0E]; + block[0x2A] = temp_block[0x15]; block[0x23] = temp_block[0x1C]; + if(last_non_zero_p1 <= 32) goto end; + block[0x1C] = temp_block[0x23]; block[0x15] = temp_block[0x2A]; + block[0x0E] = temp_block[0x31]; block[0x07] = temp_block[0x38]; + block[0x0F] = temp_block[0x39]; block[0x16] = temp_block[0x32]; + block[0x1D] = temp_block[0x2B]; block[0x24] = temp_block[0x24]; + if(last_non_zero_p1 <= 40) goto end; + block[0x2B] = temp_block[0x1D]; block[0x32] = temp_block[0x16]; + block[0x39] = temp_block[0x0F]; block[0x3A] = temp_block[0x17]; + block[0x33] = temp_block[0x1E]; block[0x2C] = temp_block[0x25]; + block[0x25] = temp_block[0x2C]; block[0x1E] = temp_block[0x33]; + if(last_non_zero_p1 <= 48) goto end; + block[0x17] = temp_block[0x3A]; block[0x1F] = temp_block[0x3B]; + block[0x26] = temp_block[0x34]; block[0x2D] = temp_block[0x2D]; + block[0x34] = temp_block[0x26]; block[0x3B] = temp_block[0x1F]; + block[0x3C] = temp_block[0x27]; block[0x35] = temp_block[0x2E]; + if(last_non_zero_p1 <= 56) goto end; + block[0x2E] = temp_block[0x35]; block[0x27] = temp_block[0x3C]; + block[0x2F] = temp_block[0x3D]; block[0x36] = temp_block[0x36]; + block[0x3D] = temp_block[0x2F]; block[0x3E] = temp_block[0x37]; + block[0x37] = temp_block[0x3E]; block[0x3F] = temp_block[0x3F]; + } else { + av_log(s, AV_LOG_DEBUG, "s->idsp.perm_type: %d\n", + (int)s->idsp.perm_type); + av_assert0(s->idsp.perm_type == FF_IDCT_PERM_NONE || + s->idsp.perm_type == FF_IDCT_PERM_LIBMPEG2 || + s->idsp.perm_type == FF_IDCT_PERM_SIMPLE || + s->idsp.perm_type == FF_IDCT_PERM_TRANSPOSE); + } + end: + return last_non_zero_p1 - 1; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoencdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoencdsp.asm new file mode 100644 index 00000000..aec73f82 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoencdsp.asm @@ -0,0 +1,154 @@ +;***************************************************************************** +;* SIMD-optimized MPEG encoding functions +;***************************************************************************** +;* Copyright (c) 2000, 2001 Fabrice Bellard +;* Copyright (c) 2002-2004 Michael Niedermayer +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pw_1 + +SECTION .text +; int ff_pix_sum16_mmx(uint8_t *pix, int line_size) +; %1 = number of loops +; %2 = number of GPRs used +%macro PIX_SUM16 3 +cglobal pix_sum16, 2, %2, 6 + movsxdifnidn r1, r1d + mov r2, %1 +%if mmsize == 16 + lea r3, [r1*3] +%endif +%if notcpuflag(xop) + pxor m5, m5 +%endif + pxor m4, m4 +.loop: +%if cpuflag(xop) + vphaddubq m0, [r0] + vphaddubq m1, [r0+r1] + vphaddubq m2, [r0+r1*2] + vphaddubq m3, [r0+r3] +%else + mova m0, [r0] +%if mmsize == 8 + mova m1, [r0+8] +%if cpuflag(mmxext) + mova m2, [r0+r1] + mova m3, [r0+r1+8] +%endif +%else ; sse2 + mova m1, [r0+r1] + mova m2, [r0+r1*2] + mova m3, [r0+r3] +%endif +%if cpuflag(mmxext) + psadbw m0, m5 + psadbw m1, m5 + psadbw m2, m5 + psadbw m3, m5 +%else ; mmx + punpckhbw m2, m0, m5 + punpcklbw m0, m5 + punpckhbw m3, m1, m5 + punpcklbw m1, m5 +%endif ; cpuflag(mmxext) +%endif ; cpuflag(xop) + paddw m1, m0 + paddw m3, m2 + paddw m3, m1 + paddw m4, m3 +%if cpuflag(mmxext) + lea r0, [r0+r1*%3] +%else + add r0, r1 +%endif + dec r2 + jne .loop +%if mmsize == 16 + pshufd m0, m4, q0032 + paddd m4, m0 +%elif notcpuflag(mmxext) + HADDW m4, m5 +%endif + movd eax, m4 + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +PIX_SUM16 16, 3, 0 +INIT_MMX mmxext +PIX_SUM16 8, 4, 2 +%endif +INIT_XMM sse2 +PIX_SUM16 4, 4, 4 +%if HAVE_XOP_EXTERNAL +INIT_XMM xop +PIX_SUM16 4, 4, 4 +%endif + +; int ff_pix_norm1_mmx(uint8_t *pix, int line_size) +; %1 = number of xmm registers used +; %2 = number of loops +%macro PIX_NORM1 2 +cglobal pix_norm1, 2, 3, %1 + movsxdifnidn r1, r1d + mov r2, %2 + pxor m0, m0 + pxor m5, m5 +.loop: + mova m2, [r0+0] +%if mmsize == 8 + mova m3, [r0+8] +%else + mova m3, [r0+r1] +%endif + punpckhbw m1, m2, m0 + punpcklbw m2, m0 + punpckhbw m4, m3, m0 + punpcklbw m3, m0 + pmaddwd m1, m1 + pmaddwd m2, m2 + pmaddwd m3, m3 + pmaddwd m4, m4 + paddd m2, m1 + paddd m4, m3 + paddd m5, m2 + paddd m5, m4 +%if mmsize == 8 + add r0, r1 +%else + lea r0, [r0+r1*2] +%endif + dec r2 + jne .loop + HADDD m5, m1 + movd eax, m5 + RET +%endmacro + +INIT_MMX mmx +PIX_NORM1 0, 16 +INIT_XMM sse2 +PIX_NORM1 6, 8 + diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoencdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoencdsp_init.c new file mode 100644 index 00000000..532836ce --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/mpegvideoencdsp_init.c @@ -0,0 +1,272 @@ +/* + * 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 "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/mpegvideoencdsp.h" + +int ff_pix_sum16_mmx(uint8_t *pix, int line_size); +int ff_pix_sum16_mmxext(uint8_t *pix, int line_size); +int ff_pix_sum16_sse2(uint8_t *pix, int line_size); +int ff_pix_sum16_xop(uint8_t *pix, int line_size); +int ff_pix_norm1_mmx(uint8_t *pix, int line_size); +int ff_pix_norm1_sse2(uint8_t *pix, int line_size); + +#if HAVE_INLINE_ASM + +#define PHADDD(a, t) \ + "movq " #a ", " #t " \n\t" \ + "psrlq $32, " #a " \n\t" \ + "paddd " #t ", " #a " \n\t" + +/* + * pmulhw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15])[16 - 31] + * pmulhrw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15] + 0x8000)[16 - 31] + * pmulhrsw: dst[0 - 15] = (src[0 - 15] * dst[0 - 15] + 0x4000)[15 - 30] + */ +#define PMULHRW(x, y, s, o) \ + "pmulhw " #s ", " #x " \n\t" \ + "pmulhw " #s ", " #y " \n\t" \ + "paddw " #o ", " #x " \n\t" \ + "paddw " #o ", " #y " \n\t" \ + "psraw $1, " #x " \n\t" \ + "psraw $1, " #y " \n\t" +#define DEF(x) x ## _mmx +#define SET_RND MOVQ_WONE +#define SCALE_OFFSET 1 + +#include "mpegvideoenc_qns_template.c" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW + +#define DEF(x) x ## _3dnow +#define SET_RND(x) +#define SCALE_OFFSET 0 +#define PMULHRW(x, y, s, o) \ + "pmulhrw " #s ", " #x " \n\t" \ + "pmulhrw " #s ", " #y " \n\t" + +#include "mpegvideoenc_qns_template.c" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW + +#if HAVE_SSSE3_INLINE +#undef PHADDD +#define DEF(x) x ## _ssse3 +#define SET_RND(x) +#define SCALE_OFFSET -1 + +#define PHADDD(a, t) \ + "pshufw $0x0E, " #a ", " #t " \n\t" \ + /* faster than phaddd on core2 */ \ + "paddd " #t ", " #a " \n\t" + +#define PMULHRW(x, y, s, o) \ + "pmulhrsw " #s ", " #x " \n\t" \ + "pmulhrsw " #s ", " #y " \n\t" + +#include "mpegvideoenc_qns_template.c" + +#undef DEF +#undef SET_RND +#undef SCALE_OFFSET +#undef PMULHRW +#undef PHADDD +#endif /* HAVE_SSSE3_INLINE */ + +/* Draw the edges of width 'w' of an image of size width, height + * this MMX version can only handle w == 8 || w == 16. */ +static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, + int w, int h, int sides) +{ + uint8_t *ptr, *last_line; + int i; + + last_line = buf + (height - 1) * wrap; + /* left and right */ + ptr = buf; + if (w == 8) { + __asm__ volatile ( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "punpckldq %%mm0, %%mm0 \n\t" + "movq %%mm0, -8(%0) \n\t" + "movq -8(%0, %2), %%mm1 \n\t" + "punpckhbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm1, (%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) wrap), "r" ((x86_reg) width), + "r" (ptr + wrap * height)); + } else if (w == 16) { + __asm__ volatile ( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "punpckldq %%mm0, %%mm0 \n\t" + "movq %%mm0, -8(%0) \n\t" + "movq %%mm0, -16(%0) \n\t" + "movq -8(%0, %2), %%mm1 \n\t" + "punpckhbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movq %%mm1, (%0, %2) \n\t" + "movq %%mm1, 8(%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + "jb 1b \n\t" + : "+r"(ptr) + : "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height) + ); + } else { + av_assert1(w == 4); + __asm__ volatile ( + "1: \n\t" + "movd (%0), %%mm0 \n\t" + "punpcklbw %%mm0, %%mm0 \n\t" + "punpcklwd %%mm0, %%mm0 \n\t" + "movd %%mm0, -4(%0) \n\t" + "movd -4(%0, %2), %%mm1 \n\t" + "punpcklbw %%mm1, %%mm1 \n\t" + "punpckhwd %%mm1, %%mm1 \n\t" + "punpckhdq %%mm1, %%mm1 \n\t" + "movd %%mm1, (%0, %2) \n\t" + "add %1, %0 \n\t" + "cmp %3, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) wrap), "r" ((x86_reg) width), + "r" (ptr + wrap * height)); + } + + /* top and bottom (and hopefully also the corners) */ + if (sides & EDGE_TOP) { + for (i = 0; i < h; i += 4) { + ptr = buf - (i + 1) * wrap - w; + __asm__ volatile ( + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm0, (%0, %2) \n\t" + "movq %%mm0, (%0, %2, 2) \n\t" + "movq %%mm0, (%0, %3) \n\t" + "add $8, %0 \n\t" + "cmp %4, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) buf - (x86_reg) ptr - w), + "r" ((x86_reg) - wrap), "r" ((x86_reg) - wrap * 3), + "r" (ptr + width + 2 * w)); + } + } + + if (sides & EDGE_BOTTOM) { + for (i = 0; i < h; i += 4) { + ptr = last_line + (i + 1) * wrap - w; + __asm__ volatile ( + "1: \n\t" + "movq (%1, %0), %%mm0 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm0, (%0, %2) \n\t" + "movq %%mm0, (%0, %2, 2) \n\t" + "movq %%mm0, (%0, %3) \n\t" + "add $8, %0 \n\t" + "cmp %4, %0 \n\t" + "jb 1b \n\t" + : "+r" (ptr) + : "r" ((x86_reg) last_line - (x86_reg) ptr - w), + "r" ((x86_reg) wrap), "r" ((x86_reg) wrap * 3), + "r" (ptr + width + 2 * w)); + } + } +} + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_mpegvideoencdsp_init_x86(MpegvideoEncDSPContext *c, + AVCodecContext *avctx) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) { + c->pix_sum = ff_pix_sum16_mmx; + c->pix_norm1 = ff_pix_norm1_mmx; + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->pix_sum = ff_pix_sum16_mmxext; + } +#endif + + if (EXTERNAL_SSE2(cpu_flags)) { + c->pix_sum = ff_pix_sum16_sse2; + c->pix_norm1 = ff_pix_norm1_sse2; + } + + if (EXTERNAL_XOP(cpu_flags)) { + c->pix_sum = ff_pix_sum16_xop; + } + +#if HAVE_INLINE_ASM + + if (INLINE_MMX(cpu_flags)) { + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_mmx; + } + c->add_8x8basis = add_8x8basis_mmx; + + if (avctx->bits_per_raw_sample <= 8) { + c->draw_edges = draw_edges_mmx; + } + } + + if (INLINE_AMD3DNOW(cpu_flags)) { + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_3dnow; + } + c->add_8x8basis = add_8x8basis_3dnow; + } + +#if HAVE_SSSE3_INLINE + if (INLINE_SSSE3(cpu_flags)) { + if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) { + c->try_8x8basis = try_8x8basis_ssse3; + } + c->add_8x8basis = add_8x8basis_ssse3; + } +#endif /* HAVE_SSSE3_INLINE */ + +#endif /* HAVE_INLINE_ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/opusdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/opusdsp.asm new file mode 100644 index 00000000..418cc163 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/opusdsp.asm @@ -0,0 +1,111 @@ +;****************************************************************************** +;* Opus SIMD functions +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + + ; 0.85..^1 0.85..^2 0.85..^3 0.85..^4 +tab_st: dd 0x3f599a00, 0x3f38f671, 0x3f1d382a, 0x3f05a32f + +SECTION .text + +INIT_XMM fma3 +%if UNIX64 +cglobal opus_deemphasis, 3, 3, 8, out, in, len +%else +cglobal opus_deemphasis, 4, 4, 8, out, in, coeff, len +%endif +%if ARCH_X86_32 + VBROADCASTSS m0, coeffm +%elif WIN64 + shufps m0, m2, m2, 0 +%else + shufps m0, m0, 0 +%endif + + movaps m4, [tab_st] + VBROADCASTSS m5, m4 + shufps m6, m4, m4, q1111 + shufps m7, m4, m4, q2222 + +.loop: + movaps m1, [inq] ; x0, x1, x2, x3 + + pslldq m2, m1, 4 ; 0, x0, x1, x2 + pslldq m3, m1, 8 ; 0, 0, x0, x1 + + fmaddps m2, m2, m5, m1 ; x + c1*x[0-2] + pslldq m1, 12 ; 0, 0, 0, x0 + + fmaddps m2, m3, m6, m2 ; x + c1*x[0-2] + c2*x[0-1] + fmaddps m1, m1, m7, m2 ; x + c1*x[0-2] + c2*x[0-1] + c3*x[0] + fmaddps m0, m0, m4, m1 ; x + c1*x[0-2] + c2*x[0-1] + c3*x[0] + c*s + + movaps [outq], m0 + shufps m0, m0, q3333 ; new state + + add inq, mmsize + add outq, mmsize + sub lend, mmsize >> 2 + jg .loop + +%if ARCH_X86_64 == 0 + movss r0m, m0 + fld dword r0m +%endif + RET + + +INIT_XMM fma3 +cglobal opus_postfilter, 4, 4, 8, data, period, gains, len + VBROADCASTSS m0, [gainsq + 0] + VBROADCASTSS m1, [gainsq + 4] + VBROADCASTSS m2, [gainsq + 8] + + shl periodd, 2 + add periodq, 8 + neg periodq + + movups m3, [dataq + periodq] + mulps m3, m2 + +.loop: + movups m4, [dataq + periodq + 4] + movups m5, [dataq + periodq + 8] + movups m6, [dataq + periodq + 12] + movups m7, [dataq + periodq + 16] + + fmaddps m3, m7, m2, m3 + addps m6, m4 + + fmaddps m5, m5, m0, [dataq] + fmaddps m6, m6, m1, m3 + + addps m5, m6 + mulps m3, m7, m2 + + movaps [dataq], m5 + + add dataq, mmsize + sub lend, mmsize >> 2 + jg .loop + + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/opusdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/opusdsp_init.c new file mode 100644 index 00000000..5c8a4c22 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/opusdsp_init.c @@ -0,0 +1,35 @@ +/* + * 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.h" + +#include "libavutil/x86/cpu.h" +#include "libavcodec/opusdsp.h" + +void ff_opus_postfilter_fma3(float *data, int period, float *gains, int len); +float ff_opus_deemphasis_fma3(float *out, float *in, float coeff, int len); + +av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_FMA3(cpu_flags)) { + ctx->postfilter = ff_opus_postfilter_fma3; + ctx->deemphasis = ff_opus_deemphasis_fma3; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pixblockdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pixblockdsp.asm new file mode 100644 index 00000000..440fe29b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pixblockdsp.asm @@ -0,0 +1,128 @@ +;***************************************************************************** +;* SIMD-optimized pixel operations +;***************************************************************************** +;* Copyright (c) 2000, 2001 Fabrice Bellard +;* Copyright (c) 2002-2004 Michael Niedermayer +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_MMX mmx +; void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, ptrdiff_t stride) +cglobal get_pixels, 3,4 + add r0, 128 + mov r3, -128 + pxor m7, m7 +.loop: + mova m0, [r1] + mova m2, [r1+r2] + mova m1, m0 + mova m3, m2 + punpcklbw m0, m7 + punpckhbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + mova [r0+r3+ 0], m0 + mova [r0+r3+ 8], m1 + mova [r0+r3+16], m2 + mova [r0+r3+24], m3 + lea r1, [r1+r2*2] + add r3, 32 + js .loop + REP_RET + +INIT_XMM sse2 +cglobal get_pixels, 3, 4, 5 + lea r3, [r2*3] + pxor m4, m4 + movh m0, [r1] + movh m1, [r1+r2] + movh m2, [r1+r2*2] + movh m3, [r1+r3] + lea r1, [r1+r2*4] + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpcklbw m3, m4 + mova [r0], m0 + mova [r0+0x10], m1 + mova [r0+0x20], m2 + mova [r0+0x30], m3 + movh m0, [r1] + movh m1, [r1+r2*1] + movh m2, [r1+r2*2] + movh m3, [r1+r3] + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpcklbw m3, m4 + mova [r0+0x40], m0 + mova [r0+0x50], m1 + mova [r0+0x60], m2 + mova [r0+0x70], m3 + RET + +; void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, +; ptrdiff_t stride); +%macro DIFF_PIXELS 0 +cglobal diff_pixels, 4,5,5 + pxor m4, m4 + add r0, 128 + mov r4, -128 +.loop: + movq m0, [r1] + movq m2, [r2] +%if mmsize == 8 + movq m1, m0 + movq m3, m2 + punpcklbw m0, m4 + punpckhbw m1, m4 + punpcklbw m2, m4 + punpckhbw m3, m4 +%else + movq m1, [r1+r3] + movq m3, [r2+r3] + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpcklbw m3, m4 +%endif + psubw m0, m2 + psubw m1, m3 + mova [r0+r4+0], m0 + mova [r0+r4+mmsize], m1 +%if mmsize == 8 + add r1, r3 + add r2, r3 +%else + lea r1, [r1+r3*2] + lea r2, [r2+r3*2] +%endif + add r4, 2 * mmsize + jne .loop + RET +%endmacro + +INIT_MMX mmx +DIFF_PIXELS + +INIT_XMM sse2 +DIFF_PIXELS diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pixblockdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pixblockdsp_init.c new file mode 100644 index 00000000..3a5eb695 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pixblockdsp_init.c @@ -0,0 +1,56 @@ +/* + * SIMD-optimized pixel operations + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/pixblockdsp.h" + +void ff_get_pixels_mmx(int16_t *block, const uint8_t *pixels, ptrdiff_t stride); +void ff_get_pixels_sse2(int16_t *block, const uint8_t *pixels, ptrdiff_t stride); +void ff_diff_pixels_mmx(int16_t *block, const uint8_t *s1, const uint8_t *s2, + ptrdiff_t stride); +void ff_diff_pixels_sse2(int16_t *block, const uint8_t *s1, const uint8_t *s2, + ptrdiff_t stride); + +av_cold void ff_pixblockdsp_init_x86(PixblockDSPContext *c, + AVCodecContext *avctx, + unsigned high_bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + if (!high_bit_depth) { + c->get_pixels_unaligned = + c->get_pixels = ff_get_pixels_mmx; + } + c->diff_pixels_unaligned = + c->diff_pixels = ff_diff_pixels_mmx; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + if (!high_bit_depth) { + c->get_pixels_unaligned = + c->get_pixels = ff_get_pixels_sse2; + } + c->diff_pixels_unaligned = + c->diff_pixels = ff_diff_pixels_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pngdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pngdsp.asm new file mode 100644 index 00000000..50e4255d --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pngdsp.asm @@ -0,0 +1,173 @@ +;****************************************************************************** +;* x86 optimizations for PNG decoding +;* +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2012 Ronald S. Bultje +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pw_255 + +SECTION .text + +; %1 = nr. of xmm registers used +%macro ADD_BYTES_FN 1 +cglobal add_bytes_l2, 4, 6, %1, dst, src1, src2, wa, w, i +%if ARCH_X86_64 + movsxd waq, wad +%endif + xor iq, iq + + ; vector loop + mov wq, waq + and waq, ~(mmsize*2-1) + jmp .end_v +.loop_v: + movu m0, [src2q+iq] + movu m1, [src2q+iq+mmsize] + paddb m0, [src1q+iq] + paddb m1, [src1q+iq+mmsize] + movu [dstq+iq ], m0 + movu [dstq+iq+mmsize], m1 + add iq, mmsize*2 +.end_v: + cmp iq, waq + jl .loop_v + +%if mmsize == 16 + ; vector loop + mov waq, wq + and waq, ~7 + jmp .end_l +.loop_l: + movq mm0, [src1q+iq] + paddb mm0, [src2q+iq] + movq [dstq+iq ], mm0 + add iq, 8 +.end_l: + cmp iq, waq + jl .loop_l +%endif + + ; scalar loop for leftover + jmp .end_s +.loop_s: + mov wab, [src1q+iq] + add wab, [src2q+iq] + mov [dstq+iq], wab + inc iq +.end_s: + cmp iq, wq + jl .loop_s + REP_RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +ADD_BYTES_FN 0 +%endif + +INIT_XMM sse2 +ADD_BYTES_FN 2 + +%macro ADD_PAETH_PRED_FN 1 +cglobal add_png_paeth_prediction, 5, 7, %1, dst, src, top, w, bpp, end, cntr +%if ARCH_X86_64 + movsxd bppq, bppd + movsxd wq, wd +%endif + lea endq, [dstq+wq-(mmsize/2-1)] + sub topq, dstq + sub srcq, dstq + sub dstq, bppq + pxor m7, m7 + + PUSH dstq + lea cntrq, [bppq-1] + shr cntrq, 2 + mmsize/16 +.bpp_loop: + lea dstq, [dstq+cntrq*(mmsize/2)] + movh m0, [dstq] + movh m1, [topq+dstq] + punpcklbw m0, m7 + punpcklbw m1, m7 + add dstq, bppq +.loop: + mova m2, m1 + movh m1, [topq+dstq] + mova m3, m2 + punpcklbw m1, m7 + mova m4, m2 + psubw m3, m1 + psubw m4, m0 + mova m5, m3 + paddw m5, m4 +%if cpuflag(ssse3) + pabsw m3, m3 + pabsw m4, m4 + pabsw m5, m5 +%else ; !cpuflag(ssse3) + psubw m7, m5 + pmaxsw m5, m7 + pxor m6, m6 + pxor m7, m7 + psubw m6, m3 + psubw m7, m4 + pmaxsw m3, m6 + pmaxsw m4, m7 + pxor m7, m7 +%endif ; cpuflag(ssse3) + mova m6, m4 + pminsw m6, m5 + pcmpgtw m3, m6 + pcmpgtw m4, m5 + mova m6, m4 + pand m4, m3 + pandn m6, m3 + pandn m3, m0 + movh m0, [srcq+dstq] + pand m6, m1 + pand m2, m4 + punpcklbw m0, m7 + paddw m0, m6 + paddw m3, m2 + paddw m0, m3 + pand m0, [pw_255] + mova m3, m0 + packuswb m3, m3 + movh [dstq], m3 + add dstq, bppq + cmp dstq, endq + jl .loop + + mov dstq, [rsp] + dec cntrq + jge .bpp_loop + POP dstq + RET +%endmacro + +INIT_MMX mmxext +ADD_PAETH_PRED_FN 0 + +INIT_MMX ssse3 +ADD_PAETH_PRED_FN 0 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pngdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pngdsp_init.c new file mode 100644 index 00000000..7dca62c6 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/pngdsp_init.c @@ -0,0 +1,50 @@ +/* + * x86 PNG optimizations. + * Copyright (c) 2008 Loren Merrit + * + * 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 "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/pngdsp.h" + +void ff_add_png_paeth_prediction_mmxext(uint8_t *dst, uint8_t *src, + uint8_t *top, int w, int bpp); +void ff_add_png_paeth_prediction_ssse3(uint8_t *dst, uint8_t *src, + uint8_t *top, int w, int bpp); +void ff_add_bytes_l2_mmx (uint8_t *dst, uint8_t *src1, + uint8_t *src2, int w); +void ff_add_bytes_l2_sse2(uint8_t *dst, uint8_t *src1, + uint8_t *src2, int w); + +av_cold void ff_pngdsp_init_x86(PNGDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) + dsp->add_bytes_l2 = ff_add_bytes_l2_mmx; +#endif + if (EXTERNAL_MMXEXT(cpu_flags)) + dsp->add_paeth_prediction = ff_add_png_paeth_prediction_mmxext; + if (EXTERNAL_SSE2(cpu_flags)) + dsp->add_bytes_l2 = ff_add_bytes_l2_sse2; + if (EXTERNAL_SSSE3(cpu_flags)) + dsp->add_paeth_prediction = ff_add_png_paeth_prediction_ssse3; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/proresdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/proresdsp.asm new file mode 100644 index 00000000..65c9fad5 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/proresdsp.asm @@ -0,0 +1,68 @@ +;****************************************************************************** +;* x86-SIMD-optimized IDCT for prores +;* this is identical to "simple" IDCT written by Michael Niedermayer +;* except for the clip range +;* +;* Copyright (c) 2011 Ronald S. Bultje +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 + +SECTION_RODATA + +pw_88: times 8 dw 0x2008 +cextern pw_1 +cextern pw_4 +cextern pw_1019 +; Below are defined in simple_idct10.asm built from selecting idctdsp +cextern w4_plus_w2_hi +cextern w4_min_w2_hi +cextern w4_plus_w6_hi +cextern w4_min_w6_hi +cextern w1_plus_w3_hi +cextern w3_min_w1_hi +cextern w7_plus_w3_hi +cextern w3_min_w7_hi +cextern w1_plus_w5 +cextern w5_min_w1 +cextern w5_plus_w7 +cextern w7_min_w5 + +%include "libavcodec/x86/simple_idct10_template.asm" + +SECTION .text + +define_constants _hi + +%macro idct_fn 0 +cglobal prores_idct_put_10, 4, 4, 15, pixels, lsize, block, qmat + IDCT_FN pw_1, 15, pw_88, 18, "put", pw_4, pw_1019, r3 + RET +%endmacro + +INIT_XMM sse2 +idct_fn +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +idct_fn +%endif + +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/proresdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/proresdsp_init.c new file mode 100644 index 00000000..bde79ab8 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/proresdsp_init.c @@ -0,0 +1,50 @@ +/* + * Apple ProRes compatible decoder + * + * Copyright (c) 2010-2011 Maxim Poliakovski + * + * 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 "libavutil/attributes.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/idctdsp.h" +#include "libavcodec/proresdsp.h" + +void ff_prores_idct_put_10_sse2(uint16_t *dst, ptrdiff_t linesize, + int16_t *block, const int16_t *qmat); +void ff_prores_idct_put_10_avx (uint16_t *dst, ptrdiff_t linesize, + int16_t *block, const int16_t *qmat); + +av_cold void ff_proresdsp_init_x86(ProresDSPContext *dsp, AVCodecContext *avctx) +{ +#if ARCH_X86_64 + int cpu_flags = av_get_cpu_flags(); + + if (avctx->bits_per_raw_sample == 10){ + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->idct_permutation_type = FF_IDCT_PERM_TRANSPOSE; + dsp->idct_put = ff_prores_idct_put_10_sse2; + } + + if (EXTERNAL_AVX(cpu_flags)) { + dsp->idct_permutation_type = FF_IDCT_PERM_TRANSPOSE; + dsp->idct_put = ff_prores_idct_put_10_avx; + } + } +#endif /* ARCH_X86_64 */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpel.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpel.asm new file mode 100644 index 00000000..4e72d508 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpel.asm @@ -0,0 +1,179 @@ +;****************************************************************************** +;* SIMD-optimized quarterpel functions +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2003-2013 Michael Niedermayer +;* Copyright (c) 2013 Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro op_avgh 3 + movh %3, %2 + pavgb %1, %3 + movh %2, %1 +%endmacro + +%macro op_avg 2 + pavgb %1, %2 + mova %2, %1 +%endmacro + +%macro op_puth 2-3 + movh %2, %1 +%endmacro + +%macro op_put 2 + mova %2, %1 +%endmacro + +; void ff_put/avg_pixels4_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, +; int dstStride, int src1Stride, int h) +%macro PIXELS4_L2 1 +%define OP op_%1h +cglobal %1_pixels4_l2, 6,6 + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + test r5d, 1 + je .loop + movd m0, [r1] + movd m1, [r2] + add r1, r4 + add r2, 4 + pavgb m0, m1 + OP m0, [r0], m3 + add r0, r3 + dec r5d +.loop: + mova m0, [r1] + mova m1, [r1+r4] + lea r1, [r1+2*r4] + pavgb m0, [r2] + pavgb m1, [r2+4] + OP m0, [r0], m3 + OP m1, [r0+r3], m3 + lea r0, [r0+2*r3] + mova m0, [r1] + mova m1, [r1+r4] + lea r1, [r1+2*r4] + pavgb m0, [r2+8] + pavgb m1, [r2+12] + OP m0, [r0], m3 + OP m1, [r0+r3], m3 + lea r0, [r0+2*r3] + add r2, 16 + sub r5d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PIXELS4_L2 put +PIXELS4_L2 avg + +; void ff_put/avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, +; int dstStride, int src1Stride, int h) +%macro PIXELS8_L2 1 +%define OP op_%1 +cglobal %1_pixels8_l2, 6,6 + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + test r5d, 1 + je .loop + mova m0, [r1] + mova m1, [r2] + add r1, r4 + add r2, 8 + pavgb m0, m1 + OP m0, [r0] + add r0, r3 + dec r5d +.loop: + mova m0, [r1] + mova m1, [r1+r4] + lea r1, [r1+2*r4] + pavgb m0, [r2] + pavgb m1, [r2+8] + OP m0, [r0] + OP m1, [r0+r3] + lea r0, [r0+2*r3] + mova m0, [r1] + mova m1, [r1+r4] + lea r1, [r1+2*r4] + pavgb m0, [r2+16] + pavgb m1, [r2+24] + OP m0, [r0] + OP m1, [r0+r3] + lea r0, [r0+2*r3] + add r2, 32 + sub r5d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PIXELS8_L2 put +PIXELS8_L2 avg + +; void ff_put/avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2, +; int dstStride, int src1Stride, int h) +%macro PIXELS16_L2 1 +%define OP op_%1 +cglobal %1_pixels16_l2, 6,6 + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + test r5d, 1 + je .loop + mova m0, [r1] + mova m1, [r1+8] + pavgb m0, [r2] + pavgb m1, [r2+8] + add r1, r4 + add r2, 16 + OP m0, [r0] + OP m1, [r0+8] + add r0, r3 + dec r5d +.loop: + mova m0, [r1] + mova m1, [r1+8] + add r1, r4 + pavgb m0, [r2] + pavgb m1, [r2+8] + OP m0, [r0] + OP m1, [r0+8] + add r0, r3 + mova m0, [r1] + mova m1, [r1+8] + add r1, r4 + pavgb m0, [r2+16] + pavgb m1, [r2+24] + OP m0, [r0] + OP m1, [r0+8] + add r0, r3 + add r2, 32 + sub r5d, 2 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PIXELS16_L2 put +PIXELS16_L2 avg diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpeldsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpeldsp.asm new file mode 100644 index 00000000..282faed1 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpeldsp.asm @@ -0,0 +1,560 @@ +;****************************************************************************** +;* mpeg4 qpel +;* Copyright (c) 2003 Michael Niedermayer +;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2013 Daniel Kang +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +cextern pb_1 +cextern pw_3 +cextern pw_15 +cextern pw_16 +cextern pw_20 + + +SECTION .text + +; void ff_put_no_rnd_pixels8_l2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +%macro PUT_NO_RND_PIXELS8_L2 0 +cglobal put_no_rnd_pixels8_l2, 6,6 + movsxdifnidn r4, r4d + movsxdifnidn r3, r3d + pcmpeqb m6, m6 + test r5d, 1 + je .loop + mova m0, [r1] + mova m1, [r2] + add r1, r4 + add r2, 8 + pxor m0, m6 + pxor m1, m6 + PAVGB m0, m1 + pxor m0, m6 + mova [r0], m0 + add r0, r3 + dec r5d +.loop: + mova m0, [r1] + add r1, r4 + mova m1, [r1] + add r1, r4 + mova m2, [r2] + mova m3, [r2+8] + pxor m0, m6 + pxor m1, m6 + pxor m2, m6 + pxor m3, m6 + PAVGB m0, m2 + PAVGB m1, m3 + pxor m0, m6 + pxor m1, m6 + mova [r0], m0 + add r0, r3 + mova [r0], m1 + add r0, r3 + mova m0, [r1] + add r1, r4 + mova m1, [r1] + add r1, r4 + mova m2, [r2+16] + mova m3, [r2+24] + pxor m0, m6 + pxor m1, m6 + pxor m2, m6 + pxor m3, m6 + PAVGB m0, m2 + PAVGB m1, m3 + pxor m0, m6 + pxor m1, m6 + mova [r0], m0 + add r0, r3 + mova [r0], m1 + add r0, r3 + add r2, 32 + sub r5d, 4 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_NO_RND_PIXELS8_L2 + + +; void ff_put_no_rnd_pixels16_l2(uint8_t *dst, uint8_t *src1, uint8_t *src2, int dstStride, int src1Stride, int h) +%macro PUT_NO_RND_PIXELS16_l2 0 +cglobal put_no_rnd_pixels16_l2, 6,6 + movsxdifnidn r3, r3d + movsxdifnidn r4, r4d + pcmpeqb m6, m6 + test r5d, 1 + je .loop + mova m0, [r1] + mova m1, [r1+8] + mova m2, [r2] + mova m3, [r2+8] + pxor m0, m6 + pxor m1, m6 + pxor m2, m6 + pxor m3, m6 + PAVGB m0, m2 + PAVGB m1, m3 + pxor m0, m6 + pxor m1, m6 + add r1, r4 + add r2, 16 + mova [r0], m0 + mova [r0+8], m1 + add r0, r3 + dec r5d +.loop: + mova m0, [r1] + mova m1, [r1+8] + add r1, r4 + mova m2, [r2] + mova m3, [r2+8] + pxor m0, m6 + pxor m1, m6 + pxor m2, m6 + pxor m3, m6 + PAVGB m0, m2 + PAVGB m1, m3 + pxor m0, m6 + pxor m1, m6 + mova [r0], m0 + mova [r0+8], m1 + add r0, r3 + mova m0, [r1] + mova m1, [r1+8] + add r1, r4 + mova m2, [r2+16] + mova m3, [r2+24] + pxor m0, m6 + pxor m1, m6 + pxor m2, m6 + pxor m3, m6 + PAVGB m0, m2 + PAVGB m1, m3 + pxor m0, m6 + pxor m1, m6 + mova [r0], m0 + mova [r0+8], m1 + add r0, r3 + add r2, 32 + sub r5d, 2 + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PUT_NO_RND_PIXELS16_l2 +INIT_MMX 3dnow +PUT_NO_RND_PIXELS16_l2 + +%macro MPEG4_QPEL16_H_LOWPASS 1 +cglobal %1_mpeg4_qpel16_h_lowpass, 5, 5, 0, 16 + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + pxor m7, m7 +.loop: + mova m0, [r1] + mova m1, m0 + mova m2, m0 + punpcklbw m0, m7 + punpckhbw m1, m7 + pshufw m5, m0, 0x90 + pshufw m6, m0, 0x41 + mova m3, m2 + mova m4, m2 + psllq m2, 8 + psllq m3, 16 + psllq m4, 24 + punpckhbw m2, m7 + punpckhbw m3, m7 + punpckhbw m4, m7 + paddw m5, m3 + paddw m6, m2 + paddw m5, m5 + psubw m6, m5 + pshufw m5, m0, 6 + pmullw m6, [pw_3] + paddw m0, m4 + paddw m5, m1 + pmullw m0, [pw_20] + psubw m0, m5 + paddw m6, [PW_ROUND] + paddw m0, m6 + psraw m0, 5 + mova [rsp+8], m0 + mova m0, [r1+5] + mova m5, m0 + mova m6, m0 + psrlq m0, 8 + psrlq m5, 16 + punpcklbw m0, m7 + punpcklbw m5, m7 + paddw m2, m0 + paddw m3, m5 + paddw m2, m2 + psubw m3, m2 + mova m2, m6 + psrlq m6, 24 + punpcklbw m2, m7 + punpcklbw m6, m7 + pmullw m3, [pw_3] + paddw m1, m2 + paddw m4, m6 + pmullw m1, [pw_20] + psubw m3, m4 + paddw m1, [PW_ROUND] + paddw m3, m1 + psraw m3, 5 + mova m1, [rsp+8] + packuswb m1, m3 + OP_MOV [r0], m1, m4 + mova m1, [r1+9] + mova m4, m1 + mova m3, m1 + psrlq m1, 8 + psrlq m4, 16 + punpcklbw m1, m7 + punpcklbw m4, m7 + paddw m5, m1 + paddw m0, m4 + paddw m5, m5 + psubw m0, m5 + mova m5, m3 + psrlq m3, 24 + pmullw m0, [pw_3] + punpcklbw m3, m7 + paddw m2, m3 + psubw m0, m2 + mova m2, m5 + punpcklbw m2, m7 + punpckhbw m5, m7 + paddw m6, m2 + pmullw m6, [pw_20] + paddw m0, [PW_ROUND] + paddw m0, m6 + psraw m0, 5 + paddw m3, m5 + pshufw m6, m5, 0xf9 + paddw m6, m4 + pshufw m4, m5, 0xbe + pshufw m5, m5, 0x6f + paddw m4, m1 + paddw m5, m2 + paddw m6, m6 + psubw m4, m6 + pmullw m3, [pw_20] + pmullw m4, [pw_3] + psubw m3, m5 + paddw m4, [PW_ROUND] + paddw m4, m3 + psraw m4, 5 + packuswb m0, m4 + OP_MOV [r0+8], m0, m4 + add r1, r3 + add r0, r2 + dec r4d + jne .loop + REP_RET +%endmacro + +%macro PUT_OP 2-3 + mova %1, %2 +%endmacro + +%macro AVG_OP 2-3 + mova %3, %1 + pavgb %2, %3 + mova %1, %2 +%endmacro + +INIT_MMX mmxext +%define PW_ROUND pw_16 +%define OP_MOV PUT_OP +MPEG4_QPEL16_H_LOWPASS put +%define PW_ROUND pw_16 +%define OP_MOV AVG_OP +MPEG4_QPEL16_H_LOWPASS avg +%define PW_ROUND pw_15 +%define OP_MOV PUT_OP +MPEG4_QPEL16_H_LOWPASS put_no_rnd + + + +%macro MPEG4_QPEL8_H_LOWPASS 1 +cglobal %1_mpeg4_qpel8_h_lowpass, 5, 5, 0, 8 + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + pxor m7, m7 +.loop: + mova m0, [r1] + mova m1, m0 + mova m2, m0 + punpcklbw m0, m7 + punpckhbw m1, m7 + pshufw m5, m0, 0x90 + pshufw m6, m0, 0x41 + mova m3, m2 + mova m4, m2 + psllq m2, 8 + psllq m3, 16 + psllq m4, 24 + punpckhbw m2, m7 + punpckhbw m3, m7 + punpckhbw m4, m7 + paddw m5, m3 + paddw m6, m2 + paddw m5, m5 + psubw m6, m5 + pshufw m5, m0, 0x6 + pmullw m6, [pw_3] + paddw m0, m4 + paddw m5, m1 + pmullw m0, [pw_20] + psubw m0, m5 + paddw m6, [PW_ROUND] + paddw m0, m6 + psraw m0, 5 + movh m5, [r1+5] + punpcklbw m5, m7 + pshufw m6, m5, 0xf9 + paddw m1, m5 + paddw m2, m6 + pshufw m6, m5, 0xbe + pshufw m5, m5, 0x6f + paddw m3, m6 + paddw m4, m5 + paddw m2, m2 + psubw m3, m2 + pmullw m1, [pw_20] + pmullw m3, [pw_3] + psubw m3, m4 + paddw m1, [PW_ROUND] + paddw m3, m1 + psraw m3, 5 + packuswb m0, m3 + OP_MOV [r0], m0, m4 + add r1, r3 + add r0, r2 + dec r4d + jne .loop + REP_RET +%endmacro + +INIT_MMX mmxext +%define PW_ROUND pw_16 +%define OP_MOV PUT_OP +MPEG4_QPEL8_H_LOWPASS put +%define PW_ROUND pw_16 +%define OP_MOV AVG_OP +MPEG4_QPEL8_H_LOWPASS avg +%define PW_ROUND pw_15 +%define OP_MOV PUT_OP +MPEG4_QPEL8_H_LOWPASS put_no_rnd + + + +%macro QPEL_V_LOW 5 + paddw m0, m1 + mova m4, [pw_20] + pmullw m4, m0 + mova m0, %4 + mova m5, %1 + paddw m5, m0 + psubw m4, m5 + mova m5, %2 + mova m6, %3 + paddw m5, m3 + paddw m6, m2 + paddw m6, m6 + psubw m5, m6 + pmullw m5, [pw_3] + paddw m4, [PW_ROUND] + paddw m5, m4 + psraw m5, 5 + packuswb m5, m5 + OP_MOV %5, m5, m7 + SWAP 0,1,2,3 +%endmacro + +%macro MPEG4_QPEL16_V_LOWPASS 1 +cglobal %1_mpeg4_qpel16_v_lowpass, 4, 6, 0, 544 + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + + mov r4d, 17 + mov r5, rsp + pxor m7, m7 +.looph: + mova m0, [r1] + mova m1, [r1] + mova m2, [r1+8] + mova m3, [r1+8] + punpcklbw m0, m7 + punpckhbw m1, m7 + punpcklbw m2, m7 + punpckhbw m3, m7 + mova [r5], m0 + mova [r5+0x88], m1 + mova [r5+0x110], m2 + mova [r5+0x198], m3 + add r5, 8 + add r1, r3 + dec r4d + jne .looph + + + ; NOTE: r1 CHANGES VALUES: r1 -> 4 - 14*dstStride + mov r4d, 4 + mov r1, 4 + neg r2 + lea r1, [r1+r2*8] + lea r1, [r1+r2*4] + lea r1, [r1+r2*2] + neg r2 + mov r5, rsp +.loopv: + pxor m7, m7 + mova m0, [r5+ 0x0] + mova m1, [r5+ 0x8] + mova m2, [r5+0x10] + mova m3, [r5+0x18] + QPEL_V_LOW [r5+0x10], [r5+ 0x8], [r5+ 0x0], [r5+0x20], [r0] + QPEL_V_LOW [r5+ 0x8], [r5+ 0x0], [r5+ 0x0], [r5+0x28], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+ 0x0], [r5+ 0x0], [r5+ 0x8], [r5+0x30], [r0] + QPEL_V_LOW [r5+ 0x0], [r5+ 0x8], [r5+0x10], [r5+0x38], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+ 0x8], [r5+0x10], [r5+0x18], [r5+0x40], [r0] + QPEL_V_LOW [r5+0x10], [r5+0x18], [r5+0x20], [r5+0x48], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+0x18], [r5+0x20], [r5+0x28], [r5+0x50], [r0] + QPEL_V_LOW [r5+0x20], [r5+0x28], [r5+0x30], [r5+0x58], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+0x28], [r5+0x30], [r5+0x38], [r5+0x60], [r0] + QPEL_V_LOW [r5+0x30], [r5+0x38], [r5+0x40], [r5+0x68], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+0x38], [r5+0x40], [r5+0x48], [r5+0x70], [r0] + QPEL_V_LOW [r5+0x40], [r5+0x48], [r5+0x50], [r5+0x78], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+0x48], [r5+0x50], [r5+0x58], [r5+0x80], [r0] + QPEL_V_LOW [r5+0x50], [r5+0x58], [r5+0x60], [r5+0x80], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+0x58], [r5+0x60], [r5+0x68], [r5+0x78], [r0] + QPEL_V_LOW [r5+0x60], [r5+0x68], [r5+0x70], [r5+0x70], [r0+r2] + + add r5, 0x88 + add r0, r1 + dec r4d + jne .loopv + REP_RET +%endmacro + +%macro PUT_OPH 2-3 + movh %1, %2 +%endmacro + +%macro AVG_OPH 2-3 + movh %3, %1 + pavgb %2, %3 + movh %1, %2 +%endmacro + +INIT_MMX mmxext +%define PW_ROUND pw_16 +%define OP_MOV PUT_OPH +MPEG4_QPEL16_V_LOWPASS put +%define PW_ROUND pw_16 +%define OP_MOV AVG_OPH +MPEG4_QPEL16_V_LOWPASS avg +%define PW_ROUND pw_15 +%define OP_MOV PUT_OPH +MPEG4_QPEL16_V_LOWPASS put_no_rnd + + + +%macro MPEG4_QPEL8_V_LOWPASS 1 +cglobal %1_mpeg4_qpel8_v_lowpass, 4, 6, 0, 288 + movsxdifnidn r2, r2d + movsxdifnidn r3, r3d + + mov r4d, 9 + mov r5, rsp + pxor m7, m7 +.looph: + mova m0, [r1] + mova m1, [r1] + punpcklbw m0, m7 + punpckhbw m1, m7 + mova [r5], m0 + mova [r5+0x48], m1 + add r5, 8 + add r1, r3 + dec r4d + jne .looph + + + ; NOTE: r1 CHANGES VALUES: r1 -> 4 - 6*dstStride + mov r4d, 2 + mov r1, 4 + neg r2 + lea r1, [r1+r2*4] + lea r1, [r1+r2*2] + neg r2 + mov r5, rsp +.loopv: + pxor m7, m7 + mova m0, [r5+ 0x0] + mova m1, [r5+ 0x8] + mova m2, [r5+0x10] + mova m3, [r5+0x18] + QPEL_V_LOW [r5+0x10], [r5+ 0x8], [r5+ 0x0], [r5+0x20], [r0] + QPEL_V_LOW [r5+ 0x8], [r5+ 0x0], [r5+ 0x0], [r5+0x28], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+ 0x0], [r5+ 0x0], [r5+ 0x8], [r5+0x30], [r0] + QPEL_V_LOW [r5+ 0x0], [r5+ 0x8], [r5+0x10], [r5+0x38], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+ 0x8], [r5+0x10], [r5+0x18], [r5+0x40], [r0] + QPEL_V_LOW [r5+0x10], [r5+0x18], [r5+0x20], [r5+0x40], [r0+r2] + lea r0, [r0+r2*2] + QPEL_V_LOW [r5+0x18], [r5+0x20], [r5+0x28], [r5+0x38], [r0] + QPEL_V_LOW [r5+0x20], [r5+0x28], [r5+0x30], [r5+0x30], [r0+r2] + + add r5, 0x48 + add r0, r1 + dec r4d + jne .loopv + REP_RET +%endmacro + +INIT_MMX mmxext +%define PW_ROUND pw_16 +%define OP_MOV PUT_OPH +MPEG4_QPEL8_V_LOWPASS put +%define PW_ROUND pw_16 +%define OP_MOV AVG_OPH +MPEG4_QPEL8_V_LOWPASS avg +%define PW_ROUND pw_15 +%define OP_MOV PUT_OPH +MPEG4_QPEL8_V_LOWPASS put_no_rnd diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpeldsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpeldsp_init.c new file mode 100644 index 00000000..3b05e156 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/qpeldsp_init.c @@ -0,0 +1,544 @@ +/* + * quarterpel DSP functions + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * 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 +#include + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/pixels.h" +#include "libavcodec/qpeldsp.h" +#include "fpel.h" + +void ff_put_pixels8_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels8_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_pixels16_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_avg_pixels16_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, + const uint8_t *src1, const uint8_t *src2, + int dstStride, int src1Stride, int h); +void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride, + int h); +void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride, int h); +void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride, + int h); +void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride); +void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, const uint8_t *src, + int dstStride, int srcStride); +void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, + const uint8_t *src, + int dstStride, int srcStride); +#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmx +#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmx + +#if HAVE_X86ASM + +#define ff_put_pixels16_mmxext ff_put_pixels16_mmx +#define ff_put_pixels8_mmxext ff_put_pixels8_mmx + +#define QPEL_OP(OPNAME, RND, MMX) \ +static void OPNAME ## qpel8_mc00_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \ + stride, 8); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \ + stride, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \ + stride, 8); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \ + 8, stride); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \ + stride, stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src, \ + stride, stride); \ +} \ + \ +static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[8]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \ + 8, stride); \ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half + 64; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\ + ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \ + stride, 8, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, \ + 8, stride, 9); \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[8 + 9]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \ + stride, 9); \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[9]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \ + stride, 9); \ + ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \ + stride, 8); \ +} \ + \ +static void OPNAME ## qpel16_mc00_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \ + stride, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src, \ + stride, stride, 16);\ +} \ + \ +static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t*) temp; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \ + stride, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half, \ + stride, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \ + stride); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src, \ + stride, stride); \ +} \ + \ +static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t temp[32]; \ + uint8_t *const half = (uint8_t *) temp; \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \ + stride); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half, \ + stride, stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[16 * 2 + 17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half + 256; \ + uint8_t *const halfHV = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \ + 16, 16); \ + ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \ + stride, 16, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \ + stride, 17); \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \ + stride, 17); \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ + stride, 16); \ +} \ + \ +static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + uint64_t half[17 * 2]; \ + uint8_t *const halfH = (uint8_t *) half; \ + ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \ + stride, 17); \ + ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \ + stride, 16); \ +} + +QPEL_OP(put_, _, mmxext) +QPEL_OP(avg_, _, mmxext) +QPEL_OP(put_no_rnd_, _no_rnd_, mmxext) + +#endif /* HAVE_X86ASM */ + +#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \ +do { \ + c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \ + c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \ +} while (0) + +av_cold void ff_qpeldsp_init_x86(QpelDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (X86_MMXEXT(cpu_flags)) { +#if HAVE_MMXEXT_EXTERNAL + SET_QPEL_FUNCS(avg_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(avg_qpel, 1, 8, mmxext, ); + + SET_QPEL_FUNCS(put_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(put_qpel, 1, 8, mmxext, ); + SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, ); + SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmxext, ); +#endif /* HAVE_MMXEXT_EXTERNAL */ + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rnd_template.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rnd_template.c new file mode 100644 index 00000000..09946bd2 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rnd_template.c @@ -0,0 +1,175 @@ +/* + * SIMD-optimized halfpel functions are compiled twice for rnd/no_rnd + * Copyright (c) 2000, 2001 Fabrice Bellard + * Copyright (c) 2003-2004 Michael Niedermayer + * + * MMX optimization by Nick Kurshev + * mostly rewritten by Michael Niedermayer + * and improved by Zdenek Kabelac + * + * 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 +#include + +#include "inline_asm.h" + +// put_pixels +av_unused STATIC void DEF(put, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h) +{ + MOVQ_ZERO(mm7); + SET_RND(mm6); // =2 for rnd and =1 for no_rnd version + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"FF_REG_a", %%"FF_REG_a" \n\t" + "add %3, %1 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "movq %%mm4, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "movq %%mm0, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} + +// avg_pixels +// this routine is 'slightly' suboptimal but mostly unused +av_unused STATIC void DEF(avg, pixels8_xy2)(uint8_t *block, const uint8_t *pixels, + ptrdiff_t line_size, int h) +{ + MOVQ_ZERO(mm7); + SET_RND(mm6); // =2 for rnd and =1 for no_rnd version + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 1(%1), %%mm4 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "xor %%"FF_REG_a", %%"FF_REG_a" \n\t" + "add %3, %1 \n\t" + ".p2align 3 \n\t" + "1: \n\t" + "movq (%1, %%"FF_REG_a"), %%mm0 \n\t" + "movq 1(%1, %%"FF_REG_a"), %%mm2 \n\t" + "movq %%mm0, %%mm1 \n\t" + "movq %%mm2, %%mm3 \n\t" + "punpcklbw %%mm7, %%mm0 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpckhbw %%mm7, %%mm1 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "paddusw %%mm2, %%mm0 \n\t" + "paddusw %%mm3, %%mm1 \n\t" + "paddusw %%mm6, %%mm4 \n\t" + "paddusw %%mm6, %%mm5 \n\t" + "paddusw %%mm0, %%mm4 \n\t" + "paddusw %%mm1, %%mm5 \n\t" + "psrlw $2, %%mm4 \n\t" + "psrlw $2, %%mm5 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "packuswb %%mm5, %%mm4 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB_MMX(%%mm3, %%mm4, %%mm5, %%mm2) + "movq %%mm5, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "movq (%1, %%"FF_REG_a"), %%mm2 \n\t" // 0 <-> 2 1 <-> 3 + "movq 1(%1, %%"FF_REG_a"), %%mm4 \n\t" + "movq %%mm2, %%mm3 \n\t" + "movq %%mm4, %%mm5 \n\t" + "punpcklbw %%mm7, %%mm2 \n\t" + "punpcklbw %%mm7, %%mm4 \n\t" + "punpckhbw %%mm7, %%mm3 \n\t" + "punpckhbw %%mm7, %%mm5 \n\t" + "paddusw %%mm2, %%mm4 \n\t" + "paddusw %%mm3, %%mm5 \n\t" + "paddusw %%mm6, %%mm0 \n\t" + "paddusw %%mm6, %%mm1 \n\t" + "paddusw %%mm4, %%mm0 \n\t" + "paddusw %%mm5, %%mm1 \n\t" + "psrlw $2, %%mm0 \n\t" + "psrlw $2, %%mm1 \n\t" + "movq (%2, %%"FF_REG_a"), %%mm3 \n\t" + "packuswb %%mm1, %%mm0 \n\t" + "pcmpeqd %%mm2, %%mm2 \n\t" + "paddb %%mm2, %%mm2 \n\t" + PAVGB_MMX(%%mm3, %%mm0, %%mm1, %%mm2) + "movq %%mm1, (%2, %%"FF_REG_a") \n\t" + "add %3, %%"FF_REG_a" \n\t" + + "subl $2, %0 \n\t" + "jnz 1b \n\t" + :"+g"(h), "+S"(pixels) + :"D"(block), "r"((x86_reg)line_size) + :FF_REG_a, "memory"); +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv34dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv34dsp.asm new file mode 100644 index 00000000..692b4acf --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv34dsp.asm @@ -0,0 +1,213 @@ +;****************************************************************************** +;* MMX/SSE2-optimized functions for the RV30 and RV40 decoders +;* Copyright (C) 2012 Christophe Gisquet +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +pw_row_coeffs: times 4 dw 13 + times 4 dw 17 + times 4 dw 7 +pd_512: times 2 dd 0x200 +pw_col_coeffs: dw 13, 13, 13, -13 + dw 17, 7, 7, -17 + dw 13, -13, 13, 13 + dw -7, 17, -17, -7 + +SECTION .text + +%macro IDCT_DC_NOROUND 1 + imul %1, 13*13*3 + sar %1, 11 +%endmacro + +%macro IDCT_DC_ROUND 1 + imul %1, 13*13 + add %1, 0x200 + sar %1, 10 +%endmacro + +%macro rv34_idct 1 +cglobal rv34_idct_%1, 1, 2, 0 + movsx r1, word [r0] + IDCT_DC r1 + movd m0, r1d + pshufw m0, m0, 0 + movq [r0+ 0], m0 + movq [r0+ 8], m0 + movq [r0+16], m0 + movq [r0+24], m0 + REP_RET +%endmacro + +INIT_MMX mmxext +%define IDCT_DC IDCT_DC_ROUND +rv34_idct dc +%define IDCT_DC IDCT_DC_NOROUND +rv34_idct dc_noround + +; ff_rv34_idct_dc_add_mmx(uint8_t *dst, int stride, int dc); +%if ARCH_X86_32 +INIT_MMX mmx +cglobal rv34_idct_dc_add, 3, 3 + ; calculate DC + IDCT_DC_ROUND r2 + pxor m1, m1 + movd m0, r2d + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 + punpcklbw m0, m0 + punpcklbw m1, m1 + punpcklwd m0, m0 + punpcklwd m1, m1 + + ; add DC + lea r2, [r0+r1*2] + movh m2, [r0] + movh m3, [r0+r1] + movh m4, [r2] + movh m5, [r2+r1] + paddusb m2, m0 + paddusb m3, m0 + paddusb m4, m0 + paddusb m5, m0 + psubusb m2, m1 + psubusb m3, m1 + psubusb m4, m1 + psubusb m5, m1 + movh [r0], m2 + movh [r0+r1], m3 + movh [r2], m4 + movh [r2+r1], m5 + RET +%endif + +; Load coeffs and perform row transform +; Output: coeffs in mm[0467], rounder in mm5 +%macro ROW_TRANSFORM 1 + pxor mm7, mm7 + mova mm0, [%1+ 0*8] + mova mm1, [%1+ 1*8] + mova mm2, [%1+ 2*8] + mova mm3, [%1+ 3*8] + mova [%1+ 0*8], mm7 + mova [%1+ 1*8], mm7 + mova [%1+ 2*8], mm7 + mova [%1+ 3*8], mm7 + mova mm4, mm0 + mova mm6, [pw_row_coeffs+ 0] + paddsw mm0, mm2 ; b0 + b2 + psubsw mm4, mm2 ; b0 - b2 + pmullw mm0, mm6 ; *13 = z0 + pmullw mm4, mm6 ; *13 = z1 + mova mm5, mm1 + pmullw mm1, [pw_row_coeffs+ 8] ; b1*17 + pmullw mm5, [pw_row_coeffs+16] ; b1* 7 + mova mm7, mm3 + pmullw mm3, [pw_row_coeffs+ 8] ; b3*17 + pmullw mm7, [pw_row_coeffs+16] ; b3* 7 + paddsw mm1, mm7 ; z3 = b1*17 + b3* 7 + psubsw mm5, mm3 ; z2 = b1* 7 - b3*17 + mova mm7, mm0 + mova mm6, mm4 + paddsw mm0, mm1 ; z0 + z3 + psubsw mm7, mm1 ; z0 - z3 + paddsw mm4, mm5 ; z1 + z2 + psubsw mm6, mm5 ; z1 - z2 + mova mm5, [pd_512] ; 0x200 +%endmacro + +; ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block); +%macro COL_TRANSFORM 4 + pshufw mm3, %2, 0xDD ; col. 1,3,1,3 + pshufw %2, %2, 0x88 ; col. 0,2,0,2 + pmaddwd %2, %3 ; 13*c0+13*c2 | 13*c0-13*c2 = z0 | z1 + pmaddwd mm3, %4 ; 17*c1+ 7*c3 | 7*c1-17*c3 = z3 | z2 + paddd %2, mm5 + pshufw mm1, %2, 01001110b ; z1 | z0 + pshufw mm2, mm3, 01001110b ; z2 | z3 + paddd %2, mm3 ; z0+z3 | z1+z2 + psubd mm1, mm2 ; z1-z2 | z0-z3 + movd mm3, %1 + psrad %2, 10 + pxor mm2, mm2 + psrad mm1, 10 + punpcklbw mm3, mm2 + packssdw %2, mm1 + paddw %2, mm3 + packuswb %2, %2 + movd %1, %2 +%endmacro +INIT_MMX mmxext +cglobal rv34_idct_add, 3,3,0, d, s, b + ROW_TRANSFORM bq + COL_TRANSFORM [dq], mm0, [pw_col_coeffs+ 0], [pw_col_coeffs+ 8] + mova mm0, [pw_col_coeffs+ 0] + COL_TRANSFORM [dq+sq], mm4, mm0, [pw_col_coeffs+ 8] + mova mm4, [pw_col_coeffs+ 8] + lea dq, [dq + 2*sq] + COL_TRANSFORM [dq], mm6, mm0, mm4 + COL_TRANSFORM [dq+sq], mm7, mm0, mm4 + ret + +; ff_rv34_idct_dc_add_sse4(uint8_t *dst, int stride, int dc); +%macro RV34_IDCT_DC_ADD 0 +cglobal rv34_idct_dc_add, 3, 3, 6 + ; load data + IDCT_DC_ROUND r2 + pxor m1, m1 + + ; calculate DC + movd m0, r2d + lea r2, [r0+r1*2] + movd m2, [r0] + movd m3, [r0+r1] + pshuflw m0, m0, 0 + movd m4, [r2] + movd m5, [r2+r1] + punpcklqdq m0, m0 + punpckldq m2, m3 + punpckldq m4, m5 + punpcklbw m2, m1 + punpcklbw m4, m1 + paddw m2, m0 + paddw m4, m0 + packuswb m2, m4 + movd [r0], m2 +%if cpuflag(sse4) + pextrd [r0+r1], m2, 1 + pextrd [r2], m2, 2 + pextrd [r2+r1], m2, 3 +%else + psrldq m2, 4 + movd [r0+r1], m2 + psrldq m2, 4 + movd [r2], m2 + psrldq m2, 4 + movd [r2+r1], m2 +%endif + RET +%endmacro + +INIT_XMM sse2 +RV34_IDCT_DC_ADD +INIT_XMM sse4 +RV34_IDCT_DC_ADD diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv34dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv34dsp_init.c new file mode 100644 index 00000000..73101224 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv34dsp_init.c @@ -0,0 +1,48 @@ +/* + * RV30/40 MMX/SSE2 optimizations + * Copyright (C) 2012 Christophe Gisquet + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/rv34dsp.h" + +void ff_rv34_idct_dc_mmxext(int16_t *block); +void ff_rv34_idct_dc_noround_mmxext(int16_t *block); +void ff_rv34_idct_dc_add_mmx(uint8_t *dst, ptrdiff_t stride, int dc); +void ff_rv34_idct_dc_add_sse2(uint8_t *dst, ptrdiff_t stride, int dc); +void ff_rv34_idct_dc_add_sse4(uint8_t *dst, ptrdiff_t stride, int dc); +void ff_rv34_idct_add_mmxext(uint8_t *dst, ptrdiff_t stride, int16_t *block); + +av_cold void ff_rv34dsp_init_x86(RV34DSPContext* c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (ARCH_X86_32 && EXTERNAL_MMX(cpu_flags)) + c->rv34_idct_dc_add = ff_rv34_idct_dc_add_mmx; + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->rv34_inv_transform_dc = ff_rv34_idct_dc_noround_mmxext; + c->rv34_idct_add = ff_rv34_idct_add_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) + c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse2; + if (EXTERNAL_SSE4(cpu_flags)) + c->rv34_idct_dc_add = ff_rv34_idct_dc_add_sse4; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv40dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv40dsp.asm new file mode 100644 index 00000000..bcad1aee --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv40dsp.asm @@ -0,0 +1,500 @@ +;****************************************************************************** +;* MMX/SSE2-optimized functions for the RV40 decoder +;* Copyright (c) 2010 Ronald S. Bultje +;* Copyright (c) 2010 Fiona Glaser +;* Copyright (C) 2012 Christophe Gisquet +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pw_1024: times 8 dw 1 << (16 - 6) ; pw_1024 + +sixtap_filter_hb_m: times 8 db 1, -5 + times 8 db 52, 20 + ; multiplied by 2 to have the same shift + times 8 db 2, -10 + times 8 db 40, 40 + ; back to normal + times 8 db 1, -5 + times 8 db 20, 52 + +sixtap_filter_v_m: times 8 dw 1 + times 8 dw -5 + times 8 dw 52 + times 8 dw 20 + ; multiplied by 2 to have the same shift + times 8 dw 2 + times 8 dw -10 + times 8 dw 40 + times 8 dw 40 + ; back to normal + times 8 dw 1 + times 8 dw -5 + times 8 dw 20 + times 8 dw 52 + +%ifdef PIC +%define sixtap_filter_hw picregq +%define sixtap_filter_hb picregq +%define sixtap_filter_v picregq +%define npicregs 1 +%else +%define sixtap_filter_hw sixtap_filter_hw_m +%define sixtap_filter_hb sixtap_filter_hb_m +%define sixtap_filter_v sixtap_filter_v_m +%define npicregs 0 +%endif + +filter_h6_shuf1: db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 +filter_h6_shuf2: db 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10 +filter_h6_shuf3: db 5, 4, 6, 5, 7, 6, 8, 7, 9, 8, 10, 9, 11, 10, 12, 11 + +cextern pw_32 +cextern pw_16 +cextern pw_512 + +SECTION .text + +;----------------------------------------------------------------------------- +; subpel MC functions: +; +; void ff_[put|rv40]_rv40_qpel_[h|v]_(uint8_t *dst, int deststride, +; uint8_t *src, int srcstride, +; int len, int m); +;---------------------------------------------------------------------- +%macro LOAD 2 +%if WIN64 + movsxd %1q, %1d +%endif +%ifdef PIC + add %1q, picregq +%else + add %1q, %2 +%endif +%endmacro + +%macro STORE 3 +%ifidn %3, avg + movh %2, [dstq] +%endif + packuswb %1, %1 +%ifidn %3, avg + PAVGB %1, %2 +%endif + movh [dstq], %1 +%endmacro + +%macro FILTER_V 1 +cglobal %1_rv40_qpel_v, 6,6+npicregs,12, dst, dststride, src, srcstride, height, my, picreg +%ifdef PIC + lea picregq, [sixtap_filter_v_m] +%endif + pxor m7, m7 + LOAD my, sixtap_filter_v + + ; read 5 lines + sub srcq, srcstrideq + sub srcq, srcstrideq + movh m0, [srcq] + movh m1, [srcq+srcstrideq] + movh m2, [srcq+srcstrideq*2] + lea srcq, [srcq+srcstrideq*2] + add srcq, srcstrideq + movh m3, [srcq] + movh m4, [srcq+srcstrideq] + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + +%ifdef m8 + mova m8, [myq+ 0] + mova m9, [myq+16] + mova m10, [myq+32] + mova m11, [myq+48] +%define COEFF05 m8 +%define COEFF14 m9 +%define COEFF2 m10 +%define COEFF3 m11 +%else +%define COEFF05 [myq+ 0] +%define COEFF14 [myq+16] +%define COEFF2 [myq+32] +%define COEFF3 [myq+48] +%endif +.nextrow: + mova m6, m1 + movh m5, [srcq+2*srcstrideq] ; read new row + paddw m6, m4 + punpcklbw m5, m7 + pmullw m6, COEFF14 + paddw m0, m5 + pmullw m0, COEFF05 + paddw m6, m0 + mova m0, m1 + paddw m6, [pw_32] + mova m1, m2 + pmullw m2, COEFF2 + paddw m6, m2 + mova m2, m3 + pmullw m3, COEFF3 + paddw m6, m3 + + ; round/clip/store + mova m3, m4 + psraw m6, 6 + mova m4, m5 + STORE m6, m5, %1 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET +%endmacro + +%macro FILTER_H 1 +cglobal %1_rv40_qpel_h, 6, 6+npicregs, 12, dst, dststride, src, srcstride, height, mx, picreg +%ifdef PIC + lea picregq, [sixtap_filter_v_m] +%endif + pxor m7, m7 + LOAD mx, sixtap_filter_v + mova m6, [pw_32] +%ifdef m8 + mova m8, [mxq+ 0] + mova m9, [mxq+16] + mova m10, [mxq+32] + mova m11, [mxq+48] +%define COEFF05 m8 +%define COEFF14 m9 +%define COEFF2 m10 +%define COEFF3 m11 +%else +%define COEFF05 [mxq+ 0] +%define COEFF14 [mxq+16] +%define COEFF2 [mxq+32] +%define COEFF3 [mxq+48] +%endif +.nextrow: + movq m0, [srcq-2] + movq m5, [srcq+3] + movq m1, [srcq-1] + movq m4, [srcq+2] + punpcklbw m0, m7 + punpcklbw m5, m7 + punpcklbw m1, m7 + punpcklbw m4, m7 + movq m2, [srcq-0] + movq m3, [srcq+1] + paddw m0, m5 + paddw m1, m4 + punpcklbw m2, m7 + punpcklbw m3, m7 + pmullw m0, COEFF05 + pmullw m1, COEFF14 + pmullw m2, COEFF2 + pmullw m3, COEFF3 + paddw m0, m6 + paddw m1, m2 + paddw m0, m3 + paddw m0, m1 + psraw m0, 6 + STORE m0, m1, %1 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +FILTER_V put +FILTER_H put + +INIT_MMX mmxext +FILTER_V avg +FILTER_H avg + +INIT_MMX 3dnow +FILTER_V avg +FILTER_H avg +%endif + +INIT_XMM sse2 +FILTER_H put +FILTER_H avg +FILTER_V put +FILTER_V avg + +%macro FILTER_SSSE3 1 +cglobal %1_rv40_qpel_v, 6,6+npicregs,8, dst, dststride, src, srcstride, height, my, picreg +%ifdef PIC + lea picregq, [sixtap_filter_hb_m] +%endif + + ; read 5 lines + sub srcq, srcstrideq + LOAD my, sixtap_filter_hb + sub srcq, srcstrideq + movh m0, [srcq] + movh m1, [srcq+srcstrideq] + movh m2, [srcq+srcstrideq*2] + lea srcq, [srcq+srcstrideq*2] + add srcq, srcstrideq + mova m5, [myq] + movh m3, [srcq] + movh m4, [srcq+srcstrideq] + lea srcq, [srcq+2*srcstrideq] + +.nextrow: + mova m6, m2 + punpcklbw m0, m1 + punpcklbw m6, m3 + pmaddubsw m0, m5 + pmaddubsw m6, [myq+16] + movh m7, [srcq] ; read new row + paddw m6, m0 + mova m0, m1 + mova m1, m2 + mova m2, m3 + mova m3, m4 + mova m4, m7 + punpcklbw m7, m3 + pmaddubsw m7, m5 + paddw m6, m7 + pmulhrsw m6, [pw_512] + STORE m6, m7, %1 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +cglobal %1_rv40_qpel_h, 6,6+npicregs,8, dst, dststride, src, srcstride, height, mx, picreg +%ifdef PIC + lea picregq, [sixtap_filter_hb_m] +%endif + mova m3, [filter_h6_shuf2] + mova m4, [filter_h6_shuf3] + LOAD mx, sixtap_filter_hb + mova m5, [mxq] ; set up 6tap filter in bytes + mova m6, [mxq+16] + mova m7, [filter_h6_shuf1] + +.nextrow: + movu m0, [srcq-2] + mova m1, m0 + mova m2, m0 + pshufb m0, m7 + pshufb m1, m3 + pshufb m2, m4 + pmaddubsw m0, m5 + pmaddubsw m1, m6 + pmaddubsw m2, m5 + paddw m0, m1 + paddw m0, m2 + pmulhrsw m0, [pw_512] + STORE m0, m1, %1 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET +%endmacro + +INIT_XMM ssse3 +FILTER_SSSE3 put +FILTER_SSSE3 avg + +; %1=5-bit weights?, %2=dst %3=src1 %4=src3 %5=stride if SSE2 +%macro RV40_WCORE 4-5 + movh m4, [%3 + r6 + 0] + movh m5, [%4 + r6 + 0] +%if %0 == 4 +%define OFFSET r6 + mmsize / 2 +%else + ; 8x8 block and SSE2, stride was provided +%define OFFSET r6 + add r6, r5 +%endif + movh m6, [%3 + OFFSET] + movh m7, [%4 + OFFSET] + +%if %1 == 0 + ; 14-bit weights + punpcklbw m4, m0 + punpcklbw m5, m0 + punpcklbw m6, m0 + punpcklbw m7, m0 + + psllw m4, 7 + psllw m5, 7 + psllw m6, 7 + psllw m7, 7 + pmulhw m4, m3 + pmulhw m5, m2 + pmulhw m6, m3 + pmulhw m7, m2 + + paddw m4, m5 + paddw m6, m7 +%else + ; 5-bit weights +%if cpuflag(ssse3) + punpcklbw m4, m5 + punpcklbw m6, m7 + + pmaddubsw m4, m3 + pmaddubsw m6, m3 +%else + punpcklbw m4, m0 + punpcklbw m5, m0 + punpcklbw m6, m0 + punpcklbw m7, m0 + + pmullw m4, m3 + pmullw m5, m2 + pmullw m6, m3 + pmullw m7, m2 + paddw m4, m5 + paddw m6, m7 +%endif + +%endif + + ; bias and shift down +%if cpuflag(ssse3) + pmulhrsw m4, m1 + pmulhrsw m6, m1 +%else + paddw m4, m1 + paddw m6, m1 + psrlw m4, 5 + psrlw m6, 5 +%endif + + packuswb m4, m6 +%if %0 == 5 + ; Only called for 8x8 blocks and SSE2 + sub r6, r5 + movh [%2 + r6], m4 + add r6, r5 + movhps [%2 + r6], m4 +%else + mova [%2 + r6], m4 +%endif +%endmacro + + +%macro MAIN_LOOP 2 +%if mmsize == 8 + RV40_WCORE %2, r0, r1, r2 +%if %1 == 16 + RV40_WCORE %2, r0 + 8, r1 + 8, r2 + 8 +%endif + + ; Prepare for next loop + add r6, r5 +%else +%ifidn %1, 8 + RV40_WCORE %2, r0, r1, r2, r5 + ; Prepare 2 next lines + add r6, r5 +%else + RV40_WCORE %2, r0, r1, r2 + ; Prepare single next line + add r6, r5 +%endif +%endif + +%endmacro + +; void ff_rv40_weight_func_%1(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, int stride) +; %1=size %2=num of xmm regs +; The weights are FP0.14 notation of fractions depending on pts. +; For timebases without rounding error (i.e. PAL), the fractions +; can be simplified, and several operations can be avoided. +; Therefore, we check here whether they are multiples of 2^9 for +; those simplifications to occur. +%macro RV40_WEIGHT 3 +cglobal rv40_weight_func_%1_%2, 6, 7, 8 +%if cpuflag(ssse3) + mova m1, [pw_1024] +%else + mova m1, [pw_16] +%endif + pxor m0, m0 + ; Set loop counter and increments + mov r6, r5 + shl r6, %3 + add r0, r6 + add r1, r6 + add r2, r6 + neg r6 + + movd m2, r3d + movd m3, r4d +%ifidn %1,rnd +%define RND 0 + SPLATW m2, m2 +%else +%define RND 1 +%if cpuflag(ssse3) + punpcklbw m3, m2 +%else + SPLATW m2, m2 +%endif +%endif + SPLATW m3, m3 + +.loop: + MAIN_LOOP %2, RND + jnz .loop + REP_RET +%endmacro + +INIT_MMX mmxext +RV40_WEIGHT rnd, 8, 3 +RV40_WEIGHT rnd, 16, 4 +RV40_WEIGHT nornd, 8, 3 +RV40_WEIGHT nornd, 16, 4 + +INIT_XMM sse2 +RV40_WEIGHT rnd, 8, 3 +RV40_WEIGHT rnd, 16, 4 +RV40_WEIGHT nornd, 8, 3 +RV40_WEIGHT nornd, 16, 4 + +INIT_XMM ssse3 +RV40_WEIGHT rnd, 8, 3 +RV40_WEIGHT rnd, 16, 4 +RV40_WEIGHT nornd, 8, 3 +RV40_WEIGHT nornd, 16, 4 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv40dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv40dsp_init.c new file mode 100644 index 00000000..79a617ff --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/rv40dsp_init.c @@ -0,0 +1,279 @@ +/* + * RV40 decoder motion compensation functions x86-optimised + * Copyright (c) 2008 Konstantin Shishkov + * + * 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 + */ + +/** + * @file + * RV40 decoder motion compensation functions x86-optimised + * 2,0 and 0,2 have h264 equivalents. + * 3,3 is bugged in the rv40 format and maps to _xy2 version + */ + +#include "libavcodec/rv34dsp.h" +#include "libavutil/attributes.h" +#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/cpu.h" +#include "hpeldsp.h" + +#define DEFINE_FN(op, size, insn) \ +static void op##_rv40_qpel##size##_mc33_##insn(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + ff_##op##_pixels##size##_xy2_##insn(dst, src, stride, size); \ +} + +#if HAVE_X86ASM +void ff_put_rv40_chroma_mc8_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc8_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc8_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +void ff_put_rv40_chroma_mc4_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc4_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_rv40_chroma_mc4_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); + +#define DECLARE_WEIGHT(opt) \ +void ff_rv40_weight_func_rnd_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); \ +void ff_rv40_weight_func_rnd_8_##opt (uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); \ +void ff_rv40_weight_func_nornd_16_##opt(uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); \ +void ff_rv40_weight_func_nornd_8_##opt (uint8_t *dst, uint8_t *src1, uint8_t *src2, \ + int w1, int w2, ptrdiff_t stride); +DECLARE_WEIGHT(mmxext) +DECLARE_WEIGHT(sse2) +DECLARE_WEIGHT(ssse3) + +/** @{ */ +/** + * Define one qpel function. + * LOOPSIZE must be already set to the number of pixels processed per + * iteration in the inner loop of the called functions. + * COFF(x) must be already defined so as to provide the offset into any + * array of coeffs used by the called function for the qpel position x. + */ +#define QPEL_FUNC_DECL(OP, SIZE, PH, PV, OPT) \ +static void OP ## rv40_qpel ##SIZE ##_mc ##PH ##PV ##OPT(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride) \ +{ \ + int i; \ + if (PH && PV) { \ + LOCAL_ALIGNED(16, uint8_t, tmp, [SIZE * (SIZE + 5)]); \ + uint8_t *tmpptr = tmp + SIZE * 2; \ + src -= stride * 2; \ + \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_put_rv40_qpel_h ##OPT(tmp + i, SIZE, src + i, stride, \ + SIZE + 5, HCOFF(PH)); \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_ ##OP ##rv40_qpel_v ##OPT(dst + i, stride, tmpptr + i, \ + SIZE, SIZE, VCOFF(PV)); \ + } else if (PV) { \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_ ##OP ##rv40_qpel_v ## OPT(dst + i, stride, src + i, \ + stride, SIZE, VCOFF(PV)); \ + } else { \ + for (i = 0; i < SIZE; i += LOOPSIZE) \ + ff_ ##OP ##rv40_qpel_h ## OPT(dst + i, stride, src + i, \ + stride, SIZE, HCOFF(PH)); \ + } \ +} + +/** Declare functions for sizes 8 and 16 and given operations + * and qpel position. */ +#define QPEL_FUNCS_DECL(OP, PH, PV, OPT) \ + QPEL_FUNC_DECL(OP, 8, PH, PV, OPT) \ + QPEL_FUNC_DECL(OP, 16, PH, PV, OPT) + +/** Declare all functions for all sizes and qpel positions */ +#define QPEL_MC_DECL(OP, OPT) \ +void ff_ ##OP ##rv40_qpel_h ##OPT(uint8_t *dst, ptrdiff_t dstStride, \ + const uint8_t *src, \ + ptrdiff_t srcStride, \ + int len, int m); \ +void ff_ ##OP ##rv40_qpel_v ##OPT(uint8_t *dst, ptrdiff_t dstStride, \ + const uint8_t *src, \ + ptrdiff_t srcStride, \ + int len, int m); \ +QPEL_FUNCS_DECL(OP, 0, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 0, 3, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 0, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 2, OPT) \ +QPEL_FUNCS_DECL(OP, 1, 3, OPT) \ +QPEL_FUNCS_DECL(OP, 2, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 2, 2, OPT) \ +QPEL_FUNCS_DECL(OP, 2, 3, OPT) \ +QPEL_FUNCS_DECL(OP, 3, 0, OPT) \ +QPEL_FUNCS_DECL(OP, 3, 1, OPT) \ +QPEL_FUNCS_DECL(OP, 3, 2, OPT) +/** @} */ + +#define LOOPSIZE 8 +#define HCOFF(x) (32 * ((x) - 1)) +#define VCOFF(x) (32 * ((x) - 1)) +QPEL_MC_DECL(put_, _ssse3) +QPEL_MC_DECL(avg_, _ssse3) + +#undef LOOPSIZE +#undef HCOFF +#undef VCOFF +#define LOOPSIZE 8 +#define HCOFF(x) (64 * ((x) - 1)) +#define VCOFF(x) (64 * ((x) - 1)) +QPEL_MC_DECL(put_, _sse2) +QPEL_MC_DECL(avg_, _sse2) + +#if ARCH_X86_32 +#undef LOOPSIZE +#undef HCOFF +#undef VCOFF +#define LOOPSIZE 4 +#define HCOFF(x) (64 * ((x) - 1)) +#define VCOFF(x) (64 * ((x) - 1)) + +QPEL_MC_DECL(put_, _mmx) + +#define ff_put_rv40_qpel_h_mmxext ff_put_rv40_qpel_h_mmx +#define ff_put_rv40_qpel_v_mmxext ff_put_rv40_qpel_v_mmx +QPEL_MC_DECL(avg_, _mmxext) + +#define ff_put_rv40_qpel_h_3dnow ff_put_rv40_qpel_h_mmx +#define ff_put_rv40_qpel_v_3dnow ff_put_rv40_qpel_v_mmx +QPEL_MC_DECL(avg_, _3dnow) +#endif + +/** @{ */ +/** Set one function */ +#define QPEL_FUNC_SET(OP, SIZE, PH, PV, OPT) \ + c-> OP ## pixels_tab[2 - SIZE / 8][4 * PV + PH] = OP ## rv40_qpel ##SIZE ## _mc ##PH ##PV ##OPT; + +/** Set functions put and avg for sizes 8 and 16 and a given qpel position */ +#define QPEL_FUNCS_SET(OP, PH, PV, OPT) \ + QPEL_FUNC_SET(OP, 8, PH, PV, OPT) \ + QPEL_FUNC_SET(OP, 16, PH, PV, OPT) + +/** Set all functions for all sizes and qpel positions */ +#define QPEL_MC_SET(OP, OPT) \ +QPEL_FUNCS_SET (OP, 0, 1, OPT) \ +QPEL_FUNCS_SET (OP, 0, 3, OPT) \ +QPEL_FUNCS_SET (OP, 1, 0, OPT) \ +QPEL_FUNCS_SET (OP, 1, 1, OPT) \ +QPEL_FUNCS_SET (OP, 1, 2, OPT) \ +QPEL_FUNCS_SET (OP, 1, 3, OPT) \ +QPEL_FUNCS_SET (OP, 2, 1, OPT) \ +QPEL_FUNCS_SET (OP, 2, 2, OPT) \ +QPEL_FUNCS_SET (OP, 2, 3, OPT) \ +QPEL_FUNCS_SET (OP, 3, 0, OPT) \ +QPEL_FUNCS_SET (OP, 3, 1, OPT) \ +QPEL_FUNCS_SET (OP, 3, 2, OPT) +/** @} */ + +DEFINE_FN(put, 8, ssse3) + +DEFINE_FN(put, 16, sse2) +DEFINE_FN(put, 16, ssse3) + +DEFINE_FN(avg, 8, mmxext) +DEFINE_FN(avg, 8, ssse3) + +DEFINE_FN(avg, 16, sse2) +DEFINE_FN(avg, 16, ssse3) +#endif /* HAVE_X86ASM */ + +#if HAVE_MMX_INLINE +DEFINE_FN(put, 8, mmx) +DEFINE_FN(avg, 8, mmx) +DEFINE_FN(put, 16, mmx) +DEFINE_FN(avg, 16, mmx) +#endif + +av_cold void ff_rv40dsp_init_x86(RV34DSPContext *c) +{ + av_unused int cpu_flags = av_get_cpu_flags(); + +#if HAVE_MMX_INLINE + if (INLINE_MMX(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_mmx; + c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_mmx; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_mmx; + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmx; + } +#endif /* HAVE_MMX_INLINE */ + +#if HAVE_X86ASM + if (EXTERNAL_MMX(cpu_flags)) { + c->put_chroma_pixels_tab[0] = ff_put_rv40_chroma_mc8_mmx; + c->put_chroma_pixels_tab[1] = ff_put_rv40_chroma_mc4_mmx; +#if ARCH_X86_32 + QPEL_MC_SET(put_, _mmx) +#endif + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_3dnow; + c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_3dnow; +#if ARCH_X86_32 + QPEL_MC_SET(avg_, _3dnow) +#endif + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_mmxext; + c->avg_chroma_pixels_tab[0] = ff_avg_rv40_chroma_mc8_mmxext; + c->avg_chroma_pixels_tab[1] = ff_avg_rv40_chroma_mc4_mmxext; + c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_mmxext; + c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_mmxext; + c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_mmxext; + c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_mmxext; +#if ARCH_X86_32 + QPEL_MC_SET(avg_, _mmxext) +#endif + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_sse2; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_sse2; + c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_sse2; + c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_sse2; + c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_sse2; + c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_sse2; + QPEL_MC_SET(put_, _sse2) + QPEL_MC_SET(avg_, _sse2) + } + if (EXTERNAL_SSSE3(cpu_flags)) { + c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_ssse3; + c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_ssse3; + c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_ssse3; + c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_ssse3; + c->rv40_weight_pixels_tab[0][0] = ff_rv40_weight_func_rnd_16_ssse3; + c->rv40_weight_pixels_tab[0][1] = ff_rv40_weight_func_rnd_8_ssse3; + c->rv40_weight_pixels_tab[1][0] = ff_rv40_weight_func_nornd_16_ssse3; + c->rv40_weight_pixels_tab[1][1] = ff_rv40_weight_func_nornd_8_ssse3; + QPEL_MC_SET(put_, _ssse3) + QPEL_MC_SET(avg_, _ssse3) + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbcdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbcdsp.asm new file mode 100644 index 00000000..d68d3a9a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbcdsp.asm @@ -0,0 +1,168 @@ +;****************************************************************************** +;* SIMD optimized SBC encoder DSP functions +;* +;* Copyright (C) 2017 Aurelien Jacobs +;* Copyright (C) 2008-2010 Nokia Corporation +;* Copyright (C) 2004-2010 Marcel Holtmann +;* Copyright (C) 2004-2005 Henryk Ploetz +;* Copyright (C) 2005-2006 Brad Midgley +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +scale_mask: times 2 dd 0x8000 ; 1 << (SBC_PROTO_FIXED_SCALE - 1) + +SECTION .text + +%macro NIDN 3 +%ifnidn %2, %3 + %1 %2, %3 +%endif +%endmacro + +%macro ANALYZE_MAC 9 ; out1, out2, in1, in2, tmp1, tmp2, add1, add2, offset + NIDN movq, %5, %3 + NIDN movq, %6, %4 + pmaddwd %5, [constsq+%9] + pmaddwd %6, [constsq+%9+8] + NIDN paddd, %1, %7 + NIDN paddd, %2, %8 +%endmacro + +%macro ANALYZE_MAC_IN 7 ; out1, out2, tmp1, tmp2, add1, add2, offset + ANALYZE_MAC %1, %2, [inq+%7], [inq+%7+8], %3, %4, %5, %6, %7 +%endmacro + +%macro ANALYZE_MAC_REG 7 ; out1, out2, in, tmp1, tmp2, offset, pack +%ifidn %7, pack + psrad %3, 16 ; SBC_PROTO_FIXED_SCALE + packssdw %3, %3 +%endif + ANALYZE_MAC %1, %2, %3, %3, %4, %5, %4, %5, %6 +%endmacro + +;******************************************************************* +;void ff_sbc_analyze_4(const int16_t *in, int32_t *out, const int16_t *consts); +;******************************************************************* +INIT_MMX mmx +cglobal sbc_analyze_4, 3, 3, 4, in, out, consts + ANALYZE_MAC_IN m0, m1, m0, m1, [scale_mask], [scale_mask], 0 + ANALYZE_MAC_IN m0, m1, m2, m3, m2, m3, 16 + ANALYZE_MAC_IN m0, m1, m2, m3, m2, m3, 32 + ANALYZE_MAC_IN m0, m1, m2, m3, m2, m3, 48 + ANALYZE_MAC_IN m0, m1, m2, m3, m2, m3, 64 + + ANALYZE_MAC_REG m0, m2, m0, m0, m2, 80, pack + ANALYZE_MAC_REG m0, m2, m1, m1, m3, 96, pack + + movq [outq ], m0 + movq [outq+8], m2 + + RET + + +;******************************************************************* +;void ff_sbc_analyze_8(const int16_t *in, int32_t *out, const int16_t *consts); +;******************************************************************* +INIT_MMX mmx +cglobal sbc_analyze_8, 3, 3, 4, in, out, consts + ANALYZE_MAC_IN m0, m1, m0, m1, [scale_mask], [scale_mask], 0 + ANALYZE_MAC_IN m2, m3, m2, m3, [scale_mask], [scale_mask], 16 + ANALYZE_MAC_IN m0, m1, m4, m5, m4, m5, 32 + ANALYZE_MAC_IN m2, m3, m6, m7, m6, m7, 48 + ANALYZE_MAC_IN m0, m1, m4, m5, m4, m5, 64 + ANALYZE_MAC_IN m2, m3, m6, m7, m6, m7, 80 + ANALYZE_MAC_IN m0, m1, m4, m5, m4, m5, 96 + ANALYZE_MAC_IN m2, m3, m6, m7, m6, m7, 112 + ANALYZE_MAC_IN m0, m1, m4, m5, m4, m5, 128 + ANALYZE_MAC_IN m2, m3, m6, m7, m6, m7, 144 + + ANALYZE_MAC_REG m4, m5, m0, m4, m5, 160, pack + ANALYZE_MAC_REG m4, m5, m1, m6, m7, 192, pack + ANALYZE_MAC_REG m4, m5, m2, m6, m7, 224, pack + ANALYZE_MAC_REG m4, m5, m3, m6, m7, 256, pack + + movq [outq ], m4 + movq [outq+8], m5 + + ANALYZE_MAC_REG m0, m5, m0, m0, m5, 176, no + ANALYZE_MAC_REG m0, m5, m1, m1, m7, 208, no + ANALYZE_MAC_REG m0, m5, m2, m2, m7, 240, no + ANALYZE_MAC_REG m0, m5, m3, m3, m7, 272, no + + movq [outq+16], m0 + movq [outq+24], m5 + + RET + + +;******************************************************************* +;void ff_sbc_calc_scalefactors(int32_t sb_sample_f[16][2][8], +; uint32_t scale_factor[2][8], +; int blocks, int channels, int subbands) +;******************************************************************* +INIT_MMX mmx +cglobal sbc_calc_scalefactors, 5, 7, 4, sb_sample_f, scale_factor, blocks, channels, subbands, ptr, blk + ; subbands = 4 * subbands * channels + movq m3, [scale_mask] + shl subbandsd, 2 + cmp channelsd, 2 + jl .loop_1 + shl subbandsd, 1 + +.loop_1: + sub subbandsq, 8 + lea ptrq, [sb_sample_fq + subbandsq] + + ; blk = (blocks - 1) * 64; + lea blkq, [blocksq - 1] + shl blkd, 6 + + movq m0, m3 +.loop_2: + movq m1, [ptrq+blkq] + pxor m2, m2 + pcmpgtd m1, m2 + paddd m1, [ptrq+blkq] + pcmpgtd m2, m1 + pxor m1, m2 + + por m0, m1 + + sub blkq, 64 + jns .loop_2 + + movd blkd, m0 + psrlq m0, 32 + bsr blkd, blkd + sub blkd, 15 ; SCALE_OUT_BITS + mov [scale_factorq + subbandsq], blkd + + movd blkd, m0 + bsr blkd, blkd + sub blkd, 15 ; SCALE_OUT_BITS + mov [scale_factorq + subbandsq + 4], blkd + + cmp subbandsq, 0 + jg .loop_1 + + emms + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbcdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbcdsp_init.c new file mode 100644 index 00000000..86effecf --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbcdsp_init.c @@ -0,0 +1,51 @@ +/* + * Bluetooth low-complexity, subband codec (SBC) + * + * Copyright (C) 2017 Aurelien Jacobs + * Copyright (C) 2008-2010 Nokia Corporation + * Copyright (C) 2004-2010 Marcel Holtmann + * Copyright (C) 2004-2005 Henryk Ploetz + * Copyright (C) 2005-2006 Brad Midgley + * + * 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 + */ + +/** + * @file + * SBC MMX optimization for some basic "building bricks" + */ + +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/sbcdsp.h" + +void ff_sbc_analyze_4_mmx(const int16_t *in, int32_t *out, const int16_t *consts); +void ff_sbc_analyze_8_mmx(const int16_t *in, int32_t *out, const int16_t *consts); +void ff_sbc_calc_scalefactors_mmx(int32_t sb_sample_f[16][2][8], + uint32_t scale_factor[2][8], + int blocks, int channels, int subbands); + +av_cold void ff_sbcdsp_init_x86(SBCDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + s->sbc_analyze_4 = ff_sbc_analyze_4_mmx; + s->sbc_analyze_8 = ff_sbc_analyze_8_mmx; + s->sbc_calc_scalefactors = ff_sbc_calc_scalefactors_mmx; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbrdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbrdsp.asm new file mode 100644 index 00000000..62bbe512 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbrdsp.asm @@ -0,0 +1,548 @@ +;****************************************************************************** +;* AAC Spectral Band Replication decoding functions +;* Copyright (C) 2012 Christophe Gisquet +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +; mask equivalent for multiply by -1.0 1.0 +ps_mask times 2 dd 1<<31, 0 +ps_mask2 times 2 dd 0, 1<<31 +ps_mask3 dd 0, 0, 0, 1<<31 +ps_noise0 times 2 dd 1.0, 0.0, +ps_noise2 times 2 dd -1.0, 0.0 +ps_noise13 dd 0.0, 1.0, 0.0, -1.0 + dd 0.0, -1.0, 0.0, 1.0 + dd 0.0, 1.0, 0.0, -1.0 +cextern sbr_noise_table +cextern ps_neg + +SECTION .text + +INIT_XMM sse +cglobal sbr_sum_square, 2, 3, 6 + mov r2d, r1d + xorps m0, m0 + xorps m1, m1 + sar r2, 3 + jz .prepare +.loop: + movu m2, [r0 + 0] + movu m3, [r0 + 16] + movu m4, [r0 + 32] + movu m5, [r0 + 48] + mulps m2, m2 + mulps m3, m3 + mulps m4, m4 + mulps m5, m5 + addps m0, m2 + addps m1, m3 + addps m0, m4 + addps m1, m5 + add r0, 64 + dec r2 + jnz .loop +.prepare: + and r1, 7 + sar r1, 1 + jz .end +; len is a multiple of 2, thus there are at least 4 elements to process +.endloop: + movu m2, [r0] + add r0, 16 + mulps m2, m2 + dec r1 + addps m0, m2 + jnz .endloop +.end: + addps m0, m1 + movhlps m2, m0 + addps m0, m2 + movss m1, m0 + shufps m0, m0, 1 + addss m0, m1 +%if ARCH_X86_64 == 0 + movss r0m, m0 + fld dword r0m +%endif + RET + +%define STEP 40*4*2 +cglobal sbr_hf_g_filt, 5, 6, 5 + lea r1, [r1 + 8*r4] ; offset by ixh elements into X_high + mov r5, r3 + and r3, 0xFC + lea r2, [r2 + r3*4] + lea r0, [r0 + r3*8] + neg r3 + jz .loop1 +.loop4: + movlps m0, [r2 + 4*r3 + 0] + movlps m1, [r2 + 4*r3 + 8] + movlps m2, [r1 + 0*STEP] + movlps m3, [r1 + 2*STEP] + movhps m2, [r1 + 1*STEP] + movhps m3, [r1 + 3*STEP] + unpcklps m0, m0 + unpcklps m1, m1 + mulps m0, m2 + mulps m1, m3 + movu [r0 + 8*r3 + 0], m0 + movu [r0 + 8*r3 + 16], m1 + add r1, 4*STEP + add r3, 4 + jnz .loop4 + and r5, 3 ; number of single element loops + jz .end +.loop1: ; element 0 and 1 can be computed at the same time + movss m0, [r2] + movlps m2, [r1] + unpcklps m0, m0 + mulps m2, m0 + movlps [r0], m2 + add r0, 8 + add r2, 4 + add r1, STEP + dec r5 + jnz .loop1 +.end: + RET + +; void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], +; const float alpha0[2], const float alpha1[2], +; float bw, int start, int end) +; +cglobal sbr_hf_gen, 4,4,8, X_high, X_low, alpha0, alpha1, BW, S, E + ; load alpha factors +%define bw m0 +%if ARCH_X86_64 == 0 || WIN64 + movss bw, BWm +%endif + movlps m2, [alpha1q] + movlps m1, [alpha0q] + shufps bw, bw, 0 + mulps m2, bw ; (a1[0] a1[1])*bw + mulps m1, bw ; (a0[0] a0[1])*bw = (a2 a3) + mulps m2, bw ; (a1[0] a1[1])*bw*bw = (a0 a1) + mova m3, m1 + mova m4, m2 + + ; Set pointers +%if ARCH_X86_64 == 0 || WIN64 + ; start and end 6th and 7th args on stack + mov r2d, Sm + mov r3d, Em + DEFINE_ARGS X_high, X_low, start, end +%else +; BW does not actually occupy a register, so shift by 1 + DEFINE_ARGS X_high, X_low, alpha0, alpha1, start, end + movsxd startq, startd + movsxd endq, endd +%endif + sub startq, endq ; neg num of loops + lea X_highq, [X_highq + endq*2*4] + lea X_lowq, [X_lowq + endq*2*4 - 2*2*4] + shl startq, 3 ; offset from num loops + + mova m0, [X_lowq + startq] + shufps m3, m3, q1111 + shufps m4, m4, q1111 + xorps m3, [ps_mask] + shufps m1, m1, q0000 + shufps m2, m2, q0000 + xorps m4, [ps_mask] +.loop2: + movu m7, [X_lowq + startq + 8] ; BbCc + mova m6, m0 + mova m5, m7 + shufps m0, m0, q2301 ; aAbB + shufps m7, m7, q2301 ; bBcC + mulps m0, m4 + mulps m7, m3 + mulps m6, m2 + mulps m5, m1 + addps m7, m0 + mova m0, [X_lowq + startq + 16] ; CcDd + addps m7, m0 + addps m6, m5 + addps m7, m6 + mova [X_highq + startq], m7 + add startq, 16 + jnz .loop2 + RET + +cglobal sbr_sum64x5, 1,2,4,z + lea r1q, [zq+ 256] +.loop: + mova m0, [zq+ 0] + mova m2, [zq+ 16] + mova m1, [zq+ 256] + mova m3, [zq+ 272] + addps m0, [zq+ 512] + addps m2, [zq+ 528] + addps m1, [zq+ 768] + addps m3, [zq+ 784] + addps m0, [zq+1024] + addps m2, [zq+1040] + addps m0, m1 + addps m2, m3 + mova [zq], m0 + mova [zq+16], m2 + add zq, 32 + cmp zq, r1q + jne .loop + REP_RET + +INIT_XMM sse +cglobal sbr_qmf_post_shuffle, 2,3,4,W,z + lea r2q, [zq + (64-4)*4] + mova m3, [ps_neg] +.loop: + mova m1, [zq] + xorps m0, m3, [r2q] + shufps m0, m0, m0, q0123 + unpcklps m2, m0, m1 + unpckhps m0, m0, m1 + mova [Wq + 0], m2 + mova [Wq + 16], m0 + add Wq, 32 + sub r2q, 16 + add zq, 16 + cmp zq, r2q + jl .loop + REP_RET + +INIT_XMM sse +cglobal sbr_neg_odd_64, 1,2,4,z + lea r1q, [zq+256] +.loop: + mova m0, [zq+ 0] + mova m1, [zq+16] + mova m2, [zq+32] + mova m3, [zq+48] + xorps m0, [ps_mask2] + xorps m1, [ps_mask2] + xorps m2, [ps_mask2] + xorps m3, [ps_mask2] + mova [zq+ 0], m0 + mova [zq+16], m1 + mova [zq+32], m2 + mova [zq+48], m3 + add zq, 64 + cmp zq, r1q + jne .loop + REP_RET + +; void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1) +%macro SBR_QMF_DEINT_BFLY 0 +cglobal sbr_qmf_deint_bfly, 3,5,8, v,src0,src1,vrev,c + mov cq, 64*4-2*mmsize + lea vrevq, [vq + 64*4] +.loop: + mova m0, [src0q+cq] + mova m1, [src1q] + mova m4, [src0q+cq+mmsize] + mova m5, [src1q+mmsize] +%if cpuflag(sse2) + pshufd m2, m0, q0123 + pshufd m3, m1, q0123 + pshufd m6, m4, q0123 + pshufd m7, m5, q0123 +%else + shufps m2, m0, m0, q0123 + shufps m3, m1, m1, q0123 + shufps m6, m4, m4, q0123 + shufps m7, m5, m5, q0123 +%endif + addps m5, m2 + subps m0, m7 + addps m1, m6 + subps m4, m3 + mova [vrevq], m1 + mova [vrevq+mmsize], m5 + mova [vq+cq], m0 + mova [vq+cq+mmsize], m4 + add src1q, 2*mmsize + add vrevq, 2*mmsize + sub cq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +SBR_QMF_DEINT_BFLY + +INIT_XMM sse2 +cglobal sbr_qmf_pre_shuffle, 1,4,6,z +%define OFFSET (32*4-2*mmsize) + mov r3q, OFFSET + lea r1q, [zq + (32+1)*4] + lea r2q, [zq + 64*4] + mova m5, [ps_neg] +.loop: + movu m0, [r1q] + movu m2, [r1q + mmsize] + movu m1, [zq + r3q + 4 + mmsize] + movu m3, [zq + r3q + 4] + + pxor m2, m5 + pxor m0, m5 + pshufd m2, m2, q0123 + pshufd m0, m0, q0123 + SBUTTERFLY dq, 2, 3, 4 + SBUTTERFLY dq, 0, 1, 4 + mova [r2q + 2*r3q + 0*mmsize], m2 + mova [r2q + 2*r3q + 1*mmsize], m3 + mova [r2q + 2*r3q + 2*mmsize], m0 + mova [r2q + 2*r3q + 3*mmsize], m1 + add r1q, 2*mmsize + sub r3q, 2*mmsize + jge .loop + movq m2, [zq] + movq [r2q], m2 + REP_RET + +%ifdef PIC +%define NREGS 1 +%if UNIX64 +%define NOISE_TABLE r6q ; r5q is m_max +%else +%define NOISE_TABLE r5q +%endif +%else +%define NREGS 0 +%define NOISE_TABLE sbr_noise_table +%endif + +%macro LOAD_NST 1 +%ifdef PIC + lea NOISE_TABLE, [%1] + mova m0, [kxq + NOISE_TABLE] +%else + mova m0, [kxq + %1] +%endif +%endmacro + +INIT_XMM sse2 +; sbr_hf_apply_noise_0(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_0, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise0] + jmp apply_noise_main + +; sbr_hf_apply_noise_1(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_1, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13 + jmp apply_noise_main + +; sbr_hf_apply_noise_2(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_2, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + mova m0, [ps_noise2] + jmp apply_noise_main + +; sbr_hf_apply_noise_3(float (*Y)[2], const float *s_m, +; const float *q_filt, int noise, +; int kx, int m_max) +cglobal sbr_hf_apply_noise_3, 5,5+NREGS+UNIX64,8, Y,s_m,q_filt,noise,kx,m_max + and kxq, 1 + shl kxq, 4 + LOAD_NST ps_noise13+16 + +apply_noise_main: +%if ARCH_X86_64 == 0 || WIN64 + mov kxd, m_maxm + DEFINE_ARGS Y, s_m, q_filt, noise, count +%else + DEFINE_ARGS Y, s_m, q_filt, noise, kx, count +%endif + movsxdifnidn noiseq, noised + dec noiseq + shl countd, 2 +%ifdef PIC + lea NOISE_TABLE, [sbr_noise_table] +%endif + lea Yq, [Yq + 2*countq] + add s_mq, countq + add q_filtq, countq + shl noiseq, 3 + pxor m5, m5 + neg countq +.loop: + mova m1, [q_filtq + countq] + movu m3, [noiseq + NOISE_TABLE + 1*mmsize] + movu m4, [noiseq + NOISE_TABLE + 2*mmsize] + add noiseq, 2*mmsize + and noiseq, 0x1ff<<3 + punpckhdq m2, m1, m1 + punpckldq m1, m1 + mulps m1, m3 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mulps m2, m4 ; m2 = q_filt[m] * ff_sbr_noise_table[noise] + mova m3, [s_mq + countq] + ; TODO: replace by a vpermd in AVX2 + punpckhdq m4, m3, m3 + punpckldq m3, m3 + pcmpeqd m6, m3, m5 ; m6 == 0 + pcmpeqd m7, m4, m5 ; m7 == 0 + mulps m3, m0 ; s_m[m] * phi_sign + mulps m4, m0 ; s_m[m] * phi_sign + pand m1, m6 + pand m2, m7 + movu m6, [Yq + 2*countq] + movu m7, [Yq + 2*countq + mmsize] + addps m3, m1 + addps m4, m2 + addps m6, m3 + addps m7, m4 + movu [Yq + 2*countq], m6 + movu [Yq + 2*countq + mmsize], m7 + add countq, mmsize + jl .loop + RET + +INIT_XMM sse +cglobal sbr_qmf_deint_neg, 2,4,4,v,src,vrev,c +%define COUNT 32*4 +%define OFFSET 32*4 + mov cq, -COUNT + lea vrevq, [vq + OFFSET + COUNT] + add vq, OFFSET-mmsize + add srcq, 2*COUNT + mova m3, [ps_neg] +.loop: + mova m0, [srcq + 2*cq + 0*mmsize] + mova m1, [srcq + 2*cq + 1*mmsize] + shufps m2, m0, m1, q2020 + shufps m1, m0, q1313 + xorps m2, m3 + mova [vq], m1 + mova [vrevq + cq], m2 + sub vq, mmsize + add cq, mmsize + jl .loop + REP_RET + +%macro SBR_AUTOCORRELATE 0 +cglobal sbr_autocorrelate, 2,3,8,32, x, phi, cnt + mov cntq, 37*8 + add xq, cntq + neg cntq + +%if cpuflag(sse3) +%define MOVH movsd + movddup m5, [xq+cntq] +%else +%define MOVH movlps + movlps m5, [xq+cntq] + movlhps m5, m5 +%endif + MOVH m7, [xq+cntq+8 ] + MOVH m1, [xq+cntq+16] + shufps m7, m7, q0110 + shufps m1, m1, q0110 + mulps m3, m5, m7 ; x[0][0] * x[1][0], x[0][1] * x[1][1], x[0][0] * x[1][1], x[0][1] * x[1][0] + mulps m4, m5, m5 ; x[0][0] * x[0][0], x[0][1] * x[0][1]; + mulps m5, m1 ; real_sum2 = x[0][0] * x[2][0], x[0][1] * x[2][1]; imag_sum2 = x[0][0] * x[2][1], x[0][1] * x[2][0] + movaps [rsp ], m3 + movaps [rsp+16], m4 + add cntq, 8 + + MOVH m2, [xq+cntq+16] + movlhps m7, m7 + shufps m2, m2, q0110 + mulps m6, m7, m1 ; real_sum1 = x[1][0] * x[2][0], x[1][1] * x[2][1]; imag_sum1 += x[1][0] * x[2][1], x[1][1] * x[2][0] + mulps m4, m7, m2 + mulps m7, m7 ; real_sum0 = x[1][0] * x[1][0], x[1][1] * x[1][1]; + addps m5, m4 ; real_sum2 += x[1][0] * x[3][0], x[1][1] * x[3][1]; imag_sum2 += x[1][0] * x[3][1], x[1][1] * x[3][0] + +align 16 +.loop: + add cntq, 8 + MOVH m0, [xq+cntq+16] + movlhps m1, m1 + shufps m0, m0, q0110 + mulps m3, m1, m2 + mulps m4, m1, m0 + mulps m1, m1 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m1 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + add cntq, 8 + MOVH m1, [xq+cntq+16] + movlhps m2, m2 + shufps m1, m1, q0110 + mulps m3, m2, m0 + mulps m4, m2, m1 + mulps m2, m2 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m2 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + add cntq, 8 + MOVH m2, [xq+cntq+16] + movlhps m0, m0 + shufps m2, m2, q0110 + mulps m3, m0, m1 + mulps m4, m0, m2 + mulps m0, m0 + addps m6, m3 ; real_sum1 += x[i][0] * x[i + 1][0], x[i][1] * x[i + 1][1]; imag_sum1 += x[i][0] * x[i + 1][1], x[i][1] * x[i + 1][0]; + addps m5, m4 ; real_sum2 += x[i][0] * x[i + 2][0], x[i][1] * x[i + 2][1]; imag_sum2 += x[i][0] * x[i + 2][1], x[i][1] * x[i + 2][0]; + addps m7, m0 ; real_sum0 += x[i][0] * x[i][0], x[i][1] * x[i][1]; + jl .loop + + movlhps m1, m1 + mulps m2, m1 + mulps m1, m1 + addps m2, m6 ; real_sum1 + x[38][0] * x[39][0], x[38][1] * x[39][1]; imag_sum1 + x[38][0] * x[39][1], x[38][1] * x[39][0]; + addps m1, m7 ; real_sum0 + x[38][0] * x[38][0], x[38][1] * x[38][1]; + addps m6, [rsp ] ; real_sum1 + x[ 0][0] * x[ 1][0], x[ 0][1] * x[ 1][1]; imag_sum1 + x[ 0][0] * x[ 1][1], x[ 0][1] * x[ 1][0]; + addps m7, [rsp+16] ; real_sum0 + x[ 0][0] * x[ 0][0], x[ 0][1] * x[ 0][1]; + + xorps m2, [ps_mask3] + xorps m5, [ps_mask3] + xorps m6, [ps_mask3] + HADDPS m2, m5, m3 + HADDPS m7, m6, m4 +%if cpuflag(sse3) + movshdup m0, m1 +%else + movss m0, m1 + shufps m1, m1, q0001 +%endif + addss m1, m0 + movaps [phiq ], m2 + movhps [phiq+0x18], m7 + movss [phiq+0x28], m7 + movss [phiq+0x10], m1 + RET +%endmacro + +INIT_XMM sse +SBR_AUTOCORRELATE +INIT_XMM sse3 +SBR_AUTOCORRELATE diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbrdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbrdsp_init.c new file mode 100644 index 00000000..6911a1a5 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/sbrdsp_init.c @@ -0,0 +1,87 @@ +/* + * AAC Spectral Band Replication decoding functions + * Copyright (c) 2012 Christophe Gisquet + * + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/sbrdsp.h" + +float ff_sbr_sum_square_sse(float (*x)[2], int n); +void ff_sbr_sum64x5_sse(float *z); +void ff_sbr_hf_g_filt_sse(float (*Y)[2], const float (*X_high)[40][2], + const float *g_filt, int m_max, intptr_t ixh); +void ff_sbr_hf_gen_sse(float (*X_high)[2], const float (*X_low)[2], + const float alpha0[2], const float alpha1[2], + float bw, int start, int end); +void ff_sbr_neg_odd_64_sse(float *z); +void ff_sbr_qmf_post_shuffle_sse(float W[32][2], const float *z); +void ff_sbr_qmf_deint_bfly_sse(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_deint_bfly_sse2(float *v, const float *src0, const float *src1); +void ff_sbr_qmf_pre_shuffle_sse2(float *z); + +void ff_sbr_hf_apply_noise_0_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_1_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_2_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); +void ff_sbr_hf_apply_noise_3_sse2(float (*Y)[2], const float *s_m, + const float *q_filt, int noise, + int kx, int m_max); + +void ff_sbr_qmf_deint_neg_sse(float *v, const float *src); + +void ff_sbr_autocorrelate_sse (const float x[40][2], float phi[3][2][2]); +void ff_sbr_autocorrelate_sse3(const float x[40][2], float phi[3][2][2]); + +av_cold void ff_sbrdsp_init_x86(SBRDSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { + s->neg_odd_64 = ff_sbr_neg_odd_64_sse; + s->sum_square = ff_sbr_sum_square_sse; + s->sum64x5 = ff_sbr_sum64x5_sse; + s->hf_g_filt = ff_sbr_hf_g_filt_sse; + s->hf_gen = ff_sbr_hf_gen_sse; + s->qmf_post_shuffle = ff_sbr_qmf_post_shuffle_sse; + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse; + s->qmf_deint_neg = ff_sbr_qmf_deint_neg_sse; + s->autocorrelate = ff_sbr_autocorrelate_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + s->qmf_deint_bfly = ff_sbr_qmf_deint_bfly_sse2; + s->qmf_pre_shuffle = ff_sbr_qmf_pre_shuffle_sse2; + s->hf_apply_noise[0] = ff_sbr_hf_apply_noise_0_sse2; + s->hf_apply_noise[1] = ff_sbr_hf_apply_noise_1_sse2; + s->hf_apply_noise[2] = ff_sbr_hf_apply_noise_2_sse2; + s->hf_apply_noise[3] = ff_sbr_hf_apply_noise_3_sse2; + } + + if (EXTERNAL_SSE3(cpu_flags)) { + s->autocorrelate = ff_sbr_autocorrelate_sse3; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct.asm new file mode 100644 index 00000000..6fedbb57 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct.asm @@ -0,0 +1,889 @@ +; +; Simple IDCT MMX +; +; Copyright (c) 2001, 2002 Michael Niedermayer +; +; Conversion from gcc syntax to x264asm syntax with minimal modifications +; by James Darnley . +; +; 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pb_80 + +wm1010: dw 0, 0xffff, 0, 0xffff +d40000: dd 4 << 16, 0 + +; 23170.475006 +; 22725.260826 +; 21406.727617 +; 19265.545870 +; 16384.000000 +; 12872.826198 +; 8866.956905 +; 4520.335430 + +%define C0 23170 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +%define C1 22725 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +%define C2 21407 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +%define C3 19266 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +%define C4 16383 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) - 0.5 +%define C5 12873 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +%define C6 8867 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 +%define C7 4520 ; cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5 + +%define ROW_SHIFT 11 +%define COL_SHIFT 20 ; 6 + +coeffs: + dw 1 << (ROW_SHIFT - 1), 0 + dw 1 << (ROW_SHIFT - 1), 0 + dw 1 << (ROW_SHIFT - 1), 1 + dw 1 << (ROW_SHIFT - 1), 0 + + dw C4, C4, C4, C4 + dw C4, -C4, C4, -C4 + + dw C2, C6, C2, C6 + dw C6, -C2, C6, -C2 + + dw C1, C3, C1, C3 + dw C5, C7, C5, C7 + + dw C3, -C7, C3, -C7 + dw -C1, -C5, -C1, -C5 + + dw C5, -C1, C5, -C1 + dw C7, C3, C7, C3 + + dw C7, -C5, C7, -C5 + dw C3, -C1, C3, -C1 + +SECTION .text + +%macro DC_COND_IDCT 7 + movq mm0, [blockq + %1] ; R4 R0 r4 r0 + movq mm1, [blockq + %2] ; R6 R2 r6 r2 + movq mm2, [blockq + %3] ; R3 R1 r3 r1 + movq mm3, [blockq + %4] ; R7 R5 r7 r5 + movq mm4, [wm1010] + pand mm4, mm0 + por mm4, mm1 + por mm4, mm2 + por mm4, mm3 + packssdw mm4, mm4 + movd t0d, mm4 + or t0d, t0d + jz %%1 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm5, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm5, mm1 ; C6R6+C2R2 C6r6+C2r2 + movq mm6, [coeffs + 40] ; -C2 C6 -C2 C6 + pmaddwd mm1, mm6 ; -C2R6+C6R2 -C2r6+C6r2 + movq mm7, [coeffs + 48] ; C3 C1 C3 C1 + pmaddwd mm7, mm2 ; C3R3+C1R1 C3r3+C1r1 + paddd mm4, [coeffs + 8] + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + paddd mm4, mm5 ; A0 a0 + psubd mm6, mm5 ; A3 a3 + movq mm5, [coeffs + 56] ; C7 C5 C7 C5 + pmaddwd mm5, mm3 ; C7R7+C5R5 C7r7+C5r5 + paddd mm0, [coeffs + 8] + paddd mm1, mm0 ; A1 a1 + paddd mm0, mm0 + psubd mm0, mm1 ; A2 a2 + pmaddwd mm2, [coeffs + 64] ; -C7R3+C3R1 -C7r3+C3r1 + paddd mm7, mm5 ; B0 b0 + movq mm5, [coeffs + 72] ; -C5 -C1 -C5 -C1 + pmaddwd mm5, mm3 ; -C5R7-C1R5 -C5r7-C1r5 + paddd mm7, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm7 ; A0-B0 a0-b0 + paddd mm5, mm2 ; B1 b1 + psrad mm7, %7 + psrad mm4, %7 + movq mm2, mm1 ; A1 a1 + paddd mm1, mm5 ; A1+B1 a1+b1 + psubd mm2, mm5 ; A1-B1 a1-b1 + psrad mm1, %7 + psrad mm2, %7 + packssdw mm7, mm1 ; A1+B1 a1+b1 A0+B0 a0+b0 + packssdw mm2, mm4 ; A0-B0 a0-b0 A1-B1 a1-b1 + movq [%5], mm7 + movq mm1, [blockq + %3] ; R3 R1 r3 r1 + movq mm4, [coeffs + 80] ; -C1 C5 -C1 C5 + movq [24 + %5], mm2 + pmaddwd mm4, mm1 ; -C1R3+C5R1 -C1r3+C5r1 + movq mm7, [coeffs + 88] ; C3 C7 C3 C7 + pmaddwd mm1, [coeffs + 96] ; -C5R3+C7R1 -C5r3+C7r1 + pmaddwd mm7, mm3 ; C3R7+C7R5 C3r7+C7r5 + movq mm2, mm0 ; A2 a2 + pmaddwd mm3, [coeffs + 104] ; -C1R7+C3R5 -C1r7+C3r5 + paddd mm4, mm7 ; B2 b2 + paddd mm2, mm4 ; A2+B2 a2+b2 + psubd mm0, mm4 ; a2-B2 a2-b2 + psrad mm2, %7 + psrad mm0, %7 + movq mm4, mm6 ; A3 a3 + paddd mm3, mm1 ; B3 b3 + paddd mm6, mm3 ; A3+B3 a3+b3 + psubd mm4, mm3 ; a3-B3 a3-b3 + psrad mm6, %7 + packssdw mm2, mm6 ; A3+B3 a3+b3 A2+B2 a2+b2 + movq [8 + %5], mm2 + psrad mm4, %7 + packssdw mm4, mm0 ; A2-B2 a2-b2 A3-B3 a3-b3 + movq [16 + %5], mm4 + jmp %%2 +%%1: + pslld mm0, 16 + paddd mm0, [d40000] + psrad mm0, 13 + packssdw mm0, mm0 + movq [%5], mm0 + movq [8 + %5], mm0 + movq [16 + %5], mm0 + movq [24 + %5], mm0 +%%2: +%endmacro + +%macro Z_COND_IDCT 8 + movq mm0, [blockq + %1] ; R4 R0 r4 r0 + movq mm1, [blockq + %2] ; R6 R2 r6 r2 + movq mm2, [blockq + %3] ; R3 R1 r3 r1 + movq mm3, [blockq + %4] ; R7 R5 r7 r5 + movq mm4, mm0 + por mm4, mm1 + por mm4, mm2 + por mm4, mm3 + packssdw mm4, mm4 + movd t0d, mm4 + or t0d, t0d + jz %8 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm5, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm5, mm1 ; C6R6+C2R2 C6r6+C2r2 + movq mm6, [coeffs + 40] ; -C2 C6 -C2 C6 + pmaddwd mm1, mm6 ; -C2R6+C6R2 -C2r6+C6r2 + movq mm7, [coeffs + 48] ; C3 C1 C3 C1 + pmaddwd mm7, mm2 ; C3R3+C1R1 C3r3+C1r1 + paddd mm4, [coeffs] + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + paddd mm4, mm5 ; A0 a0 + psubd mm6, mm5 ; A3 a3 + movq mm5, [coeffs + 56] ; C7 C5 C7 C5 + pmaddwd mm5, mm3 ; C7R7+C5R5 C7r7+C5r5 + paddd mm0, [coeffs] + paddd mm1, mm0 ; A1 a1 + paddd mm0, mm0 + psubd mm0, mm1 ; A2 a2 + pmaddwd mm2, [coeffs + 64] ; -C7R3+C3R1 -C7r3+C3r1 + paddd mm7, mm5 ; B0 b0 + movq mm5, [coeffs + 72] ; -C5 -C1 -C5 -C1 + pmaddwd mm5, mm3 ; -C5R7-C1R5 -C5r7-C1r5 + paddd mm7, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm7 ; A0-B0 a0-b0 + paddd mm5, mm2 ; B1 b1 + psrad mm7, %7 + psrad mm4, %7 + movq mm2, mm1 ; A1 a1 + paddd mm1, mm5 ; A1+B1 a1+b1 + psubd mm2, mm5 ; A1-B1 a1-b1 + psrad mm1, %7 + psrad mm2, %7 + packssdw mm7, mm1 ; A1+B1 a1+b1 A0+B0 a0+b0 + packssdw mm2, mm4 ; A0-B0 a0-b0 A1-B1 a1-b1 + movq [%5], mm7 + movq mm1, [blockq + %3] ; R3 R1 r3 r1 + movq mm4, [coeffs + 80] ; -C1 C5 -C1 C5 + movq [24 + %5], mm2 + pmaddwd mm4, mm1 ; -C1R3+C5R1 -C1r3+C5r1 + movq mm7, [coeffs + 88] ; C3 C7 C3 C7 + pmaddwd mm1, [coeffs + 96] ; -C5R3+C7R1 -C5r3+C7r1 + pmaddwd mm7, mm3 ; C3R7+C7R5 C3r7+C7r5 + movq mm2, mm0 ; A2 a2 + pmaddwd mm3, [coeffs + 104] ; -C1R7+C3R5 -C1r7+C3r5 + paddd mm4, mm7 ; B2 b2 + paddd mm2, mm4 ; A2+B2 a2+b2 + psubd mm0, mm4 ; a2-B2 a2-b2 + psrad mm2, %7 + psrad mm0, %7 + movq mm4, mm6 ; A3 a3 + paddd mm3, mm1 ; B3 b3 + paddd mm6, mm3 ; A3+B3 a3+b3 + psubd mm4, mm3 ; a3-B3 a3-b3 + psrad mm6, %7 + packssdw mm2, mm6 ; A3+B3 a3+b3 A2+B2 a2+b2 + movq [8 + %5], mm2 + psrad mm4, %7 + packssdw mm4, mm0 ; A2-B2 a2-b2 A3-B3 a3-b3 + movq [16 + %5], mm4 +%endmacro + +%macro IDCT1 6 + movq mm0, %1 ; R4 R0 r4 r0 + movq mm1, %2 ; R6 R2 r6 r2 + movq mm2, %3 ; R3 R1 r3 r1 + movq mm3, %4 ; R7 R5 r7 r5 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm5, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm5, mm1 ; C6R6+C2R2 C6r6+C2r2 + movq mm6, [coeffs + 40] ; -C2 C6 -C2 C6 + pmaddwd mm1, mm6 ; -C2R6+C6R2 -C2r6+C6r2 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + movq mm7, [coeffs + 48] ; C3 C1 C3 C1 + pmaddwd mm7, mm2 ; C3R3+C1R1 C3r3+C1r1 + paddd mm4, mm5 ; A0 a0 + psubd mm6, mm5 ; A3 a3 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + paddd mm0, mm1 ; A1 a1 + psubd mm5, mm1 ; A2 a2 + movq mm1, [coeffs + 56] ; C7 C5 C7 C5 + pmaddwd mm1, mm3 ; C7R7+C5R5 C7r7+C5r5 + pmaddwd mm2, [coeffs + 64] ; -C7R3+C3R1 -C7r3+C3r1 + paddd mm7, mm1 ; B0 b0 + movq mm1, [coeffs + 72] ; -C5 -C1 -C5 -C1 + pmaddwd mm1, mm3 ; -C5R7-C1R5 -C5r7-C1r5 + paddd mm7, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm7 ; A0-B0 a0-b0 + paddd mm1, mm2 ; B1 b1 + psrad mm7, %6 + psrad mm4, %6 + movq mm2, mm0 ; A1 a1 + paddd mm0, mm1 ; A1+B1 a1+b1 + psubd mm2, mm1 ; A1-B1 a1-b1 + psrad mm0, %6 + psrad mm2, %6 + packssdw mm7, mm7 ; A0+B0 a0+b0 + movd [%5], mm7 + packssdw mm0, mm0 ; A1+B1 a1+b1 + movd [16 + %5], mm0 + packssdw mm2, mm2 ; A1-B1 a1-b1 + movd [96 + %5], mm2 + packssdw mm4, mm4 ; A0-B0 a0-b0 + movd [112 + %5], mm4 + movq mm0, %3 ; R3 R1 r3 r1 + movq mm4, [coeffs + 80] ; -C1 C5 -C1 C5 + pmaddwd mm4, mm0 ; -C1R3+C5R1 -C1r3+C5r1 + movq mm7, [coeffs + 88] ; C3 C7 C3 C7 + pmaddwd mm0, [coeffs + 96] ; -C5R3+C7R1 -C5r3+C7r1 + pmaddwd mm7, mm3 ; C3R7+C7R5 C3r7+C7r5 + movq mm2, mm5 ; A2 a2 + pmaddwd mm3, [coeffs + 104] ; -C1R7+C3R5 -C1r7+C3r5 + paddd mm4, mm7 ; B2 b2 + paddd mm2, mm4 ; A2+B2 a2+b2 + psubd mm5, mm4 ; a2-B2 a2-b2 + psrad mm2, %6 + psrad mm5, %6 + movq mm4, mm6 ; A3 a3 + paddd mm3, mm0 ; B3 b3 + paddd mm6, mm3 ; A3+B3 a3+b3 + psubd mm4, mm3 ; a3-B3 a3-b3 + psrad mm6, %6 + psrad mm4, %6 + packssdw mm2, mm2 ; A2+B2 a2+b2 + packssdw mm6, mm6 ; A3+B3 a3+b3 + movd [32 + %5], mm2 + packssdw mm4, mm4 ; A3-B3 a3-b3 + packssdw mm5, mm5 ; A2-B2 a2-b2 + movd [48 + %5], mm6 + movd [64 + %5], mm4 + movd [80 + %5], mm5 +%endmacro + +%macro IDCT2 6 + movq mm0, %1 ; R4 R0 r4 r0 + movq mm1, %2 ; R6 R2 r6 r2 + movq mm3, %4 ; R7 R5 r7 r5 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm5, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm5, mm1 ; C6R6+C2R2 C6r6+C2r2 + movq mm6, [coeffs + 40] ; -C2 C6 -C2 C6 + pmaddwd mm1, mm6 ; -C2R6+C6R2 -C2r6+C6r2 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + paddd mm4, mm5 ; A0 a0 + psubd mm6, mm5 ; A3 a3 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + paddd mm0, mm1 ; A1 a1 + psubd mm5, mm1 ; A2 a2 + movq mm1, [coeffs + 56] ; C7 C5 C7 C5 + pmaddwd mm1, mm3 ; C7R7+C5R5 C7r7+C5r5 + movq mm7, [coeffs + 72] ; -C5 -C1 -C5 -C1 + pmaddwd mm7, mm3 ; -C5R7-C1R5 -C5r7-C1r5 + paddd mm1, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm1 ; A0-B0 a0-b0 + psrad mm1, %6 + psrad mm4, %6 + movq mm2, mm0 ; A1 a1 + paddd mm0, mm7 ; A1+B1 a1+b1 + psubd mm2, mm7 ; A1-B1 a1-b1 + psrad mm0, %6 + psrad mm2, %6 + packssdw mm1, mm1 ; A0+B0 a0+b0 + movd [%5], mm1 + packssdw mm0, mm0 ; A1+B1 a1+b1 + movd [16 + %5], mm0 + packssdw mm2, mm2 ; A1-B1 a1-b1 + movd [96 + %5], mm2 + packssdw mm4, mm4 ; A0-B0 a0-b0 + movd [112 + %5], mm4 + movq mm1, [coeffs + 88] ; C3 C7 C3 C7 + pmaddwd mm1, mm3 ; C3R7+C7R5 C3r7+C7r5 + movq mm2, mm5 ; A2 a2 + pmaddwd mm3, [coeffs + 104] ; -C1R7+C3R5 -C1r7+C3r5 + paddd mm2, mm1 ; A2+B2 a2+b2 + psubd mm5, mm1 ; a2-B2 a2-b2 + psrad mm2, %6 + psrad mm5, %6 + movq mm1, mm6 ; A3 a3 + paddd mm6, mm3 ; A3+B3 a3+b3 + psubd mm1, mm3 ; a3-B3 a3-b3 + psrad mm6, %6 + psrad mm1, %6 + packssdw mm2, mm2 ; A2+B2 a2+b2 + packssdw mm6, mm6 ; A3+B3 a3+b3 + movd [32 + %5], mm2 + packssdw mm1, mm1 ; A3-B3 a3-b3 + packssdw mm5, mm5 ; A2-B2 a2-b2 + movd [48 + %5], mm6 + movd [64 + %5], mm1 + movd [80 + %5], mm5 +%endmacro + +%macro IDCT3 6 + movq mm0, %1 ; R4 R0 r4 r0 + movq mm3, %4 ; R7 R5 r7 r5 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm1, [coeffs + 56] ; C7 C5 C7 C5 + pmaddwd mm1, mm3 ; C7R7+C5R5 C7r7+C5r5 + movq mm7, [coeffs + 72] ; -C5 -C1 -C5 -C1 + pmaddwd mm7, mm3 ; -C5R7-C1R5 -C5r7-C1r5 + paddd mm1, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm1 ; A0-B0 a0-b0 + psrad mm1, %6 + psrad mm4, %6 + movq mm2, mm0 ; A1 a1 + paddd mm0, mm7 ; A1+B1 a1+b1 + psubd mm2, mm7 ; A1-B1 a1-b1 + psrad mm0, %6 + psrad mm2, %6 + packssdw mm1, mm1 ; A0+B0 a0+b0 + movd [%5], mm1 + packssdw mm0, mm0 ; A1+B1 a1+b1 + movd [16 + %5], mm0 + packssdw mm2, mm2 ; A1-B1 a1-b1 + movd [96 + %5], mm2 + packssdw mm4, mm4 ; A0-B0 a0-b0 + movd [112 + %5], mm4 + movq mm1, [coeffs + 88] ; C3 C7 C3 C7 + pmaddwd mm1, mm3 ; C3R7+C7R5 C3r7+C7r5 + movq mm2, mm5 ; A2 a2 + pmaddwd mm3, [coeffs + 104] ; -C1R7+C3R5 -C1r7+C3r5 + paddd mm2, mm1 ; A2+B2 a2+b2 + psubd mm5, mm1 ; a2-B2 a2-b2 + psrad mm2, %6 + psrad mm5, %6 + movq mm1, mm6 ; A3 a3 + paddd mm6, mm3 ; A3+B3 a3+b3 + psubd mm1, mm3 ; a3-B3 a3-b3 + psrad mm6, %6 + psrad mm1, %6 + packssdw mm2, mm2 ; A2+B2 a2+b2 + packssdw mm6, mm6 ; A3+B3 a3+b3 + movd [32 + %5], mm2 + packssdw mm1, mm1 ; A3-B3 a3-b3 + packssdw mm5, mm5 ; A2-B2 a2-b2 + movd [48 + %5], mm6 + movd [64 + %5], mm1 + movd [80 + %5], mm5 +%endmacro + +%macro IDCT4 6 + movq mm0, %1 ; R4 R0 r4 r0 + movq mm2, %3 ; R3 R1 r3 r1 + movq mm3, %4 ; R7 R5 r7 r5 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + movq mm7, [coeffs + 48] ; C3 C1 C3 C1 + pmaddwd mm7, mm2 ; C3R3+C1R1 C3r3+C1r1 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm1, [coeffs + 56] ; C7 C5 C7 C5 + pmaddwd mm1, mm3 ; C7R7+C5R5 C7r7+C5r5 + pmaddwd mm2, [coeffs + 64] ; -C7R3+C3R1 -C7r3+C3r1 + paddd mm7, mm1 ; B0 b0 + movq mm1, [coeffs + 72] ; -C5 -C1 -C5 -C1 + pmaddwd mm1, mm3 ; -C5R7-C1R5 -C5r7-C1r5 + paddd mm7, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm7 ; A0-B0 a0-b0 + paddd mm1, mm2 ; B1 b1 + psrad mm7, %6 + psrad mm4, %6 + movq mm2, mm0 ; A1 a1 + paddd mm0, mm1 ; A1+B1 a1+b1 + psubd mm2, mm1 ; A1-B1 a1-b1 + psrad mm0, %6 + psrad mm2, %6 + packssdw mm7, mm7 ; A0+B0 a0+b0 + movd [%5], mm7 + packssdw mm0, mm0 ; A1+B1 a1+b1 + movd [16 + %5], mm0 + packssdw mm2, mm2 ; A1-B1 a1-b1 + movd [96 + %5], mm2 + packssdw mm4, mm4 ; A0-B0 a0-b0 + movd [112 + %5], mm4 + movq mm0, %3 ; R3 R1 r3 r1 + movq mm4, [coeffs + 80] ; -C1 C5 -C1 C5 + pmaddwd mm4, mm0 ; -C1R3+C5R1 -C1r3+C5r1 + movq mm7, [coeffs + 88] ; C3 C7 C3 C7 + pmaddwd mm0, [coeffs + 96] ; -C5R3+C7R1 -C5r3+C7r1 + pmaddwd mm7, mm3 ; C3R7+C7R5 C3r7+C7r5 + movq mm2, mm5 ; A2 a2 + pmaddwd mm3, [coeffs + 104] ; -C1R7+C3R5 -C1r7+C3r5 + paddd mm4, mm7 ; B2 b2 + paddd mm2, mm4 ; A2+B2 a2+b2 + psubd mm5, mm4 ; a2-B2 a2-b2 + psrad mm2, %6 + psrad mm5, %6 + movq mm4, mm6 ; A3 a3 + paddd mm3, mm0 ; B3 b3 + paddd mm6, mm3 ; A3+B3 a3+b3 + psubd mm4, mm3 ; a3-B3 a3-b3 + psrad mm6, %6 + psrad mm4, %6 + packssdw mm2, mm2 ; A2+B2 a2+b2 + packssdw mm6, mm6 ; A3+B3 a3+b3 + movd [32 + %5], mm2 + packssdw mm4, mm4 ; A3-B3 a3-b3 + packssdw mm5, mm5 ; A2-B2 a2-b2 + movd [48 + %5], mm6 + movd [64 + %5], mm4 + movd [80 + %5], mm5 +%endmacro + +%macro IDCT5 6 + movq mm0, %1 ; R4 R0 r4 r0 + movq mm2, %3 ; R3 R1 r3 r1 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + movq mm7, [coeffs + 48] ; C3 C1 C3 C1 + pmaddwd mm7, mm2 ; C3R3+C1R1 C3r3+C1r1 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm3, [coeffs + 64] + pmaddwd mm3, mm2 ; -C7R3+C3R1 -C7r3+C3r1 + paddd mm7, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm7 ; A0-B0 a0-b0 + psrad mm7, %6 + psrad mm4, %6 + movq mm1, mm0 ; A1 a1 + paddd mm0, mm3 ; A1+B1 a1+b1 + psubd mm1, mm3 ; A1-B1 a1-b1 + psrad mm0, %6 + psrad mm1, %6 + packssdw mm7, mm7 ; A0+B0 a0+b0 + movd [%5], mm7 + packssdw mm0, mm0 ; A1+B1 a1+b1 + movd [16 + %5], mm0 + packssdw mm1, mm1 ; A1-B1 a1-b1 + movd [96 + %5], mm1 + packssdw mm4, mm4 ; A0-B0 a0-b0 + movd [112 + %5], mm4 + movq mm4, [coeffs + 80] ; -C1 C5 -C1 C5 + pmaddwd mm4, mm2 ; -C1R3+C5R1 -C1r3+C5r1 + pmaddwd mm2, [coeffs + 96] ; -C5R3+C7R1 -C5r3+C7r1 + movq mm1, mm5 ; A2 a2 + paddd mm1, mm4 ; A2+B2 a2+b2 + psubd mm5, mm4 ; a2-B2 a2-b2 + psrad mm1, %6 + psrad mm5, %6 + movq mm4, mm6 ; A3 a3 + paddd mm6, mm2 ; A3+B3 a3+b3 + psubd mm4, mm2 ; a3-B3 a3-b3 + psrad mm6, %6 + psrad mm4, %6 + packssdw mm1, mm1 ; A2+B2 a2+b2 + packssdw mm6, mm6 ; A3+B3 a3+b3 + movd [32 + %5], mm1 + packssdw mm4, mm4 ; A3-B3 a3-b3 + packssdw mm5, mm5 ; A2-B2 a2-b2 + movd [48 + %5], mm6 + movd [64 + %5], mm4 + movd [80 + %5], mm5 +%endmacro + +%macro IDCT6 6 + movq mm0, [%1] ; R4 R0 r4 r0 + movq mm1, [%2] ; R6 R2 r6 r2 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm5, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm5, mm1 ; C6R6+C2R2 C6r6+C2r2 + movq mm6, [coeffs + 40] ; -C2 C6 -C2 C6 + pmaddwd mm1, mm6 ; -C2R6+C6R2 -C2r6+C6r2 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + paddd mm4, mm5 ; A0 a0 + psubd mm6, mm5 ; A3 a3 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + paddd mm0, mm1 ; A1 a1 + psubd mm5, mm1 ; A2 a2 + movq mm2, [8 + %1] ; R4 R0 r4 r0 + movq mm3, [8 + %2] ; R6 R2 r6 r2 + movq mm1, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm1, mm2 ; C4R4+C4R0 C4r4+C4r0 + movq mm7, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm2, mm7 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm7, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm7, mm3 ; C6R6+C2R2 C6r6+C2r2 + pmaddwd mm3, [coeffs + 40] ; -C2R6+C6R2 -C2r6+C6r2 + paddd mm7, mm1 ; A0 a0 + paddd mm1, mm1 ; 2C0 2c0 + psubd mm1, mm7 ; A3 a3 + paddd mm3, mm2 ; A1 a1 + paddd mm2, mm2 ; 2C1 2c1 + psubd mm2, mm3 ; A2 a2 + psrad mm4, %6 + psrad mm7, %6 + psrad mm3, %6 + packssdw mm4, mm7 ; A0 a0 + movq [%5], mm4 + psrad mm0, %6 + packssdw mm0, mm3 ; A1 a1 + movq [16 + %5], mm0 + movq [96 + %5], mm0 + movq [112 + %5], mm4 + psrad mm5, %6 + psrad mm6, %6 + psrad mm2, %6 + packssdw mm5, mm2 ; A2-B2 a2-b2 + movq [32 + %5], mm5 + psrad mm1, %6 + packssdw mm6, mm1 ; A3+B3 a3+b3 + movq [48 + %5], mm6 + movq [64 + %5], mm6 + movq [80 + %5], mm5 +%endmacro + +%macro IDCT7 6 + movq mm0, %1 ; R4 R0 r4 r0 + movq mm1, %2 ; R6 R2 r6 r2 + movq mm2, %3 ; R3 R1 r3 r1 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm5, [coeffs + 32] ; C6 C2 C6 C2 + pmaddwd mm5, mm1 ; C6R6+C2R2 C6r6+C2r2 + movq mm6, [coeffs + 40] ; -C2 C6 -C2 C6 + pmaddwd mm1, mm6 ; -C2R6+C6R2 -C2r6+C6r2 + movq mm6, mm4 ; C4R4+C4R0 C4r4+C4r0 + movq mm7, [coeffs + 48] ; C3 C1 C3 C1 + pmaddwd mm7, mm2 ; C3R3+C1R1 C3r3+C1r1 + paddd mm4, mm5 ; A0 a0 + psubd mm6, mm5 ; A3 a3 + movq mm5, mm0 ; -C4R4+C4R0 -C4r4+C4r0 + paddd mm0, mm1 ; A1 a1 + psubd mm5, mm1 ; A2 a2 + movq mm1, [coeffs + 64] + pmaddwd mm1, mm2 ; -C7R3+C3R1 -C7r3+C3r1 + paddd mm7, mm4 ; A0+B0 a0+b0 + paddd mm4, mm4 ; 2A0 2a0 + psubd mm4, mm7 ; A0-B0 a0-b0 + psrad mm7, %6 + psrad mm4, %6 + movq mm3, mm0 ; A1 a1 + paddd mm0, mm1 ; A1+B1 a1+b1 + psubd mm3, mm1 ; A1-B1 a1-b1 + psrad mm0, %6 + psrad mm3, %6 + packssdw mm7, mm7 ; A0+B0 a0+b0 + movd [%5], mm7 + packssdw mm0, mm0 ; A1+B1 a1+b1 + movd [16 + %5], mm0 + packssdw mm3, mm3 ; A1-B1 a1-b1 + movd [96 + %5], mm3 + packssdw mm4, mm4 ; A0-B0 a0-b0 + movd [112 + %5], mm4 + movq mm4, [coeffs + 80] ; -C1 C5 -C1 C5 + pmaddwd mm4, mm2 ; -C1R3+C5R1 -C1r3+C5r1 + pmaddwd mm2, [coeffs + 96] ; -C5R3+C7R1 -C5r3+C7r1 + movq mm3, mm5 ; A2 a2 + paddd mm3, mm4 ; A2+B2 a2+b2 + psubd mm5, mm4 ; a2-B2 a2-b2 + psrad mm3, %6 + psrad mm5, %6 + movq mm4, mm6 ; A3 a3 + paddd mm6, mm2 ; A3+B3 a3+b3 + psubd mm4, mm2 ; a3-B3 a3-b3 + psrad mm6, %6 + packssdw mm3, mm3 ; A2+B2 a2+b2 + movd [32 + %5], mm3 + psrad mm4, %6 + packssdw mm6, mm6 ; A3+B3 a3+b3 + movd [48 + %5], mm6 + packssdw mm4, mm4 ; A3-B3 a3-b3 + packssdw mm5, mm5 ; A2-B2 a2-b2 + movd [64 + %5], mm4 + movd [80 + %5], mm5 +%endmacro + +%macro IDCT8 6 + movq mm0, [%1] ; R4 R0 r4 r0 + movq mm4, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm4, mm0 ; C4R4+C4R0 C4r4+C4r0 + movq mm5, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm0, mm5 ; -C4R4+C4R0 -C4r4+C4r0 + psrad mm4, %6 + psrad mm0, %6 + movq mm2, [8 + %1] ; R4 R0 r4 r0 + movq mm1, [coeffs + 16] ; C4 C4 C4 C4 + pmaddwd mm1, mm2 ; C4R4+C4R0 C4r4+C4r0 + movq mm7, [coeffs + 24] ; -C4 C4 -C4 C4 + pmaddwd mm2, mm7 ; -C4R4+C4R0 -C4r4+C4r0 + movq mm7, [coeffs + 32] ; C6 C2 C6 C2 + psrad mm1, %6 + packssdw mm4, mm1 ; A0 a0 + movq [%5], mm4 + psrad mm2, %6 + packssdw mm0, mm2 ; A1 a1 + movq [16 + %5], mm0 + movq [96 + %5], mm0 + movq [112 + %5], mm4 + movq [32 + %5], mm0 + movq [48 + %5], mm4 + movq [64 + %5], mm4 + movq [80 + %5], mm0 +%endmacro + +%macro IDCT 0 + DC_COND_IDCT 0, 8, 16, 24, rsp + 0, null, 11 + Z_COND_IDCT 32, 40, 48, 56, rsp + 32, null, 11, %%4 + Z_COND_IDCT 64, 72, 80, 88, rsp + 64, null, 11, %%2 + Z_COND_IDCT 96, 104, 112, 120, rsp + 96, null, 11, %%1 + + IDCT1 [rsp + 0], [rsp + 64], [rsp + 32], [rsp + 96], blockq + 0, 20 + IDCT1 [rsp + 8], [rsp + 72], [rsp + 40], [rsp + 104], blockq + 4, 20 + IDCT1 [rsp + 16], [rsp + 80], [rsp + 48], [rsp + 112], blockq + 8, 20 + IDCT1 [rsp + 24], [rsp + 88], [rsp + 56], [rsp + 120], blockq + 12, 20 + jmp %%9 + + ALIGN 16 + %%4: + Z_COND_IDCT 64, 72, 80, 88, rsp + 64, null, 11, %%6 + Z_COND_IDCT 96, 104, 112, 120, rsp + 96, null, 11, %%5 + + IDCT2 [rsp + 0], [rsp + 64], [rsp + 32], [rsp + 96], blockq + 0, 20 + IDCT2 [rsp + 8], [rsp + 72], [rsp + 40], [rsp + 104], blockq + 4, 20 + IDCT2 [rsp + 16], [rsp + 80], [rsp + 48], [rsp + 112], blockq + 8, 20 + IDCT2 [rsp + 24], [rsp + 88], [rsp + 56], [rsp + 120], blockq + 12, 20 + jmp %%9 + + ALIGN 16 + %%6: + Z_COND_IDCT 96, 104, 112, 120, rsp + 96, null, 11, %%7 + + IDCT3 [rsp + 0], [rsp + 64], [rsp + 32], [rsp + 96], blockq + 0, 20 + IDCT3 [rsp + 8], [rsp + 72], [rsp + 40], [rsp + 104], blockq + 4, 20 + IDCT3 [rsp + 16], [rsp + 80], [rsp + 48], [rsp + 112], blockq + 8, 20 + IDCT3 [rsp + 24], [rsp + 88], [rsp + 56], [rsp + 120], blockq + 12, 20 + jmp %%9 + + ALIGN 16 + %%2: + Z_COND_IDCT 96, 104, 112, 120, rsp + 96, null, 11, %%3 + + IDCT4 [rsp + 0], [rsp + 64], [rsp + 32], [rsp + 96], blockq + 0, 20 + IDCT4 [rsp + 8], [rsp + 72], [rsp + 40], [rsp + 104], blockq + 4, 20 + IDCT4 [rsp + 16], [rsp + 80], [rsp + 48], [rsp + 112], blockq + 8, 20 + IDCT4 [rsp + 24], [rsp + 88], [rsp + 56], [rsp + 120], blockq + 12, 20 + jmp %%9 + + ALIGN 16 + %%3: + + IDCT5 [rsp + 0], [rsp + 64], [rsp + 32], [rsp + 96], blockq + 0, 20 + IDCT5 [rsp + 8], [rsp + 72], [rsp + 40], [rsp + 104], blockq + 4, 20 + IDCT5 [rsp + 16], [rsp + 80], [rsp + 48], [rsp + 112], blockq + 8, 20 + IDCT5 [rsp + 24], [rsp + 88], [rsp + 56], [rsp + 120], blockq + 12, 20 + jmp %%9 + + ALIGN 16 + %%5: + + IDCT6 rsp + 0, rsp + 64, rsp + 32, rsp + 96, blockq + 0, 20 + IDCT6 rsp + 16, rsp + 80, rsp + 48, rsp + 112, blockq + 8, 20 + jmp %%9 + + ALIGN 16 + %%1: + + IDCT7 [rsp + 0], [rsp + 64], [rsp + 32], [rsp + 96], blockq + 0, 20 + IDCT7 [rsp + 8], [rsp + 72], [rsp + 40], [rsp + 104], blockq + 4, 20 + IDCT7 [rsp + 16], [rsp + 80], [rsp + 48], [rsp + 112], blockq + 8, 20 + IDCT7 [rsp + 24], [rsp + 88], [rsp + 56], [rsp + 120], blockq + 12, 20 + jmp %%9 + + ALIGN 16 + %%7: + + IDCT8 rsp + 0, rsp + 64, rsp + 32, rsp + 96, blockq + 0, 20 + IDCT8 rsp + 16, rsp + 80, rsp + 48, rsp + 112, blockq + 8, 20 + + %%9: +%endmacro + +%macro PUT_PIXELS_CLAMPED_HALF 1 + mova m0, [blockq+mmsize*0+%1] + mova m1, [blockq+mmsize*2+%1] +%if mmsize == 8 + mova m2, [blockq+mmsize*4+%1] + mova m3, [blockq+mmsize*6+%1] +%endif + packuswb m0, [blockq+mmsize*1+%1] + packuswb m1, [blockq+mmsize*3+%1] +%if mmsize == 8 + packuswb m2, [blockq+mmsize*5+%1] + packuswb m3, [blockq+mmsize*7+%1] + movq [pixelsq], m0 + movq [lsizeq+pixelsq], m1 + movq [2*lsizeq+pixelsq], m2 + movq [lsize3q+pixelsq], m3 +%else + movq [pixelsq], m0 + movhps [lsizeq+pixelsq], m0 + movq [2*lsizeq+pixelsq], m1 + movhps [lsize3q+pixelsq], m1 +%endif +%endmacro + +%macro ADD_PIXELS_CLAMPED 1 + mova m0, [blockq+mmsize*0+%1] + mova m1, [blockq+mmsize*1+%1] +%if mmsize == 8 + mova m5, [blockq+mmsize*2+%1] + mova m6, [blockq+mmsize*3+%1] +%endif + movq m2, [pixelsq] + movq m3, [pixelsq+lsizeq] +%if mmsize == 8 + mova m7, m2 + punpcklbw m2, m4 + punpckhbw m7, m4 + paddsw m0, m2 + paddsw m1, m7 + mova m7, m3 + punpcklbw m3, m4 + punpckhbw m7, m4 + paddsw m5, m3 + paddsw m6, m7 +%else + punpcklbw m2, m4 + punpcklbw m3, m4 + paddsw m0, m2 + paddsw m1, m3 +%endif + packuswb m0, m1 +%if mmsize == 8 + packuswb m5, m6 + movq [pixelsq], m0 + movq [pixelsq+lsizeq], m5 +%else + movq [pixelsq], m0 + movhps [pixelsq+lsizeq], m0 +%endif +%endmacro + +INIT_MMX mmx + +cglobal simple_idct, 1, 2, 8, 128, block, t0 + IDCT +RET + +cglobal simple_idct_put, 3, 5, 8, 128, pixels, lsize, block, lsize3, t0 + IDCT + lea lsize3q, [lsizeq*3] + PUT_PIXELS_CLAMPED_HALF 0 + lea pixelsq, [pixelsq+lsizeq*4] + PUT_PIXELS_CLAMPED_HALF 64 +RET + +cglobal simple_idct_add, 3, 4, 8, 128, pixels, lsize, block, t0 + IDCT + pxor m4, m4 + ADD_PIXELS_CLAMPED 0 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 32 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 64 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 96 +RET + +INIT_XMM sse2 + +cglobal simple_idct_put, 3, 5, 8, 128, pixels, lsize, block, lsize3, t0 + IDCT + lea lsize3q, [lsizeq*3] + PUT_PIXELS_CLAMPED_HALF 0 + lea pixelsq, [pixelsq+lsizeq*4] + PUT_PIXELS_CLAMPED_HALF 64 +RET + +cglobal simple_idct_add, 3, 4, 8, 128, pixels, lsize, block, t0 + IDCT + pxor m4, m4 + ADD_PIXELS_CLAMPED 0 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 32 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 64 + lea pixelsq, [pixelsq+lsizeq*2] + ADD_PIXELS_CLAMPED 96 +RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct.h new file mode 100644 index 00000000..9b64cfe9 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct.h @@ -0,0 +1,53 @@ +/* + * 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 + */ + +#ifndef AVCODEC_X86_SIMPLE_IDCT_H +#define AVCODEC_X86_SIMPLE_IDCT_H + +#include +#include + +void ff_simple_idct_mmx(int16_t *block); +void ff_simple_idct_add_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_put_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct_add_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct8_sse2(int16_t *block); +void ff_simple_idct8_avx(int16_t *block); + +void ff_simple_idct8_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct8_put_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct8_add_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct8_add_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct10_sse2(int16_t *block); +void ff_simple_idct10_avx(int16_t *block); + +void ff_simple_idct10_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct10_put_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_simple_idct12_sse2(int16_t *block); +void ff_simple_idct12_avx(int16_t *block); + +void ff_simple_idct12_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_simple_idct12_put_avx(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +#endif /* AVCODEC_X86_SIMPLE_IDCT_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct10.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct10.asm new file mode 100644 index 00000000..069bb613 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct10.asm @@ -0,0 +1,205 @@ +;****************************************************************************** +;* x86-SIMD-optimized IDCT for prores +;* this is identical to "simple" IDCT written by Michael Niedermayer +;* except for the clip range +;* +;* Copyright (c) 2011 Ronald S. Bultje +;* Copyright (c) 2015 Christophe Gisquet +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "libavutil/x86/x86util.asm" + +%if ARCH_X86_64 + +SECTION_RODATA + +cextern pw_2 +cextern pw_16 +cextern pw_32 +cextern pw_1023 +cextern pw_4095 +pd_round_11: times 4 dd 1<<(11-1) +pd_round_12: times 4 dd 1<<(12-1) +pd_round_15: times 4 dd 1<<(15-1) +pd_round_19: times 4 dd 1<<(19-1) +pd_round_20: times 4 dd 1<<(20-1) + +%macro CONST_DEC 3 +const %1 +times 4 dw %2, %3 +%endmacro + +%define W1sh2 22725 ; W1 = 90901 = 22725<<2 + 1 +%define W2sh2 21407 ; W2 = 85627 = 21407<<2 - 1 +%define W3sh2 19265 ; W3 = 77062 = 19265<<2 + 2 +%define W4sh2 16384 ; W4 = 65535 = 16384<<2 - 1 +%define W3sh2_lo 19266 +%define W4sh2_lo 16383 +%define W5sh2 12873 ; W5 = 51491 = 12873<<2 - 1 +%define W6sh2 8867 ; W6 = 35468 = 8867<<2 +%define W7sh2 4520 ; W7 = 18081 = 4520<<2 + 1 + +CONST_DEC w4_plus_w2_hi, W4sh2, +W2sh2 +CONST_DEC w4_min_w2_hi, W4sh2, -W2sh2 +CONST_DEC w4_plus_w6_hi, W4sh2, +W6sh2 +CONST_DEC w4_min_w6_hi, W4sh2, -W6sh2 +CONST_DEC w1_plus_w3_hi, W1sh2, +W3sh2 +CONST_DEC w3_min_w1_hi, W3sh2, -W1sh2 +CONST_DEC w7_plus_w3_hi, W7sh2, +W3sh2 +CONST_DEC w3_min_w7_hi, W3sh2, -W7sh2 +CONST_DEC w1_plus_w5, W1sh2, +W5sh2 +CONST_DEC w5_min_w1, W5sh2, -W1sh2 +CONST_DEC w5_plus_w7, W5sh2, +W7sh2 +CONST_DEC w7_min_w5, W7sh2, -W5sh2 +CONST_DEC w4_plus_w2_lo, W4sh2_lo, +W2sh2 +CONST_DEC w4_min_w2_lo, W4sh2_lo, -W2sh2 +CONST_DEC w4_plus_w6_lo, W4sh2_lo, +W6sh2 +CONST_DEC w4_min_w6_lo, W4sh2_lo, -W6sh2 +CONST_DEC w1_plus_w3_lo, W1sh2, +W3sh2_lo +CONST_DEC w3_min_w1_lo, W3sh2_lo, -W1sh2 +CONST_DEC w7_plus_w3_lo, W7sh2, +W3sh2_lo +CONST_DEC w3_min_w7_lo, W3sh2_lo, -W7sh2 + +%include "libavcodec/x86/simple_idct10_template.asm" + +SECTION .text + +%macro STORE_HI_LO 12 + movq %1, %9 + movq %3, %10 + movq %5, %11 + movq %7, %12 + movhps %2, %9 + movhps %4, %10 + movhps %6, %11 + movhps %8, %12 +%endmacro + +%macro LOAD_ZXBW_8 16 + pmovzxbw %1, %9 + pmovzxbw %2, %10 + pmovzxbw %3, %11 + pmovzxbw %4, %12 + pmovzxbw %5, %13 + pmovzxbw %6, %14 + pmovzxbw %7, %15 + pmovzxbw %8, %16 +%endmacro + +%macro LOAD_ZXBW_4 9 + movh %1, %5 + movh %2, %6 + movh %3, %7 + movh %4, %8 + punpcklbw %1, %9 + punpcklbw %2, %9 + punpcklbw %3, %9 + punpcklbw %4, %9 +%endmacro + +%define PASS4ROWS(base, stride, stride3) \ + [base], [base + stride], [base + 2*stride], [base + stride3] + +%macro idct_fn 0 + +define_constants _lo + +cglobal simple_idct8, 1, 1, 16, 32, block + IDCT_FN "", 11, pw_32, 20, "store" +RET + +cglobal simple_idct8_put, 3, 4, 16, 32, pixels, lsize, block + IDCT_FN "", 11, pw_32, 20 + lea r3, [3*lsizeq] + lea r2, [pixelsq + r3] + packuswb m8, m0 + packuswb m1, m2 + packuswb m4, m11 + packuswb m9, m10 + STORE_HI_LO PASS8ROWS(pixelsq, r2, lsizeq, r3), m8, m1, m4, m9 +RET + +cglobal simple_idct8_add, 3, 4, 16, 32, pixels, lsize, block + IDCT_FN "", 11, pw_32, 20 + lea r2, [3*lsizeq] + %if cpuflag(sse4) + lea r3, [pixelsq + r2] + LOAD_ZXBW_8 m3, m5, m6, m7, m12, m13, m14, m15, PASS8ROWS(pixelsq, r3, lsizeq, r2) + paddsw m8, m3 + paddsw m0, m5 + paddsw m1, m6 + paddsw m2, m7 + paddsw m4, m12 + paddsw m11, m13 + paddsw m9, m14 + paddsw m10, m15 + %else + pxor m12, m12 + LOAD_ZXBW_4 m3, m5, m6, m7, PASS4ROWS(pixelsq, lsizeq, r2), m12 + paddsw m8, m3 + paddsw m0, m5 + paddsw m1, m6 + paddsw m2, m7 + lea r3, [pixelsq + 4*lsizeq] + LOAD_ZXBW_4 m3, m5, m6, m7, PASS4ROWS(r3, lsizeq, r2), m12 + paddsw m4, m3 + paddsw m11, m5 + paddsw m9, m6 + paddsw m10, m7 + lea r3, [pixelsq + r2] + %endif + packuswb m8, m0 + packuswb m1, m2 + packuswb m4, m11 + packuswb m9, m10 + STORE_HI_LO PASS8ROWS(pixelsq, r3, lsizeq, r2), m8, m1, m4, m9 +RET + +define_constants _hi + +cglobal simple_idct10, 1, 1, 16, block + IDCT_FN "", 12, "", 19, "store" + RET + +cglobal simple_idct10_put, 3, 3, 16, pixels, lsize, block + IDCT_FN "", 12, "", 19, "put", 0, pw_1023 + RET + +cglobal simple_idct12, 1, 1, 16, block + ; coeffs are already 15bits, adding the offset would cause + ; overflow in the input + IDCT_FN "", 15, pw_2, 16, "store" + RET + +cglobal simple_idct12_put, 3, 3, 16, pixels, lsize, block + ; range isn't known, so the C simple_idct range is used + ; Also, using a bias on input overflows, so use the bias + ; on output of the first butterfly instead + IDCT_FN "", 15, pw_2, 16, "put", 0, pw_4095 + RET +%endmacro + +INIT_XMM sse2 +idct_fn +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +idct_fn +%endif + +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct10_template.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct10_template.asm new file mode 100644 index 00000000..0d04a981 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/simple_idct10_template.asm @@ -0,0 +1,369 @@ +;****************************************************************************** +;* x86-SIMD-optimized IDCT for prores +;* this is identical to "simple" IDCT written by Michael Niedermayer +;* except for the clip range +;* +;* Copyright (c) 2011 Ronald S. Bultje +;* +;* 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 +;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +; add SECTION_RODATA and proper include before including this file! + +%if ARCH_X86_64 + +%macro define_constants 1 + %undef w4_plus_w2 + %undef w4_min_w2 + %undef w4_plus_w6 + %undef w4_min_w6 + %undef w1_plus_w3 + %undef w3_min_w1 + %undef w7_plus_w3 + %undef w3_min_w7 + %define w4_plus_w2 w4_plus_w2%1 + %define w4_min_w2 w4_min_w2%1 + %define w4_plus_w6 w4_plus_w6%1 + %define w4_min_w6 w4_min_w6%1 + %define w1_plus_w3 w1_plus_w3%1 + %define w3_min_w1 w3_min_w1%1 + %define w7_plus_w3 w7_plus_w3%1 + %define w3_min_w7 w3_min_w7%1 +%endmacro + +; interleave data while maintaining source +; %1=type, %2=dstlo, %3=dsthi, %4=src, %5=interleave +%macro SBUTTERFLY3 5 + punpckl%1 m%2, m%4, m%5 + punpckh%1 m%3, m%4, m%5 +%endmacro + +; %1/%2=src1/dst1, %3/%4=dst2, %5/%6=src2, %7=shift +; action: %3/%4 = %1/%2 - %5/%6; %1/%2 += %5/%6 +; %1/%2/%3/%4 >>= %7; dword -> word (in %1/%3) +%macro SUMSUB_SHPK 7 + psubd %3, %1, %5 ; { a0 - b0 }[0-3] + psubd %4, %2, %6 ; { a0 - b0 }[4-7] + paddd %1, %5 ; { a0 + b0 }[0-3] + paddd %2, %6 ; { a0 + b0 }[4-7] + psrad %1, %7 + psrad %2, %7 + psrad %3, %7 + psrad %4, %7 + packssdw %1, %2 ; row[0] + packssdw %3, %4 ; row[7] +%endmacro + +; %1 = initial bias ("" if nop) +; %2 = number of bits to shift at the end +; %3 = qmat (for prores) +%macro IDCT_1D 2-3 + ; a0 = (W4 * row[0]) + (1 << (15 - 1)); + ; a1 = a0; + ; a2 = a0; + ; a3 = a0; + ; a0 += W2 * row[2]; + ; a1 += W6 * row[2]; + ; a2 -= W6 * row[2]; + ; a3 -= W2 * row[2]; +%ifstr %1 + mova m15, [pd_round_ %+ %2] +%else + paddw m10, [%1] +%endif + SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[0], row[2] }[0-3]/[4-7] + pmaddwd m2, m0, [w4_plus_w6] + pmaddwd m3, m1, [w4_plus_w6] + pmaddwd m4, m0, [w4_min_w6] + pmaddwd m5, m1, [w4_min_w6] + pmaddwd m6, m0, [w4_min_w2] + pmaddwd m7, m1, [w4_min_w2] + pmaddwd m0, [w4_plus_w2] + pmaddwd m1, [w4_plus_w2] +%ifstr %1 + ; Adding 1<<(%2-1) for >=15 bits values + paddd m2, m15 + paddd m3, m15 + paddd m4, m15 + paddd m5, m15 + paddd m6, m15 + paddd m7, m15 + paddd m0, m15 + paddd m1, m15 +%endif + + ; a0: -1*row[0]-1*row[2] + ; a1: -1*row[0] + ; a2: -1*row[0] + ; a3: -1*row[0]+1*row[2] + + ; a0 += W4*row[4] + W6*row[6]; i.e. -1*row[4] + ; a1 -= W4*row[4] + W2*row[6]; i.e. -1*row[4]-1*row[6] + ; a2 -= W4*row[4] - W2*row[6]; i.e. -1*row[4]+1*row[6] + ; a3 += W4*row[4] - W6*row[6]; i.e. -1*row[4] + SBUTTERFLY3 wd, 8, 9, 13, 12 ; { row[4], row[6] }[0-3]/[4-7] + pmaddwd m10, m8, [w4_plus_w6] + pmaddwd m11, m9, [w4_plus_w6] + paddd m0, m10 ; a0[0-3] + paddd m1, m11 ; a0[4-7] + pmaddwd m10, m8, [w4_min_w6] + pmaddwd m11, m9, [w4_min_w6] + paddd m6, m10 ; a3[0-3] + paddd m7, m11 ; a3[4-7] + pmaddwd m10, m8, [w4_min_w2] + pmaddwd m11, m9, [w4_min_w2] + pmaddwd m8, [w4_plus_w2] + pmaddwd m9, [w4_plus_w2] + psubd m4, m10 ; a2[0-3] intermediate + psubd m5, m11 ; a2[4-7] intermediate + psubd m2, m8 ; a1[0-3] intermediate + psubd m3, m9 ; a1[4-7] intermediate + + ; load/store + mova [blockq+ 0], m0 + mova [blockq+ 32], m2 + mova [blockq+ 64], m4 + mova [blockq+ 96], m6 + mova m10,[blockq+ 16] ; { row[1] }[0-7] + mova m8, [blockq+ 48] ; { row[3] }[0-7] + mova m13,[blockq+ 80] ; { row[5] }[0-7] + mova m14,[blockq+112] ; { row[7] }[0-7] + mova [blockq+ 16], m1 + mova [blockq+ 48], m3 + mova [blockq+ 80], m5 + mova [blockq+112], m7 +%if %0 == 3 + pmullw m10,[%3+ 16] + pmullw m8, [%3+ 48] + pmullw m13,[%3+ 80] + pmullw m14,[%3+112] +%endif + + ; b0 = MUL(W1, row[1]); + ; MAC(b0, W3, row[3]); + ; b1 = MUL(W3, row[1]); + ; MAC(b1, -W7, row[3]); + ; b2 = MUL(W5, row[1]); + ; MAC(b2, -W1, row[3]); + ; b3 = MUL(W7, row[1]); + ; MAC(b3, -W5, row[3]); + SBUTTERFLY3 wd, 0, 1, 10, 8 ; { row[1], row[3] }[0-3]/[4-7] + pmaddwd m2, m0, [w3_min_w7] + pmaddwd m3, m1, [w3_min_w7] + pmaddwd m4, m0, [w5_min_w1] + pmaddwd m5, m1, [w5_min_w1] + pmaddwd m6, m0, [w7_min_w5] + pmaddwd m7, m1, [w7_min_w5] + pmaddwd m0, [w1_plus_w3] + pmaddwd m1, [w1_plus_w3] + + ; b0: +1*row[1]+2*row[3] + ; b1: +2*row[1]-1*row[3] + ; b2: -1*row[1]-1*row[3] + ; b3: +1*row[1]+1*row[3] + + ; MAC(b0, W5, row[5]); + ; MAC(b0, W7, row[7]); + ; MAC(b1, -W1, row[5]); + ; MAC(b1, -W5, row[7]); + ; MAC(b2, W7, row[5]); + ; MAC(b2, W3, row[7]); + ; MAC(b3, W3, row[5]); + ; MAC(b3, -W1, row[7]); + SBUTTERFLY3 wd, 8, 9, 13, 14 ; { row[5], row[7] }[0-3]/[4-7] + + ; b0: -1*row[5]+1*row[7] + ; b1: -1*row[5]+1*row[7] + ; b2: +1*row[5]+2*row[7] + ; b3: +2*row[5]-1*row[7] + + pmaddwd m10, m8, [w1_plus_w5] + pmaddwd m11, m9, [w1_plus_w5] + pmaddwd m12, m8, [w5_plus_w7] + pmaddwd m13, m9, [w5_plus_w7] + psubd m2, m10 ; b1[0-3] + psubd m3, m11 ; b1[4-7] + paddd m0, m12 ; b0[0-3] + paddd m1, m13 ; b0[4-7] + pmaddwd m12, m8, [w7_plus_w3] + pmaddwd m13, m9, [w7_plus_w3] + pmaddwd m8, [w3_min_w1] + pmaddwd m9, [w3_min_w1] + paddd m4, m12 ; b2[0-3] + paddd m5, m13 ; b2[4-7] + paddd m6, m8 ; b3[0-3] + paddd m7, m9 ; b3[4-7] + + ; row[0] = (a0 + b0) >> 15; + ; row[7] = (a0 - b0) >> 15; + ; row[1] = (a1 + b1) >> 15; + ; row[6] = (a1 - b1) >> 15; + ; row[2] = (a2 + b2) >> 15; + ; row[5] = (a2 - b2) >> 15; + ; row[3] = (a3 + b3) >> 15; + ; row[4] = (a3 - b3) >> 15; + mova m8, [blockq+ 0] ; a0[0-3] + mova m9, [blockq+16] ; a0[4-7] + SUMSUB_SHPK m8, m9, m10, m11, m0, m1, %2 + mova m0, [blockq+32] ; a1[0-3] + mova m1, [blockq+48] ; a1[4-7] + SUMSUB_SHPK m0, m1, m9, m11, m2, m3, %2 + mova m1, [blockq+64] ; a2[0-3] + mova m2, [blockq+80] ; a2[4-7] + SUMSUB_SHPK m1, m2, m11, m3, m4, m5, %2 + mova m2, [blockq+96] ; a3[0-3] + mova m3, [blockq+112] ; a3[4-7] + SUMSUB_SHPK m2, m3, m4, m5, m6, m7, %2 +%endmacro + +; void ff_prores_idct_put_10_(uint8_t *pixels, ptrdiff_t stride, +; int16_t *block, const int16_t *qmat); + +; %1 = row shift +; %2 = row bias macro +; %3 = column shift +; %4 = column bias macro +; %5 = final action (nothing, "store", "put", "add") +; %6 = min pixel value +; %7 = max pixel value +; %8 = qmat (for prores) + +%macro IDCT_FN 4-8 + ; for (i = 0; i < 8; i++) + ; idctRowCondDC(block + i*8); + mova m10,[blockq+ 0] ; { row[0] }[0-7] + mova m8, [blockq+32] ; { row[2] }[0-7] + mova m13,[blockq+64] ; { row[4] }[0-7] + mova m12,[blockq+96] ; { row[6] }[0-7] + +%if %0 == 8 + pmullw m10,[%8+ 0] + pmullw m8, [%8+32] + pmullw m13,[%8+64] + pmullw m12,[%8+96] + + IDCT_1D %1, %2, %8 +%elif %2 == 11 + ; This copies the DC-only shortcut. When there is only a DC coefficient the + ; C shifts the value and splats it to all coeffs rather than multiplying and + ; doing the full IDCT. This causes a difference on 8-bit because the + ; coefficient is 16383 rather than 16384 (which you can get with shifting). + por m1, m8, m13 + por m1, m12 + por m1, [blockq+ 16] ; { row[1] }[0-7] + por m1, [blockq+ 48] ; { row[3] }[0-7] + por m1, [blockq+ 80] ; { row[5] }[0-7] + por m1, [blockq+112] ; { row[7] }[0-7] + pxor m2, m2 + pcmpeqw m1, m2 + psllw m2, m10, 3 + pand m2, m1 + pcmpeqb m3, m3 + pxor m1, m3 + mova [rsp], m1 + mova [rsp+16], m2 + + IDCT_1D %1, %2 + + mova m5, [rsp] + mova m6, [rsp+16] + pand m8, m5 + por m8, m6 + pand m0, m5 + por m0, m6 + pand m1, m5 + por m1, m6 + pand m2, m5 + por m2, m6 + pand m4, m5 + por m4, m6 + pand m11, m5 + por m11, m6 + pand m9, m5 + por m9, m6 + pand m10, m5 + por m10, m6 +%else + IDCT_1D %1, %2 +%endif + + ; transpose for second part of IDCT + TRANSPOSE8x8W 8, 0, 1, 2, 4, 11, 9, 10, 3 + mova [blockq+ 16], m0 + mova [blockq+ 48], m2 + mova [blockq+ 80], m11 + mova [blockq+112], m10 + SWAP 8, 10 + SWAP 1, 8 + SWAP 4, 13 + SWAP 9, 12 + + ; for (i = 0; i < 8; i++) + ; idctSparseColAdd(dest + i, line_size, block + i); + IDCT_1D %3, %4 + + ; clip/store +%if %0 >= 5 +%ifidn %5,"store" + ; No clamping, means pure idct + mova [blockq+ 0], m8 + mova [blockq+ 16], m0 + mova [blockq+ 32], m1 + mova [blockq+ 48], m2 + mova [blockq+ 64], m4 + mova [blockq+ 80], m11 + mova [blockq+ 96], m9 + mova [blockq+112], m10 +%elifidn %5,"put" +%ifidn %6, 0 + pxor m3, m3 +%else + mova m3, [%6] +%endif ; ifidn %6, 0 + mova m5, [%7] + pmaxsw m8, m3 + pmaxsw m0, m3 + pmaxsw m1, m3 + pmaxsw m2, m3 + pmaxsw m4, m3 + pmaxsw m11, m3 + pmaxsw m9, m3 + pmaxsw m10, m3 + pminsw m8, m5 + pminsw m0, m5 + pminsw m1, m5 + pminsw m2, m5 + pminsw m4, m5 + pminsw m11, m5 + pminsw m9, m5 + pminsw m10, m5 + + lea r2, [r1*3] + mova [r0 ], m8 + mova [r0+r1 ], m0 + mova [r0+r1*2], m1 + mova [r0+r2 ], m2 + lea r0, [r0+r1*4] + mova [r0 ], m4 + mova [r0+r1 ], m11 + mova [r0+r1*2], m9 + mova [r0+r2 ], m10 +%endif ; %5 action +%endif; if %0 >= 5 +%endmacro + +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/snowdsp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/snowdsp.c new file mode 100644 index 00000000..218e6864 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/snowdsp.c @@ -0,0 +1,908 @@ +/* + * MMX and SSE2 optimized snow DSP utils + * Copyright (c) 2005-2006 Robert Edele + * + * 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 "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/snow.h" +#include "libavcodec/snow_dwt.h" + +#if HAVE_INLINE_ASM + +static void ff_snow_horizontal_compose97i_sse2(IDWTELEM *b, IDWTELEM *temp, int width){ + const int w2= (width+1)>>1; + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + + { // Lift 0 + IDWTELEM * const ref = b + w2 - 1; + IDWTELEM b_0 = b[0]; //By allowing the first entry in b[0] to be calculated twice + // (the first time erroneously), we allow the SSE2 code to run an extra pass. + // The savings in code and time are well worth having to store this value and + // calculate b[0] correctly afterwards. + + i = 0; + __asm__ volatile( + "pcmpeqd %%xmm7, %%xmm7 \n\t" + "pcmpeqd %%xmm3, %%xmm3 \n\t" + "psllw $1, %%xmm3 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "psllw $13, %%xmm3 \n\t" + ::); + for(; i>W_DS); + } + + { // Lift 1 + IDWTELEM * const dst = b+w2; + + i = 0; + for(; (((x86_reg)&dst[i]) & 0x1F) && i> W_BS); + } + + { // Lift 3 + IDWTELEM * const src = b+w2; + + i = 0; + for(; (((x86_reg)&temp[i]) & 0x1F) && i>W_AS); + } + for(; i>1]; + b[i] = b[i>>1]; + } + for (i-=62; i>=0; i-=64){ + __asm__ volatile( + "movdqa (%1), %%xmm0 \n\t" + "movdqa 16(%1), %%xmm2 \n\t" + "movdqa 32(%1), %%xmm4 \n\t" + "movdqa 48(%1), %%xmm6 \n\t" + "movdqa (%1), %%xmm1 \n\t" + "movdqa 16(%1), %%xmm3 \n\t" + "movdqa 32(%1), %%xmm5 \n\t" + "movdqa 48(%1), %%xmm7 \n\t" + "punpcklwd (%2), %%xmm0 \n\t" + "punpcklwd 16(%2), %%xmm2 \n\t" + "punpcklwd 32(%2), %%xmm4 \n\t" + "punpcklwd 48(%2), %%xmm6 \n\t" + "movdqa %%xmm0, (%0) \n\t" + "movdqa %%xmm2, 32(%0) \n\t" + "movdqa %%xmm4, 64(%0) \n\t" + "movdqa %%xmm6, 96(%0) \n\t" + "punpckhwd (%2), %%xmm1 \n\t" + "punpckhwd 16(%2), %%xmm3 \n\t" + "punpckhwd 32(%2), %%xmm5 \n\t" + "punpckhwd 48(%2), %%xmm7 \n\t" + "movdqa %%xmm1, 16(%0) \n\t" + "movdqa %%xmm3, 48(%0) \n\t" + "movdqa %%xmm5, 80(%0) \n\t" + "movdqa %%xmm7, 112(%0) \n\t" + :: "r"(&(b)[i]), "r"(&(b)[i>>1]), "r"(&(temp)[i>>1]) + : "memory" + ); + } + } +} + +static void ff_snow_horizontal_compose97i_mmx(IDWTELEM *b, IDWTELEM *temp, int width){ + const int w2= (width+1)>>1; + const int w_l= (width>>1); + const int w_r= w2 - 1; + int i; + + { // Lift 0 + IDWTELEM * const ref = b + w2 - 1; + + i = 1; + b[0] = b[0] - ((W_DM * 2 * ref[1]+W_DO)>>W_DS); + __asm__ volatile( + "pcmpeqw %%mm7, %%mm7 \n\t" + "pcmpeqw %%mm3, %%mm3 \n\t" + "psllw $1, %%mm3 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "psllw $13, %%mm3 \n\t" + ::); + for(; i> W_BS); + __asm__ volatile( + "psllw $15, %%mm7 \n\t" + "pcmpeqw %%mm6, %%mm6 \n\t" + "psrlw $13, %%mm6 \n\t" + "paddw %%mm7, %%mm6 \n\t" + ::); + for(; i>1]; + b[i] = b[i>>1]; + } + for (i-=30; i>=0; i-=32){ + __asm__ volatile( + "movq (%1), %%mm0 \n\t" + "movq 8(%1), %%mm2 \n\t" + "movq 16(%1), %%mm4 \n\t" + "movq 24(%1), %%mm6 \n\t" + "movq (%1), %%mm1 \n\t" + "movq 8(%1), %%mm3 \n\t" + "movq 16(%1), %%mm5 \n\t" + "movq 24(%1), %%mm7 \n\t" + "punpcklwd (%2), %%mm0 \n\t" + "punpcklwd 8(%2), %%mm2 \n\t" + "punpcklwd 16(%2), %%mm4 \n\t" + "punpcklwd 24(%2), %%mm6 \n\t" + "movq %%mm0, (%0) \n\t" + "movq %%mm2, 16(%0) \n\t" + "movq %%mm4, 32(%0) \n\t" + "movq %%mm6, 48(%0) \n\t" + "punpckhwd (%2), %%mm1 \n\t" + "punpckhwd 8(%2), %%mm3 \n\t" + "punpckhwd 16(%2), %%mm5 \n\t" + "punpckhwd 24(%2), %%mm7 \n\t" + "movq %%mm1, 8(%0) \n\t" + "movq %%mm3, 24(%0) \n\t" + "movq %%mm5, 40(%0) \n\t" + "movq %%mm7, 56(%0) \n\t" + :: "r"(&b[i]), "r"(&b[i>>1]), "r"(&temp[i>>1]) + : "memory" + ); + } + } +} + +#if HAVE_7REGS +#define snow_vertical_compose_sse2_load_add(op,r,t0,t1,t2,t3)\ + ""op" ("r",%%"FF_REG_d"), %%"t0" \n\t"\ + ""op" 16("r",%%"FF_REG_d"), %%"t1" \n\t"\ + ""op" 32("r",%%"FF_REG_d"), %%"t2" \n\t"\ + ""op" 48("r",%%"FF_REG_d"), %%"t3" \n\t" + +#define snow_vertical_compose_sse2_load(r,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_load_add("movdqa",r,t0,t1,t2,t3) + +#define snow_vertical_compose_sse2_add(r,t0,t1,t2,t3)\ + snow_vertical_compose_sse2_load_add("paddw",r,t0,t1,t2,t3) + +#define snow_vertical_compose_r2r_sub(s0,s1,s2,s3,t0,t1,t2,t3)\ + "psubw %%"s0", %%"t0" \n\t"\ + "psubw %%"s1", %%"t1" \n\t"\ + "psubw %%"s2", %%"t2" \n\t"\ + "psubw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_store(w,s0,s1,s2,s3)\ + "movdqa %%"s0", ("w",%%"FF_REG_d") \n\t"\ + "movdqa %%"s1", 16("w",%%"FF_REG_d") \n\t"\ + "movdqa %%"s2", 32("w",%%"FF_REG_d") \n\t"\ + "movdqa %%"s3", 48("w",%%"FF_REG_d") \n\t" + +#define snow_vertical_compose_sra(n,t0,t1,t2,t3)\ + "psraw $"n", %%"t0" \n\t"\ + "psraw $"n", %%"t1" \n\t"\ + "psraw $"n", %%"t2" \n\t"\ + "psraw $"n", %%"t3" \n\t" + +#define snow_vertical_compose_r2r_add(s0,s1,s2,s3,t0,t1,t2,t3)\ + "paddw %%"s0", %%"t0" \n\t"\ + "paddw %%"s1", %%"t1" \n\t"\ + "paddw %%"s2", %%"t2" \n\t"\ + "paddw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_r2r_pmulhw(s0,s1,s2,s3,t0,t1,t2,t3)\ + "pmulhw %%"s0", %%"t0" \n\t"\ + "pmulhw %%"s1", %%"t1" \n\t"\ + "pmulhw %%"s2", %%"t2" \n\t"\ + "pmulhw %%"s3", %%"t3" \n\t" + +#define snow_vertical_compose_sse2_move(s0,s1,s2,s3,t0,t1,t2,t3)\ + "movdqa %%"s0", %%"t0" \n\t"\ + "movdqa %%"s1", %%"t1" \n\t"\ + "movdqa %%"s2", %%"t2" \n\t"\ + "movdqa %%"s3", %%"t3" \n\t" + +static void ff_snow_vertical_compose97i_sse2(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ + x86_reg i = width; + + while(i & 0x1F) + { + i--; + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } + i+=i; + + __asm__ volatile ( + "jmp 2f \n\t" + "1: \n\t" + snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%6","xmm0","xmm2","xmm4","xmm6") + + + "pcmpeqw %%xmm0, %%xmm0 \n\t" + "pcmpeqw %%xmm2, %%xmm2 \n\t" + "paddw %%xmm2, %%xmm2 \n\t" + "paddw %%xmm0, %%xmm2 \n\t" + "psllw $13, %%xmm2 \n\t" + snow_vertical_compose_r2r_add("xmm0","xmm0","xmm0","xmm0","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_r2r_pmulhw("xmm2","xmm2","xmm2","xmm2","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_add("%5","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_store("%5","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sse2_load("%4","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_r2r_sub("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%4","xmm0","xmm2","xmm4","xmm6") + + "pcmpeqw %%xmm7, %%xmm7 \n\t" + "pcmpeqw %%xmm5, %%xmm5 \n\t" + "psllw $15, %%xmm7 \n\t" + "psrlw $13, %%xmm5 \n\t" + "paddw %%xmm7, %%xmm5 \n\t" + snow_vertical_compose_r2r_add("xmm5","xmm5","xmm5","xmm5","xmm0","xmm2","xmm4","xmm6") + "movq (%2,%%"FF_REG_d"), %%xmm1 \n\t" + "movq 8(%2,%%"FF_REG_d"), %%xmm3 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "pavgw %%xmm1, %%xmm0 \n\t" + "pavgw %%xmm3, %%xmm2 \n\t" + "movq 16(%2,%%"FF_REG_d"), %%xmm1 \n\t" + "movq 24(%2,%%"FF_REG_d"), %%xmm3 \n\t" + "paddw %%xmm7, %%xmm1 \n\t" + "paddw %%xmm7, %%xmm3 \n\t" + "pavgw %%xmm1, %%xmm4 \n\t" + "pavgw %%xmm3, %%xmm6 \n\t" + snow_vertical_compose_r2r_sub("xmm7","xmm7","xmm7","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") + + snow_vertical_compose_sra("2","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%3","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_move("xmm0","xmm2","xmm4","xmm6","xmm1","xmm3","xmm5","xmm7") + snow_vertical_compose_sra("1","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_r2r_add("xmm1","xmm3","xmm5","xmm7","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_add("%2","xmm0","xmm2","xmm4","xmm6") + snow_vertical_compose_sse2_store("%2","xmm0","xmm2","xmm4","xmm6") + + "2: \n\t" + "sub $64, %%"FF_REG_d" \n\t" + "jge 1b \n\t" + :"+d"(i) + :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); +} + +#define snow_vertical_compose_mmx_load_add(op,r,t0,t1,t2,t3)\ + ""op" ("r",%%"FF_REG_d"), %%"t0" \n\t"\ + ""op" 8("r",%%"FF_REG_d"), %%"t1" \n\t"\ + ""op" 16("r",%%"FF_REG_d"), %%"t2" \n\t"\ + ""op" 24("r",%%"FF_REG_d"), %%"t3" \n\t" + +#define snow_vertical_compose_mmx_load(r,t0,t1,t2,t3)\ + snow_vertical_compose_mmx_load_add("movq",r,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_add(r,t0,t1,t2,t3)\ + snow_vertical_compose_mmx_load_add("paddw",r,t0,t1,t2,t3) + +#define snow_vertical_compose_mmx_store(w,s0,s1,s2,s3)\ + "movq %%"s0", ("w",%%"FF_REG_d") \n\t"\ + "movq %%"s1", 8("w",%%"FF_REG_d") \n\t"\ + "movq %%"s2", 16("w",%%"FF_REG_d") \n\t"\ + "movq %%"s3", 24("w",%%"FF_REG_d") \n\t" + +#define snow_vertical_compose_mmx_move(s0,s1,s2,s3,t0,t1,t2,t3)\ + "movq %%"s0", %%"t0" \n\t"\ + "movq %%"s1", %%"t1" \n\t"\ + "movq %%"s2", %%"t2" \n\t"\ + "movq %%"s3", %%"t3" \n\t" + + +static void ff_snow_vertical_compose97i_mmx(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, IDWTELEM *b5, int width){ + x86_reg i = width; + while(i & 15) + { + i--; + b4[i] -= (W_DM*(b3[i] + b5[i])+W_DO)>>W_DS; + b3[i] -= (W_CM*(b2[i] + b4[i])+W_CO)>>W_CS; + b2[i] += (W_BM*(b1[i] + b3[i])+4*b2[i]+W_BO)>>W_BS; + b1[i] += (W_AM*(b0[i] + b2[i])+W_AO)>>W_AS; + } + i+=i; + __asm__ volatile( + "jmp 2f \n\t" + "1: \n\t" + + snow_vertical_compose_mmx_load("%4","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add("%6","mm1","mm3","mm5","mm7") + "pcmpeqw %%mm0, %%mm0 \n\t" + "pcmpeqw %%mm2, %%mm2 \n\t" + "paddw %%mm2, %%mm2 \n\t" + "paddw %%mm0, %%mm2 \n\t" + "psllw $13, %%mm2 \n\t" + snow_vertical_compose_r2r_add("mm0","mm0","mm0","mm0","mm1","mm3","mm5","mm7") + snow_vertical_compose_r2r_pmulhw("mm2","mm2","mm2","mm2","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_add("%5","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_store("%5","mm1","mm3","mm5","mm7") + snow_vertical_compose_mmx_load("%4","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm1","mm3","mm5","mm7") + snow_vertical_compose_r2r_sub("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%4","mm0","mm2","mm4","mm6") + "pcmpeqw %%mm7, %%mm7 \n\t" + "pcmpeqw %%mm5, %%mm5 \n\t" + "psllw $15, %%mm7 \n\t" + "psrlw $13, %%mm5 \n\t" + "paddw %%mm7, %%mm5 \n\t" + snow_vertical_compose_r2r_add("mm5","mm5","mm5","mm5","mm0","mm2","mm4","mm6") + "movq (%2,%%"FF_REG_d"), %%mm1 \n\t" + "movq 8(%2,%%"FF_REG_d"), %%mm3 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "pavgw %%mm1, %%mm0 \n\t" + "pavgw %%mm3, %%mm2 \n\t" + "movq 16(%2,%%"FF_REG_d"), %%mm1 \n\t" + "movq 24(%2,%%"FF_REG_d"), %%mm3 \n\t" + "paddw %%mm7, %%mm1 \n\t" + "paddw %%mm7, %%mm3 \n\t" + "pavgw %%mm1, %%mm4 \n\t" + "pavgw %%mm3, %%mm6 \n\t" + snow_vertical_compose_r2r_sub("mm7","mm7","mm7","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") + + snow_vertical_compose_sra("2","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%3","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%1","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_move("mm0","mm2","mm4","mm6","mm1","mm3","mm5","mm7") + snow_vertical_compose_sra("1","mm0","mm2","mm4","mm6") + snow_vertical_compose_r2r_add("mm1","mm3","mm5","mm7","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_add("%2","mm0","mm2","mm4","mm6") + snow_vertical_compose_mmx_store("%2","mm0","mm2","mm4","mm6") + + "2: \n\t" + "sub $32, %%"FF_REG_d" \n\t" + "jge 1b \n\t" + :"+d"(i) + :"r"(b0),"r"(b1),"r"(b2),"r"(b3),"r"(b4),"r"(b5)); +} +#endif //HAVE_7REGS + +#if HAVE_6REGS +#define snow_inner_add_yblock_sse2_header \ + IDWTELEM * * dst_array = sb->line + src_y;\ + x86_reg tmp;\ + __asm__ volatile(\ + "mov %7, %%"FF_REG_c" \n\t"\ + "mov %6, %2 \n\t"\ + "mov %4, %%"FF_REG_S" \n\t"\ + "pxor %%xmm7, %%xmm7 \n\t" /* 0 */\ + "pcmpeqd %%xmm3, %%xmm3 \n\t"\ + "psllw $15, %%xmm3 \n\t"\ + "psrlw $12, %%xmm3 \n\t" /* FRAC_BITS >> 1 */\ + "1: \n\t"\ + "mov %1, %%"FF_REG_D" \n\t"\ + "mov (%%"FF_REG_D"), %%"FF_REG_D" \n\t"\ + "add %3, %%"FF_REG_D" \n\t" + +#define snow_inner_add_yblock_sse2_start_8(out_reg1, out_reg2, ptr_offset, s_offset)\ + "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; \n\t"\ + "movq (%%"FF_REG_d"), %%"out_reg1" \n\t"\ + "movq (%%"FF_REG_d", %%"FF_REG_c"), %%"out_reg2" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg1" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg2" \n\t"\ + "movq "s_offset"(%%"FF_REG_S"), %%xmm0 \n\t"\ + "movq "s_offset"+16(%%"FF_REG_S"), %%xmm4 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + "pmullw %%xmm0, %%"out_reg1" \n\t"\ + "pmullw %%xmm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_sse2_start_16(out_reg1, out_reg2, ptr_offset, s_offset)\ + "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; \n\t"\ + "movq (%%"FF_REG_d"), %%"out_reg1" \n\t"\ + "movq 8(%%"FF_REG_d"), %%"out_reg2" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg1" \n\t"\ + "punpcklbw %%xmm7, %%"out_reg2" \n\t"\ + "movq "s_offset"(%%"FF_REG_S"), %%xmm0 \n\t"\ + "movq "s_offset"+8(%%"FF_REG_S"), %%xmm4 \n\t"\ + "punpcklbw %%xmm7, %%xmm0 \n\t"\ + "punpcklbw %%xmm7, %%xmm4 \n\t"\ + "pmullw %%xmm0, %%"out_reg1" \n\t"\ + "pmullw %%xmm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_sse2_accum_8(ptr_offset, s_offset) \ + snow_inner_add_yblock_sse2_start_8("xmm2", "xmm6", ptr_offset, s_offset)\ + "paddusw %%xmm2, %%xmm1 \n\t"\ + "paddusw %%xmm6, %%xmm5 \n\t" + +#define snow_inner_add_yblock_sse2_accum_16(ptr_offset, s_offset) \ + snow_inner_add_yblock_sse2_start_16("xmm2", "xmm6", ptr_offset, s_offset)\ + "paddusw %%xmm2, %%xmm1 \n\t"\ + "paddusw %%xmm6, %%xmm5 \n\t" + +#define snow_inner_add_yblock_sse2_end_common1\ + "add $32, %%"FF_REG_S" \n\t"\ + "add %%"FF_REG_c", %0 \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*3(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*2(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*1(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", (%%"FF_REG_a") \n\t" + +#define snow_inner_add_yblock_sse2_end_common2\ + "jnz 1b \n\t"\ + :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ + :\ + "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\ + XMM_CLOBBERS("%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", )\ + "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d""); + +#define snow_inner_add_yblock_sse2_end_8\ + "sal $1, %%"FF_REG_c" \n\t"\ + "add"FF_OPSIZE" $"FF_PTR_SIZE"*2, %1 \n\t"\ + snow_inner_add_yblock_sse2_end_common1\ + "sar $1, %%"FF_REG_c" \n\t"\ + "sub $2, %2 \n\t"\ + snow_inner_add_yblock_sse2_end_common2 + +#define snow_inner_add_yblock_sse2_end_16\ + "add"FF_OPSIZE" $"FF_PTR_SIZE"*1, %1 \n\t"\ + snow_inner_add_yblock_sse2_end_common1\ + "dec %2 \n\t"\ + snow_inner_add_yblock_sse2_end_common2 + +static void inner_add_yblock_bw_8_obmc_16_bh_even_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_sse2_header +snow_inner_add_yblock_sse2_start_8("xmm1", "xmm5", "3", "0") +snow_inner_add_yblock_sse2_accum_8("2", "8") +snow_inner_add_yblock_sse2_accum_8("1", "128") +snow_inner_add_yblock_sse2_accum_8("0", "136") + + "mov %0, %%"FF_REG_d" \n\t" + "movdqa (%%"FF_REG_D"), %%xmm0 \n\t" + "movdqa %%xmm1, %%xmm2 \n\t" + + "punpckhwd %%xmm7, %%xmm1 \n\t" + "punpcklwd %%xmm7, %%xmm2 \n\t" + "paddd %%xmm2, %%xmm0 \n\t" + "movdqa 16(%%"FF_REG_D"), %%xmm2\n\t" + "paddd %%xmm1, %%xmm2 \n\t" + "paddd %%xmm3, %%xmm0 \n\t" + "paddd %%xmm3, %%xmm2 \n\t" + + "mov %1, %%"FF_REG_D" \n\t" + "mov "FF_PTR_SIZE"(%%"FF_REG_D"), %%"FF_REG_D"; \n\t" + "add %3, %%"FF_REG_D" \n\t" + + "movdqa (%%"FF_REG_D"), %%xmm4 \n\t" + "movdqa %%xmm5, %%xmm6 \n\t" + "punpckhwd %%xmm7, %%xmm5 \n\t" + "punpcklwd %%xmm7, %%xmm6 \n\t" + "paddd %%xmm6, %%xmm4 \n\t" + "movdqa 16(%%"FF_REG_D"), %%xmm6\n\t" + "paddd %%xmm5, %%xmm6 \n\t" + "paddd %%xmm3, %%xmm4 \n\t" + "paddd %%xmm3, %%xmm6 \n\t" + + "psrad $8, %%xmm0 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm2 \n\t" /* FRAC_BITS. */ + "packssdw %%xmm2, %%xmm0 \n\t" + "packuswb %%xmm7, %%xmm0 \n\t" + "movq %%xmm0, (%%"FF_REG_d") \n\t" + + "psrad $8, %%xmm4 \n\t" /* FRAC_BITS. */ + "psrad $8, %%xmm6 \n\t" /* FRAC_BITS. */ + "packssdw %%xmm6, %%xmm4 \n\t" + "packuswb %%xmm7, %%xmm4 \n\t" + "movq %%xmm4, (%%"FF_REG_d",%%"FF_REG_c"); \n\t" +snow_inner_add_yblock_sse2_end_8 +} + +static void inner_add_yblock_bw_16_obmc_32_sse2(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_sse2_header +snow_inner_add_yblock_sse2_start_16("xmm1", "xmm5", "3", "0") +snow_inner_add_yblock_sse2_accum_16("2", "16") +snow_inner_add_yblock_sse2_accum_16("1", "512") +snow_inner_add_yblock_sse2_accum_16("0", "528") + + "mov %0, %%"FF_REG_d" \n\t" + "psrlw $4, %%xmm1 \n\t" + "psrlw $4, %%xmm5 \n\t" + "paddw (%%"FF_REG_D"), %%xmm1 \n\t" + "paddw 16(%%"FF_REG_D"), %%xmm5 \n\t" + "paddw %%xmm3, %%xmm1 \n\t" + "paddw %%xmm3, %%xmm5 \n\t" + "psraw $4, %%xmm1 \n\t" /* FRAC_BITS. */ + "psraw $4, %%xmm5 \n\t" /* FRAC_BITS. */ + "packuswb %%xmm5, %%xmm1 \n\t" + + "movdqu %%xmm1, (%%"FF_REG_d") \n\t" + +snow_inner_add_yblock_sse2_end_16 +} + +#define snow_inner_add_yblock_mmx_header \ + IDWTELEM * * dst_array = sb->line + src_y;\ + x86_reg tmp;\ + __asm__ volatile(\ + "mov %7, %%"FF_REG_c" \n\t"\ + "mov %6, %2 \n\t"\ + "mov %4, %%"FF_REG_S" \n\t"\ + "pxor %%mm7, %%mm7 \n\t" /* 0 */\ + "pcmpeqd %%mm3, %%mm3 \n\t"\ + "psllw $15, %%mm3 \n\t"\ + "psrlw $12, %%mm3 \n\t" /* FRAC_BITS >> 1 */\ + "1: \n\t"\ + "mov %1, %%"FF_REG_D" \n\t"\ + "mov (%%"FF_REG_D"), %%"FF_REG_D" \n\t"\ + "add %3, %%"FF_REG_D" \n\t" + +#define snow_inner_add_yblock_mmx_start(out_reg1, out_reg2, ptr_offset, s_offset, d_offset)\ + "mov "FF_PTR_SIZE"*"ptr_offset"(%%"FF_REG_a"), %%"FF_REG_d"; \n\t"\ + "movd "d_offset"(%%"FF_REG_d"), %%"out_reg1" \n\t"\ + "movd "d_offset"+4(%%"FF_REG_d"), %%"out_reg2" \n\t"\ + "punpcklbw %%mm7, %%"out_reg1" \n\t"\ + "punpcklbw %%mm7, %%"out_reg2" \n\t"\ + "movd "s_offset"(%%"FF_REG_S"), %%mm0 \n\t"\ + "movd "s_offset"+4(%%"FF_REG_S"), %%mm4 \n\t"\ + "punpcklbw %%mm7, %%mm0 \n\t"\ + "punpcklbw %%mm7, %%mm4 \n\t"\ + "pmullw %%mm0, %%"out_reg1" \n\t"\ + "pmullw %%mm4, %%"out_reg2" \n\t" + +#define snow_inner_add_yblock_mmx_accum(ptr_offset, s_offset, d_offset) \ + snow_inner_add_yblock_mmx_start("mm2", "mm6", ptr_offset, s_offset, d_offset)\ + "paddusw %%mm2, %%mm1 \n\t"\ + "paddusw %%mm6, %%mm5 \n\t" + +#define snow_inner_add_yblock_mmx_mix(read_offset, write_offset)\ + "mov %0, %%"FF_REG_d" \n\t"\ + "psrlw $4, %%mm1 \n\t"\ + "psrlw $4, %%mm5 \n\t"\ + "paddw "read_offset"(%%"FF_REG_D"), %%mm1 \n\t"\ + "paddw "read_offset"+8(%%"FF_REG_D"), %%mm5 \n\t"\ + "paddw %%mm3, %%mm1 \n\t"\ + "paddw %%mm3, %%mm5 \n\t"\ + "psraw $4, %%mm1 \n\t"\ + "psraw $4, %%mm5 \n\t"\ + "packuswb %%mm5, %%mm1 \n\t"\ + "movq %%mm1, "write_offset"(%%"FF_REG_d") \n\t" + +#define snow_inner_add_yblock_mmx_end(s_step)\ + "add $"s_step", %%"FF_REG_S" \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*3(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*2(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", "FF_PTR_SIZE"*1(%%"FF_REG_a"); \n\t"\ + "add %%"FF_REG_c", (%%"FF_REG_a") \n\t"\ + "add"FF_OPSIZE " $"FF_PTR_SIZE"*1, %1 \n\t"\ + "add %%"FF_REG_c", %0 \n\t"\ + "dec %2 \n\t"\ + "jnz 1b \n\t"\ + :"+m"(dst8),"+m"(dst_array),"=&r"(tmp)\ + :\ + "rm"((x86_reg)(src_x<<1)),"m"(obmc),"a"(block),"m"(b_h),"m"(src_stride):\ + "%"FF_REG_c"","%"FF_REG_S"","%"FF_REG_D"","%"FF_REG_d""); + +static void inner_add_yblock_bw_8_obmc_16_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_mmx_header +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0") +snow_inner_add_yblock_mmx_accum("2", "8", "0") +snow_inner_add_yblock_mmx_accum("1", "128", "0") +snow_inner_add_yblock_mmx_accum("0", "136", "0") +snow_inner_add_yblock_mmx_mix("0", "0") +snow_inner_add_yblock_mmx_end("16") +} + +static void inner_add_yblock_bw_16_obmc_32_mmx(const uint8_t *obmc, const x86_reg obmc_stride, uint8_t * * block, int b_w, x86_reg b_h, + int src_x, int src_y, x86_reg src_stride, slice_buffer * sb, int add, uint8_t * dst8){ +snow_inner_add_yblock_mmx_header +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "0", "0") +snow_inner_add_yblock_mmx_accum("2", "16", "0") +snow_inner_add_yblock_mmx_accum("1", "512", "0") +snow_inner_add_yblock_mmx_accum("0", "528", "0") +snow_inner_add_yblock_mmx_mix("0", "0") + +snow_inner_add_yblock_mmx_start("mm1", "mm5", "3", "8", "8") +snow_inner_add_yblock_mmx_accum("2", "24", "8") +snow_inner_add_yblock_mmx_accum("1", "520", "8") +snow_inner_add_yblock_mmx_accum("0", "536", "8") +snow_inner_add_yblock_mmx_mix("16", "8") +snow_inner_add_yblock_mmx_end("32") +} + +static void ff_snow_inner_add_yblock_sse2(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ + + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else if (b_w == 8 && obmc_stride == 16) { + if (!(b_h & 1)) + inner_add_yblock_bw_8_obmc_16_bh_even_sse2(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else + inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + } else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); +} + +static void ff_snow_inner_add_yblock_mmx(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h, + int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){ + if (b_w == 16) + inner_add_yblock_bw_16_obmc_32_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else if (b_w == 8 && obmc_stride == 16) + inner_add_yblock_bw_8_obmc_16_mmx(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); + else + ff_snow_inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8); +} +#endif /* HAVE_6REGS */ + +#endif /* HAVE_INLINE_ASM */ + +av_cold void ff_dwt_init_x86(SnowDWTContext *c) +{ +#if HAVE_INLINE_ASM + int mm_flags = av_get_cpu_flags(); + + if (mm_flags & AV_CPU_FLAG_MMX) { + if(mm_flags & AV_CPU_FLAG_SSE2 & 0){ + c->horizontal_compose97i = ff_snow_horizontal_compose97i_sse2; +#if HAVE_7REGS + c->vertical_compose97i = ff_snow_vertical_compose97i_sse2; +#endif +#if HAVE_6REGS + c->inner_add_yblock = ff_snow_inner_add_yblock_sse2; +#endif + } + else{ + if (mm_flags & AV_CPU_FLAG_MMXEXT) { + c->horizontal_compose97i = ff_snow_horizontal_compose97i_mmx; +#if HAVE_7REGS + c->vertical_compose97i = ff_snow_vertical_compose97i_mmx; +#endif + } +#if HAVE_6REGS + c->inner_add_yblock = ff_snow_inner_add_yblock_mmx; +#endif + } + } +#endif /* HAVE_INLINE_ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/svq1enc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/svq1enc.asm new file mode 100644 index 00000000..a8763283 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/svq1enc.asm @@ -0,0 +1,61 @@ +;****************************************************************************** +;* SIMD-optimized SVQ1 encoder functions +;* Copyright (c) 2007 Loren Merritt +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro SSD_INT8_VS_INT16 0 +cglobal ssd_int8_vs_int16, 3, 3, 3, pix1, pix2, size + pxor m0, m0 +.loop: + sub sizeq, 8 + movq m1, [pix1q + sizeq] + mova m2, [pix2q + sizeq*2] +%if mmsize == 8 + movq m3, [pix2q + sizeq*2 + mmsize] + punpckhbw m4, m1 + punpcklbw m1, m1 + psraw m4, 8 + psraw m1, 8 + psubw m3, m4 + psubw m2, m1 + pmaddwd m3, m3 + pmaddwd m2, m2 + paddd m0, m3 + paddd m0, m2 +%else + punpcklbw m1, m1 + psraw m1, 8 + psubw m2, m1 + pmaddwd m2, m2 + paddd m0, m2 +%endif + jg .loop + HADDD m0, m1 + movd eax, m0 + RET +%endmacro + +INIT_MMX mmx +SSD_INT8_VS_INT16 +INIT_XMM sse2 +SSD_INT8_VS_INT16 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/svq1enc_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/svq1enc_init.c new file mode 100644 index 00000000..40b4b0e1 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/svq1enc_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2007 Loren Merritt + * + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/svq1enc.h" + +int ff_ssd_int8_vs_int16_mmx(const int8_t *pix1, const int16_t *pix2, + intptr_t size); +int ff_ssd_int8_vs_int16_sse2(const int8_t *pix1, const int16_t *pix2, + intptr_t size); + +av_cold void ff_svq1enc_init_x86(SVQ1EncContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->ssd_int8_vs_int16 = ff_ssd_int8_vs_int16_mmx; + } + if (EXTERNAL_SSE2(cpu_flags)) { + c->ssd_int8_vs_int16 = ff_ssd_int8_vs_int16_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/synth_filter.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/synth_filter.asm new file mode 100644 index 00000000..bc1a48f4 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/synth_filter.asm @@ -0,0 +1,246 @@ +;****************************************************************************** +;* SSE-optimized functions for the DCA decoder +;* Copyright (C) 2012-2014 Christophe Gisquet +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +%macro SETZERO 1 +%if cpuflag(sse2) && notcpuflag(avx) + pxor %1, %1 +%else + xorps %1, %1, %1 +%endif +%endmacro + +%macro SHUF 3 +%if cpuflag(avx) + mova %3, [%2 - 16] + vperm2f128 %1, %3, %3, 1 + vshufps %1, %1, %1, q0123 +%elif cpuflag(sse2) + pshufd %1, [%2], q0123 +%else + mova %1, [%2] + shufps %1, %1, q0123 +%endif +%endmacro + +%macro INNER_LOOP 1 + ; reading backwards: ptr1 = synth_buf + j + i; ptr2 = synth_buf + j - i + ;~ a += window[i + j] * (-synth_buf[15 - i + j]) + ;~ b += window[i + j + 16] * (synth_buf[i + j]) + SHUF m5, ptr2 + j + (15 - 3) * 4, m6 + mova m6, [ptr1 + j] +%if ARCH_X86_64 + SHUF m11, ptr2 + j + (15 - 3) * 4 - mmsize, m12 + mova m12, [ptr1 + j + mmsize] +%endif +%if cpuflag(fma3) + fmaddps m2, m6, [win + %1 + j + 16 * 4], m2 + fnmaddps m1, m5, [win + %1 + j], m1 +%if ARCH_X86_64 + fmaddps m8, m12, [win + %1 + j + mmsize + 16 * 4], m8 + fnmaddps m7, m11, [win + %1 + j + mmsize], m7 +%endif +%else ; non-FMA + mulps m6, m6, [win + %1 + j + 16 * 4] + mulps m5, m5, [win + %1 + j] +%if ARCH_X86_64 + mulps m12, m12, [win + %1 + j + mmsize + 16 * 4] + mulps m11, m11, [win + %1 + j + mmsize] +%endif + addps m2, m2, m6 + subps m1, m1, m5 +%if ARCH_X86_64 + addps m8, m8, m12 + subps m7, m7, m11 +%endif +%endif ; cpuflag(fma3) + ;~ c += window[i + j + 32] * (synth_buf[16 + i + j]) + ;~ d += window[i + j + 48] * (synth_buf[31 - i + j]) + SHUF m6, ptr2 + j + (31 - 3) * 4, m5 + mova m5, [ptr1 + j + 16 * 4] +%if ARCH_X86_64 + SHUF m12, ptr2 + j + (31 - 3) * 4 - mmsize, m11 + mova m11, [ptr1 + j + mmsize + 16 * 4] +%endif +%if cpuflag(fma3) + fmaddps m3, m5, [win + %1 + j + 32 * 4], m3 + fmaddps m4, m6, [win + %1 + j + 48 * 4], m4 +%if ARCH_X86_64 + fmaddps m9, m11, [win + %1 + j + mmsize + 32 * 4], m9 + fmaddps m10, m12, [win + %1 + j + mmsize + 48 * 4], m10 +%endif +%else ; non-FMA + mulps m5, m5, [win + %1 + j + 32 * 4] + mulps m6, m6, [win + %1 + j + 48 * 4] +%if ARCH_X86_64 + mulps m11, m11, [win + %1 + j + mmsize + 32 * 4] + mulps m12, m12, [win + %1 + j + mmsize + 48 * 4] +%endif + addps m3, m3, m5 + addps m4, m4, m6 +%if ARCH_X86_64 + addps m9, m9, m11 + addps m10, m10, m12 +%endif +%endif ; cpuflag(fma3) + sub j, 64 * 4 +%endmacro + +; void ff_synth_filter_inner_(float *synth_buf, float synth_buf2[32], +; const float window[512], float out[32], +; intptr_t offset, float scale) +%macro SYNTH_FILTER 0 +cglobal synth_filter_inner, 0, 6 + 4 * ARCH_X86_64, 7 + 6 * ARCH_X86_64, \ + synth_buf, synth_buf2, window, out, off, scale +%define scale m0 +%if ARCH_X86_32 || WIN64 +%if cpuflag(sse2) && notcpuflag(avx) + movd scale, scalem + SPLATD m0 +%else + VBROADCASTSS m0, scalem +%endif +; Make sure offset is in a register and not on the stack +%define OFFQ r4q +%else + SPLATD xmm0 +%if cpuflag(avx) + vinsertf128 m0, m0, xmm0, 1 +%endif +%define OFFQ offq +%endif + ; prepare inner counter limit 1 + mov r5q, 480 + sub r5q, offmp + and r5q, -64 + shl r5q, 2 +%if ARCH_X86_32 || notcpuflag(avx) + mov OFFQ, r5q +%define i r5q + mov i, 16 * 4 - (ARCH_X86_64 + 1) * mmsize ; main loop counter +%else +%define i 0 +%define OFFQ r5q +%endif + +%define buf2 synth_buf2q +%if ARCH_X86_32 + mov buf2, synth_buf2mp +%endif +.mainloop: + ; m1 = a m2 = b m3 = c m4 = d + SETZERO m3 + SETZERO m4 + mova m1, [buf2 + i] + mova m2, [buf2 + i + 16 * 4] +%if ARCH_X86_32 +%define ptr1 r0q +%define ptr2 r1q +%define win r2q +%define j r3q + mov win, windowm + mov ptr1, synth_bufm +%if ARCH_X86_32 || notcpuflag(avx) + add win, i + add ptr1, i +%endif +%else ; ARCH_X86_64 +%define ptr1 r6q +%define ptr2 r7q ; must be loaded +%define win r8q +%define j r9q + SETZERO m9 + SETZERO m10 + mova m7, [buf2 + i + mmsize] + mova m8, [buf2 + i + mmsize + 16 * 4] + lea win, [windowq + i] + lea ptr1, [synth_bufq + i] +%endif + mov ptr2, synth_bufmp + ; prepare the inner loop counter + mov j, OFFQ +%if ARCH_X86_32 || notcpuflag(avx) + sub ptr2, i +%endif +.loop1: + INNER_LOOP 0 + jge .loop1 + + mov j, 448 * 4 + sub j, OFFQ + jz .end + sub ptr1, j + sub ptr2, j + add win, OFFQ ; now at j-64, so define OFFSET + sub j, 64 * 4 +.loop2: + INNER_LOOP 64 * 4 + jge .loop2 + +.end: +%if ARCH_X86_32 + mov buf2, synth_buf2m ; needed for next iteration anyway + mov outq, outmp ; j, which will be set again during it +%endif + ;~ out[i] = a * scale; + ;~ out[i + 16] = b * scale; + mulps m1, m1, scale + mulps m2, m2, scale +%if ARCH_X86_64 + mulps m7, m7, scale + mulps m8, m8, scale +%endif + ;~ synth_buf2[i] = c; + ;~ synth_buf2[i + 16] = d; + mova [buf2 + i + 0 * 4], m3 + mova [buf2 + i + 16 * 4], m4 +%if ARCH_X86_64 + mova [buf2 + i + 0 * 4 + mmsize], m9 + mova [buf2 + i + 16 * 4 + mmsize], m10 +%endif + ;~ out[i] = a; + ;~ out[i + 16] = a; + mova [outq + i + 0 * 4], m1 + mova [outq + i + 16 * 4], m2 +%if ARCH_X86_64 + mova [outq + i + 0 * 4 + mmsize], m7 + mova [outq + i + 16 * 4 + mmsize], m8 +%endif +%if ARCH_X86_32 || notcpuflag(avx) + sub i, (ARCH_X86_64 + 1) * mmsize + jge .mainloop +%endif + RET +%endmacro + +%if ARCH_X86_32 +INIT_XMM sse +SYNTH_FILTER +%endif +INIT_XMM sse2 +SYNTH_FILTER +INIT_YMM avx +SYNTH_FILTER +INIT_YMM fma3 +SYNTH_FILTER diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/synth_filter_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/synth_filter_init.c new file mode 100644 index 00000000..35e2b47a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/synth_filter_init.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-2014 Christophe Gisquet + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/synth_filter.h" + +#define SYNTH_FILTER_FUNC(opt) \ +void ff_synth_filter_inner_##opt(float *synth_buf_ptr, float synth_buf2[32], \ + const float window[512], \ + float out[32], intptr_t offset, float scale); \ +static void synth_filter_##opt(FFTContext *imdct, \ + float *synth_buf_ptr, int *synth_buf_offset, \ + float synth_buf2[32], const float window[512], \ + float out[32], const float in[32], float scale) \ +{ \ + float *synth_buf= synth_buf_ptr + *synth_buf_offset; \ + \ + imdct->imdct_half(imdct, synth_buf, in); \ + \ + ff_synth_filter_inner_##opt(synth_buf, synth_buf2, window, \ + out, *synth_buf_offset, scale); \ + \ + *synth_buf_offset = (*synth_buf_offset - 32) & 511; \ +} \ + +#if HAVE_X86ASM +#if ARCH_X86_32 +SYNTH_FILTER_FUNC(sse) +#endif +SYNTH_FILTER_FUNC(sse2) +SYNTH_FILTER_FUNC(avx) +SYNTH_FILTER_FUNC(fma3) +#endif /* HAVE_X86ASM */ + +av_cold void ff_synth_filter_init_x86(SynthFilterContext *s) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) { + s->synth_filter_float = synth_filter_sse; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + s->synth_filter_float = synth_filter_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + s->synth_filter_float = synth_filter_avx; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + s->synth_filter_float = synth_filter_fma3; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/takdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/takdsp.asm new file mode 100644 index 00000000..5f3ded3e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/takdsp.asm @@ -0,0 +1,116 @@ +;****************************************************************************** +;* TAK DSP SIMD optimizations +;* +;* Copyright (C) 2015 Paul B Mahol +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pd_128: times 4 dd 128 + +SECTION .text + +INIT_XMM sse2 +cglobal tak_decorrelate_ls, 3, 3, 2, p1, p2, length + shl lengthd, 2 + add p1q, lengthq + add p2q, lengthq + neg lengthq +.loop: + mova m0, [p1q+lengthq+mmsize*0] + mova m1, [p1q+lengthq+mmsize*1] + paddd m0, [p2q+lengthq+mmsize*0] + paddd m1, [p2q+lengthq+mmsize*1] + mova [p2q+lengthq+mmsize*0], m0 + mova [p2q+lengthq+mmsize*1], m1 + add lengthq, mmsize*2 + jl .loop + REP_RET + +cglobal tak_decorrelate_sr, 3, 3, 2, p1, p2, length + shl lengthd, 2 + add p1q, lengthq + add p2q, lengthq + neg lengthq + +.loop: + mova m0, [p2q+lengthq+mmsize*0] + mova m1, [p2q+lengthq+mmsize*1] + psubd m0, [p1q+lengthq+mmsize*0] + psubd m1, [p1q+lengthq+mmsize*1] + mova [p1q+lengthq+mmsize*0], m0 + mova [p1q+lengthq+mmsize*1], m1 + add lengthq, mmsize*2 + jl .loop + REP_RET + +cglobal tak_decorrelate_sm, 3, 3, 6, p1, p2, length + shl lengthd, 2 + add p1q, lengthq + add p2q, lengthq + neg lengthq + +.loop: + mova m0, [p1q+lengthq] + mova m1, [p2q+lengthq] + mova m3, [p1q+lengthq+mmsize] + mova m4, [p2q+lengthq+mmsize] + mova m2, m1 + mova m5, m4 + psrad m2, 1 + psrad m5, 1 + psubd m0, m2 + psubd m3, m5 + paddd m1, m0 + paddd m4, m3 + mova [p1q+lengthq], m0 + mova [p2q+lengthq], m1 + mova [p1q+lengthq+mmsize], m3 + mova [p2q+lengthq+mmsize], m4 + add lengthq, mmsize*2 + jl .loop + REP_RET + +INIT_XMM sse4 +cglobal tak_decorrelate_sf, 3, 3, 5, p1, p2, length, dshift, dfactor + shl lengthd, 2 + add p1q, lengthq + add p2q, lengthq + neg lengthq + + movd m2, dshiftm + movd m3, dfactorm + pshufd m3, m3, 0 + mova m4, [pd_128] + +.loop: + mova m0, [p1q+lengthq] + mova m1, [p2q+lengthq] + psrad m1, m2 + pmulld m1, m3 + paddd m1, m4 + psrad m1, 8 + pslld m1, m2 + psubd m1, m0 + mova [p1q+lengthq], m1 + add lengthq, mmsize + jl .loop + REP_RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/takdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/takdsp_init.c new file mode 100644 index 00000000..fe0c846a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/takdsp_init.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 Paul B Mahol + * + * 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 "libavcodec/takdsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_tak_decorrelate_ls_sse2(int32_t *p1, int32_t *p2, int length); +void ff_tak_decorrelate_sr_sse2(int32_t *p1, int32_t *p2, int length); +void ff_tak_decorrelate_sm_sse2(int32_t *p1, int32_t *p2, int length); +void ff_tak_decorrelate_sf_sse4(int32_t *p1, int32_t *p2, int length, int dshift, int dfactor); + +av_cold void ff_takdsp_init_x86(TAKDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->decorrelate_ls = ff_tak_decorrelate_ls_sse2; + c->decorrelate_sr = ff_tak_decorrelate_sr_sse2; + c->decorrelate_sm = ff_tak_decorrelate_sm_sse2; + } + + if (EXTERNAL_SSE4(cpu_flags)) { + c->decorrelate_sf = ff_tak_decorrelate_sf_sse4; + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttadsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttadsp.asm new file mode 100644 index 00000000..db12a32e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttadsp.asm @@ -0,0 +1,119 @@ +;****************************************************************************** +;* 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 "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 +INIT_XMM %1 +cglobal tta_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 m6, [errorq] ; if (filter->error < 0) { + SPLATD m6 ; for (int i = 0; i < 8; i++) + psignd m0, m4, m6 ; filter->qm[i] -= filter->dx[i]; + psignd m1, m5, m6 ; } else if (filter->error > 0) { + 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 +%else + pshufd m6, m0, 0xb1 + pshufd m7, m2, 0xb1 + pmuludq m6, m7 + pshufd m6, m6, 0xd8 + pmuludq m2, m0 + pshufd m2, m2, 0xd8 + punpckldq m2, m6 + + pshufd m6, m1, 0xb1 + pshufd m7, m3, 0xb1 + pmuludq m6, m7 + pshufd m6, m6, 0xd8 + pmuludq m3, m1 + pshufd m3, m3, 0xd8 + punpckldq m3, m6 +%endif + ; Using horizontal add (phaddd) seems to be slower than shuffling stuff around + paddd m2, m3 ; int sum = filter->round + + ; 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] + + movd m6, roundm ; filter->dl[4] * filter->qm[4] + + paddd m6, m2 ; filter->dl[5] * filter->qm[5] + + pshufd m2, m2, 0x1 ; filter->dl[6] * filter->qm[6] + + paddd m6, m2 ; filter->dl[7] * filter->qm[7]; + + 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]; + + 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 m4, m1, 30 ; filter->dx[4] = ((filter->dl[4] >> 30) | 1); + por m4, [pd_1224 ] ; filter->dx[5] = ((filter->dl[5] >> 30) | 2) & ~1; + pand m4, [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], m4 + movd m0, [inq] ; filter->error = *in; + movd [errorq], m0 ; + + movd m2, shiftm ; *in += (sum >> filter->shift); + psrad m6, m2 ; + paddd m0, m6 ; + movd [inq], m0 ; + + psrldq m1, 4 ; + pslldq m0, 12 ; filter->dl[4] = -filter->dl[5]; + pshufd m0, m0, 0xf0 ; filter->dl[5] = -filter->dl[6]; + psubd m0, m1 ; filter->dl[6] = *in - filter->dl[7]; + psrldq m1, m0, 4 ; filter->dl[7] = *in; + pshufd m1, m1, 0xf4 ; filter->dl[5] += filter->dl[6]; + paddd m0, m1 ; filter->dl[4] += filter->dl[5]; + psrldq m1, 4 ; + paddd m0, m1 ; + mova [dlq + 0x10], m0 ; + RET +%endmacro + +TTA_FILTER ssse3, 8 +TTA_FILTER sse4, 7 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttadsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttadsp_init.c new file mode 100644 index 00000000..7441c977 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttadsp_init.c @@ -0,0 +1,42 @@ +/* + * 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 "libavcodec/ttadsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_tta_filter_process_ssse3(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); +void ff_tta_filter_process_sse4(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); + +av_cold void ff_ttadsp_init_x86(TTADSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) + c->filter_process = ff_tta_filter_process_ssse3; + if (EXTERNAL_SSE4(cpu_flags)) + c->filter_process = ff_tta_filter_process_sse4; +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttaencdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttaencdsp.asm new file mode 100644 index 00000000..c9cbd498 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttaencdsp.asm @@ -0,0 +1,119 @@ +;****************************************************************************** +;* TTA Encoder DSP SIMD optimizations +;* +;* Copyright (C) 2014-2016 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pd_n0113: dd ~0, ~1, ~1, ~3 +pd_1224: dd 1, 2, 2, 4 + +SECTION .text + +%macro TTAENC_FILTER 2 +INIT_XMM %1 +cglobal ttaenc_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 m6, [errorq] ; if (filter->error < 0) { + SPLATD m6 ; for (int i = 0; i < 8; i++) + psignd m0, m4, m6 ; filter->qm[i] -= filter->dx[i]; + psignd m1, m5, m6 ; } else if (filter->error > 0) { + 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 +%else + pshufd m6, m0, 0xb1 + pshufd m7, m2, 0xb1 + pmuludq m6, m7 + pshufd m6, m6, 0xd8 + pmuludq m2, m0 + pshufd m2, m2, 0xd8 + punpckldq m2, m6 + + pshufd m6, m1, 0xb1 + pshufd m7, m3, 0xb1 + pmuludq m6, m7 + pshufd m6, m6, 0xd8 + pmuludq m3, m1 + pshufd m3, m3, 0xd8 + punpckldq m3, m6 +%endif + ; Using horizontal add (phaddd) seems to be slower than shuffling stuff around + paddd m2, m3 ; int sum = filter->round + + ; 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] + + movd m6, roundm ; filter->dl[4] * filter->qm[4] + + paddd m6, m2 ; filter->dl[5] * filter->qm[5] + + pshufd m2, m2, 0x1 ; filter->dl[6] * filter->qm[6] + + paddd m6, m2 ; filter->dl[7] * filter->qm[7]; + + 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]; + + 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 m4, m1, 30 ; filter->dx[4] = ((filter->dl[4] >> 30) | 1); + por m4, [pd_1224 ] ; filter->dx[5] = ((filter->dl[5] >> 30) | 2) & ~1; + pand m4, [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], m4 + + movd m2, shiftm ; + movd m0, [inq] ; + psrad m6, m2 ; + psubd m3, m0, m6 ; + movd [inq], m3 ; *in -= (sum >> filter->shift); + movd [errorq], m3 ; filter->error = *in; + + psrldq m1, 4 ; + pslldq m0, 12 ; filter->dl[4] = -filter->dl[5]; + pshufd m0, m0, 0xf0 ; filter->dl[5] = -filter->dl[6]; + psubd m0, m1 ; filter->dl[6] = *in - filter->dl[7]; + psrldq m1, m0, 4 ; filter->dl[7] = *in; + pshufd m1, m1, 0xf4 ; filter->dl[5] += filter->dl[6]; + paddd m0, m1 ; filter->dl[4] += filter->dl[5]; + psrldq m1, 4 ; + paddd m0, m1 ; + mova [dlq + 0x10], m0 ; + RET +%endmacro + +TTAENC_FILTER ssse3, 8 +TTAENC_FILTER sse4, 7 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttaencdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttaencdsp_init.c new file mode 100644 index 00000000..61971a42 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/ttaencdsp_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014-2016 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 "libavcodec/ttaencdsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_ttaenc_filter_process_ssse3(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); +void ff_ttaenc_filter_process_sse4(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); + +av_cold void ff_ttaencdsp_init_x86(TTAEncDSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) + c->filter_process = ff_ttaenc_filter_process_ssse3; + if (EXTERNAL_SSE4(cpu_flags)) + c->filter_process = ff_ttaenc_filter_process_sse4; +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/utvideodsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/utvideodsp.asm new file mode 100644 index 00000000..b799c44b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/utvideodsp.asm @@ -0,0 +1,137 @@ +;****************************************************************************** +;* SIMD-optimized UTVideo functions +;* Copyright (c) 2017 Paul B Mahol +;* Copyright (c) 2017 Jokyo Images +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pb_80 +cextern pw_512 +cextern pw_1023 + +SECTION .text + +;------------------------------------------------------------------------------------------- +; void restore_rgb_planes(uint8_t *src_r, uint8_t *src_g, uint8_t *src_b, +; ptrdiff_t linesize_r, ptrdiff_t linesize_g, ptrdiff_t linesize_b, +; int width, int height) +;------------------------------------------------------------------------------------------- +%macro RESTORE_RGB_PLANES 0 +cglobal restore_rgb_planes, 7 + ARCH_X86_64, 7 + ARCH_X86_64 * 2, 4, src_r, src_g, src_b, linesize_r, linesize_g, linesize_b, w, h, x + movsxdifnidn wq, wd + add src_rq, wq + add src_gq, wq + add src_bq, wq + neg wq +%if ARCH_X86_64 == 0 + mov wm, wq +DEFINE_ARGS src_r, src_g, src_b, linesize_r, linesize_g, linesize_b, x +%define wq r6m +%define hd r7mp +%endif + mova m3, [pb_80] +.nextrow: + mov xq, wq + + .loop: + mova m0, [src_rq + xq] + mova m1, [src_gq + xq] + mova m2, [src_bq + xq] + psubb m1, m3 + paddb m0, m1 + paddb m2, m1 + mova [src_rq+xq], m0 + mova [src_bq+xq], m2 + add xq, mmsize + jl .loop + + add src_rq, linesize_rq + add src_gq, linesize_gq + add src_bq, linesize_bq + sub hd, 1 + jg .nextrow + REP_RET +%endmacro + +INIT_XMM sse2 +RESTORE_RGB_PLANES + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +RESTORE_RGB_PLANES +%endif + +;------------------------------------------------------------------------------------------- +; void restore_rgb_planes10(uint16_t *src_r, uint16_t *src_g, uint16_t *src_b, +; ptrdiff_t linesize_r, ptrdiff_t linesize_g, ptrdiff_t linesize_b, +; int width, int height) +;------------------------------------------------------------------------------------------- +%macro RESTORE_RGB_PLANES10 0 +cglobal restore_rgb_planes10, 7 + ARCH_X86_64, 7 + ARCH_X86_64 * 2, 5, src_r, src_g, src_b, linesize_r, linesize_g, linesize_b, w, h, x + shl wd, 1 + shl linesize_rq, 1 + shl linesize_gq, 1 + shl linesize_bq, 1 + add src_rq, wq + add src_gq, wq + add src_bq, wq + mova m3, [pw_512] + mova m4, [pw_1023] + neg wq +%if ARCH_X86_64 == 0 + mov wm, wq +DEFINE_ARGS src_r, src_g, src_b, linesize_r, linesize_g, linesize_b, x +%define wq r6m +%define hd r7mp +%endif +.nextrow: + mov xq, wq + + .loop: + mova m0, [src_rq + xq] + mova m1, [src_gq + xq] + mova m2, [src_bq + xq] + psubw m1, m3 + paddw m0, m1 + paddw m2, m1 + pand m0, m4 + pand m2, m4 + mova [src_rq+xq], m0 + mova [src_bq+xq], m2 + add xq, mmsize + jl .loop + + add src_rq, linesize_rq + add src_gq, linesize_gq + add src_bq, linesize_bq + sub hd, 1 + jg .nextrow + REP_RET +%endmacro + +INIT_XMM sse2 +RESTORE_RGB_PLANES10 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +RESTORE_RGB_PLANES10 +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/utvideodsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/utvideodsp_init.c new file mode 100644 index 00000000..2b436c6c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/utvideodsp_init.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Paul B Mahol + * + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/utvideodsp.h" + +void ff_restore_rgb_planes_sse2(uint8_t *src_r, uint8_t *src_g, uint8_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); +void ff_restore_rgb_planes_avx2(uint8_t *src_r, uint8_t *src_g, uint8_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); + +void ff_restore_rgb_planes10_sse2(uint16_t *src_r, uint16_t *src_g, uint16_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); +void ff_restore_rgb_planes10_avx2(uint16_t *src_r, uint16_t *src_g, uint16_t *src_b, + ptrdiff_t linesize_r, ptrdiff_t linesize_g, + ptrdiff_t linesize_b, int width, int height); + +av_cold void ff_utvideodsp_init_x86(UTVideoDSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + c->restore_rgb_planes = ff_restore_rgb_planes_sse2; + c->restore_rgb_planes10 = ff_restore_rgb_planes10_sse2; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + c->restore_rgb_planes = ff_restore_rgb_planes_avx2; + c->restore_rgb_planes10 = ff_restore_rgb_planes10_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210-init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210-init.c new file mode 100644 index 00000000..cb9a6cbd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210-init.c @@ -0,0 +1,56 @@ +/* + * 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 "libavutil/cpu.h" +#include "libavcodec/v210dec.h" + +extern void ff_v210_planar_unpack_unaligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_unaligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_unaligned_avx2(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + +extern void ff_v210_planar_unpack_aligned_ssse3(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_aligned_avx(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); +extern void ff_v210_planar_unpack_aligned_avx2(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width); + +av_cold void ff_v210_x86_init(V210DecContext *s) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (s->aligned_input) { + if (cpu_flags & AV_CPU_FLAG_SSSE3) + s->unpack_frame = ff_v210_planar_unpack_aligned_ssse3; + + if (HAVE_AVX_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX) + s->unpack_frame = ff_v210_planar_unpack_aligned_avx; + + if (HAVE_AVX2_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX2) + s->unpack_frame = ff_v210_planar_unpack_aligned_avx2; + } + else { + if (cpu_flags & AV_CPU_FLAG_SSSE3) + s->unpack_frame = ff_v210_planar_unpack_unaligned_ssse3; + + if (HAVE_AVX_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX) + s->unpack_frame = ff_v210_planar_unpack_unaligned_avx; + + if (HAVE_AVX2_EXTERNAL && cpu_flags & AV_CPU_FLAG_AVX2) + s->unpack_frame = ff_v210_planar_unpack_unaligned_avx2; + } +#endif +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210.asm new file mode 100644 index 00000000..3b9e0761 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210.asm @@ -0,0 +1,129 @@ +;****************************************************************************** +;* V210 SIMD unpack +;* Copyright (c) 2011 Loren Merritt +;* Copyright (c) 2011 Kieran Kunhya +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +; for AVX2 version only +v210_luma_permute: dd 0,1,2,4,5,6,7,7 ; 32-byte alignment required +v210_chroma_shuf2: db 0,1,2,3,4,5,8,9,10,11,12,13,-1,-1,-1,-1 +v210_luma_shuf_avx2: db 0,1,4,5,6,7,8,9,12,13,14,15,-1,-1,-1,-1 +v210_chroma_shuf_avx2: db 0,1,4,5,10,11,-1,-1,2,3,8,9,12,13,-1,-1 + +v210_mult: dw 64,4,64,4,64,4,64,4 +v210_luma_shuf: db 8,9,0,1,2,3,12,13,4,5,6,7,-1,-1,-1,-1 +v210_chroma_shuf: db 0,1,8,9,6,7,-1,-1,2,3,4,5,12,13,-1,-1 + +SECTION .text + +%macro v210_planar_unpack 1 + +; v210_planar_unpack(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width) +cglobal v210_planar_unpack_%1, 5, 5, 6 + 2 * cpuflag(avx2), src, y, u, v, w + movsxdifnidn wq, wd + lea yq, [yq+2*wq] + add uq, wq + add vq, wq + neg wq + + VBROADCASTI128 m3, [v210_mult] + +%if cpuflag(avx2) + VBROADCASTI128 m4, [v210_luma_shuf_avx2] + VBROADCASTI128 m5, [v210_chroma_shuf_avx2] + mova m6, [v210_luma_permute] + VBROADCASTI128 m7, [v210_chroma_shuf2] +%else + VBROADCASTI128 m4, [v210_luma_shuf] + VBROADCASTI128 m5, [v210_chroma_shuf] +%endif + +.loop: +%ifidn %1, unaligned + movu m0, [srcq] ; yB v5 yA u5 y9 v4 y8 u4 y7 v3 y6 u3 y5 v2 y4 u2 y3 v1 y2 u1 y1 v0 y0 u0 +%else + mova m0, [srcq] +%endif + + pmullw m1, m0, m3 + pslld m0, 12 + psrlw m1, 6 ; yB yA u5 v4 y8 y7 v3 u3 y5 y4 u2 v1 y2 y1 v0 u0 + psrld m0, 22 ; 00 v5 00 y9 00 u4 00 y6 00 v2 00 y3 00 u1 00 y0 + +%if cpuflag(avx2) + vpblendd m2, m1, m0, 0x55 ; yB yA 00 y9 y8 y7 00 y6 y5 y4 00 y3 y2 y1 00 y0 + pshufb m2, m4 ; 00 00 yB yA y9 y8 y7 y6 00 00 y5 y4 y3 y2 y1 y0 + vpermd m2, m6, m2 ; 00 00 00 00 yB yA y9 y8 y7 y6 y5 y4 y3 y2 y1 y0 + movu [yq+2*wq], m2 + + vpblendd m1, m1, m0, 0xaa ; 00 v5 u5 v4 00 u4 v3 u3 00 v2 u2 v1 00 u1 v0 u0 + pshufb m1, m5 ; 00 v5 v4 v3 00 u5 u4 u3 00 v2 v1 v0 00 u2 u1 u0 + vpermq m1, m1, 0xd8 ; 00 v5 v4 v3 00 v2 v1 v0 00 u5 u4 u3 00 u2 u1 u0 + pshufb m1, m7 ; 00 00 v5 v4 v3 v2 v1 v0 00 00 u5 u4 u3 u2 u1 u0 + + movu [uq+wq], xm1 + vextracti128 [vq+wq], m1, 1 +%else + shufps m2, m1, m0, 0x8d ; 00 y9 00 y6 yB yA y8 y7 00 y3 00 y0 y5 y4 y2 y1 + pshufb m2, m4 ; 00 00 yB yA y9 y8 y7 y6 00 00 y5 y4 y3 y2 y1 y0 + movu [yq+2*wq], m2 + + shufps m1, m0, 0xd8 ; 00 v5 00 u4 u5 v4 v3 u3 00 v2 00 u1 u2 v1 v0 u0 + pshufb m1, m5 ; 00 v5 v4 v3 00 u5 u4 u3 00 v2 v1 v0 00 u2 u1 u0 + + movq [uq+wq], m1 + movhps [vq+wq], m1 +%endif + + add srcq, mmsize + add wq, (mmsize*3)/8 + jl .loop + + REP_RET +%endmacro + +INIT_XMM ssse3 +v210_planar_unpack unaligned + +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +v210_planar_unpack unaligned +%endif + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +v210_planar_unpack unaligned +%endif + +INIT_XMM ssse3 +v210_planar_unpack aligned + +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +v210_planar_unpack aligned +%endif + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +v210_planar_unpack aligned +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210enc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210enc.asm new file mode 100644 index 00000000..965f2bea --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210enc.asm @@ -0,0 +1,184 @@ +;****************************************************************************** +;* V210 SIMD pack +;* Copyright (c) 2014 Kieran Kunhya +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +cextern pw_4 +%define v210_enc_min_10 pw_4 +v210_enc_max_10: times 16 dw 0x3fb + +v210_enc_luma_mult_10: times 2 dw 4,1,16,4,1,16,0,0 +v210_enc_luma_shuf_10: times 2 db -1,0,1,-1,2,3,4,5,-1,6,7,-1,8,9,10,11 + +v210_enc_chroma_mult_10: times 2 dw 1,4,16,0,16,1,4,0 +v210_enc_chroma_shuf_10: times 2 db 0,1,8,9,-1,2,3,-1,10,11,4,5,-1,12,13,-1 + +cextern pb_1 +%define v210_enc_min_8 pb_1 +cextern pb_FE +%define v210_enc_max_8 pb_FE + +v210_enc_luma_shuf_8: times 2 db 6,-1,7,-1,8,-1,9,-1,10,-1,11,-1,-1,-1,-1,-1 +v210_enc_luma_mult_8: times 2 dw 16,4,64,16,4,64,0,0 + +v210_enc_chroma_shuf1_8: times 2 db 0,-1,1,-1,2,-1,3,-1,8,-1,9,-1,10,-1,11,-1 +v210_enc_chroma_shuf2_8: times 2 db 3,-1,4,-1,5,-1,7,-1,11,-1,12,-1,13,-1,15,-1 + +v210_enc_chroma_mult_8: times 2 dw 4,16,64,0,64,4,16,0 + +SECTION .text + +%macro v210_planar_pack_10 0 + +; v210_planar_pack_10(const uint16_t *y, const uint16_t *u, const uint16_t *v, uint8_t *dst, ptrdiff_t width) +cglobal v210_planar_pack_10, 5, 5, 4+cpuflag(avx2), y, u, v, dst, width + lea r0, [yq+2*widthq] + add uq, widthq + add vq, widthq + neg widthq + + mova m2, [v210_enc_min_10] + mova m3, [v210_enc_max_10] + +.loop: + movu xm0, [yq+2*widthq] +%if cpuflag(avx2) + vinserti128 m0, m0, [yq+widthq*2+12], 1 +%endif + CLIPW m0, m2, m3 + + movq xm1, [uq+widthq] + movhps xm1, [vq+widthq] +%if cpuflag(avx2) + movq xm4, [uq+widthq+6] + movhps xm4, [vq+widthq+6] + vinserti128 m1, m1, xm4, 1 +%endif + CLIPW m1, m2, m3 + + pmullw m0, [v210_enc_luma_mult_10] + pshufb m0, [v210_enc_luma_shuf_10] + + pmullw m1, [v210_enc_chroma_mult_10] + pshufb m1, [v210_enc_chroma_shuf_10] + + por m0, m1 + + movu [dstq], m0 + + add dstq, mmsize + add widthq, (mmsize*3)/8 + jl .loop + + RET +%endmacro + +%if HAVE_SSSE3_EXTERNAL +INIT_XMM ssse3 +v210_planar_pack_10 +%endif + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +v210_planar_pack_10 +%endif + +%macro v210_planar_pack_8 0 + +; v210_planar_pack_8(const uint8_t *y, const uint8_t *u, const uint8_t *v, uint8_t *dst, ptrdiff_t width) +cglobal v210_planar_pack_8, 5, 5, 7, y, u, v, dst, width + add yq, widthq + shr widthq, 1 + add uq, widthq + add vq, widthq + neg widthq + + mova m4, [v210_enc_min_8] + mova m5, [v210_enc_max_8] + pxor m6, m6 + +.loop: + movu xm1, [yq+widthq*2] +%if cpuflag(avx2) + vinserti128 m1, m1, [yq+widthq*2+12], 1 +%endif + CLIPUB m1, m4, m5 + + punpcklbw m0, m1, m6 + ; can't unpack high bytes in the same way because we process + ; only six bytes at a time + pshufb m1, [v210_enc_luma_shuf_8] + + pmullw m0, [v210_enc_luma_mult_8] + pmullw m1, [v210_enc_luma_mult_8] + pshufb m0, [v210_enc_luma_shuf_10] + pshufb m1, [v210_enc_luma_shuf_10] + + movq xm3, [uq+widthq] + movhps xm3, [vq+widthq] +%if cpuflag(avx2) + movq xm2, [uq+widthq+6] + movhps xm2, [vq+widthq+6] + vinserti128 m3, m3, xm2, 1 +%endif + CLIPUB m3, m4, m5 + + ; shuffle and multiply to get the same packing as in 10-bit + pshufb m2, m3, [v210_enc_chroma_shuf1_8] + pshufb m3, [v210_enc_chroma_shuf2_8] + + pmullw m2, [v210_enc_chroma_mult_8] + pmullw m3, [v210_enc_chroma_mult_8] + pshufb m2, [v210_enc_chroma_shuf_10] + pshufb m3, [v210_enc_chroma_shuf_10] + + por m0, m2 + por m1, m3 + + movu [dstq], xm0 + movu [dstq+16], xm1 +%if cpuflag(avx2) + vextracti128 [dstq+32], m0, 1 + vextracti128 [dstq+48], m1, 1 +%endif + + add dstq, 2*mmsize + add widthq, (mmsize*3)/8 + jl .loop + + RET +%endmacro + +%if HAVE_SSSE3_EXTERNAL +INIT_XMM ssse3 +v210_planar_pack_8 +%endif +%if HAVE_AVX_EXTERNAL +INIT_XMM avx +v210_planar_pack_8 +%endif + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +v210_planar_pack_8 +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210enc_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210enc_init.c new file mode 100644 index 00000000..e997b4b6 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/v210enc_init.c @@ -0,0 +1,54 @@ +/* + * 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 "libavutil/x86/cpu.h" +#include "libavcodec/v210enc.h" + +void ff_v210_planar_pack_8_ssse3(const uint8_t *y, const uint8_t *u, + const uint8_t *v, uint8_t *dst, + ptrdiff_t width); +void ff_v210_planar_pack_8_avx(const uint8_t *y, const uint8_t *u, + const uint8_t *v, uint8_t *dst, ptrdiff_t width); +void ff_v210_planar_pack_8_avx2(const uint8_t *y, const uint8_t *u, + const uint8_t *v, uint8_t *dst, ptrdiff_t width); +void ff_v210_planar_pack_10_ssse3(const uint16_t *y, const uint16_t *u, + const uint16_t *v, uint8_t *dst, + ptrdiff_t width); +void ff_v210_planar_pack_10_avx2(const uint16_t *y, const uint16_t *u, + const uint16_t *v, uint8_t *dst, + ptrdiff_t width); + +av_cold void ff_v210enc_init_x86(V210EncContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) { + s->pack_line_8 = ff_v210_planar_pack_8_ssse3; + s->pack_line_10 = ff_v210_planar_pack_10_ssse3; + } + + if (EXTERNAL_AVX(cpu_flags)) + s->pack_line_8 = ff_v210_planar_pack_8_avx; + + if (EXTERNAL_AVX2(cpu_flags)) { + s->sample_factor_8 = 2; + s->pack_line_8 = ff_v210_planar_pack_8_avx2; + s->sample_factor_10 = 2; + s->pack_line_10 = ff_v210_planar_pack_10_avx2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp.h new file mode 100644 index 00000000..fdd4de18 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp.h @@ -0,0 +1,29 @@ +/* + * VC-1 and WMV3 decoder - X86 DSP init functions + * + * 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 + */ + +#ifndef AVCODEC_X86_VC1DSP_H +#define AVCODEC_X86_VC1DSP_H + +#include "libavcodec/vc1dsp.h" + +void ff_vc1dsp_init_mmx(VC1DSPContext *dsp); +void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp); + +#endif /* AVCODEC_X86_VC1DSP_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_init.c new file mode 100644 index 00000000..8e0c284c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_init.c @@ -0,0 +1,168 @@ +/* + * VC-1 and WMV3 - DSP functions MMX-optimized + * Copyright (c) 2007 Christophe GISQUET + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavutil/x86/asm.h" +#include "libavcodec/vc1dsp.h" +#include "fpel.h" +#include "vc1dsp.h" +#include "config.h" + +#define LOOP_FILTER(EXT) \ +void ff_vc1_v_loop_filter4_ ## EXT(uint8_t *src, int stride, int pq); \ +void ff_vc1_h_loop_filter4_ ## EXT(uint8_t *src, int stride, int pq); \ +void ff_vc1_v_loop_filter8_ ## EXT(uint8_t *src, int stride, int pq); \ +void ff_vc1_h_loop_filter8_ ## EXT(uint8_t *src, int stride, int pq); \ +\ +static void vc1_v_loop_filter16_ ## EXT(uint8_t *src, int stride, int pq) \ +{ \ + ff_vc1_v_loop_filter8_ ## EXT(src, stride, pq); \ + ff_vc1_v_loop_filter8_ ## EXT(src+8, stride, pq); \ +} \ +\ +static void vc1_h_loop_filter16_ ## EXT(uint8_t *src, int stride, int pq) \ +{ \ + ff_vc1_h_loop_filter8_ ## EXT(src, stride, pq); \ + ff_vc1_h_loop_filter8_ ## EXT(src+8*stride, stride, pq); \ +} + +#if HAVE_X86ASM +LOOP_FILTER(mmxext) +LOOP_FILTER(sse2) +LOOP_FILTER(ssse3) + +void ff_vc1_h_loop_filter8_sse4(uint8_t *src, int stride, int pq); + +static void vc1_h_loop_filter16_sse4(uint8_t *src, int stride, int pq) +{ + ff_vc1_h_loop_filter8_sse4(src, stride, pq); + ff_vc1_h_loop_filter8_sse4(src+8*stride, stride, pq); +} + +#define DECLARE_FUNCTION(OP, DEPTH, INSN) \ + static void OP##vc1_mspel_mc00_##DEPTH##INSN(uint8_t *dst, \ + const uint8_t *src, ptrdiff_t stride, int rnd) \ + { \ + ff_ ## OP ## pixels ## DEPTH ## INSN(dst, src, stride, DEPTH); \ + } + +DECLARE_FUNCTION(put_, 8, _mmx) +DECLARE_FUNCTION(put_, 16, _mmx) +DECLARE_FUNCTION(avg_, 8, _mmx) +DECLARE_FUNCTION(avg_, 16, _mmx) +DECLARE_FUNCTION(avg_, 8, _mmxext) +DECLARE_FUNCTION(avg_, 16, _mmxext) +DECLARE_FUNCTION(put_, 16, _sse2) +DECLARE_FUNCTION(avg_, 16, _sse2) + +#endif /* HAVE_X86ASM */ + +void ff_put_vc1_chroma_mc8_nornd_mmx (uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_vc1_chroma_mc8_nornd_mmxext(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_vc1_chroma_mc8_nornd_3dnow(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_put_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_avg_vc1_chroma_mc8_nornd_ssse3(uint8_t *dst, uint8_t *src, + ptrdiff_t stride, int h, int x, int y); +void ff_vc1_inv_trans_4x4_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_4x8_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_8x4_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); +void ff_vc1_inv_trans_8x8_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, + int16_t *block); + + +av_cold void ff_vc1dsp_init_x86(VC1DSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (HAVE_6REGS && INLINE_MMX(cpu_flags)) + if (EXTERNAL_MMX(cpu_flags)) + ff_vc1dsp_init_mmx(dsp); + + if (HAVE_6REGS && INLINE_MMXEXT(cpu_flags)) + if (EXTERNAL_MMXEXT(cpu_flags)) + ff_vc1dsp_init_mmxext(dsp); + +#define ASSIGN_LF(EXT) \ + dsp->vc1_v_loop_filter4 = ff_vc1_v_loop_filter4_ ## EXT; \ + dsp->vc1_h_loop_filter4 = ff_vc1_h_loop_filter4_ ## EXT; \ + dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_ ## EXT; \ + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_ ## EXT; \ + dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_ ## EXT; \ + dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_ ## EXT + +#if HAVE_X86ASM + if (EXTERNAL_MMX(cpu_flags)) { + dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_mmx; + + dsp->put_vc1_mspel_pixels_tab[1][0] = put_vc1_mspel_mc00_8_mmx; + dsp->put_vc1_mspel_pixels_tab[0][0] = put_vc1_mspel_mc00_16_mmx; + dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_vc1_mspel_mc00_8_mmx; + dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_mmx; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_3dnow; + } + if (EXTERNAL_MMXEXT(cpu_flags)) { + ASSIGN_LF(mmxext); + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_mmxext; + + dsp->avg_vc1_mspel_pixels_tab[1][0] = avg_vc1_mspel_mc00_8_mmxext; + dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_mmxext; + + dsp->vc1_inv_trans_8x8_dc = ff_vc1_inv_trans_8x8_dc_mmxext; + dsp->vc1_inv_trans_4x8_dc = ff_vc1_inv_trans_4x8_dc_mmxext; + dsp->vc1_inv_trans_8x4_dc = ff_vc1_inv_trans_8x4_dc_mmxext; + dsp->vc1_inv_trans_4x4_dc = ff_vc1_inv_trans_4x4_dc_mmxext; + } + if (EXTERNAL_SSE2(cpu_flags)) { + dsp->vc1_v_loop_filter8 = ff_vc1_v_loop_filter8_sse2; + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_sse2; + dsp->vc1_v_loop_filter16 = vc1_v_loop_filter16_sse2; + dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse2; + + dsp->put_vc1_mspel_pixels_tab[0][0] = put_vc1_mspel_mc00_16_sse2; + dsp->avg_vc1_mspel_pixels_tab[0][0] = avg_vc1_mspel_mc00_16_sse2; + } + if (EXTERNAL_SSSE3(cpu_flags)) { + ASSIGN_LF(ssse3); + dsp->put_no_rnd_vc1_chroma_pixels_tab[0] = ff_put_vc1_chroma_mc8_nornd_ssse3; + dsp->avg_no_rnd_vc1_chroma_pixels_tab[0] = ff_avg_vc1_chroma_mc8_nornd_ssse3; + } + if (EXTERNAL_SSE4(cpu_flags)) { + dsp->vc1_h_loop_filter8 = ff_vc1_h_loop_filter8_sse4; + dsp->vc1_h_loop_filter16 = vc1_h_loop_filter16_sse4; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_loopfilter.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_loopfilter.asm new file mode 100644 index 00000000..fd33bd13 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_loopfilter.asm @@ -0,0 +1,317 @@ +;****************************************************************************** +;* VC1 loopfilter optimizations +;* Copyright (c) 2009 David Conrad +;* +;* 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 "libavutil/x86/x86util.asm" + +cextern pw_4 +cextern pw_5 + +SECTION .text + +; dst_low, dst_high (src), zero +; zero-extends one vector from 8 to 16 bits +%macro UNPACK_8TO16 4 + mova m%2, m%3 + punpckh%1 m%3, m%4 + punpckl%1 m%2, m%4 +%endmacro + +%macro STORE_4_WORDS 6 +%if cpuflag(sse4) + pextrw %1, %5, %6+0 + pextrw %2, %5, %6+1 + pextrw %3, %5, %6+2 + pextrw %4, %5, %6+3 +%else + movd %6d, %5 +%if mmsize==16 + psrldq %5, 4 +%else + psrlq %5, 32 +%endif + mov %1, %6w + shr %6, 16 + mov %2, %6w + movd %6d, %5 + mov %3, %6w + shr %6, 16 + mov %4, %6w +%endif +%endmacro + +; in: p1 p0 q0 q1, clobbers p0 +; out: p1 = (2*(p1 - q1) - 5*(p0 - q0) + 4) >> 3 +%macro VC1_LOOP_FILTER_A0 4 + psubw %1, %4 + psubw %2, %3 + paddw %1, %1 + pmullw %2, [pw_5] + psubw %1, %2 + paddw %1, [pw_4] + psraw %1, 3 +%endmacro + +; in: p0 q0 a0 a1 a2 +; m0 m1 m7 m6 m5 +; %1: size +; out: m0=p0' m1=q0' +%macro VC1_FILTER 1 + PABSW m4, m7 + PABSW m3, m6 + PABSW m2, m5 + mova m6, m4 + pminsw m3, m2 + pcmpgtw m6, m3 ; if (a2 < a0 || a1 < a0) + psubw m3, m4 + pmullw m3, [pw_5] ; 5*(a3 - a0) + PABSW m2, m3 + psraw m2, 3 ; abs(d/8) + pxor m7, m3 ; d_sign ^= a0_sign + + pxor m5, m5 + movd m3, r2d +%if %1 > 4 + punpcklbw m3, m3 +%endif + punpcklbw m3, m5 + pcmpgtw m3, m4 ; if (a0 < pq) + pand m6, m3 + + mova m3, m0 + psubw m3, m1 + PABSW m4, m3 + psraw m4, 1 + pxor m3, m7 ; d_sign ^ clip_sign + psraw m3, 15 + pminsw m2, m4 ; min(d, clip) + pcmpgtw m4, m5 + pand m6, m4 ; filt3 (C return value) + +; each set of 4 pixels is not filtered if the 3rd is not +%if mmsize==16 + pshuflw m4, m6, 0xaa +%if %1 > 4 + pshufhw m4, m4, 0xaa +%endif +%else + pshufw m4, m6, 0xaa +%endif + pandn m3, m4 + pand m2, m6 + pand m3, m2 ; d final + + psraw m7, 15 + pxor m3, m7 + psubw m3, m7 + psubw m0, m3 + paddw m1, m3 + packuswb m0, m0 + packuswb m1, m1 +%endmacro + +; 1st param: size of filter +; 2nd param: mov suffix equivalent to the filter size +%macro VC1_V_LOOP_FILTER 2 + pxor m5, m5 + mov%2 m6, [r4] + mov%2 m4, [r4+r1] + mov%2 m7, [r4+2*r1] + mov%2 m0, [r4+r3] + punpcklbw m6, m5 + punpcklbw m4, m5 + punpcklbw m7, m5 + punpcklbw m0, m5 + + VC1_LOOP_FILTER_A0 m6, m4, m7, m0 + mov%2 m1, [r0] + mov%2 m2, [r0+r1] + punpcklbw m1, m5 + punpcklbw m2, m5 + mova m4, m0 + VC1_LOOP_FILTER_A0 m7, m4, m1, m2 + mov%2 m3, [r0+2*r1] + mov%2 m4, [r0+r3] + punpcklbw m3, m5 + punpcklbw m4, m5 + mova m5, m1 + VC1_LOOP_FILTER_A0 m5, m2, m3, m4 + + VC1_FILTER %1 + mov%2 [r4+r3], m0 + mov%2 [r0], m1 +%endmacro + +; 1st param: size of filter +; NOTE: UNPACK_8TO16 this number of 8 bit numbers are in half a register +; 2nd (optional) param: temp register to use for storing words +%macro VC1_H_LOOP_FILTER 1-2 +%if %1 == 4 + movq m0, [r0 -4] + movq m1, [r0+ r1-4] + movq m2, [r0+2*r1-4] + movq m3, [r0+ r3-4] + TRANSPOSE4x4B 0, 1, 2, 3, 4 +%else + movq m0, [r0 -4] + movq m4, [r0+ r1-4] + movq m1, [r0+2*r1-4] + movq m5, [r0+ r3-4] + movq m2, [r4 -4] + movq m6, [r4+ r1-4] + movq m3, [r4+2*r1-4] + movq m7, [r4+ r3-4] + punpcklbw m0, m4 + punpcklbw m1, m5 + punpcklbw m2, m6 + punpcklbw m3, m7 + TRANSPOSE4x4W 0, 1, 2, 3, 4 +%endif + pxor m5, m5 + + UNPACK_8TO16 bw, 6, 0, 5 + UNPACK_8TO16 bw, 7, 1, 5 + VC1_LOOP_FILTER_A0 m6, m0, m7, m1 + UNPACK_8TO16 bw, 4, 2, 5 + mova m0, m1 ; m0 = p0 + VC1_LOOP_FILTER_A0 m7, m1, m4, m2 + UNPACK_8TO16 bw, 1, 3, 5 + mova m5, m4 + VC1_LOOP_FILTER_A0 m5, m2, m1, m3 + SWAP 1, 4 ; m1 = q0 + + VC1_FILTER %1 + punpcklbw m0, m1 +%if %0 > 1 + STORE_4_WORDS [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, %2 +%if %1 > 4 + psrldq m0, 4 + STORE_4_WORDS [r4-1], [r4+r1-1], [r4+2*r1-1], [r4+r3-1], m0, %2 +%endif +%else + STORE_4_WORDS [r0-1], [r0+r1-1], [r0+2*r1-1], [r0+r3-1], m0, 0 + STORE_4_WORDS [r4-1], [r4+r1-1], [r4+2*r1-1], [r4+r3-1], m0, 4 +%endif +%endmacro + + +%macro START_V_FILTER 0 + mov r4, r0 + lea r3, [4*r1] + sub r4, r3 + lea r3, [r1+2*r1] + imul r2, 0x01010101 +%endmacro + +%macro START_H_FILTER 1 + lea r3, [r1+2*r1] +%if %1 > 4 + lea r4, [r0+4*r1] +%endif + imul r2, 0x01010101 +%endmacro + +%macro VC1_LF 0 +cglobal vc1_v_loop_filter_internal + VC1_V_LOOP_FILTER 4, d + ret + +cglobal vc1_h_loop_filter_internal + VC1_H_LOOP_FILTER 4, r4 + ret + +; void ff_vc1_v_loop_filter4_mmxext(uint8_t *src, int stride, int pq) +cglobal vc1_v_loop_filter4, 3,5,0 + START_V_FILTER + call vc1_v_loop_filter_internal + RET + +; void ff_vc1_h_loop_filter4_mmxext(uint8_t *src, int stride, int pq) +cglobal vc1_h_loop_filter4, 3,5,0 + START_H_FILTER 4 + call vc1_h_loop_filter_internal + RET + +; void ff_vc1_v_loop_filter8_mmxext(uint8_t *src, int stride, int pq) +cglobal vc1_v_loop_filter8, 3,5,0 + START_V_FILTER + call vc1_v_loop_filter_internal + add r4, 4 + add r0, 4 + call vc1_v_loop_filter_internal + RET + +; void ff_vc1_h_loop_filter8_mmxext(uint8_t *src, int stride, int pq) +cglobal vc1_h_loop_filter8, 3,5,0 + START_H_FILTER 4 + call vc1_h_loop_filter_internal + lea r0, [r0+4*r1] + call vc1_h_loop_filter_internal + RET +%endmacro + +INIT_MMX mmxext +VC1_LF + +INIT_XMM sse2 +; void ff_vc1_v_loop_filter8_sse2(uint8_t *src, int stride, int pq) +cglobal vc1_v_loop_filter8, 3,5,8 + START_V_FILTER + VC1_V_LOOP_FILTER 8, q + RET + +; void ff_vc1_h_loop_filter8_sse2(uint8_t *src, int stride, int pq) +cglobal vc1_h_loop_filter8, 3,6,8 + START_H_FILTER 8 + VC1_H_LOOP_FILTER 8, r5 + RET + +INIT_MMX ssse3 +; void ff_vc1_v_loop_filter4_ssse3(uint8_t *src, int stride, int pq) +cglobal vc1_v_loop_filter4, 3,5,0 + START_V_FILTER + VC1_V_LOOP_FILTER 4, d + RET + +; void ff_vc1_h_loop_filter4_ssse3(uint8_t *src, int stride, int pq) +cglobal vc1_h_loop_filter4, 3,5,0 + START_H_FILTER 4 + VC1_H_LOOP_FILTER 4, r4 + RET + +INIT_XMM ssse3 +; void ff_vc1_v_loop_filter8_ssse3(uint8_t *src, int stride, int pq) +cglobal vc1_v_loop_filter8, 3,5,8 + START_V_FILTER + VC1_V_LOOP_FILTER 8, q + RET + +; void ff_vc1_h_loop_filter8_ssse3(uint8_t *src, int stride, int pq) +cglobal vc1_h_loop_filter8, 3,6,8 + START_H_FILTER 8 + VC1_H_LOOP_FILTER 8, r5 + RET + +INIT_XMM sse4 +; void ff_vc1_h_loop_filter8_sse4(uint8_t *src, int stride, int pq) +cglobal vc1_h_loop_filter8, 3,5,8 + START_H_FILTER 8 + VC1_H_LOOP_FILTER 8 + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_mc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_mc.asm new file mode 100644 index 00000000..0e6d87dd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_mc.asm @@ -0,0 +1,292 @@ +;****************************************************************************** +;* VC1 motion compensation optimizations +;* Copyright (c) 2007 Christophe GISQUET +;* +;* 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 "libavutil/x86/x86util.asm" + +cextern pw_9 +cextern pw_128 + +SECTION .text + +%if HAVE_MMX_INLINE + +; XXX some of these macros are not used right now, but they will in the future +; when more functions are ported. + +%macro OP_PUT 2 ; dst, src +%endmacro + +%macro OP_AVG 2 ; dst, src + pavgb %1, %2 +%endmacro + +%macro NORMALIZE_MMX 1 ; shift + paddw m3, m7 ; +bias-r + paddw m4, m7 ; +bias-r + psraw m3, %1 + psraw m4, %1 +%endmacro + +%macro TRANSFER_DO_PACK 2 ; op, dst + packuswb m3, m4 + %1 m3, [%2] + mova [%2], m3 +%endmacro + +%macro TRANSFER_DONT_PACK 2 ; op, dst + %1 m3, [%2] + %1 m3, [%2 + mmsize] + mova [%2], m3 + mova [mmsize + %2], m4 +%endmacro + +; see MSPEL_FILTER13_CORE for use as UNPACK macro +%macro DO_UNPACK 1 ; reg + punpcklbw %1, m0 +%endmacro +%macro DONT_UNPACK 1 ; reg +%endmacro + +; Compute the rounder 32-r or 8-r and unpacks it to m7 +%macro LOAD_ROUNDER_MMX 1 ; round + movd m7, %1 + punpcklwd m7, m7 + punpckldq m7, m7 +%endmacro + +%macro SHIFT2_LINE 5 ; off, r0, r1, r2, r3 + paddw m%3, m%4 + movh m%2, [srcq + stride_neg2] + pmullw m%3, m6 + punpcklbw m%2, m0 + movh m%5, [srcq + strideq] + psubw m%3, m%2 + punpcklbw m%5, m0 + paddw m%3, m7 + psubw m%3, m%5 + psraw m%3, shift + movu [dstq + %1], m%3 + add srcq, strideq +%endmacro + +INIT_MMX mmx +; void ff_vc1_put_ver_16b_shift2_mmx(int16_t *dst, const uint8_t *src, +; x86_reg stride, int rnd, int64_t shift) +; Sacrificing m6 makes it possible to pipeline loads from src +%if ARCH_X86_32 +cglobal vc1_put_ver_16b_shift2, 3,6,0, dst, src, stride + DECLARE_REG_TMP 3, 4, 5 + %define rnd r3mp + %define shift qword r4m +%else ; X86_64 +cglobal vc1_put_ver_16b_shift2, 4,7,0, dst, src, stride + DECLARE_REG_TMP 4, 5, 6 + %define rnd r3d + ; We need shift either in memory or in a mm reg as it's used in psraw + ; On WIN64, the arg is already on the stack + ; On UNIX64, m5 doesn't seem to be used +%if WIN64 + %define shift r4mp +%else ; UNIX64 + %define shift m5 + mova shift, r4q +%endif ; WIN64 +%endif ; X86_32 +%define stride_neg2 t0q +%define stride_9minus4 t1q +%define i t2q + mov stride_neg2, strideq + neg stride_neg2 + add stride_neg2, stride_neg2 + lea stride_9minus4, [strideq * 9 - 4] + mov i, 3 + LOAD_ROUNDER_MMX rnd + mova m6, [pw_9] + pxor m0, m0 +.loop: + movh m2, [srcq] + add srcq, strideq + movh m3, [srcq] + punpcklbw m2, m0 + punpcklbw m3, m0 + SHIFT2_LINE 0, 1, 2, 3, 4 + SHIFT2_LINE 24, 2, 3, 4, 1 + SHIFT2_LINE 48, 3, 4, 1, 2 + SHIFT2_LINE 72, 4, 1, 2, 3 + SHIFT2_LINE 96, 1, 2, 3, 4 + SHIFT2_LINE 120, 2, 3, 4, 1 + SHIFT2_LINE 144, 3, 4, 1, 2 + SHIFT2_LINE 168, 4, 1, 2, 3 + sub srcq, stride_9minus4 + add dstq, 8 + dec i + jnz .loop + REP_RET +%undef rnd +%undef shift +%undef stride_neg2 +%undef stride_9minus4 +%undef i + +; void ff_vc1_*_hor_16b_shift2_mmx(uint8_t *dst, x86_reg stride, +; const int16_t *src, int rnd); +; Data is already unpacked, so some operations can directly be made from +; memory. +%macro HOR_16B_SHIFT2 2 ; op, opname +cglobal vc1_%2_hor_16b_shift2, 4, 5, 0, dst, stride, src, rnd, h + mov hq, 8 + sub srcq, 2 + sub rndd, (-1+9+9-1) * 1024 ; add -1024 bias + LOAD_ROUNDER_MMX rndd + mova m5, [pw_9] + mova m6, [pw_128] + pxor m0, m0 + +.loop: + mova m1, [srcq + 2 * 0] + mova m2, [srcq + 2 * 0 + mmsize] + mova m3, [srcq + 2 * 1] + mova m4, [srcq + 2 * 1 + mmsize] + paddw m3, [srcq + 2 * 2] + paddw m4, [srcq + 2 * 2 + mmsize] + paddw m1, [srcq + 2 * 3] + paddw m2, [srcq + 2 * 3 + mmsize] + pmullw m3, m5 + pmullw m4, m5 + psubw m3, m1 + psubw m4, m2 + NORMALIZE_MMX 7 + ; remove bias + paddw m3, m6 + paddw m4, m6 + TRANSFER_DO_PACK %1, dstq + add srcq, 24 + add dstq, strideq + dec hq + jnz .loop + + RET +%endmacro + +INIT_MMX mmx +HOR_16B_SHIFT2 OP_PUT, put + +INIT_MMX mmxext +HOR_16B_SHIFT2 OP_AVG, avg +%endif ; HAVE_MMX_INLINE + +%macro INV_TRANS_INIT 0 + movsxdifnidn linesizeq, linesized + movd m0, blockd + SPLATW m0, m0 + pxor m1, m1 + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 + + DEFINE_ARGS dest, linesize, linesize3 + lea linesize3q, [linesizeq*3] +%endmacro + +%macro INV_TRANS_PROCESS 1 + mov%1 m2, [destq+linesizeq*0] + mov%1 m3, [destq+linesizeq*1] + mov%1 m4, [destq+linesizeq*2] + mov%1 m5, [destq+linesize3q] + paddusb m2, m0 + paddusb m3, m0 + paddusb m4, m0 + paddusb m5, m0 + psubusb m2, m1 + psubusb m3, m1 + psubusb m4, m1 + psubusb m5, m1 + mov%1 [linesizeq*0+destq], m2 + mov%1 [linesizeq*1+destq], m3 + mov%1 [linesizeq*2+destq], m4 + mov%1 [linesize3q +destq], m5 +%endmacro + +; ff_vc1_inv_trans_?x?_dc_mmxext(uint8_t *dest, ptrdiff_t linesize, int16_t *block) +INIT_MMX mmxext +cglobal vc1_inv_trans_4x4_dc, 3,4,0, dest, linesize, block + movsx r3d, WORD [blockq] + mov blockd, r3d ; dc + shl blockd, 4 ; 16 * dc + lea blockd, [blockq+r3+4] ; 17 * dc + 4 + sar blockd, 3 ; >> 3 + mov r3d, blockd ; dc + shl blockd, 4 ; 16 * dc + lea blockd, [blockq+r3+64] ; 17 * dc + 64 + sar blockd, 7 ; >> 7 + + INV_TRANS_INIT + + INV_TRANS_PROCESS h + RET + +INIT_MMX mmxext +cglobal vc1_inv_trans_4x8_dc, 3,4,0, dest, linesize, block + movsx r3d, WORD [blockq] + mov blockd, r3d ; dc + shl blockd, 4 ; 16 * dc + lea blockd, [blockq+r3+4] ; 17 * dc + 4 + sar blockd, 3 ; >> 3 + shl blockd, 2 ; 4 * dc + lea blockd, [blockq*3+64] ; 12 * dc + 64 + sar blockd, 7 ; >> 7 + + INV_TRANS_INIT + + INV_TRANS_PROCESS h + lea destq, [destq+linesizeq*4] + INV_TRANS_PROCESS h + RET + +INIT_MMX mmxext +cglobal vc1_inv_trans_8x4_dc, 3,4,0, dest, linesize, block + movsx blockd, WORD [blockq] ; dc + lea blockd, [blockq*3+1] ; 3 * dc + 1 + sar blockd, 1 ; >> 1 + mov r3d, blockd ; dc + shl blockd, 4 ; 16 * dc + lea blockd, [blockq+r3+64] ; 17 * dc + 64 + sar blockd, 7 ; >> 7 + + INV_TRANS_INIT + + INV_TRANS_PROCESS a + RET + +INIT_MMX mmxext +cglobal vc1_inv_trans_8x8_dc, 3,3,0, dest, linesize, block + movsx blockd, WORD [blockq] ; dc + lea blockd, [blockq*3+1] ; 3 * dc + 1 + sar blockd, 1 ; >> 1 + lea blockd, [blockq*3+16] ; 3 * dc + 16 + sar blockd, 5 ; >> 5 + + INV_TRANS_INIT + + INV_TRANS_PROCESS a + lea destq, [destq+linesizeq*4] + INV_TRANS_PROCESS a + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_mmx.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_mmx.c new file mode 100644 index 00000000..6541dda4 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vc1dsp_mmx.c @@ -0,0 +1,487 @@ +/* + * VC-1 and WMV3 - DSP functions MMX-optimized + * Copyright (c) 2007 Christophe GISQUET + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vc1dsp.h" +#include "constants.h" +#include "fpel.h" +#include "vc1dsp.h" + +#if HAVE_6REGS && HAVE_INLINE_ASM && HAVE_MMX_EXTERNAL + +void ff_vc1_put_ver_16b_shift2_mmx(int16_t *dst, + const uint8_t *src, x86_reg stride, + int rnd, int64_t shift); +void ff_vc1_put_hor_16b_shift2_mmx(uint8_t *dst, x86_reg stride, + const int16_t *src, int rnd); +void ff_vc1_avg_hor_16b_shift2_mmxext(uint8_t *dst, x86_reg stride, + const int16_t *src, int rnd); + +#define OP_PUT(S,D) +#define OP_AVG(S,D) "pavgb " #S ", " #D " \n\t" + +/** Add rounder from mm7 to mm3 and pack result at destination */ +#define NORMALIZE_MMX(SHIFT) \ + "paddw %%mm7, %%mm3 \n\t" /* +bias-r */ \ + "paddw %%mm7, %%mm4 \n\t" /* +bias-r */ \ + "psraw "SHIFT", %%mm3 \n\t" \ + "psraw "SHIFT", %%mm4 \n\t" + +#define TRANSFER_DO_PACK(OP) \ + "packuswb %%mm4, %%mm3 \n\t" \ + OP((%2), %%mm3) \ + "movq %%mm3, (%2) \n\t" + +#define TRANSFER_DONT_PACK(OP) \ + OP(0(%2), %%mm3) \ + OP(8(%2), %%mm4) \ + "movq %%mm3, 0(%2) \n\t" \ + "movq %%mm4, 8(%2) \n\t" + +/** @see MSPEL_FILTER13_CORE for use as UNPACK macro */ +#define DO_UNPACK(reg) "punpcklbw %%mm0, " reg "\n\t" +#define DONT_UNPACK(reg) + +/** Compute the rounder 32-r or 8-r and unpacks it to mm7 */ +#define LOAD_ROUNDER_MMX(ROUND) \ + "movd "ROUND", %%mm7 \n\t" \ + "punpcklwd %%mm7, %%mm7 \n\t" \ + "punpckldq %%mm7, %%mm7 \n\t" + +/** + * Purely vertical or horizontal 1/2 shift interpolation. + * Sacrifice mm6 for *9 factor. + */ +#define VC1_SHIFT2(OP, OPNAME)\ +static void OPNAME ## vc1_shift2_mmx(uint8_t *dst, const uint8_t *src,\ + x86_reg stride, int rnd, x86_reg offset)\ +{\ + rnd = 8-rnd;\ + __asm__ volatile(\ + "mov $8, %%"FF_REG_c" \n\t"\ + LOAD_ROUNDER_MMX("%5")\ + "movq "MANGLE(ff_pw_9)", %%mm6\n\t"\ + "1: \n\t"\ + "movd 0(%0 ), %%mm3 \n\t"\ + "movd 4(%0 ), %%mm4 \n\t"\ + "movd 0(%0,%2), %%mm1 \n\t"\ + "movd 4(%0,%2), %%mm2 \n\t"\ + "add %2, %0 \n\t"\ + "punpcklbw %%mm0, %%mm3 \n\t"\ + "punpcklbw %%mm0, %%mm4 \n\t"\ + "punpcklbw %%mm0, %%mm1 \n\t"\ + "punpcklbw %%mm0, %%mm2 \n\t"\ + "paddw %%mm1, %%mm3 \n\t"\ + "paddw %%mm2, %%mm4 \n\t"\ + "movd 0(%0,%3), %%mm1 \n\t"\ + "movd 4(%0,%3), %%mm2 \n\t"\ + "pmullw %%mm6, %%mm3 \n\t" /* 0,9,9,0*/\ + "pmullw %%mm6, %%mm4 \n\t" /* 0,9,9,0*/\ + "punpcklbw %%mm0, %%mm1 \n\t"\ + "punpcklbw %%mm0, %%mm2 \n\t"\ + "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,0*/\ + "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,0*/\ + "movd 0(%0,%2), %%mm1 \n\t"\ + "movd 4(%0,%2), %%mm2 \n\t"\ + "punpcklbw %%mm0, %%mm1 \n\t"\ + "punpcklbw %%mm0, %%mm2 \n\t"\ + "psubw %%mm1, %%mm3 \n\t" /*-1,9,9,-1*/\ + "psubw %%mm2, %%mm4 \n\t" /*-1,9,9,-1*/\ + NORMALIZE_MMX("$4")\ + "packuswb %%mm4, %%mm3 \n\t"\ + OP((%1), %%mm3)\ + "movq %%mm3, (%1) \n\t"\ + "add %6, %0 \n\t"\ + "add %4, %1 \n\t"\ + "dec %%"FF_REG_c" \n\t"\ + "jnz 1b \n\t"\ + : "+r"(src), "+r"(dst)\ + : "r"(offset), "r"(-2*offset), "g"(stride), "m"(rnd),\ + "g"(stride-offset)\ + NAMED_CONSTRAINTS_ADD(ff_pw_9)\ + : "%"FF_REG_c, "memory"\ + );\ +} + +VC1_SHIFT2(OP_PUT, put_) +VC1_SHIFT2(OP_AVG, avg_) + +/** + * Core of the 1/4 and 3/4 shift bicubic interpolation. + * + * @param UNPACK Macro unpacking arguments from 8 to 16 bits (can be empty). + * @param MOVQ "movd 1" or "movq 2", if data read is already unpacked. + * @param A1 Address of 1st tap (beware of unpacked/packed). + * @param A2 Address of 2nd tap + * @param A3 Address of 3rd tap + * @param A4 Address of 4th tap + */ +#define MSPEL_FILTER13_CORE(UNPACK, MOVQ, A1, A2, A3, A4) \ + MOVQ "*0+"A1", %%mm1 \n\t" \ + MOVQ "*4+"A1", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "pmullw "MANGLE(ff_pw_3)", %%mm1\n\t" \ + "pmullw "MANGLE(ff_pw_3)", %%mm2\n\t" \ + MOVQ "*0+"A2", %%mm3 \n\t" \ + MOVQ "*4+"A2", %%mm4 \n\t" \ + UNPACK("%%mm3") \ + UNPACK("%%mm4") \ + "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ + "pmullw %%mm6, %%mm4 \n\t" /* *18 */ \ + "psubw %%mm1, %%mm3 \n\t" /* 18,-3 */ \ + "psubw %%mm2, %%mm4 \n\t" /* 18,-3 */ \ + MOVQ "*0+"A4", %%mm1 \n\t" \ + MOVQ "*4+"A4", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "psllw $2, %%mm1 \n\t" /* 4* */ \ + "psllw $2, %%mm2 \n\t" /* 4* */ \ + "psubw %%mm1, %%mm3 \n\t" /* -4,18,-3 */ \ + "psubw %%mm2, %%mm4 \n\t" /* -4,18,-3 */ \ + MOVQ "*0+"A3", %%mm1 \n\t" \ + MOVQ "*4+"A3", %%mm2 \n\t" \ + UNPACK("%%mm1") \ + UNPACK("%%mm2") \ + "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ + "pmullw %%mm5, %%mm2 \n\t" /* *53 */ \ + "paddw %%mm1, %%mm3 \n\t" /* 4,53,18,-3 */ \ + "paddw %%mm2, %%mm4 \n\t" /* 4,53,18,-3 */ + +/** + * Macro to build the vertical 16 bits version of vc1_put_shift[13]. + * Here, offset=src_stride. Parameters passed A1 to A4 must use + * %3 (src_stride) and %4 (3*src_stride). + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_VER_16B(NAME, A1, A2, A3, A4) \ +static void \ +vc1_put_ver_16b_ ## NAME ## _mmx(int16_t *dst, const uint8_t *src, \ + x86_reg src_stride, \ + int rnd, int64_t shift) \ +{ \ + int h = 8; \ + src -= src_stride; \ + __asm__ volatile( \ + LOAD_ROUNDER_MMX("%5") \ + "movq "MANGLE(ff_pw_53)", %%mm5\n\t" \ + "movq "MANGLE(ff_pw_18)", %%mm6\n\t" \ + ".p2align 3 \n\t" \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ + NORMALIZE_MMX("%6") \ + TRANSFER_DONT_PACK(OP_PUT) \ + /* Last 3 (in fact 4) bytes on the line */ \ + "movd 8+"A1", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "movq %%mm1, %%mm3 \n\t" \ + "paddw %%mm1, %%mm1 \n\t" \ + "paddw %%mm3, %%mm1 \n\t" /* 3* */ \ + "movd 8+"A2", %%mm3 \n\t" \ + DO_UNPACK("%%mm3") \ + "pmullw %%mm6, %%mm3 \n\t" /* *18 */ \ + "psubw %%mm1, %%mm3 \n\t" /*18,-3 */ \ + "movd 8+"A3", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "pmullw %%mm5, %%mm1 \n\t" /* *53 */ \ + "paddw %%mm1, %%mm3 \n\t" /*53,18,-3 */ \ + "movd 8+"A4", %%mm1 \n\t" \ + DO_UNPACK("%%mm1") \ + "psllw $2, %%mm1 \n\t" /* 4* */ \ + "psubw %%mm1, %%mm3 \n\t" \ + "paddw %%mm7, %%mm3 \n\t" \ + "psraw %6, %%mm3 \n\t" \ + "movq %%mm3, 16(%2) \n\t" \ + "add %3, %1 \n\t" \ + "add $24, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(src_stride), "r"(3*src_stride), \ + "m"(rnd), "m"(shift) \ + NAMED_CONSTRAINTS_ADD(ff_pw_3,ff_pw_53,ff_pw_18) \ + : "memory" \ + ); \ +} + +/** + * Macro to build the horizontal 16 bits version of vc1_put_shift[13]. + * Here, offset=16 bits, so parameters passed A1 to A4 should be simple. + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_HOR_16B(NAME, A1, A2, A3, A4, OP, OPNAME) \ +static void \ +OPNAME ## vc1_hor_16b_ ## NAME ## _mmx(uint8_t *dst, x86_reg stride, \ + const int16_t *src, int rnd) \ +{ \ + int h = 8; \ + src -= 1; \ + rnd -= (-4+58+13-3)*256; /* Add -256 bias */ \ + __asm__ volatile( \ + LOAD_ROUNDER_MMX("%4") \ + "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ + "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ + ".p2align 3 \n\t" \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DONT_UNPACK, "movq 2", A1, A2, A3, A4) \ + NORMALIZE_MMX("$7") \ + /* Remove bias */ \ + "paddw "MANGLE(ff_pw_128)", %%mm3 \n\t" \ + "paddw "MANGLE(ff_pw_128)", %%mm4 \n\t" \ + TRANSFER_DO_PACK(OP) \ + "add $24, %1 \n\t" \ + "add %3, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(stride), "m"(rnd) \ + NAMED_CONSTRAINTS_ADD(ff_pw_3,ff_pw_18,ff_pw_53,ff_pw_128) \ + : "memory" \ + ); \ +} + +/** + * Macro to build the 8 bits, any direction, version of vc1_put_shift[13]. + * Here, offset=src_stride. Parameters passed A1 to A4 must use + * %3 (offset) and %4 (3*offset). + * + * @param NAME Either 1 or 3 + * @see MSPEL_FILTER13_CORE for information on A1->A4 + */ +#define MSPEL_FILTER13_8B(NAME, A1, A2, A3, A4, OP, OPNAME) \ +static void \ +OPNAME ## vc1_## NAME ## _mmx(uint8_t *dst, const uint8_t *src, \ + x86_reg stride, int rnd, x86_reg offset) \ +{ \ + int h = 8; \ + src -= offset; \ + rnd = 32-rnd; \ + __asm__ volatile ( \ + LOAD_ROUNDER_MMX("%6") \ + "movq "MANGLE(ff_pw_53)", %%mm5 \n\t" \ + "movq "MANGLE(ff_pw_18)", %%mm6 \n\t" \ + ".p2align 3 \n\t" \ + "1: \n\t" \ + MSPEL_FILTER13_CORE(DO_UNPACK, "movd 1", A1, A2, A3, A4) \ + NORMALIZE_MMX("$6") \ + TRANSFER_DO_PACK(OP) \ + "add %5, %1 \n\t" \ + "add %5, %2 \n\t" \ + "decl %0 \n\t" \ + "jnz 1b \n\t" \ + : "+r"(h), "+r" (src), "+r" (dst) \ + : "r"(offset), "r"(3*offset), "g"(stride), "m"(rnd) \ + NAMED_CONSTRAINTS_ADD(ff_pw_53,ff_pw_18,ff_pw_3) \ + : "memory" \ + ); \ +} + +/** 1/4 shift bicubic interpolation */ +MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )", OP_PUT, put_) +MSPEL_FILTER13_8B (shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )", OP_AVG, avg_) +MSPEL_FILTER13_VER_16B(shift1, "0(%1,%4 )", "0(%1,%3,2)", "0(%1,%3 )", "0(%1 )") +MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)", OP_PUT, put_) +MSPEL_FILTER13_HOR_16B(shift1, "2*3(%1)", "2*2(%1)", "2*1(%1)", "2*0(%1)", OP_AVG, avg_) + +/** 3/4 shift bicubic interpolation */ +MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )", OP_PUT, put_) +MSPEL_FILTER13_8B (shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )", OP_AVG, avg_) +MSPEL_FILTER13_VER_16B(shift3, "0(%1 )", "0(%1,%3 )", "0(%1,%3,2)", "0(%1,%4 )") +MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)", OP_PUT, put_) +MSPEL_FILTER13_HOR_16B(shift3, "2*0(%1)", "2*1(%1)", "2*2(%1)", "2*3(%1)", OP_AVG, avg_) + +typedef void (*vc1_mspel_mc_filter_ver_16bits)(int16_t *dst, const uint8_t *src, x86_reg src_stride, int rnd, int64_t shift); +typedef void (*vc1_mspel_mc_filter_hor_16bits)(uint8_t *dst, x86_reg dst_stride, const int16_t *src, int rnd); +typedef void (*vc1_mspel_mc_filter_8bits)(uint8_t *dst, const uint8_t *src, x86_reg stride, int rnd, x86_reg offset); + +/** + * Interpolate fractional pel values by applying proper vertical then + * horizontal filter. + * + * @param dst Destination buffer for interpolated pels. + * @param src Source buffer. + * @param stride Stride for both src and dst buffers. + * @param hmode Horizontal filter (expressed in quarter pixels shift). + * @param hmode Vertical filter. + * @param rnd Rounding bias. + */ +#define VC1_MSPEL_MC(OP, INSTR)\ +static void OP ## vc1_mspel_mc(uint8_t *dst, const uint8_t *src, int stride,\ + int hmode, int vmode, int rnd)\ +{\ + static const vc1_mspel_mc_filter_ver_16bits vc1_put_shift_ver_16bits[] =\ + { NULL, vc1_put_ver_16b_shift1_mmx, ff_vc1_put_ver_16b_shift2_mmx, vc1_put_ver_16b_shift3_mmx };\ + static const vc1_mspel_mc_filter_hor_16bits vc1_put_shift_hor_16bits[] =\ + { NULL, OP ## vc1_hor_16b_shift1_mmx, ff_vc1_ ## OP ## hor_16b_shift2_ ## INSTR, OP ## vc1_hor_16b_shift3_mmx };\ + static const vc1_mspel_mc_filter_8bits vc1_put_shift_8bits[] =\ + { NULL, OP ## vc1_shift1_mmx, OP ## vc1_shift2_mmx, OP ## vc1_shift3_mmx };\ +\ + __asm__ volatile(\ + "pxor %%mm0, %%mm0 \n\t"\ + ::: "memory"\ + );\ +\ + if (vmode) { /* Vertical filter to apply */\ + if (hmode) { /* Horizontal filter to apply, output to tmp */\ + static const int shift_value[] = { 0, 5, 1, 5 };\ + int shift = (shift_value[hmode]+shift_value[vmode])>>1;\ + int r;\ + LOCAL_ALIGNED(16, int16_t, tmp, [12*8]);\ +\ + r = (1<<(shift-1)) + rnd-1;\ + vc1_put_shift_ver_16bits[vmode](tmp, src-1, stride, r, shift);\ +\ + vc1_put_shift_hor_16bits[hmode](dst, stride, tmp+1, 64-rnd);\ + return;\ + }\ + else { /* No horizontal filter, output 8 lines to dst */\ + vc1_put_shift_8bits[vmode](dst, src, stride, 1-rnd, stride);\ + return;\ + }\ + }\ +\ + /* Horizontal mode with no vertical mode */\ + vc1_put_shift_8bits[hmode](dst, src, stride, rnd, 1);\ +} \ +static void OP ## vc1_mspel_mc_16(uint8_t *dst, const uint8_t *src, \ + int stride, int hmode, int vmode, int rnd)\ +{ \ + OP ## vc1_mspel_mc(dst + 0, src + 0, stride, hmode, vmode, rnd); \ + OP ## vc1_mspel_mc(dst + 8, src + 8, stride, hmode, vmode, rnd); \ + dst += 8*stride; src += 8*stride; \ + OP ## vc1_mspel_mc(dst + 0, src + 0, stride, hmode, vmode, rnd); \ + OP ## vc1_mspel_mc(dst + 8, src + 8, stride, hmode, vmode, rnd); \ +} + +VC1_MSPEL_MC(put_, mmx) +VC1_MSPEL_MC(avg_, mmxext) + +/** Macro to ease bicubic filter interpolation functions declarations */ +#define DECLARE_FUNCTION(a, b) \ +static void put_vc1_mspel_mc ## a ## b ## _mmx(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride, \ + int rnd) \ +{ \ + put_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ +}\ +static void avg_vc1_mspel_mc ## a ## b ## _mmxext(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride, \ + int rnd) \ +{ \ + avg_vc1_mspel_mc(dst, src, stride, a, b, rnd); \ +}\ +static void put_vc1_mspel_mc ## a ## b ## _16_mmx(uint8_t *dst, \ + const uint8_t *src, \ + ptrdiff_t stride, \ + int rnd) \ +{ \ + put_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \ +}\ +static void avg_vc1_mspel_mc ## a ## b ## _16_mmxext(uint8_t *dst, \ + const uint8_t *src,\ + ptrdiff_t stride, \ + int rnd) \ +{ \ + avg_vc1_mspel_mc_16(dst, src, stride, a, b, rnd); \ +} + +DECLARE_FUNCTION(0, 1) +DECLARE_FUNCTION(0, 2) +DECLARE_FUNCTION(0, 3) + +DECLARE_FUNCTION(1, 0) +DECLARE_FUNCTION(1, 1) +DECLARE_FUNCTION(1, 2) +DECLARE_FUNCTION(1, 3) + +DECLARE_FUNCTION(2, 0) +DECLARE_FUNCTION(2, 1) +DECLARE_FUNCTION(2, 2) +DECLARE_FUNCTION(2, 3) + +DECLARE_FUNCTION(3, 0) +DECLARE_FUNCTION(3, 1) +DECLARE_FUNCTION(3, 2) +DECLARE_FUNCTION(3, 3) + +#define FN_ASSIGN(OP, X, Y, INSN) \ + dsp->OP##vc1_mspel_pixels_tab[1][X+4*Y] = OP##vc1_mspel_mc##X##Y##INSN; \ + dsp->OP##vc1_mspel_pixels_tab[0][X+4*Y] = OP##vc1_mspel_mc##X##Y##_16##INSN + +av_cold void ff_vc1dsp_init_mmx(VC1DSPContext *dsp) +{ + FN_ASSIGN(put_, 0, 1, _mmx); + FN_ASSIGN(put_, 0, 2, _mmx); + FN_ASSIGN(put_, 0, 3, _mmx); + + FN_ASSIGN(put_, 1, 0, _mmx); + FN_ASSIGN(put_, 1, 1, _mmx); + FN_ASSIGN(put_, 1, 2, _mmx); + FN_ASSIGN(put_, 1, 3, _mmx); + + FN_ASSIGN(put_, 2, 0, _mmx); + FN_ASSIGN(put_, 2, 1, _mmx); + FN_ASSIGN(put_, 2, 2, _mmx); + FN_ASSIGN(put_, 2, 3, _mmx); + + FN_ASSIGN(put_, 3, 0, _mmx); + FN_ASSIGN(put_, 3, 1, _mmx); + FN_ASSIGN(put_, 3, 2, _mmx); + FN_ASSIGN(put_, 3, 3, _mmx); +} + +av_cold void ff_vc1dsp_init_mmxext(VC1DSPContext *dsp) +{ + FN_ASSIGN(avg_, 0, 1, _mmxext); + FN_ASSIGN(avg_, 0, 2, _mmxext); + FN_ASSIGN(avg_, 0, 3, _mmxext); + + FN_ASSIGN(avg_, 1, 0, _mmxext); + FN_ASSIGN(avg_, 1, 1, _mmxext); + FN_ASSIGN(avg_, 1, 2, _mmxext); + FN_ASSIGN(avg_, 1, 3, _mmxext); + + FN_ASSIGN(avg_, 2, 0, _mmxext); + FN_ASSIGN(avg_, 2, 1, _mmxext); + FN_ASSIGN(avg_, 2, 2, _mmxext); + FN_ASSIGN(avg_, 2, 3, _mmxext); + + FN_ASSIGN(avg_, 3, 0, _mmxext); + FN_ASSIGN(avg_, 3, 1, _mmxext); + FN_ASSIGN(avg_, 3, 2, _mmxext); + FN_ASSIGN(avg_, 3, 3, _mmxext); +} +#endif /* HAVE_6REGS && HAVE_INLINE_ASM && HAVE_MMX_EXTERNAL */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/videodsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/videodsp.asm new file mode 100644 index 00000000..e2378607 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/videodsp.asm @@ -0,0 +1,468 @@ +;****************************************************************************** +;* Core video DSP functions +;* Copyright (c) 2012 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +; slow vertical extension loop function. Works with variable-width, and +; does per-line reading/writing of source data + +%macro V_COPY_ROW 2 ; type (top/body/bottom), h +.%1_y_loop: ; do { + mov wq, r7mp ; initialize w (r7mp = wmp) +.%1_x_loop: ; do { + movu m0, [srcq+wq] ; m0 = read($mmsize) + movu [dstq+wq], m0 ; write(m0, $mmsize) + add wq, mmsize ; w -= $mmsize + cmp wq, -mmsize ; } while (w > $mmsize); + jl .%1_x_loop + movu m0, [srcq-mmsize] ; m0 = read($mmsize) + movu [dstq-mmsize], m0 ; write(m0, $mmsize) +%ifidn %1, body ; if ($type == body) { + add srcq, src_strideq ; src += src_stride +%endif ; } + add dstq, dst_strideq ; dst += dst_stride + dec %2 ; } while (--$h); + jnz .%1_y_loop +%endmacro + +%macro vvar_fn 0 +; .----. <- zero +; | | <- top is copied from first line in body of source +; |----| <- start_y +; | | <- body is copied verbatim (line-by-line) from source +; |----| <- end_y +; | | <- bottom is copied from last line in body of source +; '----' <- bh +%if ARCH_X86_64 +cglobal emu_edge_vvar, 7, 8, 1, dst, dst_stride, src, src_stride, \ + start_y, end_y, bh, w +%else ; x86-32 +cglobal emu_edge_vvar, 1, 6, 1, dst, src, start_y, end_y, bh, w +%define src_strideq r3mp +%define dst_strideq r1mp + mov srcq, r2mp + mov start_yq, r4mp + mov end_yq, r5mp + mov bhq, r6mp +%endif + sub bhq, end_yq ; bh -= end_q + sub end_yq, start_yq ; end_q -= start_q + add srcq, r7mp ; (r7mp = wmp) + add dstq, r7mp ; (r7mp = wmp) + neg r7mp ; (r7mp = wmp) + test start_yq, start_yq ; if (start_q) { + jz .body + V_COPY_ROW top, start_yq ; v_copy_row(top, start_yq) +.body: ; } + V_COPY_ROW body, end_yq ; v_copy_row(body, end_yq) + test bhq, bhq ; if (bh) { + jz .end + sub srcq, src_strideq ; src -= src_stride + V_COPY_ROW bottom, bhq ; v_copy_row(bottom, bh) +.end: ; } + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +vvar_fn +%endif + +INIT_XMM sse +vvar_fn + +%macro hvar_fn 0 +cglobal emu_edge_hvar, 5, 6, 1, dst, dst_stride, start_x, n_words, h, w + lea dstq, [dstq+n_wordsq*2] + neg n_wordsq + lea start_xq, [start_xq+n_wordsq*2] +.y_loop: ; do { +%if cpuflag(avx2) + vpbroadcastb m0, [dstq+start_xq] + mov wq, n_wordsq ; initialize w +%else + movzx wd, byte [dstq+start_xq] ; w = read(1) + imul wd, 0x01010101 ; w *= 0x01010101 + movd m0, wd + mov wq, n_wordsq ; initialize w +%if cpuflag(sse2) + pshufd m0, m0, q0000 ; splat +%else ; mmx + punpckldq m0, m0 ; splat +%endif ; mmx/sse +%endif ; avx2 +.x_loop: ; do { + movu [dstq+wq*2], m0 ; write($reg, $mmsize) + add wq, mmsize/2 ; w -= $mmsize/2 + cmp wq, -(mmsize/2) ; } while (w > $mmsize/2) + jl .x_loop + movu [dstq-mmsize], m0 ; write($reg, $mmsize) + add dstq, dst_strideq ; dst += dst_stride + dec hq ; } while (h--) + jnz .y_loop + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +hvar_fn +%endif + +INIT_XMM sse2 +hvar_fn + +%if HAVE_AVX2_EXTERNAL +INIT_XMM avx2 +hvar_fn +%endif + +; macro to read/write a horizontal number of pixels (%2) to/from registers +; on sse, - fills xmm0-15 for consecutive sets of 16 pixels +; - if (%2 & 8) fills 8 bytes into xmm$next +; - if (%2 & 4) fills 4 bytes into xmm$next +; - if (%2 & 3) fills 1, 2 or 4 bytes in eax +; on mmx, - fills mm0-7 for consecutive sets of 8 pixels +; - if (%2 & 4) fills 4 bytes into mm$next +; - if (%2 & 3) fills 1, 2 or 4 bytes in eax +; writing data out is in the same way +%macro READ_NUM_BYTES 2 +%assign %%off 0 ; offset in source buffer +%assign %%mmx_idx 0 ; mmx register index +%assign %%xmm_idx 0 ; xmm register index + +%rep %2/mmsize +%if mmsize == 16 + movu xmm %+ %%xmm_idx, [srcq+%%off] +%assign %%xmm_idx %%xmm_idx+1 +%else ; mmx + movu mm %+ %%mmx_idx, [srcq+%%off] +%assign %%mmx_idx %%mmx_idx+1 +%endif +%assign %%off %%off+mmsize +%endrep ; %2/mmsize + +%if mmsize == 16 +%if (%2-%%off) >= 8 +%if %2 > 16 && (%2-%%off) > 8 + movu xmm %+ %%xmm_idx, [srcq+%2-16] +%assign %%xmm_idx %%xmm_idx+1 +%assign %%off %2 +%else + movq mm %+ %%mmx_idx, [srcq+%%off] +%assign %%mmx_idx %%mmx_idx+1 +%assign %%off %%off+8 +%endif +%endif ; (%2-%%off) >= 8 +%endif + +%if (%2-%%off) >= 4 +%if %2 > 8 && (%2-%%off) > 4 + movq mm %+ %%mmx_idx, [srcq+%2-8] +%assign %%off %2 +%else + movd mm %+ %%mmx_idx, [srcq+%%off] +%assign %%off %%off+4 +%endif +%assign %%mmx_idx %%mmx_idx+1 +%endif ; (%2-%%off) >= 4 + +%if (%2-%%off) >= 1 +%if %2 >= 4 + movd mm %+ %%mmx_idx, [srcq+%2-4] +%elif (%2-%%off) == 1 + mov valb, [srcq+%2-1] +%elif (%2-%%off) == 2 + mov valw, [srcq+%2-2] +%else + mov valb, [srcq+%2-1] + ror vald, 16 + mov valw, [srcq+%2-3] +%endif +%endif ; (%2-%%off) >= 1 +%endmacro ; READ_NUM_BYTES + +%macro WRITE_NUM_BYTES 2 +%assign %%off 0 ; offset in destination buffer +%assign %%mmx_idx 0 ; mmx register index +%assign %%xmm_idx 0 ; xmm register index + +%rep %2/mmsize +%if mmsize == 16 + movu [dstq+%%off], xmm %+ %%xmm_idx +%assign %%xmm_idx %%xmm_idx+1 +%else ; mmx + movu [dstq+%%off], mm %+ %%mmx_idx +%assign %%mmx_idx %%mmx_idx+1 +%endif +%assign %%off %%off+mmsize +%endrep ; %2/mmsize + +%if mmsize == 16 +%if (%2-%%off) >= 8 +%if %2 > 16 && (%2-%%off) > 8 + movu [dstq+%2-16], xmm %+ %%xmm_idx +%assign %%xmm_idx %%xmm_idx+1 +%assign %%off %2 +%else + movq [dstq+%%off], mm %+ %%mmx_idx +%assign %%mmx_idx %%mmx_idx+1 +%assign %%off %%off+8 +%endif +%endif ; (%2-%%off) >= 8 +%endif + +%if (%2-%%off) >= 4 +%if %2 > 8 && (%2-%%off) > 4 + movq [dstq+%2-8], mm %+ %%mmx_idx +%assign %%off %2 +%else + movd [dstq+%%off], mm %+ %%mmx_idx +%assign %%off %%off+4 +%endif +%assign %%mmx_idx %%mmx_idx+1 +%endif ; (%2-%%off) >= 4 + +%if (%2-%%off) >= 1 +%if %2 >= 4 + movd [dstq+%2-4], mm %+ %%mmx_idx +%elif (%2-%%off) == 1 + mov [dstq+%2-1], valb +%elif (%2-%%off) == 2 + mov [dstq+%2-2], valw +%else + mov [dstq+%2-3], valw + ror vald, 16 + mov [dstq+%2-1], valb +%ifnidn %1, body + ror vald, 16 +%endif +%endif +%endif ; (%2-%%off) >= 1 +%endmacro ; WRITE_NUM_BYTES + +; vertical top/bottom extend and body copy fast loops +; these are function pointers to set-width line copy functions, i.e. +; they read a fixed number of pixels into set registers, and write +; those out into the destination buffer +%macro VERTICAL_EXTEND 2 +%assign %%n %1 +%rep 1+%2-%1 +%if %%n <= 3 +%if ARCH_X86_64 +cglobal emu_edge_vfix %+ %%n, 6, 8, 0, dst, dst_stride, src, src_stride, \ + start_y, end_y, val, bh + mov bhq, r6mp ; r6mp = bhmp +%else ; x86-32 +cglobal emu_edge_vfix %+ %%n, 0, 6, 0, val, dst, src, start_y, end_y, bh + mov dstq, r0mp + mov srcq, r2mp + mov start_yq, r4mp + mov end_yq, r5mp + mov bhq, r6mp +%define dst_strideq r1mp +%define src_strideq r3mp +%endif ; x86-64/32 +%else +%if ARCH_X86_64 +cglobal emu_edge_vfix %+ %%n, 7, 7, 1, dst, dst_stride, src, src_stride, \ + start_y, end_y, bh +%else ; x86-32 +cglobal emu_edge_vfix %+ %%n, 1, 5, 1, dst, src, start_y, end_y, bh + mov srcq, r2mp + mov start_yq, r4mp + mov end_yq, r5mp + mov bhq, r6mp +%define dst_strideq r1mp +%define src_strideq r3mp +%endif ; x86-64/32 +%endif + ; FIXME move this to c wrapper? + sub bhq, end_yq ; bh -= end_y + sub end_yq, start_yq ; end_y -= start_y + + ; extend pixels above body + test start_yq, start_yq ; if (start_y) { + jz .body_loop + READ_NUM_BYTES top, %%n ; $variable_regs = read($n) +.top_loop: ; do { + WRITE_NUM_BYTES top, %%n ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += linesize + dec start_yq ; } while (--start_y) + jnz .top_loop ; } + + ; copy body pixels +.body_loop: ; do { + READ_NUM_BYTES body, %%n ; $variable_regs = read($n) + WRITE_NUM_BYTES body, %%n ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += dst_stride + add srcq, src_strideq ; src += src_stride + dec end_yq ; } while (--end_y) + jnz .body_loop + + ; copy bottom pixels + test bhq, bhq ; if (block_h) { + jz .end + sub srcq, src_strideq ; src -= linesize + READ_NUM_BYTES bottom, %%n ; $variable_regs = read($n) +.bottom_loop: ; do { + WRITE_NUM_BYTES bottom, %%n ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += linesize + dec bhq ; } while (--bh) + jnz .bottom_loop ; } + +.end: + RET +%assign %%n %%n+1 +%endrep ; 1+%2-%1 +%endmacro ; VERTICAL_EXTEND + +INIT_MMX mmx +VERTICAL_EXTEND 1, 15 +%if ARCH_X86_32 +VERTICAL_EXTEND 16, 22 +%endif + +INIT_XMM sse +VERTICAL_EXTEND 16, 22 + +; left/right (horizontal) fast extend functions +; these are essentially identical to the vertical extend ones above, +; just left/right separated because number of pixels to extend is +; obviously not the same on both sides. + +%macro READ_V_PIXEL 2 +%if cpuflag(avx2) + vpbroadcastb m0, %2 +%else + movzx vald, byte %2 + imul vald, 0x01010101 +%if %1 >= 8 + movd m0, vald +%if mmsize == 16 + pshufd m0, m0, q0000 +%else + punpckldq m0, m0 +%endif ; mmsize == 16 +%endif ; %1 > 16 +%endif ; avx2 +%endmacro ; READ_V_PIXEL + +%macro WRITE_V_PIXEL 2 +%assign %%off 0 + +%if %1 >= 8 + +%rep %1/mmsize + movu [%2+%%off], m0 +%assign %%off %%off+mmsize +%endrep ; %1/mmsize + +%if mmsize == 16 +%if %1-%%off >= 8 +%if %1 > 16 && %1-%%off > 8 + movu [%2+%1-16], m0 +%assign %%off %1 +%else + movq [%2+%%off], m0 +%assign %%off %%off+8 +%endif +%endif ; %1-%%off >= 8 +%endif ; mmsize == 16 + +%if %1-%%off >= 4 +%if %1 > 8 && %1-%%off > 4 + movq [%2+%1-8], m0 +%assign %%off %1 +%else + movd [%2+%%off], m0 +%assign %%off %%off+4 +%endif +%endif ; %1-%%off >= 4 + +%else ; %1 < 8 + +%rep %1/4 + mov [%2+%%off], vald +%assign %%off %%off+4 +%endrep ; %1/4 + +%endif ; %1 >=/< 8 + +%if %1-%%off == 2 +%if cpuflag(avx2) + movd [%2+%%off-2], m0 +%else + mov [%2+%%off], valw +%endif ; avx2 +%endif ; (%1-%%off)/2 +%endmacro ; WRITE_V_PIXEL + +%macro H_EXTEND 2 +%assign %%n %1 +%rep 1+(%2-%1)/2 +%if cpuflag(avx2) +cglobal emu_edge_hfix %+ %%n, 4, 4, 1, dst, dst_stride, start_x, bh +%else +cglobal emu_edge_hfix %+ %%n, 4, 5, 1, dst, dst_stride, start_x, bh, val +%endif +.loop_y: ; do { + READ_V_PIXEL %%n, [dstq+start_xq] ; $variable_regs = read($n) + WRITE_V_PIXEL %%n, dstq ; write($variable_regs, $n) + add dstq, dst_strideq ; dst += dst_stride + dec bhq ; } while (--bh) + jnz .loop_y + RET +%assign %%n %%n+2 +%endrep ; 1+(%2-%1)/2 +%endmacro ; H_EXTEND + +INIT_MMX mmx +H_EXTEND 2, 14 +%if ARCH_X86_32 +H_EXTEND 16, 22 +%endif + +INIT_XMM sse2 +H_EXTEND 16, 22 + +%if HAVE_AVX2_EXTERNAL +INIT_XMM avx2 +H_EXTEND 8, 22 +%endif + +%macro PREFETCH_FN 1 +cglobal prefetch, 3, 3, 0, buf, stride, h +.loop: + %1 [bufq] + add bufq, strideq + dec hd + jg .loop + REP_RET +%endmacro + +INIT_MMX mmxext +PREFETCH_FN prefetcht0 +%if ARCH_X86_32 +INIT_MMX 3dnow +PREFETCH_FN prefetch +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/videodsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/videodsp_init.c new file mode 100644 index 00000000..eeebb415 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/videodsp_init.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2002-2012 Michael Niedermayer + * Copyright (C) 2012 Ronald S. Bultje + * + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/avassert.h" +#include "libavutil/common.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/videodsp.h" + +#if HAVE_X86ASM +typedef void emu_edge_vfix_func(uint8_t *dst, x86_reg dst_stride, + const uint8_t *src, x86_reg src_stride, + x86_reg start_y, x86_reg end_y, x86_reg bh); +typedef void emu_edge_vvar_func(uint8_t *dst, x86_reg dst_stride, + const uint8_t *src, x86_reg src_stride, + x86_reg start_y, x86_reg end_y, x86_reg bh, + x86_reg w); + +extern emu_edge_vfix_func ff_emu_edge_vfix1_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix2_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix3_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix4_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix5_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix6_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix7_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix8_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix9_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix10_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix11_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix12_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix13_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix14_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix15_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix16_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix17_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix18_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix19_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix20_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix21_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix22_mmx; +#if ARCH_X86_32 +static emu_edge_vfix_func * const vfixtbl_mmx[22] = { + &ff_emu_edge_vfix1_mmx, &ff_emu_edge_vfix2_mmx, &ff_emu_edge_vfix3_mmx, + &ff_emu_edge_vfix4_mmx, &ff_emu_edge_vfix5_mmx, &ff_emu_edge_vfix6_mmx, + &ff_emu_edge_vfix7_mmx, &ff_emu_edge_vfix8_mmx, &ff_emu_edge_vfix9_mmx, + &ff_emu_edge_vfix10_mmx, &ff_emu_edge_vfix11_mmx, &ff_emu_edge_vfix12_mmx, + &ff_emu_edge_vfix13_mmx, &ff_emu_edge_vfix14_mmx, &ff_emu_edge_vfix15_mmx, + &ff_emu_edge_vfix16_mmx, &ff_emu_edge_vfix17_mmx, &ff_emu_edge_vfix18_mmx, + &ff_emu_edge_vfix19_mmx, &ff_emu_edge_vfix20_mmx, &ff_emu_edge_vfix21_mmx, + &ff_emu_edge_vfix22_mmx +}; +#endif +extern emu_edge_vvar_func ff_emu_edge_vvar_mmx; +extern emu_edge_vfix_func ff_emu_edge_vfix16_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix17_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix18_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix19_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix20_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix21_sse; +extern emu_edge_vfix_func ff_emu_edge_vfix22_sse; +static emu_edge_vfix_func * const vfixtbl_sse[22] = { + ff_emu_edge_vfix1_mmx, ff_emu_edge_vfix2_mmx, ff_emu_edge_vfix3_mmx, + ff_emu_edge_vfix4_mmx, ff_emu_edge_vfix5_mmx, ff_emu_edge_vfix6_mmx, + ff_emu_edge_vfix7_mmx, ff_emu_edge_vfix8_mmx, ff_emu_edge_vfix9_mmx, + ff_emu_edge_vfix10_mmx, ff_emu_edge_vfix11_mmx, ff_emu_edge_vfix12_mmx, + ff_emu_edge_vfix13_mmx, ff_emu_edge_vfix14_mmx, ff_emu_edge_vfix15_mmx, + ff_emu_edge_vfix16_sse, ff_emu_edge_vfix17_sse, ff_emu_edge_vfix18_sse, + ff_emu_edge_vfix19_sse, ff_emu_edge_vfix20_sse, ff_emu_edge_vfix21_sse, + ff_emu_edge_vfix22_sse +}; +extern emu_edge_vvar_func ff_emu_edge_vvar_sse; + +typedef void emu_edge_hfix_func(uint8_t *dst, x86_reg dst_stride, + x86_reg start_x, x86_reg bh); +typedef void emu_edge_hvar_func(uint8_t *dst, x86_reg dst_stride, + x86_reg start_x, x86_reg n_words, x86_reg bh); + +extern emu_edge_hfix_func ff_emu_edge_hfix2_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix4_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix6_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix8_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix10_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix12_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix14_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix16_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix18_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix20_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix22_mmx; +#if ARCH_X86_32 +static emu_edge_hfix_func * const hfixtbl_mmx[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, + ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_mmx, ff_emu_edge_hfix18_mmx, + ff_emu_edge_hfix20_mmx, ff_emu_edge_hfix22_mmx +}; +#endif +extern emu_edge_hvar_func ff_emu_edge_hvar_mmx; +extern emu_edge_hfix_func ff_emu_edge_hfix16_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix18_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix20_sse2; +extern emu_edge_hfix_func ff_emu_edge_hfix22_sse2; +static emu_edge_hfix_func * const hfixtbl_sse2[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_mmx, ff_emu_edge_hfix10_mmx, ff_emu_edge_hfix12_mmx, + ff_emu_edge_hfix14_mmx, ff_emu_edge_hfix16_sse2, ff_emu_edge_hfix18_sse2, + ff_emu_edge_hfix20_sse2, ff_emu_edge_hfix22_sse2 +}; +extern emu_edge_hvar_func ff_emu_edge_hvar_sse2; +#if HAVE_AVX2_EXTERNAL +extern emu_edge_hfix_func ff_emu_edge_hfix8_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix10_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix12_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix14_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix16_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix18_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix20_avx2; +extern emu_edge_hfix_func ff_emu_edge_hfix22_avx2; +static emu_edge_hfix_func * const hfixtbl_avx2[11] = { + ff_emu_edge_hfix2_mmx, ff_emu_edge_hfix4_mmx, ff_emu_edge_hfix6_mmx, + ff_emu_edge_hfix8_avx2, ff_emu_edge_hfix10_avx2, ff_emu_edge_hfix12_avx2, + ff_emu_edge_hfix14_avx2, ff_emu_edge_hfix16_avx2, ff_emu_edge_hfix18_avx2, + ff_emu_edge_hfix20_avx2, ff_emu_edge_hfix22_avx2 +}; +extern emu_edge_hvar_func ff_emu_edge_hvar_avx2; +#endif + +static av_always_inline void emulated_edge_mc(uint8_t *dst, const uint8_t *src, + ptrdiff_t dst_stride, + ptrdiff_t src_stride, + x86_reg block_w, x86_reg block_h, + x86_reg src_x, x86_reg src_y, + x86_reg w, x86_reg h, + emu_edge_vfix_func * const *vfix_tbl, + emu_edge_vvar_func *v_extend_var, + emu_edge_hfix_func * const *hfix_tbl, + emu_edge_hvar_func *h_extend_var) +{ + x86_reg start_y, start_x, end_y, end_x, src_y_add = 0, p; + + if (!w || !h) + return; + + av_assert2(block_w <= FFABS(dst_stride)); + + if (src_y >= h) { + src -= src_y*src_stride; + src_y_add = h - 1; + src_y = h - 1; + } else if (src_y <= -block_h) { + src -= src_y*src_stride; + src_y_add = 1 - block_h; + src_y = 1 - block_h; + } + if (src_x >= w) { + src += w - 1 - src_x; + src_x = w - 1; + } else if (src_x <= -block_w) { + src += 1 - block_w - src_x; + src_x = 1 - block_w; + } + + start_y = FFMAX(0, -src_y); + start_x = FFMAX(0, -src_x); + end_y = FFMIN(block_h, h-src_y); + end_x = FFMIN(block_w, w-src_x); + av_assert2(start_x < end_x && block_w > 0); + av_assert2(start_y < end_y && block_h > 0); + + // fill in the to-be-copied part plus all above/below + src += (src_y_add + start_y) * src_stride + start_x; + w = end_x - start_x; + if (w <= 22) { + vfix_tbl[w - 1](dst + start_x, dst_stride, src, src_stride, + start_y, end_y, block_h); + } else { + v_extend_var(dst + start_x, dst_stride, src, src_stride, + start_y, end_y, block_h, w); + } + + // fill left + if (start_x) { + if (start_x <= 22) { + hfix_tbl[(start_x - 1) >> 1](dst, dst_stride, start_x, block_h); + } else { + h_extend_var(dst, dst_stride, + start_x, (start_x + 1) >> 1, block_h); + } + } + + // fill right + p = block_w - end_x; + if (p) { + if (p <= 22) { + hfix_tbl[(p - 1) >> 1](dst + end_x - (p & 1), dst_stride, + -!(p & 1), block_h); + } else { + h_extend_var(dst + end_x - (p & 1), dst_stride, + -!(p & 1), (p + 1) >> 1, block_h); + } + } +} + +#if ARCH_X86_32 +static av_noinline void emulated_edge_mc_mmx(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_mmx, &ff_emu_edge_vvar_mmx, + hfixtbl_mmx, &ff_emu_edge_hvar_mmx); +} + +static av_noinline void emulated_edge_mc_sse(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_mmx, &ff_emu_edge_hvar_mmx); +} +#endif + +static av_noinline void emulated_edge_mc_sse2(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, + int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_sse2, &ff_emu_edge_hvar_sse2); +} + +#if HAVE_AVX2_EXTERNAL +static av_noinline void emulated_edge_mc_avx2(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_stride, + ptrdiff_t src_stride, + int block_w, int block_h, + int src_x, int src_y, int w, + int h) +{ + emulated_edge_mc(buf, src, buf_stride, src_stride, block_w, block_h, + src_x, src_y, w, h, vfixtbl_sse, &ff_emu_edge_vvar_sse, + hfixtbl_avx2, &ff_emu_edge_hvar_avx2); +} +#endif /* HAVE_AVX2_EXTERNAL */ +#endif /* HAVE_X86ASM */ + +void ff_prefetch_mmxext(uint8_t *buf, ptrdiff_t stride, int h); +void ff_prefetch_3dnow(uint8_t *buf, ptrdiff_t stride, int h); + +av_cold void ff_videodsp_init_x86(VideoDSPContext *ctx, int bpc) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_mmx; + } + if (EXTERNAL_AMD3DNOW(cpu_flags)) { + ctx->prefetch = ff_prefetch_3dnow; + } +#endif /* ARCH_X86_32 */ + if (EXTERNAL_MMXEXT(cpu_flags)) { + ctx->prefetch = ff_prefetch_mmxext; + } +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_sse; + } +#endif /* ARCH_X86_32 */ + if (EXTERNAL_SSE2(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_sse2; + } +#if HAVE_AVX2_EXTERNAL + if (EXTERNAL_AVX2(cpu_flags) && bpc <= 8) { + ctx->emulated_edge_mc = emulated_edge_mc_avx2; + } +#endif +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vorbisdsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vorbisdsp.asm new file mode 100644 index 00000000..d9522967 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vorbisdsp.asm @@ -0,0 +1,86 @@ +;****************************************************************************** +;* Vorbis x86 optimizations +;* Copyright (C) 2006 Loren Merritt +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pdw_80000000: times 4 dd 0x80000000 + +SECTION .text + +%if ARCH_X86_32 +INIT_MMX 3dnow +cglobal vorbis_inverse_coupling, 3, 3, 6, mag, ang, block_size + pxor m7, m7 + lea magq, [magq+block_sizeq*4] + lea angq, [angq+block_sizeq*4] + neg block_sizeq +.loop: + mova m0, [magq+block_sizeq*4] + mova m1, [angq+block_sizeq*4] + mova m2, m0 + mova m3, m1 + pfcmpge m2, m7 ; m <= 0.0 + pfcmpge m3, m7 ; a <= 0.0 + pslld m2, 31 ; keep only the sign bit + pxor m1, m2 + mova m4, m3 + pand m3, m1 + pandn m4, m1 + pfadd m3, m0 ; a = m + ((a < 0) & (a ^ sign(m))) + pfsub m0, m4 ; m = m + ((a > 0) & (a ^ sign(m))) + mova [angq+block_sizeq*4], m3 + mova [magq+block_sizeq*4], m0 + add block_sizeq, 2 + jl .loop + femms + RET +%endif + +INIT_XMM sse +cglobal vorbis_inverse_coupling, 3, 3, 6, mag, ang, block_size + mova m5, [pdw_80000000] + shl block_sized, 2 + add magq, block_sizeq + add angq, block_sizeq + neg block_sizeq + +align 16 +.loop: + mova m0, [magq+block_sizeq] + mova m1, [angq+block_sizeq] + xorps m2, m2 + xorps m3, m3 + cmpleps m2, m0 ; m <= 0.0 + cmpleps m3, m1 ; a <= 0.0 + andps m2, m5 ; keep only the sign bit + xorps m1, m2 + mova m4, m3 + andps m3, m1 + andnps m4, m1 + addps m3, m0 ; a = m + ((a < 0) & (a ^ sign(m))) + subps m0, m4 ; m = m + ((a > 0) & (a ^ sign(m))) + mova [angq+block_sizeq], m3 + mova [magq+block_sizeq], m0 + add block_sizeq, mmsize + jl .loop + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vorbisdsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vorbisdsp_init.c new file mode 100644 index 00000000..bc1cc43a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vorbisdsp_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006 Loren Merritt + * + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vorbisdsp.h" + +void ff_vorbis_inverse_coupling_3dnow(float *mag, float *ang, + intptr_t blocksize); +void ff_vorbis_inverse_coupling_sse(float *mag, float *ang, + intptr_t blocksize); + +av_cold void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_AMD3DNOW(cpu_flags)) + dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_3dnow; +#endif /* ARCH_X86_32 */ + if (EXTERNAL_SSE(cpu_flags)) + dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp3dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp3dsp.asm new file mode 100644 index 00000000..d88d5a1e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp3dsp.asm @@ -0,0 +1,742 @@ +;****************************************************************************** +;* MMX/SSE2-optimized functions for the VP3 decoder +;* Copyright (c) 2007 Aurelien Jacobs +;* +;* 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 "libavutil/x86/x86util.asm" + +; MMX-optimized functions cribbed from the original VP3 source code. + +SECTION_RODATA + +vp3_idct_data: times 8 dw 64277 + times 8 dw 60547 + times 8 dw 54491 + times 8 dw 46341 + times 8 dw 36410 + times 8 dw 25080 + times 8 dw 12785 + +pb_7: times 8 db 0x07 +pb_1F: times 8 db 0x1f +pb_81: times 8 db 0x81 + +cextern pb_1 +cextern pb_3 +cextern pb_80 +cextern pb_FE + +cextern pw_8 + +SECTION .text + +; this is off by one or two for some cases when filter_limit is greater than 63 +; in: p0 in mm6, p1 in mm4, p2 in mm2, p3 in mm1 +; out: p1 in mm4, p2 in mm3 +%macro VP3_LOOP_FILTER 0 + movq m7, m6 + pand m6, [pb_7] ; p0&7 + psrlw m7, 3 + pand m7, [pb_1F] ; p0>>3 + movq m3, m2 ; p2 + pxor m2, m4 + pand m2, [pb_1] ; (p2^p1)&1 + movq m5, m2 + paddb m2, m2 + paddb m2, m5 ; 3*(p2^p1)&1 + paddb m2, m6 ; extra bits lost in shifts + pcmpeqb m0, m0 + pxor m1, m0 ; 255 - p3 + pavgb m1, m2 ; (256 - p3 + extrabits) >> 1 + pxor m0, m4 ; 255 - p1 + pavgb m0, m3 ; (256 + p2-p1) >> 1 + paddb m1, [pb_3] + pavgb m1, m0 ; 128+2+( p2-p1 - p3) >> 2 + pavgb m1, m0 ; 128+1+(3*(p2-p1) - p3) >> 3 + paddusb m7, m1 ; d+128+1 + movq m6, [pb_81] + psubusb m6, m7 + psubusb m7, [pb_81] + + movq m5, [r2+516] ; flim + pminub m6, m5 + pminub m7, m5 + movq m0, m6 + movq m1, m7 + paddb m6, m6 + paddb m7, m7 + pminub m6, m5 + pminub m7, m5 + psubb m6, m0 + psubb m7, m1 + paddusb m4, m7 + psubusb m4, m6 + psubusb m3, m7 + paddusb m3, m6 +%endmacro + +%macro STORE_4_WORDS 1 + movd r2d, %1 + mov [r0 -1], r2w + psrlq %1, 32 + shr r2, 16 + mov [r0+r1 -1], r2w + movd r2d, %1 + mov [r0+r1*2-1], r2w + shr r2, 16 + mov [r0+r3 -1], r2w +%endmacro + +INIT_MMX mmxext +cglobal vp3_v_loop_filter, 3, 4 + mov r3, r1 + neg r1 + movq m6, [r0+r1*2] + movq m4, [r0+r1 ] + movq m2, [r0 ] + movq m1, [r0+r3 ] + + VP3_LOOP_FILTER + + movq [r0+r1], m4 + movq [r0 ], m3 + RET + +cglobal vp3_h_loop_filter, 3, 4 + lea r3, [r1*3] + + movd m6, [r0 -2] + movd m4, [r0+r1 -2] + movd m2, [r0+r1*2-2] + movd m1, [r0+r3 -2] + lea r0, [r0+r1*4 ] + punpcklbw m6, [r0 -2] + punpcklbw m4, [r0+r1 -2] + punpcklbw m2, [r0+r1*2-2] + punpcklbw m1, [r0+r3 -2] + sub r0, r3 + sub r0, r1 + + TRANSPOSE4x4B 6, 4, 2, 1, 0 + VP3_LOOP_FILTER + SBUTTERFLY bw, 4, 3, 5 + + STORE_4_WORDS m4 + lea r0, [r0+r1*4 ] + STORE_4_WORDS m3 + RET + +%macro PAVGB_NO_RND 0 + mova m4, m0 + mova m5, m2 + pand m4, m1 + pand m5, m3 + pxor m1, m0 + pxor m3, m2 + pand m1, m6 + pand m3, m6 + psrlq m1, 1 + psrlq m3, 1 + paddb m4, m1 + paddb m5, m3 +%endmacro + +INIT_MMX mmx +cglobal put_vp_no_rnd_pixels8_l2, 5, 6, 0, dst, src1, src2, stride, h, stride3 + mova m6, [pb_FE] + lea stride3q,[strideq+strideq*2] +.loop: + mova m0, [src1q] + mova m1, [src2q] + mova m2, [src1q+strideq] + mova m3, [src2q+strideq] + PAVGB_NO_RND + mova [dstq], m4 + mova [dstq+strideq], m5 + + mova m0, [src1q+strideq*2] + mova m1, [src2q+strideq*2] + mova m2, [src1q+stride3q] + mova m3, [src2q+stride3q] + PAVGB_NO_RND + mova [dstq+strideq*2], m4 + mova [dstq+stride3q], m5 + + lea src1q, [src1q+strideq*4] + lea src2q, [src2q+strideq*4] + lea dstq, [dstq+strideq*4] + sub hd, 4 + jnz .loop + RET + +; from original comments: The Macro does IDct on 4 1-D Dcts +%macro BeginIDCT 0 + movq m2, I(3) + movq m6, C(3) + movq m4, m2 + movq m7, J(5) + pmulhw m4, m6 ; r4 = c3*i3 - i3 + movq m1, C(5) + pmulhw m6, m7 ; r6 = c3*i5 - i5 + movq m5, m1 + pmulhw m1, m2 ; r1 = c5*i3 - i3 + movq m3, I(1) + pmulhw m5, m7 ; r5 = c5*i5 - i5 + movq m0, C(1) + paddw m4, m2 ; r4 = c3*i3 + paddw m6, m7 ; r6 = c3*i5 + paddw m2, m1 ; r2 = c5*i3 + movq m1, J(7) + paddw m7, m5 ; r7 = c5*i5 + movq m5, m0 ; r5 = c1 + pmulhw m0, m3 ; r0 = c1*i1 - i1 + paddsw m4, m7 ; r4 = C = c3*i3 + c5*i5 + pmulhw m5, m1 ; r5 = c1*i7 - i7 + movq m7, C(7) + psubsw m6, m2 ; r6 = D = c3*i5 - c5*i3 + paddw m0, m3 ; r0 = c1*i1 + pmulhw m3, m7 ; r3 = c7*i1 + movq m2, I(2) + pmulhw m7, m1 ; r7 = c7*i7 + paddw m5, m1 ; r5 = c1*i7 + movq m1, m2 ; r1 = i2 + pmulhw m2, C(2) ; r2 = c2*i2 - i2 + psubsw m3, m5 ; r3 = B = c7*i1 - c1*i7 + movq m5, J(6) + paddsw m0, m7 ; r0 = A = c1*i1 + c7*i7 + movq m7, m5 ; r7 = i6 + psubsw m0, m4 ; r0 = A - C + pmulhw m5, C(2) ; r5 = c2*i6 - i6 + paddw m2, m1 ; r2 = c2*i2 + pmulhw m1, C(6) ; r1 = c6*i2 + paddsw m4, m4 ; r4 = C + C + paddsw m4, m0 ; r4 = C. = A + C + psubsw m3, m6 ; r3 = B - D + paddw m5, m7 ; r5 = c2*i6 + paddsw m6, m6 ; r6 = D + D + pmulhw m7, C(6) ; r7 = c6*i6 + paddsw m6, m3 ; r6 = D. = B + D + movq I(1), m4 ; save C. at I(1) + psubsw m1, m5 ; r1 = H = c6*i2 - c2*i6 + movq m4, C(4) + movq m5, m3 ; r5 = B - D + pmulhw m3, m4 ; r3 = (c4 - 1) * (B - D) + paddsw m7, m2 ; r3 = (c4 - 1) * (B - D) + movq I(2), m6 ; save D. at I(2) + movq m2, m0 ; r2 = A - C + movq m6, I(0) + pmulhw m0, m4 ; r0 = (c4 - 1) * (A - C) + paddw m5, m3 ; r5 = B. = c4 * (B - D) + movq m3, J(4) + psubsw m5, m1 ; r5 = B.. = B. - H + paddw m2, m0 ; r0 = A. = c4 * (A - C) + psubsw m6, m3 ; r6 = i0 - i4 + movq m0, m6 + pmulhw m6, m4 ; r6 = (c4 - 1) * (i0 - i4) + paddsw m3, m3 ; r3 = i4 + i4 + paddsw m1, m1 ; r1 = H + H + paddsw m3, m0 ; r3 = i0 + i4 + paddsw m1, m5 ; r1 = H. = B + H + pmulhw m4, m3 ; r4 = (c4 - 1) * (i0 + i4) + paddsw m6, m0 ; r6 = F = c4 * (i0 - i4) + psubsw m6, m2 ; r6 = F. = F - A. + paddsw m2, m2 ; r2 = A. + A. + movq m0, I(1) ; r0 = C. + paddsw m2, m6 ; r2 = A.. = F + A. + paddw m4, m3 ; r4 = E = c4 * (i0 + i4) + psubsw m2, m1 ; r2 = R2 = A.. - H. +%endmacro + +; RowIDCT gets ready to transpose +%macro RowIDCT 0 + BeginIDCT + movq m3, I(2) ; r3 = D. + psubsw m4, m7 ; r4 = E. = E - G + paddsw m1, m1 ; r1 = H. + H. + paddsw m7, m7 ; r7 = G + G + paddsw m1, m2 ; r1 = R1 = A.. + H. + paddsw m7, m4 ; r1 = R1 = A.. + H. + psubsw m4, m3 ; r4 = R4 = E. - D. + paddsw m3, m3 + psubsw m6, m5 ; r6 = R6 = F. - B.. + paddsw m5, m5 + paddsw m3, m4 ; r3 = R3 = E. + D. + paddsw m5, m6 ; r5 = R5 = F. + B.. + psubsw m7, m0 ; r7 = R7 = G. - C. + paddsw m0, m0 + movq I(1), m1 ; save R1 + paddsw m0, m7 ; r0 = R0 = G. + C. +%endmacro + +; Column IDCT normalizes and stores final results +%macro ColumnIDCT 0 + BeginIDCT + paddsw m2, OC_8 ; adjust R2 (and R1) for shift + paddsw m1, m1 ; r1 = H. + H. + paddsw m1, m2 ; r1 = R1 = A.. + H. + psraw m2, 4 ; r2 = NR2 + psubsw m4, m7 ; r4 = E. = E - G + psraw m1, 4 ; r1 = NR2 + movq m3, I(2) ; r3 = D. + paddsw m7, m7 ; r7 = G + G + movq I(2), m2 ; store NR2 at I2 + paddsw m7, m4 ; r7 = G. = E + G + movq I(1), m1 ; store NR1 at I1 + psubsw m4, m3 ; r4 = R4 = E. - D. + paddsw m4, OC_8 ; adjust R4 (and R3) for shift + paddsw m3, m3 ; r3 = D. + D. + paddsw m3, m4 ; r3 = R3 = E. + D. + psraw m4, 4 ; r4 = NR4 + psubsw m6, m5 ; r6 = R6 = F. - B.. + psraw m3, 4 ; r3 = NR3 + paddsw m6, OC_8 ; adjust R6 (and R5) for shift + paddsw m5, m5 ; r5 = B.. + B.. + paddsw m5, m6 ; r5 = R5 = F. + B.. + psraw m6, 4 ; r6 = NR6 + movq J(4), m4 ; store NR4 at J4 + psraw m5, 4 ; r5 = NR5 + movq I(3), m3 ; store NR3 at I3 + psubsw m7, m0 ; r7 = R7 = G. - C. + paddsw m7, OC_8 ; adjust R7 (and R0) for shift + paddsw m0, m0 ; r0 = C. + C. + paddsw m0, m7 ; r0 = R0 = G. + C. + psraw m7, 4 ; r7 = NR7 + movq J(6), m6 ; store NR6 at J6 + psraw m0, 4 ; r0 = NR0 + movq J(5), m5 ; store NR5 at J5 + movq J(7), m7 ; store NR7 at J7 + movq I(0), m0 ; store NR0 at I0 +%endmacro + +; Following macro does two 4x4 transposes in place. +; +; At entry (we assume): +; +; r0 = a3 a2 a1 a0 +; I(1) = b3 b2 b1 b0 +; r2 = c3 c2 c1 c0 +; r3 = d3 d2 d1 d0 +; +; r4 = e3 e2 e1 e0 +; r5 = f3 f2 f1 f0 +; r6 = g3 g2 g1 g0 +; r7 = h3 h2 h1 h0 +; +; At exit, we have: +; +; I(0) = d0 c0 b0 a0 +; I(1) = d1 c1 b1 a1 +; I(2) = d2 c2 b2 a2 +; I(3) = d3 c3 b3 a3 +; +; J(4) = h0 g0 f0 e0 +; J(5) = h1 g1 f1 e1 +; J(6) = h2 g2 f2 e2 +; J(7) = h3 g3 f3 e3 +; +; I(0) I(1) I(2) I(3) is the transpose of r0 I(1) r2 r3. +; J(4) J(5) J(6) J(7) is the transpose of r4 r5 r6 r7. +; +; Since r1 is free at entry, we calculate the Js first. +%macro Transpose 0 + movq m1, m4 ; r1 = e3 e2 e1 e0 + punpcklwd m4, m5 ; r4 = f1 e1 f0 e0 + movq I(0), m0 ; save a3 a2 a1 a0 + punpckhwd m1, m5 ; r1 = f3 e3 f2 e2 + movq m0, m6 ; r0 = g3 g2 g1 g0 + punpcklwd m6, m7 ; r6 = h1 g1 h0 g0 + movq m5, m4 ; r5 = f1 e1 f0 e0 + punpckldq m4, m6 ; r4 = h0 g0 f0 e0 = R4 + punpckhdq m5, m6 ; r5 = h1 g1 f1 e1 = R5 + movq m6, m1 ; r6 = f3 e3 f2 e2 + movq J(4), m4 + punpckhwd m0, m7 ; r0 = h3 g3 h2 g2 + movq J(5), m5 + punpckhdq m6, m0 ; r6 = h3 g3 f3 e3 = R7 + movq m4, I(0) ; r4 = a3 a2 a1 a0 + punpckldq m1, m0 ; r1 = h2 g2 f2 e2 = R6 + movq m5, I(1) ; r5 = b3 b2 b1 b0 + movq m0, m4 ; r0 = a3 a2 a1 a0 + movq J(7), m6 + punpcklwd m0, m5 ; r0 = b1 a1 b0 a0 + movq J(6), m1 + punpckhwd m4, m5 ; r4 = b3 a3 b2 a2 + movq m5, m2 ; r5 = c3 c2 c1 c0 + punpcklwd m2, m3 ; r2 = d1 c1 d0 c0 + movq m1, m0 ; r1 = b1 a1 b0 a0 + punpckldq m0, m2 ; r0 = d0 c0 b0 a0 = R0 + punpckhdq m1, m2 ; r1 = d1 c1 b1 a1 = R1 + movq m2, m4 ; r2 = b3 a3 b2 a2 + movq I(0), m0 + punpckhwd m5, m3 ; r5 = d3 c3 d2 c2 + movq I(1), m1 + punpckhdq m4, m5 ; r4 = d3 c3 b3 a3 = R3 + punpckldq m2, m5 ; r2 = d2 c2 b2 a2 = R2 + movq I(3), m4 + movq I(2), m2 +%endmacro + +%macro VP3_1D_IDCT_SSE2 0 + movdqa m2, I(3) ; xmm2 = i3 + movdqa m6, C(3) ; xmm6 = c3 + movdqa m4, m2 ; xmm4 = i3 + movdqa m7, I(5) ; xmm7 = i5 + pmulhw m4, m6 ; xmm4 = c3 * i3 - i3 + movdqa m1, C(5) ; xmm1 = c5 + pmulhw m6, m7 ; xmm6 = c3 * i5 - i5 + movdqa m5, m1 ; xmm5 = c5 + pmulhw m1, m2 ; xmm1 = c5 * i3 - i3 + movdqa m3, I(1) ; xmm3 = i1 + pmulhw m5, m7 ; xmm5 = c5 * i5 - i5 + movdqa m0, C(1) ; xmm0 = c1 + paddw m4, m2 ; xmm4 = c3 * i3 + paddw m6, m7 ; xmm6 = c3 * i5 + paddw m2, m1 ; xmm2 = c5 * i3 + movdqa m1, I(7) ; xmm1 = i7 + paddw m7, m5 ; xmm7 = c5 * i5 + movdqa m5, m0 ; xmm5 = c1 + pmulhw m0, m3 ; xmm0 = c1 * i1 - i1 + paddsw m4, m7 ; xmm4 = c3 * i3 + c5 * i5 = C + pmulhw m5, m1 ; xmm5 = c1 * i7 - i7 + movdqa m7, C(7) ; xmm7 = c7 + psubsw m6, m2 ; xmm6 = c3 * i5 - c5 * i3 = D + paddw m0, m3 ; xmm0 = c1 * i1 + pmulhw m3, m7 ; xmm3 = c7 * i1 + movdqa m2, I(2) ; xmm2 = i2 + pmulhw m7, m1 ; xmm7 = c7 * i7 + paddw m5, m1 ; xmm5 = c1 * i7 + movdqa m1, m2 ; xmm1 = i2 + pmulhw m2, C(2) ; xmm2 = i2 * c2 -i2 + psubsw m3, m5 ; xmm3 = c7 * i1 - c1 * i7 = B + movdqa m5, I(6) ; xmm5 = i6 + paddsw m0, m7 ; xmm0 = c1 * i1 + c7 * i7 = A + movdqa m7, m5 ; xmm7 = i6 + psubsw m0, m4 ; xmm0 = A - C + pmulhw m5, C(2) ; xmm5 = c2 * i6 - i6 + paddw m2, m1 ; xmm2 = i2 * c2 + pmulhw m1, C(6) ; xmm1 = c6 * i2 + paddsw m4, m4 ; xmm4 = C + C + paddsw m4, m0 ; xmm4 = A + C = C. + psubsw m3, m6 ; xmm3 = B - D + paddw m5, m7 ; xmm5 = c2 * i6 + paddsw m6, m6 ; xmm6 = D + D + pmulhw m7, C(6) ; xmm7 = c6 * i6 + paddsw m6, m3 ; xmm6 = B + D = D. + movdqa I(1), m4 ; Save C. at I(1) + psubsw m1, m5 ; xmm1 = c6 * i2 - c2 * i6 = H + movdqa m4, C(4) ; xmm4 = C4 + movdqa m5, m3 ; xmm5 = B - D + pmulhw m3, m4 ; xmm3 = ( c4 -1 ) * ( B - D ) + paddsw m7, m2 ; xmm7 = c2 * i2 + c6 * i6 = G + movdqa I(2), m6 ; save D. at I(2) + movdqa m2, m0 ; xmm2 = A - C + movdqa m6, I(0) ; xmm6 = i0 + pmulhw m0, m4 ; xmm0 = ( c4 - 1 ) * ( A - C ) = A. + paddw m5, m3 ; xmm5 = c4 * ( B - D ) = B. + movdqa m3, I(4) ; xmm3 = i4 + psubsw m5, m1 ; xmm5 = B. - H = B.. + paddw m2, m0 ; xmm2 = c4 * ( A - C) = A. + psubsw m6, m3 ; xmm6 = i0 - i4 + movdqa m0, m6 ; xmm0 = i0 - i4 + pmulhw m6, m4 ; xmm6 = (c4 - 1) * (i0 - i4) = F + paddsw m3, m3 ; xmm3 = i4 + i4 + paddsw m1, m1 ; xmm1 = H + H + paddsw m3, m0 ; xmm3 = i0 + i4 + paddsw m1, m5 ; xmm1 = B. + H = H. + pmulhw m4, m3 ; xmm4 = ( c4 - 1 ) * ( i0 + i4 ) + paddw m6, m0 ; xmm6 = c4 * ( i0 - i4 ) + psubsw m6, m2 ; xmm6 = F - A. = F. + paddsw m2, m2 ; xmm2 = A. + A. + movdqa m0, I(1) ; Load C. from I(1) + paddsw m2, m6 ; xmm2 = F + A. = A.. + paddw m4, m3 ; xmm4 = c4 * ( i0 + i4 ) = 3 + psubsw m2, m1 ; xmm2 = A.. - H. = R2 + ADD(m2) ; Adjust R2 and R1 before shifting + paddsw m1, m1 ; xmm1 = H. + H. + paddsw m1, m2 ; xmm1 = A.. + H. = R1 + SHIFT(m2) ; xmm2 = op2 + psubsw m4, m7 ; xmm4 = E - G = E. + SHIFT(m1) ; xmm1 = op1 + movdqa m3, I(2) ; Load D. from I(2) + paddsw m7, m7 ; xmm7 = G + G + paddsw m7, m4 ; xmm7 = E + G = G. + psubsw m4, m3 ; xmm4 = E. - D. = R4 + ADD(m4) ; Adjust R4 and R3 before shifting + paddsw m3, m3 ; xmm3 = D. + D. + paddsw m3, m4 ; xmm3 = E. + D. = R3 + SHIFT(m4) ; xmm4 = op4 + psubsw m6, m5 ; xmm6 = F. - B..= R6 + SHIFT(m3) ; xmm3 = op3 + ADD(m6) ; Adjust R6 and R5 before shifting + paddsw m5, m5 ; xmm5 = B.. + B.. + paddsw m5, m6 ; xmm5 = F. + B.. = R5 + SHIFT(m6) ; xmm6 = op6 + SHIFT(m5) ; xmm5 = op5 + psubsw m7, m0 ; xmm7 = G. - C. = R7 + ADD(m7) ; Adjust R7 and R0 before shifting + paddsw m0, m0 ; xmm0 = C. + C. + paddsw m0, m7 ; xmm0 = G. + C. + SHIFT(m7) ; xmm7 = op7 + SHIFT(m0) ; xmm0 = op0 +%endmacro + +%macro PUT_BLOCK 8 + movdqa O(0), m%1 + movdqa O(1), m%2 + movdqa O(2), m%3 + movdqa O(3), m%4 + movdqa O(4), m%5 + movdqa O(5), m%6 + movdqa O(6), m%7 + movdqa O(7), m%8 +%endmacro + +%macro VP3_IDCT 1 +%if mmsize == 16 +%define I(x) [%1+16*x] +%define O(x) [%1+16*x] +%define C(x) [vp3_idct_data+16*(x-1)] +%define SHIFT(x) +%define ADD(x) + VP3_1D_IDCT_SSE2 +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%1], [%1+16] +%endif + PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7 + +%define SHIFT(x) psraw x, 4 +%define ADD(x) paddsw x, [pw_8] + VP3_1D_IDCT_SSE2 + PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7 +%else ; mmsize == 8 + ; eax = quantized input + ; ebx = dequantizer matrix + ; ecx = IDCT constants + ; M(I) = ecx + MaskOffset(0) + I * 8 + ; C(I) = ecx + CosineOffset(32) + (I-1) * 8 + ; edx = output + ; r0..r7 = mm0..mm7 +%define OC_8 [pw_8] +%define C(x) [vp3_idct_data+16*(x-1)] + + ; at this point, function has completed dequantization + dezigzag + + ; partial transposition; now do the idct itself +%define I(x) [%1+16*x] +%define J(x) [%1+16*x] + RowIDCT + Transpose + +%define I(x) [%1+16*x+8] +%define J(x) [%1+16*x+8] + RowIDCT + Transpose + +%define I(x) [%1+16* x] +%define J(x) [%1+16*(x-4)+8] + ColumnIDCT + +%define I(x) [%1+16* x +64] +%define J(x) [%1+16*(x-4)+72] + ColumnIDCT +%endif ; mmsize == 16/8 +%endmacro + +%macro vp3_idct_funcs 0 +cglobal vp3_idct_put, 3, 4, 9 + VP3_IDCT r2 + + mova m4, [pb_80] + lea r3, [r1*3] +%assign %%i 0 +%rep 16/mmsize + mova m0, [r2+mmsize*0+%%i] + mova m1, [r2+mmsize*2+%%i] + mova m2, [r2+mmsize*4+%%i] + mova m3, [r2+mmsize*6+%%i] +%if mmsize == 8 + packsswb m0, [r2+mmsize*8+%%i] + packsswb m1, [r2+mmsize*10+%%i] + packsswb m2, [r2+mmsize*12+%%i] + packsswb m3, [r2+mmsize*14+%%i] +%else + packsswb m0, [r2+mmsize*1+%%i] + packsswb m1, [r2+mmsize*3+%%i] + packsswb m2, [r2+mmsize*5+%%i] + packsswb m3, [r2+mmsize*7+%%i] +%endif + paddb m0, m4 + paddb m1, m4 + paddb m2, m4 + paddb m3, m4 + movq [r0 ], m0 +%if mmsize == 8 + movq [r0+r1 ], m1 + movq [r0+r1*2], m2 + movq [r0+r3 ], m3 +%else + movhps [r0+r1 ], m0 + movq [r0+r1*2], m1 + movhps [r0+r3 ], m1 +%endif +%if %%i == 0 + lea r0, [r0+r1*4] +%endif +%if mmsize == 16 + movq [r0 ], m2 + movhps [r0+r1 ], m2 + movq [r0+r1*2], m3 + movhps [r0+r3 ], m3 +%endif +%assign %%i %%i+8 +%endrep + + pxor m0, m0 +%assign %%offset 0 +%rep 128/mmsize + mova [r2+%%offset], m0 +%assign %%offset %%offset+mmsize +%endrep + RET + +cglobal vp3_idct_add, 3, 4, 9 + VP3_IDCT r2 + + lea r3, [r1*3] + pxor m4, m4 +%if mmsize == 16 +%assign %%i 0 +%rep 2 + movq m0, [r0] + movq m1, [r0+r1] + movq m2, [r0+r1*2] + movq m3, [r0+r3] + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpcklbw m3, m4 + paddsw m0, [r2+ 0+%%i] + paddsw m1, [r2+16+%%i] + paddsw m2, [r2+32+%%i] + paddsw m3, [r2+48+%%i] + packuswb m0, m1 + packuswb m2, m3 + movq [r0 ], m0 + movhps [r0+r1 ], m0 + movq [r0+r1*2], m2 + movhps [r0+r3 ], m2 +%if %%i == 0 + lea r0, [r0+r1*4] +%endif +%assign %%i %%i+64 +%endrep +%else +%assign %%i 0 +%rep 2 + movq m0, [r0] + movq m1, [r0+r1] + movq m2, [r0+r1*2] + movq m3, [r0+r3] + movq m5, m0 + movq m6, m1 + movq m7, m2 + punpcklbw m0, m4 + punpcklbw m1, m4 + punpcklbw m2, m4 + punpckhbw m5, m4 + punpckhbw m6, m4 + punpckhbw m7, m4 + paddsw m0, [r2+ 0+%%i] + paddsw m1, [r2+16+%%i] + paddsw m2, [r2+32+%%i] + paddsw m5, [r2+64+%%i] + paddsw m6, [r2+80+%%i] + paddsw m7, [r2+96+%%i] + packuswb m0, m5 + movq m5, m3 + punpcklbw m3, m4 + punpckhbw m5, m4 + packuswb m1, m6 + paddsw m3, [r2+48+%%i] + paddsw m5, [r2+112+%%i] + packuswb m2, m7 + packuswb m3, m5 + movq [r0 ], m0 + movq [r0+r1 ], m1 + movq [r0+r1*2], m2 + movq [r0+r3 ], m3 +%if %%i == 0 + lea r0, [r0+r1*4] +%endif +%assign %%i %%i+8 +%endrep +%endif +%assign %%i 0 +%rep 128/mmsize + mova [r2+%%i], m4 +%assign %%i %%i+mmsize +%endrep + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +vp3_idct_funcs +%endif + +INIT_XMM sse2 +vp3_idct_funcs + +%macro DC_ADD 0 + movq m2, [r0 ] + movq m3, [r0+r1 ] + paddusb m2, m0 + movq m4, [r0+r1*2] + paddusb m3, m0 + movq m5, [r0+r2 ] + paddusb m4, m0 + paddusb m5, m0 + psubusb m2, m1 + psubusb m3, m1 + movq [r0 ], m2 + psubusb m4, m1 + movq [r0+r1 ], m3 + psubusb m5, m1 + movq [r0+r1*2], m4 + movq [r0+r2 ], m5 +%endmacro + +INIT_MMX mmxext +cglobal vp3_idct_dc_add, 3, 4 + movsx r3, word [r2] + mov word [r2], 0 + lea r2, [r1*3] + add r3, 15 + sar r3, 5 + movd m0, r3d + pshufw m0, m0, 0x0 + pxor m1, m1 + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 + DC_ADD + lea r0, [r0+r1*4] + DC_ADD + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp3dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp3dsp_init.c new file mode 100644 index 00000000..ba47e1c6 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp3dsp_init.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009 David Conrad + * + * 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 + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/avcodec.h" +#include "libavcodec/vp3dsp.h" + +void ff_vp3_idct_put_mmx(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vp3_idct_add_mmx(uint8_t *dest, ptrdiff_t stride, int16_t *block); + +void ff_vp3_idct_put_sse2(uint8_t *dest, ptrdiff_t stride, int16_t *block); +void ff_vp3_idct_add_sse2(uint8_t *dest, ptrdiff_t stride, int16_t *block); + +void ff_vp3_idct_dc_add_mmxext(uint8_t *dest, ptrdiff_t stride, int16_t *block); + +void ff_vp3_v_loop_filter_mmxext(uint8_t *src, ptrdiff_t stride, + int *bounding_values); +void ff_vp3_h_loop_filter_mmxext(uint8_t *src, ptrdiff_t stride, + int *bounding_values); + +void ff_put_vp_no_rnd_pixels8_l2_mmx(uint8_t *dst, const uint8_t *a, + const uint8_t *b, ptrdiff_t stride, + int h); + +av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->put_no_rnd_pixels_l2 = ff_put_vp_no_rnd_pixels8_l2_mmx; +#if ARCH_X86_32 + c->idct_put = ff_vp3_idct_put_mmx; + c->idct_add = ff_vp3_idct_add_mmx; +#endif + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_dc_add = ff_vp3_idct_dc_add_mmxext; + + if (!(flags & AV_CODEC_FLAG_BITEXACT)) { + c->v_loop_filter = c->v_loop_filter_unaligned = ff_vp3_v_loop_filter_mmxext; + c->h_loop_filter = c->v_loop_filter_unaligned = ff_vp3_h_loop_filter_mmxext; + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_vp3_idct_put_sse2; + c->idct_add = ff_vp3_idct_add_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp56_arith.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp56_arith.h new file mode 100644 index 00000000..810cc8dc --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp56_arith.h @@ -0,0 +1,51 @@ +/** + * VP5 and VP6 compatible video decoder (arith decoder) + * + * Copyright (C) 2006 Aurelien Jacobs + * Copyright (C) 2010 Eli Friedman + * + * 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 + */ + +#ifndef AVCODEC_X86_VP56_ARITH_H +#define AVCODEC_X86_VP56_ARITH_H + +#if HAVE_INLINE_ASM && HAVE_FAST_CMOV && HAVE_6REGS +#define vp56_rac_get_prob vp56_rac_get_prob +static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) +{ + unsigned int code_word = vp56_rac_renorm(c); + unsigned int low = 1 + (((c->high - 1) * prob) >> 8); + unsigned int low_shift = low << 16; + int bit = 0; + c->code_word = code_word; + + __asm__( + "subl %4, %1 \n\t" + "subl %3, %2 \n\t" + "setae %b0 \n\t" + "cmovb %4, %1 \n\t" + "cmovb %5, %2 \n\t" + : "+q"(bit), "+&r"(c->high), "+&r"(c->code_word) + : "r"(low_shift), "r"(low), "r"(code_word) + ); + + return bit; +} +#endif + +#endif /* AVCODEC_X86_VP56_ARITH_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp6dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp6dsp.asm new file mode 100644 index 00000000..0be531e5 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp6dsp.asm @@ -0,0 +1,167 @@ +;****************************************************************************** +;* MMX/SSE2-optimized functions for the VP6 decoder +;* Copyright (C) 2009 Sebastien Lucas +;* Copyright (C) 2009 Zuxy Meng +;* +;* 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 "libavutil/x86/x86util.asm" + +cextern pw_64 + +SECTION .text + +%macro DIAG4 6 +%if mmsize == 8 + movq m0, [%1+%2] + movq m1, [%1+%3] + movq m3, m0 + movq m4, m1 + punpcklbw m0, m7 + punpcklbw m1, m7 + punpckhbw m3, m7 + punpckhbw m4, m7 + pmullw m0, [rsp+8*11] ; src[x-8 ] * biweight [0] + pmullw m1, [rsp+8*12] ; src[x ] * biweight [1] + pmullw m3, [rsp+8*11] ; src[x-8 ] * biweight [0] + pmullw m4, [rsp+8*12] ; src[x ] * biweight [1] + paddw m0, m1 + paddw m3, m4 + movq m1, [%1+%4] + movq m2, [%1+%5] + movq m4, m1 + movq m5, m2 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpckhbw m4, m7 + punpckhbw m5, m7 + pmullw m1, [rsp+8*13] ; src[x+8 ] * biweight [2] + pmullw m2, [rsp+8*14] ; src[x+16] * biweight [3] + pmullw m4, [rsp+8*13] ; src[x+8 ] * biweight [2] + pmullw m5, [rsp+8*14] ; src[x+16] * biweight [3] + paddw m1, m2 + paddw m4, m5 + paddsw m0, m1 + paddsw m3, m4 + paddsw m0, m6 ; Add 64 + paddsw m3, m6 ; Add 64 + psraw m0, 7 + psraw m3, 7 + packuswb m0, m3 + movq [%6], m0 +%else ; mmsize == 16 + movq m0, [%1+%2] + movq m1, [%1+%3] + punpcklbw m0, m7 + punpcklbw m1, m7 + pmullw m0, m4 ; src[x-8 ] * biweight [0] + pmullw m1, m5 ; src[x ] * biweight [1] + paddw m0, m1 + movq m1, [%1+%4] + movq m2, [%1+%5] + punpcklbw m1, m7 + punpcklbw m2, m7 + pmullw m1, m6 ; src[x+8 ] * biweight [2] + pmullw m2, m3 ; src[x+16] * biweight [3] + paddw m1, m2 + paddsw m0, m1 + paddsw m0, [pw_64] ; Add 64 + psraw m0, 7 + packuswb m0, m0 + movq [%6], m0 +%endif ; mmsize == 8/16 +%endmacro + +%macro SPLAT4REGS 0 +%if mmsize == 8 + movq m5, m3 + punpcklwd m3, m3 + movq m4, m3 + punpckldq m3, m3 + punpckhdq m4, m4 + punpckhwd m5, m5 + movq m2, m5 + punpckhdq m2, m2 + punpckldq m5, m5 + movq [rsp+8*11], m3 + movq [rsp+8*12], m4 + movq [rsp+8*13], m5 + movq [rsp+8*14], m2 +%else ; mmsize == 16 + pshuflw m4, m3, 0x0 + pshuflw m5, m3, 0x55 + pshuflw m6, m3, 0xAA + pshuflw m3, m3, 0xFF + punpcklqdq m4, m4 + punpcklqdq m5, m5 + punpcklqdq m6, m6 + punpcklqdq m3, m3 +%endif ; mmsize == 8/16 +%endmacro + +%macro vp6_filter_diag4 0 +; void ff_vp6_filter_diag4_(uint8_t *dst, uint8_t *src, ptrdiff_t stride, +; const int16_t h_weight[4], const int16_t v_weights[4]) +cglobal vp6_filter_diag4, 5, 7, 8 + mov r5, rsp ; backup stack pointer + and rsp, ~(mmsize-1) ; align stack +%if mmsize == 16 + sub rsp, 8*11 +%else + sub rsp, 8*15 + movq m6, [pw_64] +%endif + + sub r1, r2 + + pxor m7, m7 + movq m3, [r3] + SPLAT4REGS + + mov r3, rsp + mov r6, 11 +.nextrow: + DIAG4 r1, -1, 0, 1, 2, r3 + add r3, 8 + add r1, r2 + dec r6 + jnz .nextrow + + movq m3, [r4] + SPLAT4REGS + + lea r3, [rsp+8] + mov r6, 8 +.nextcol: + DIAG4 r3, -8, 0, 8, 16, r0 + add r3, 8 + add r0, r2 + dec r6 + jnz .nextcol + + mov rsp, r5 ; restore stack pointer + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +vp6_filter_diag4 +%endif + +INIT_XMM sse2 +vp6_filter_diag4 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp6dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp6dsp_init.c new file mode 100644 index 00000000..ce498931 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp6dsp_init.c @@ -0,0 +1,45 @@ +/* + * VP6 MMX/SSE2 optimizations + * Copyright (C) 2009 Sebastien Lucas + * Copyright (C) 2009 Zuxy Meng + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp56dsp.h" + +void ff_vp6_filter_diag4_mmx(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + const int16_t *h_weights,const int16_t *v_weights); +void ff_vp6_filter_diag4_sse2(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + const int16_t *h_weights,const int16_t *v_weights); + +av_cold void ff_vp6dsp_init_x86(VP56DSPContext *c) +{ + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) { + c->vp6_filter_diag4 = ff_vp6_filter_diag4_mmx; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + c->vp6_filter_diag4 = ff_vp6_filter_diag4_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp.asm new file mode 100644 index 00000000..75de5690 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp.asm @@ -0,0 +1,1231 @@ +;****************************************************************************** +;* VP8 MMXEXT optimizations +;* Copyright (c) 2010 Ronald S. Bultje +;* Copyright (c) 2010 Fiona Glaser +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +fourtap_filter_hw_m: times 4 dw -6, 123 + times 4 dw 12, -1 + times 4 dw -9, 93 + times 4 dw 50, -6 + times 4 dw -6, 50 + times 4 dw 93, -9 + times 4 dw -1, 12 + times 4 dw 123, -6 + +sixtap_filter_hw_m: times 4 dw 2, -11 + times 4 dw 108, 36 + times 4 dw -8, 1 + times 4 dw 3, -16 + times 4 dw 77, 77 + times 4 dw -16, 3 + times 4 dw 1, -8 + times 4 dw 36, 108 + times 4 dw -11, 2 + +fourtap_filter_hb_m: times 8 db -6, 123 + times 8 db 12, -1 + times 8 db -9, 93 + times 8 db 50, -6 + times 8 db -6, 50 + times 8 db 93, -9 + times 8 db -1, 12 + times 8 db 123, -6 + +sixtap_filter_hb_m: times 8 db 2, 1 + times 8 db -11, 108 + times 8 db 36, -8 + times 8 db 3, 3 + times 8 db -16, 77 + times 8 db 77, -16 + times 8 db 1, 2 + times 8 db -8, 36 + times 8 db 108, -11 + +fourtap_filter_v_m: times 8 dw -6 + times 8 dw 123 + times 8 dw 12 + times 8 dw -1 + times 8 dw -9 + times 8 dw 93 + times 8 dw 50 + times 8 dw -6 + times 8 dw -6 + times 8 dw 50 + times 8 dw 93 + times 8 dw -9 + times 8 dw -1 + times 8 dw 12 + times 8 dw 123 + times 8 dw -6 + +sixtap_filter_v_m: times 8 dw 2 + times 8 dw -11 + times 8 dw 108 + times 8 dw 36 + times 8 dw -8 + times 8 dw 1 + times 8 dw 3 + times 8 dw -16 + times 8 dw 77 + times 8 dw 77 + times 8 dw -16 + times 8 dw 3 + times 8 dw 1 + times 8 dw -8 + times 8 dw 36 + times 8 dw 108 + times 8 dw -11 + times 8 dw 2 + +bilinear_filter_vw_m: times 8 dw 1 + times 8 dw 2 + times 8 dw 3 + times 8 dw 4 + times 8 dw 5 + times 8 dw 6 + times 8 dw 7 + +bilinear_filter_vb_m: times 8 db 7, 1 + times 8 db 6, 2 + times 8 db 5, 3 + times 8 db 4, 4 + times 8 db 3, 5 + times 8 db 2, 6 + times 8 db 1, 7 + +%ifdef PIC +%define fourtap_filter_hw picregq +%define sixtap_filter_hw picregq +%define fourtap_filter_hb picregq +%define sixtap_filter_hb picregq +%define fourtap_filter_v picregq +%define sixtap_filter_v picregq +%define bilinear_filter_vw picregq +%define bilinear_filter_vb picregq +%define npicregs 1 +%else +%define fourtap_filter_hw fourtap_filter_hw_m +%define sixtap_filter_hw sixtap_filter_hw_m +%define fourtap_filter_hb fourtap_filter_hb_m +%define sixtap_filter_hb sixtap_filter_hb_m +%define fourtap_filter_v fourtap_filter_v_m +%define sixtap_filter_v sixtap_filter_v_m +%define bilinear_filter_vw bilinear_filter_vw_m +%define bilinear_filter_vb bilinear_filter_vb_m +%define npicregs 0 +%endif + +filter_h2_shuf: db 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8 +filter_h4_shuf: db 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10 + +filter_h6_shuf1: db 0, 5, 1, 6, 2, 7, 3, 8, 4, 9, 5, 10, 6, 11, 7, 12 +filter_h6_shuf2: db 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9 +filter_h6_shuf3: db 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11 + +pw_20091: times 4 dw 20091 +pw_17734: times 4 dw 17734 + +cextern pw_3 +cextern pw_4 +cextern pw_64 +cextern pw_256 + +SECTION .text + +;------------------------------------------------------------------------------- +; subpel MC functions: +; +; void ff_put_vp8_epel_hv_(uint8_t *dst, ptrdiff_t deststride, +; uint8_t *src, ptrdiff_t srcstride, +; int height, int mx, int my); +;------------------------------------------------------------------------------- + +%macro FILTER_SSSE3 1 +cglobal put_vp8_epel%1_h6, 6, 6 + npicregs, 8, dst, dststride, src, srcstride, height, mx, picreg + lea mxd, [mxq*3] + mova m3, [filter_h6_shuf2] + mova m4, [filter_h6_shuf3] +%ifdef PIC + lea picregq, [sixtap_filter_hb_m] +%endif + mova m5, [sixtap_filter_hb+mxq*8-48] ; set up 6tap filter in bytes + mova m6, [sixtap_filter_hb+mxq*8-32] + mova m7, [sixtap_filter_hb+mxq*8-16] + +.nextrow: + movu m0, [srcq-2] + mova m1, m0 + mova m2, m0 +%if mmsize == 8 +; For epel4, we need 9 bytes, but only 8 get loaded; to compensate, do the +; shuffle with a memory operand + punpcklbw m0, [srcq+3] +%else + pshufb m0, [filter_h6_shuf1] +%endif + pshufb m1, m3 + pshufb m2, m4 + pmaddubsw m0, m5 + pmaddubsw m1, m6 + pmaddubsw m2, m7 + paddsw m0, m1 + paddsw m0, m2 + pmulhrsw m0, [pw_256] + packuswb m0, m0 + movh [dstq], m0 ; store + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +cglobal put_vp8_epel%1_h4, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg + shl mxd, 4 + mova m2, [pw_256] + mova m3, [filter_h2_shuf] + mova m4, [filter_h4_shuf] +%ifdef PIC + lea picregq, [fourtap_filter_hb_m] +%endif + mova m5, [fourtap_filter_hb+mxq-16] ; set up 4tap filter in bytes + mova m6, [fourtap_filter_hb+mxq] + +.nextrow: + movu m0, [srcq-1] + mova m1, m0 + pshufb m0, m3 + pshufb m1, m4 + pmaddubsw m0, m5 + pmaddubsw m1, m6 + paddsw m0, m1 + pmulhrsw m0, m2 + packuswb m0, m0 + movh [dstq], m0 ; store + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my + shl myd, 4 +%ifdef PIC + lea picregq, [fourtap_filter_hb_m] +%endif + mova m5, [fourtap_filter_hb+myq-16] + mova m6, [fourtap_filter_hb+myq] + mova m7, [pw_256] + + ; read 3 lines + sub srcq, srcstrideq + movh m0, [srcq] + movh m1, [srcq+ srcstrideq] + movh m2, [srcq+2*srcstrideq] + add srcq, srcstrideq + +.nextrow: + movh m3, [srcq+2*srcstrideq] ; read new row + mova m4, m0 + mova m0, m1 + punpcklbw m4, m1 + mova m1, m2 + punpcklbw m2, m3 + pmaddubsw m4, m5 + pmaddubsw m2, m6 + paddsw m4, m2 + mova m2, m3 + pmulhrsw m4, m7 + packuswb m4, m4 + movh [dstq], m4 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my + lea myd, [myq*3] +%ifdef PIC + lea picregq, [sixtap_filter_hb_m] +%endif + lea myq, [sixtap_filter_hb+myq*8] + + ; read 5 lines + sub srcq, srcstrideq + sub srcq, srcstrideq + movh m0, [srcq] + movh m1, [srcq+srcstrideq] + movh m2, [srcq+srcstrideq*2] + lea srcq, [srcq+srcstrideq*2] + add srcq, srcstrideq + movh m3, [srcq] + movh m4, [srcq+srcstrideq] + +.nextrow: + movh m5, [srcq+2*srcstrideq] ; read new row + mova m6, m0 + punpcklbw m6, m5 + mova m0, m1 + punpcklbw m1, m2 + mova m7, m3 + punpcklbw m7, m4 + pmaddubsw m6, [myq-48] + pmaddubsw m1, [myq-32] + pmaddubsw m7, [myq-16] + paddsw m6, m1 + paddsw m6, m7 + mova m1, m2 + mova m2, m3 + pmulhrsw m6, [pw_256] + mova m3, m4 + packuswb m6, m6 + mova m4, m5 + movh [dstq], m6 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET +%endmacro + +INIT_MMX ssse3 +FILTER_SSSE3 4 +INIT_XMM ssse3 +FILTER_SSSE3 8 + +; 4x4 block, H-only 4-tap filter +INIT_MMX mmxext +cglobal put_vp8_epel4_h4, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, height, mx, picreg + shl mxd, 4 +%ifdef PIC + lea picregq, [fourtap_filter_hw_m] +%endif + movq mm4, [fourtap_filter_hw+mxq-16] ; set up 4tap filter in words + movq mm5, [fourtap_filter_hw+mxq] + movq mm7, [pw_64] + pxor mm6, mm6 + +.nextrow: + movq mm1, [srcq-1] ; (ABCDEFGH) load 8 horizontal pixels + + ; first set of 2 pixels + movq mm2, mm1 ; byte ABCD.. + punpcklbw mm1, mm6 ; byte->word ABCD + pshufw mm0, mm2, 9 ; byte CDEF.. + punpcklbw mm0, mm6 ; byte->word CDEF + pshufw mm3, mm1, 0x94 ; word ABBC + pshufw mm1, mm0, 0x94 ; word CDDE + pmaddwd mm3, mm4 ; multiply 2px with F0/F1 + movq mm0, mm1 ; backup for second set of pixels + pmaddwd mm1, mm5 ; multiply 2px with F2/F3 + paddd mm3, mm1 ; finish 1st 2px + + ; second set of 2 pixels, use backup of above + punpckhbw mm2, mm6 ; byte->word EFGH + pmaddwd mm0, mm4 ; multiply backed up 2px with F0/F1 + pshufw mm1, mm2, 0x94 ; word EFFG + pmaddwd mm1, mm5 ; multiply 2px with F2/F3 + paddd mm0, mm1 ; finish 2nd 2px + + ; merge two sets of 2 pixels into one set of 4, round/clip/store + packssdw mm3, mm0 ; merge dword->word (4px) + paddsw mm3, mm7 ; rounding + psraw mm3, 7 + packuswb mm3, mm6 ; clip and word->bytes + movd [dstq], mm3 ; store + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +; 4x4 block, H-only 6-tap filter +INIT_MMX mmxext +cglobal put_vp8_epel4_h6, 6, 6 + npicregs, 0, dst, dststride, src, srcstride, height, mx, picreg + lea mxd, [mxq*3] +%ifdef PIC + lea picregq, [sixtap_filter_hw_m] +%endif + movq mm4, [sixtap_filter_hw+mxq*8-48] ; set up 4tap filter in words + movq mm5, [sixtap_filter_hw+mxq*8-32] + movq mm6, [sixtap_filter_hw+mxq*8-16] + movq mm7, [pw_64] + pxor mm3, mm3 + +.nextrow: + movq mm1, [srcq-2] ; (ABCDEFGH) load 8 horizontal pixels + + ; first set of 2 pixels + movq mm2, mm1 ; byte ABCD.. + punpcklbw mm1, mm3 ; byte->word ABCD + pshufw mm0, mm2, 0x9 ; byte CDEF.. + punpckhbw mm2, mm3 ; byte->word EFGH + punpcklbw mm0, mm3 ; byte->word CDEF + pshufw mm1, mm1, 0x94 ; word ABBC + pshufw mm2, mm2, 0x94 ; word EFFG + pmaddwd mm1, mm4 ; multiply 2px with F0/F1 + pshufw mm3, mm0, 0x94 ; word CDDE + movq mm0, mm3 ; backup for second set of pixels + pmaddwd mm3, mm5 ; multiply 2px with F2/F3 + paddd mm1, mm3 ; add to 1st 2px cache + movq mm3, mm2 ; backup for second set of pixels + pmaddwd mm2, mm6 ; multiply 2px with F4/F5 + paddd mm1, mm2 ; finish 1st 2px + + ; second set of 2 pixels, use backup of above + movd mm2, [srcq+3] ; byte FGHI (prevent overreads) + pmaddwd mm0, mm4 ; multiply 1st backed up 2px with F0/F1 + pmaddwd mm3, mm5 ; multiply 2nd backed up 2px with F2/F3 + paddd mm0, mm3 ; add to 2nd 2px cache + pxor mm3, mm3 + punpcklbw mm2, mm3 ; byte->word FGHI + pshufw mm2, mm2, 0xE9 ; word GHHI + pmaddwd mm2, mm6 ; multiply 2px with F4/F5 + paddd mm0, mm2 ; finish 2nd 2px + + ; merge two sets of 2 pixels into one set of 4, round/clip/store + packssdw mm1, mm0 ; merge dword->word (4px) + paddsw mm1, mm7 ; rounding + psraw mm1, 7 + packuswb mm1, mm3 ; clip and word->bytes + movd [dstq], mm1 ; store + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +INIT_XMM sse2 +cglobal put_vp8_epel8_h4, 6, 6 + npicregs, 10, dst, dststride, src, srcstride, height, mx, picreg + shl mxd, 5 +%ifdef PIC + lea picregq, [fourtap_filter_v_m] +%endif + lea mxq, [fourtap_filter_v+mxq-32] + pxor m7, m7 + mova m4, [pw_64] + mova m5, [mxq+ 0] + mova m6, [mxq+16] +%ifdef m8 + mova m8, [mxq+32] + mova m9, [mxq+48] +%endif +.nextrow: + movq m0, [srcq-1] + movq m1, [srcq-0] + movq m2, [srcq+1] + movq m3, [srcq+2] + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + pmullw m0, m5 + pmullw m1, m6 +%ifdef m8 + pmullw m2, m8 + pmullw m3, m9 +%else + pmullw m2, [mxq+32] + pmullw m3, [mxq+48] +%endif + paddsw m0, m1 + paddsw m2, m3 + paddsw m0, m2 + paddsw m0, m4 + psraw m0, 7 + packuswb m0, m7 + movh [dstq], m0 ; store + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +INIT_XMM sse2 +cglobal put_vp8_epel8_h6, 6, 6 + npicregs, 14, dst, dststride, src, srcstride, height, mx, picreg + lea mxd, [mxq*3] + shl mxd, 4 +%ifdef PIC + lea picregq, [sixtap_filter_v_m] +%endif + lea mxq, [sixtap_filter_v+mxq-96] + pxor m7, m7 + mova m6, [pw_64] +%ifdef m8 + mova m8, [mxq+ 0] + mova m9, [mxq+16] + mova m10, [mxq+32] + mova m11, [mxq+48] + mova m12, [mxq+64] + mova m13, [mxq+80] +%endif +.nextrow: + movq m0, [srcq-2] + movq m1, [srcq-1] + movq m2, [srcq-0] + movq m3, [srcq+1] + movq m4, [srcq+2] + movq m5, [srcq+3] + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + punpcklbw m5, m7 +%ifdef m8 + pmullw m0, m8 + pmullw m1, m9 + pmullw m2, m10 + pmullw m3, m11 + pmullw m4, m12 + pmullw m5, m13 +%else + pmullw m0, [mxq+ 0] + pmullw m1, [mxq+16] + pmullw m2, [mxq+32] + pmullw m3, [mxq+48] + pmullw m4, [mxq+64] + pmullw m5, [mxq+80] +%endif + paddsw m1, m4 + paddsw m0, m5 + paddsw m1, m2 + paddsw m0, m3 + paddsw m0, m1 + paddsw m0, m6 + psraw m0, 7 + packuswb m0, m7 + movh [dstq], m0 ; store + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + +%macro FILTER_V 1 +; 4x4 block, V-only 4-tap filter +cglobal put_vp8_epel%1_v4, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my + shl myd, 5 +%ifdef PIC + lea picregq, [fourtap_filter_v_m] +%endif + lea myq, [fourtap_filter_v+myq-32] + mova m6, [pw_64] + pxor m7, m7 + mova m5, [myq+48] + + ; read 3 lines + sub srcq, srcstrideq + movh m0, [srcq] + movh m1, [srcq+ srcstrideq] + movh m2, [srcq+2*srcstrideq] + add srcq, srcstrideq + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + +.nextrow: + ; first calculate negative taps (to prevent losing positive overflows) + movh m4, [srcq+2*srcstrideq] ; read new row + punpcklbw m4, m7 + mova m3, m4 + pmullw m0, [myq+0] + pmullw m4, m5 + paddsw m4, m0 + + ; then calculate positive taps + mova m0, m1 + pmullw m1, [myq+16] + paddsw m4, m1 + mova m1, m2 + pmullw m2, [myq+32] + paddsw m4, m2 + mova m2, m3 + + ; round/clip/store + paddsw m4, m6 + psraw m4, 7 + packuswb m4, m7 + movh [dstq], m4 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET + + +; 4x4 block, V-only 6-tap filter +cglobal put_vp8_epel%1_v6, 7, 7, 8, dst, dststride, src, srcstride, height, picreg, my + shl myd, 4 + lea myq, [myq*3] +%ifdef PIC + lea picregq, [sixtap_filter_v_m] +%endif + lea myq, [sixtap_filter_v+myq-96] + pxor m7, m7 + + ; read 5 lines + sub srcq, srcstrideq + sub srcq, srcstrideq + movh m0, [srcq] + movh m1, [srcq+srcstrideq] + movh m2, [srcq+srcstrideq*2] + lea srcq, [srcq+srcstrideq*2] + add srcq, srcstrideq + movh m3, [srcq] + movh m4, [srcq+srcstrideq] + punpcklbw m0, m7 + punpcklbw m1, m7 + punpcklbw m2, m7 + punpcklbw m3, m7 + punpcklbw m4, m7 + +.nextrow: + ; first calculate negative taps (to prevent losing positive overflows) + mova m5, m1 + pmullw m5, [myq+16] + mova m6, m4 + pmullw m6, [myq+64] + paddsw m6, m5 + + ; then calculate positive taps + movh m5, [srcq+2*srcstrideq] ; read new row + punpcklbw m5, m7 + pmullw m0, [myq+0] + paddsw m6, m0 + mova m0, m1 + mova m1, m2 + pmullw m2, [myq+32] + paddsw m6, m2 + mova m2, m3 + pmullw m3, [myq+48] + paddsw m6, m3 + mova m3, m4 + mova m4, m5 + pmullw m5, [myq+80] + paddsw m6, m5 + + ; round/clip/store + paddsw m6, [pw_64] + psraw m6, 7 + packuswb m6, m7 + movh [dstq], m6 + + ; go to next line + add dstq, dststrideq + add srcq, srcstrideq + dec heightd ; next row + jg .nextrow + REP_RET +%endmacro + +INIT_MMX mmxext +FILTER_V 4 +INIT_XMM sse2 +FILTER_V 8 + +%macro FILTER_BILINEAR 1 +%if cpuflag(ssse3) +cglobal put_vp8_bilinear%1_v, 7, 7, 5, dst, dststride, src, srcstride, height, picreg, my + shl myd, 4 +%ifdef PIC + lea picregq, [bilinear_filter_vb_m] +%endif + pxor m4, m4 + mova m3, [bilinear_filter_vb+myq-16] +.nextrow: + movh m0, [srcq+srcstrideq*0] + movh m1, [srcq+srcstrideq*1] + movh m2, [srcq+srcstrideq*2] + punpcklbw m0, m1 + punpcklbw m1, m2 + pmaddubsw m0, m3 + pmaddubsw m1, m3 + psraw m0, 2 + psraw m1, 2 + pavgw m0, m4 + pavgw m1, m4 +%if mmsize==8 + packuswb m0, m0 + packuswb m1, m1 + movh [dstq+dststrideq*0], m0 + movh [dstq+dststrideq*1], m1 +%else + packuswb m0, m1 + movh [dstq+dststrideq*0], m0 + movhps [dstq+dststrideq*1], m0 +%endif +%else ; cpuflag(ssse3) +cglobal put_vp8_bilinear%1_v, 7, 7, 7, dst, dststride, src, srcstride, height, picreg, my + shl myd, 4 +%ifdef PIC + lea picregq, [bilinear_filter_vw_m] +%endif + pxor m6, m6 + mova m5, [bilinear_filter_vw+myq-1*16] + neg myq + mova m4, [bilinear_filter_vw+myq+7*16] +.nextrow: + movh m0, [srcq+srcstrideq*0] + movh m1, [srcq+srcstrideq*1] + movh m3, [srcq+srcstrideq*2] + punpcklbw m0, m6 + punpcklbw m1, m6 + punpcklbw m3, m6 + mova m2, m1 + pmullw m0, m4 + pmullw m1, m5 + pmullw m2, m4 + pmullw m3, m5 + paddsw m0, m1 + paddsw m2, m3 + psraw m0, 2 + psraw m2, 2 + pavgw m0, m6 + pavgw m2, m6 +%if mmsize == 8 + packuswb m0, m0 + packuswb m2, m2 + movh [dstq+dststrideq*0], m0 + movh [dstq+dststrideq*1], m2 +%else + packuswb m0, m2 + movh [dstq+dststrideq*0], m0 + movhps [dstq+dststrideq*1], m0 +%endif +%endif ; cpuflag(ssse3) + + lea dstq, [dstq+dststrideq*2] + lea srcq, [srcq+srcstrideq*2] + sub heightd, 2 + jg .nextrow + REP_RET + +%if cpuflag(ssse3) +cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 5, dst, dststride, src, srcstride, height, mx, picreg + shl mxd, 4 +%ifdef PIC + lea picregq, [bilinear_filter_vb_m] +%endif + pxor m4, m4 + mova m2, [filter_h2_shuf] + mova m3, [bilinear_filter_vb+mxq-16] +.nextrow: + movu m0, [srcq+srcstrideq*0] + movu m1, [srcq+srcstrideq*1] + pshufb m0, m2 + pshufb m1, m2 + pmaddubsw m0, m3 + pmaddubsw m1, m3 + psraw m0, 2 + psraw m1, 2 + pavgw m0, m4 + pavgw m1, m4 +%if mmsize==8 + packuswb m0, m0 + packuswb m1, m1 + movh [dstq+dststrideq*0], m0 + movh [dstq+dststrideq*1], m1 +%else + packuswb m0, m1 + movh [dstq+dststrideq*0], m0 + movhps [dstq+dststrideq*1], m0 +%endif +%else ; cpuflag(ssse3) +cglobal put_vp8_bilinear%1_h, 6, 6 + npicregs, 7, dst, dststride, src, srcstride, height, mx, picreg + shl mxd, 4 +%ifdef PIC + lea picregq, [bilinear_filter_vw_m] +%endif + pxor m6, m6 + mova m5, [bilinear_filter_vw+mxq-1*16] + neg mxq + mova m4, [bilinear_filter_vw+mxq+7*16] +.nextrow: + movh m0, [srcq+srcstrideq*0+0] + movh m1, [srcq+srcstrideq*0+1] + movh m2, [srcq+srcstrideq*1+0] + movh m3, [srcq+srcstrideq*1+1] + punpcklbw m0, m6 + punpcklbw m1, m6 + punpcklbw m2, m6 + punpcklbw m3, m6 + pmullw m0, m4 + pmullw m1, m5 + pmullw m2, m4 + pmullw m3, m5 + paddsw m0, m1 + paddsw m2, m3 + psraw m0, 2 + psraw m2, 2 + pavgw m0, m6 + pavgw m2, m6 +%if mmsize == 8 + packuswb m0, m0 + packuswb m2, m2 + movh [dstq+dststrideq*0], m0 + movh [dstq+dststrideq*1], m2 +%else + packuswb m0, m2 + movh [dstq+dststrideq*0], m0 + movhps [dstq+dststrideq*1], m0 +%endif +%endif ; cpuflag(ssse3) + + lea dstq, [dstq+dststrideq*2] + lea srcq, [srcq+srcstrideq*2] + sub heightd, 2 + jg .nextrow + REP_RET +%endmacro + +INIT_MMX mmxext +FILTER_BILINEAR 4 +INIT_XMM sse2 +FILTER_BILINEAR 8 +INIT_MMX ssse3 +FILTER_BILINEAR 4 +INIT_XMM ssse3 +FILTER_BILINEAR 8 + +INIT_MMX mmx +cglobal put_vp8_pixels8, 5, 5, 0, dst, dststride, src, srcstride, height +.nextrow: + movq mm0, [srcq+srcstrideq*0] + movq mm1, [srcq+srcstrideq*1] + lea srcq, [srcq+srcstrideq*2] + movq [dstq+dststrideq*0], mm0 + movq [dstq+dststrideq*1], mm1 + lea dstq, [dstq+dststrideq*2] + sub heightd, 2 + jg .nextrow + REP_RET + +%if ARCH_X86_32 +INIT_MMX mmx +cglobal put_vp8_pixels16, 5, 5, 0, dst, dststride, src, srcstride, height +.nextrow: + movq mm0, [srcq+srcstrideq*0+0] + movq mm1, [srcq+srcstrideq*0+8] + movq mm2, [srcq+srcstrideq*1+0] + movq mm3, [srcq+srcstrideq*1+8] + lea srcq, [srcq+srcstrideq*2] + movq [dstq+dststrideq*0+0], mm0 + movq [dstq+dststrideq*0+8], mm1 + movq [dstq+dststrideq*1+0], mm2 + movq [dstq+dststrideq*1+8], mm3 + lea dstq, [dstq+dststrideq*2] + sub heightd, 2 + jg .nextrow + REP_RET +%endif + +INIT_XMM sse +cglobal put_vp8_pixels16, 5, 5, 2, dst, dststride, src, srcstride, height +.nextrow: + movups xmm0, [srcq+srcstrideq*0] + movups xmm1, [srcq+srcstrideq*1] + lea srcq, [srcq+srcstrideq*2] + movaps [dstq+dststrideq*0], xmm0 + movaps [dstq+dststrideq*1], xmm1 + lea dstq, [dstq+dststrideq*2] + sub heightd, 2 + jg .nextrow + REP_RET + +;----------------------------------------------------------------------------- +; void ff_vp8_idct_dc_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +;----------------------------------------------------------------------------- + +%macro ADD_DC 4 + %4 m2, [dst1q+%3] + %4 m3, [dst1q+strideq+%3] + %4 m4, [dst2q+%3] + %4 m5, [dst2q+strideq+%3] + paddusb m2, %1 + paddusb m3, %1 + paddusb m4, %1 + paddusb m5, %1 + psubusb m2, %2 + psubusb m3, %2 + psubusb m4, %2 + psubusb m5, %2 + %4 [dst1q+%3], m2 + %4 [dst1q+strideq+%3], m3 + %4 [dst2q+%3], m4 + %4 [dst2q+strideq+%3], m5 +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +cglobal vp8_idct_dc_add, 3, 3, 0, dst, block, stride + ; load data + movd m0, [blockq] + + ; calculate DC + paddw m0, [pw_4] + pxor m1, m1 + psraw m0, 3 + movd [blockq], m1 + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 + punpcklbw m0, m0 + punpcklbw m1, m1 + punpcklwd m0, m0 + punpcklwd m1, m1 + + ; add DC + DEFINE_ARGS dst1, dst2, stride + lea dst2q, [dst1q+strideq*2] + ADD_DC m0, m1, 0, movh + RET +%endif + +%macro VP8_IDCT_DC_ADD 0 +cglobal vp8_idct_dc_add, 3, 3, 6, dst, block, stride + ; load data + movd m0, [blockq] + pxor m1, m1 + + ; calculate DC + paddw m0, [pw_4] + movd [blockq], m1 + DEFINE_ARGS dst1, dst2, stride + lea dst2q, [dst1q+strideq*2] + movd m2, [dst1q] + movd m3, [dst1q+strideq] + movd m4, [dst2q] + movd m5, [dst2q+strideq] + psraw m0, 3 + pshuflw m0, m0, 0 + punpcklqdq m0, m0 + punpckldq m2, m3 + punpckldq m4, m5 + punpcklbw m2, m1 + punpcklbw m4, m1 + paddw m2, m0 + paddw m4, m0 + packuswb m2, m4 + movd [dst1q], m2 +%if cpuflag(sse4) + pextrd [dst1q+strideq], m2, 1 + pextrd [dst2q], m2, 2 + pextrd [dst2q+strideq], m2, 3 +%else + psrldq m2, 4 + movd [dst1q+strideq], m2 + psrldq m2, 4 + movd [dst2q], m2 + psrldq m2, 4 + movd [dst2q+strideq], m2 +%endif + RET +%endmacro + +INIT_XMM sse2 +VP8_IDCT_DC_ADD +INIT_XMM sse4 +VP8_IDCT_DC_ADD + +;----------------------------------------------------------------------------- +; void ff_vp8_idct_dc_add4y_(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); +;----------------------------------------------------------------------------- + +%if ARCH_X86_32 +INIT_MMX mmx +cglobal vp8_idct_dc_add4y, 3, 3, 0, dst, block, stride + ; load data + movd m0, [blockq+32*0] ; A + movd m1, [blockq+32*2] ; C + punpcklwd m0, [blockq+32*1] ; A B + punpcklwd m1, [blockq+32*3] ; C D + punpckldq m0, m1 ; A B C D + pxor m6, m6 + + ; calculate DC + paddw m0, [pw_4] + movd [blockq+32*0], m6 + movd [blockq+32*1], m6 + movd [blockq+32*2], m6 + movd [blockq+32*3], m6 + psraw m0, 3 + psubw m6, m0 + packuswb m0, m0 + packuswb m6, m6 + punpcklbw m0, m0 ; AABBCCDD + punpcklbw m6, m6 ; AABBCCDD + movq m1, m0 + movq m7, m6 + punpcklbw m0, m0 ; AAAABBBB + punpckhbw m1, m1 ; CCCCDDDD + punpcklbw m6, m6 ; AAAABBBB + punpckhbw m7, m7 ; CCCCDDDD + + ; add DC + DEFINE_ARGS dst1, dst2, stride + lea dst2q, [dst1q+strideq*2] + ADD_DC m0, m6, 0, mova + ADD_DC m1, m7, 8, mova + RET +%endif + +INIT_XMM sse2 +cglobal vp8_idct_dc_add4y, 3, 3, 6, dst, block, stride + ; load data + movd m0, [blockq+32*0] ; A + movd m1, [blockq+32*2] ; C + punpcklwd m0, [blockq+32*1] ; A B + punpcklwd m1, [blockq+32*3] ; C D + punpckldq m0, m1 ; A B C D + pxor m1, m1 + + ; calculate DC + paddw m0, [pw_4] + movd [blockq+32*0], m1 + movd [blockq+32*1], m1 + movd [blockq+32*2], m1 + movd [blockq+32*3], m1 + psraw m0, 3 + psubw m1, m0 + packuswb m0, m0 + packuswb m1, m1 + punpcklbw m0, m0 + punpcklbw m1, m1 + punpcklbw m0, m0 + punpcklbw m1, m1 + + ; add DC + DEFINE_ARGS dst1, dst2, stride + lea dst2q, [dst1q+strideq*2] + ADD_DC m0, m1, 0, mova + RET + +;----------------------------------------------------------------------------- +; void ff_vp8_idct_dc_add4uv_(uint8_t *dst, int16_t block[4][16], ptrdiff_t stride); +;----------------------------------------------------------------------------- + +INIT_MMX mmx +cglobal vp8_idct_dc_add4uv, 3, 3, 0, dst, block, stride + ; load data + movd m0, [blockq+32*0] ; A + movd m1, [blockq+32*2] ; C + punpcklwd m0, [blockq+32*1] ; A B + punpcklwd m1, [blockq+32*3] ; C D + punpckldq m0, m1 ; A B C D + pxor m6, m6 + + ; calculate DC + paddw m0, [pw_4] + movd [blockq+32*0], m6 + movd [blockq+32*1], m6 + movd [blockq+32*2], m6 + movd [blockq+32*3], m6 + psraw m0, 3 + psubw m6, m0 + packuswb m0, m0 + packuswb m6, m6 + punpcklbw m0, m0 ; AABBCCDD + punpcklbw m6, m6 ; AABBCCDD + movq m1, m0 + movq m7, m6 + punpcklbw m0, m0 ; AAAABBBB + punpckhbw m1, m1 ; CCCCDDDD + punpcklbw m6, m6 ; AAAABBBB + punpckhbw m7, m7 ; CCCCDDDD + + ; add DC + DEFINE_ARGS dst1, dst2, stride + lea dst2q, [dst1q+strideq*2] + ADD_DC m0, m6, 0, mova + lea dst1q, [dst1q+strideq*4] + lea dst2q, [dst2q+strideq*4] + ADD_DC m1, m7, 0, mova + RET + +;----------------------------------------------------------------------------- +; void ff_vp8_idct_add_(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +;----------------------------------------------------------------------------- + +; calculate %1=mul_35468(%1)-mul_20091(%2); %2=mul_20091(%1)+mul_35468(%2) +; this macro assumes that m6/m7 have words for 20091/17734 loaded +%macro VP8_MULTIPLY_SUMSUB 4 + mova %3, %1 + mova %4, %2 + pmulhw %3, m6 ;20091(1) + pmulhw %4, m6 ;20091(2) + paddw %3, %1 + paddw %4, %2 + paddw %1, %1 + paddw %2, %2 + pmulhw %1, m7 ;35468(1) + pmulhw %2, m7 ;35468(2) + psubw %1, %4 + paddw %2, %3 +%endmacro + +; calculate x0=%1+%3; x1=%1-%3 +; x2=mul_35468(%2)-mul_20091(%4); x3=mul_20091(%2)+mul_35468(%4) +; %1=x0+x3 (tmp0); %2=x1+x2 (tmp1); %3=x1-x2 (tmp2); %4=x0-x3 (tmp3) +; %5/%6 are temporary registers +; we assume m6/m7 have constant words 20091/17734 loaded in them +%macro VP8_IDCT_TRANSFORM4x4_1D 6 + SUMSUB_BA w, %3, %1, %5 ;t0, t1 + VP8_MULTIPLY_SUMSUB m%2, m%4, m%5,m%6 ;t2, t3 + SUMSUB_BA w, %4, %3, %5 ;tmp0, tmp3 + SUMSUB_BA w, %2, %1, %5 ;tmp1, tmp2 + SWAP %4, %1 + SWAP %4, %3 +%endmacro + +%macro VP8_IDCT_ADD 0 +cglobal vp8_idct_add, 3, 3, 0, dst, block, stride + ; load block data + movq m0, [blockq+ 0] + movq m1, [blockq+ 8] + movq m2, [blockq+16] + movq m3, [blockq+24] + movq m6, [pw_20091] + movq m7, [pw_17734] +%if cpuflag(sse) + xorps xmm0, xmm0 + movaps [blockq+ 0], xmm0 + movaps [blockq+16], xmm0 +%else + pxor m4, m4 + movq [blockq+ 0], m4 + movq [blockq+ 8], m4 + movq [blockq+16], m4 + movq [blockq+24], m4 +%endif + + ; actual IDCT + VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4, 5 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + paddw m0, [pw_4] + VP8_IDCT_TRANSFORM4x4_1D 0, 1, 2, 3, 4, 5 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + + ; store + pxor m4, m4 + DEFINE_ARGS dst1, dst2, stride + lea dst2q, [dst1q+2*strideq] + STORE_DIFFx2 m0, m1, m6, m7, m4, 3, dst1q, strideq + STORE_DIFFx2 m2, m3, m6, m7, m4, 3, dst2q, strideq + + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +VP8_IDCT_ADD +%endif +INIT_MMX sse +VP8_IDCT_ADD + +;----------------------------------------------------------------------------- +; void ff_vp8_luma_dc_wht(int16_t block[4][4][16], int16_t dc[16]) +;----------------------------------------------------------------------------- + +%macro SCATTER_WHT 3 + movd dc1d, m%1 + movd dc2d, m%2 + mov [blockq+2*16*(0+%3)], dc1w + mov [blockq+2*16*(1+%3)], dc2w + shr dc1d, 16 + shr dc2d, 16 + psrlq m%1, 32 + psrlq m%2, 32 + mov [blockq+2*16*(4+%3)], dc1w + mov [blockq+2*16*(5+%3)], dc2w + movd dc1d, m%1 + movd dc2d, m%2 + mov [blockq+2*16*(8+%3)], dc1w + mov [blockq+2*16*(9+%3)], dc2w + shr dc1d, 16 + shr dc2d, 16 + mov [blockq+2*16*(12+%3)], dc1w + mov [blockq+2*16*(13+%3)], dc2w +%endmacro + +%macro HADAMARD4_1D 4 + SUMSUB_BADC w, %2, %1, %4, %3 + SUMSUB_BADC w, %4, %2, %3, %1 + SWAP %1, %4, %3 +%endmacro + +%macro VP8_DC_WHT 0 +cglobal vp8_luma_dc_wht, 2, 3, 0, block, dc1, dc2 + movq m0, [dc1q] + movq m1, [dc1q+8] + movq m2, [dc1q+16] + movq m3, [dc1q+24] +%if cpuflag(sse) + xorps xmm0, xmm0 + movaps [dc1q+ 0], xmm0 + movaps [dc1q+16], xmm0 +%else + pxor m4, m4 + movq [dc1q+ 0], m4 + movq [dc1q+ 8], m4 + movq [dc1q+16], m4 + movq [dc1q+24], m4 +%endif + HADAMARD4_1D 0, 1, 2, 3 + TRANSPOSE4x4W 0, 1, 2, 3, 4 + paddw m0, [pw_3] + HADAMARD4_1D 0, 1, 2, 3 + psraw m0, 3 + psraw m1, 3 + psraw m2, 3 + psraw m3, 3 + SCATTER_WHT 0, 1, 0 + SCATTER_WHT 2, 3, 2 + RET +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +VP8_DC_WHT +%endif +INIT_MMX sse +VP8_DC_WHT diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp_init.c new file mode 100644 index 00000000..dffa7a24 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp_init.c @@ -0,0 +1,468 @@ +/* + * VP8 DSP functions x86-optimized + * Copyright (c) 2010 Ronald S. Bultje + * Copyright (c) 2010 Fiona Glaser + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/mem_internal.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp8dsp.h" + +#if HAVE_X86ASM + +/* + * MC functions + */ +void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_h_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_v_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + + +void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); +void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, + int height, int mx, int my); + +#define TAP_W16(OPT, FILTERTYPE, TAPTYPE) \ +static void ff_put_vp8_ ## FILTERTYPE ## 16_ ## TAPTYPE ## _ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ + dst, dststride, src, srcstride, height, mx, my); \ + ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ + dst + 8, dststride, src + 8, srcstride, height, mx, my); \ +} +#define TAP_W8(OPT, FILTERTYPE, TAPTYPE) \ +static void ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + ff_put_vp8_ ## FILTERTYPE ## 4_ ## TAPTYPE ## _ ## OPT( \ + dst, dststride, src, srcstride, height, mx, my); \ + ff_put_vp8_ ## FILTERTYPE ## 4_ ## TAPTYPE ## _ ## OPT( \ + dst + 4, dststride, src + 4, srcstride, height, mx, my); \ +} + +#if ARCH_X86_32 +TAP_W8 (mmxext, epel, h4) +TAP_W8 (mmxext, epel, h6) +TAP_W16(mmxext, epel, h6) +TAP_W8 (mmxext, epel, v4) +TAP_W8 (mmxext, epel, v6) +TAP_W16(mmxext, epel, v6) +TAP_W8 (mmxext, bilinear, h) +TAP_W16(mmxext, bilinear, h) +TAP_W8 (mmxext, bilinear, v) +TAP_W16(mmxext, bilinear, v) +#endif + +TAP_W16(sse2, epel, h6) +TAP_W16(sse2, epel, v6) +TAP_W16(sse2, bilinear, h) +TAP_W16(sse2, bilinear, v) + +TAP_W16(ssse3, epel, h6) +TAP_W16(ssse3, epel, v6) +TAP_W16(ssse3, bilinear, h) +TAP_W16(ssse3, bilinear, v) + +#define HVTAP(OPT, ALIGN, TAPNUMX, TAPNUMY, SIZE, MAXHEIGHT) \ +static void ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## v ## TAPNUMY ## _ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + LOCAL_ALIGNED(ALIGN, uint8_t, tmp, [SIZE * (MAXHEIGHT + TAPNUMY - 1)]); \ + uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \ + src -= srcstride * (TAPNUMY / 2 - 1); \ + ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## _ ## OPT( \ + tmp, SIZE, src, srcstride, height + TAPNUMY - 1, mx, my); \ + ff_put_vp8_epel ## SIZE ## _v ## TAPNUMY ## _ ## OPT( \ + dst, dststride, tmpptr, SIZE, height, mx, my); \ +} + +#if ARCH_X86_32 +#define HVTAPMMX(x, y) \ +HVTAP(mmxext, 8, x, y, 4, 8) \ +HVTAP(mmxext, 8, x, y, 8, 16) + +HVTAP(mmxext, 8, 6, 6, 16, 16) +#else +#define HVTAPMMX(x, y) \ +HVTAP(mmxext, 8, x, y, 4, 8) +#endif + +HVTAPMMX(4, 4) +HVTAPMMX(4, 6) +HVTAPMMX(6, 4) +HVTAPMMX(6, 6) + +#define HVTAPSSE2(x, y, w) \ +HVTAP(sse2, 16, x, y, w, 16) \ +HVTAP(ssse3, 16, x, y, w, 16) + +HVTAPSSE2(4, 4, 8) +HVTAPSSE2(4, 6, 8) +HVTAPSSE2(6, 4, 8) +HVTAPSSE2(6, 6, 8) +HVTAPSSE2(6, 6, 16) + +HVTAP(ssse3, 16, 4, 4, 4, 8) +HVTAP(ssse3, 16, 4, 6, 4, 8) +HVTAP(ssse3, 16, 6, 4, 4, 8) +HVTAP(ssse3, 16, 6, 6, 4, 8) + +#define HVBILIN(OPT, ALIGN, SIZE, MAXHEIGHT) \ +static void ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT( \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ +{ \ + LOCAL_ALIGNED(ALIGN, uint8_t, tmp, [SIZE * (MAXHEIGHT + 2)]); \ + ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT( \ + tmp, SIZE, src, srcstride, height + 1, mx, my); \ + ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT( \ + dst, dststride, tmp, SIZE, height, mx, my); \ +} + +HVBILIN(mmxext, 8, 4, 8) +#if ARCH_X86_32 +HVBILIN(mmxext, 8, 8, 16) +HVBILIN(mmxext, 8, 16, 16) +#endif +HVBILIN(sse2, 8, 8, 16) +HVBILIN(sse2, 8, 16, 16) +HVBILIN(ssse3, 8, 4, 8) +HVBILIN(ssse3, 8, 8, 16) +HVBILIN(ssse3, 8, 16, 16) + +void ff_vp8_idct_dc_add_mmx(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse2(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add_sse4(uint8_t *dst, int16_t block[16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, int16_t block[4][16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, int16_t block[4][16], + ptrdiff_t stride); +void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, int16_t block[2][16], + ptrdiff_t stride); +void ff_vp8_luma_dc_wht_mmx(int16_t block[4][4][16], int16_t dc[16]); +void ff_vp8_luma_dc_wht_sse(int16_t block[4][4][16], int16_t dc[16]); +void ff_vp8_idct_add_mmx(uint8_t *dst, int16_t block[16], ptrdiff_t stride); +void ff_vp8_idct_add_sse(uint8_t *dst, int16_t block[16], ptrdiff_t stride); + +#define DECLARE_LOOP_FILTER(NAME) \ +void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim); \ +void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim); \ +void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int e, int i, int hvt); \ +void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); \ +void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV, \ + ptrdiff_t s, \ + int e, int i, int hvt); + +DECLARE_LOOP_FILTER(mmx) +DECLARE_LOOP_FILTER(mmxext) +DECLARE_LOOP_FILTER(sse2) +DECLARE_LOOP_FILTER(ssse3) +DECLARE_LOOP_FILTER(sse4) + +#endif /* HAVE_X86ASM */ + +#define VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) \ + c->put_vp8_epel_pixels_tab[IDX][0][2] = ff_put_vp8_epel ## SIZE ## _h6_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][2][0] = ff_put_vp8_epel ## SIZE ## _v6_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][2][2] = ff_put_vp8_epel ## SIZE ## _h6v6_ ## OPT + +#define VP8_MC_FUNC(IDX, SIZE, OPT) \ + c->put_vp8_epel_pixels_tab[IDX][0][1] = ff_put_vp8_epel ## SIZE ## _h4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][1][0] = ff_put_vp8_epel ## SIZE ## _v4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][1][1] = ff_put_vp8_epel ## SIZE ## _h4v4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][1][2] = ff_put_vp8_epel ## SIZE ## _h6v4_ ## OPT; \ + c->put_vp8_epel_pixels_tab[IDX][2][1] = ff_put_vp8_epel ## SIZE ## _h4v6_ ## OPT; \ + VP8_LUMA_MC_FUNC(IDX, SIZE, OPT) + +#define VP8_BILINEAR_MC_FUNC(IDX, SIZE, OPT) \ + c->put_vp8_bilinear_pixels_tab[IDX][0][1] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][0][2] = ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][1][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][1][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][1][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][2][0] = ff_put_vp8_bilinear ## SIZE ## _v_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][2][1] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT; \ + c->put_vp8_bilinear_pixels_tab[IDX][2][2] = ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT + + +av_cold void ff_vp78dsp_init_x86(VP8DSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { +#if ARCH_X86_32 + c->put_vp8_epel_pixels_tab[0][0][0] = + c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmx; +#endif + c->put_vp8_epel_pixels_tab[1][0][0] = + c->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmx; + } + + /* note that 4-tap width=16 functions are missing because w=16 + * is only used for luma, and luma is always a copy or sixtap. */ + if (EXTERNAL_MMXEXT(cpu_flags)) { + VP8_MC_FUNC(2, 4, mmxext); + VP8_BILINEAR_MC_FUNC(2, 4, mmxext); +#if ARCH_X86_32 + VP8_LUMA_MC_FUNC(0, 16, mmxext); + VP8_MC_FUNC(1, 8, mmxext); + VP8_BILINEAR_MC_FUNC(0, 16, mmxext); + VP8_BILINEAR_MC_FUNC(1, 8, mmxext); +#endif + } + + if (EXTERNAL_SSE(cpu_flags)) { + c->put_vp8_epel_pixels_tab[0][0][0] = + c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_sse; + } + + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { + VP8_LUMA_MC_FUNC(0, 16, sse2); + VP8_MC_FUNC(1, 8, sse2); + VP8_BILINEAR_MC_FUNC(0, 16, sse2); + VP8_BILINEAR_MC_FUNC(1, 8, sse2); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + VP8_LUMA_MC_FUNC(0, 16, ssse3); + VP8_MC_FUNC(1, 8, ssse3); + VP8_MC_FUNC(2, 4, ssse3); + VP8_BILINEAR_MC_FUNC(0, 16, ssse3); + VP8_BILINEAR_MC_FUNC(1, 8, ssse3); + VP8_BILINEAR_MC_FUNC(2, 4, ssse3); + } +#endif /* HAVE_X86ASM */ +} + +av_cold void ff_vp8dsp_init_x86(VP8DSPContext *c) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx; +#if ARCH_X86_32 + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; + c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx; + c->vp8_idct_add = ff_vp8_idct_add_mmx; + c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmx; + + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmx; + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmx; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmx; + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmx; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmx; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmx; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmx; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmx; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmx; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmx; +#endif + } + + /* note that 4-tap width=16 functions are missing because w=16 + * is only used for luma, and luma is always a copy or sixtap. */ + if (EXTERNAL_MMXEXT(cpu_flags)) { +#if ARCH_X86_32 + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmxext; + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmxext; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_mmxext; + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_mmxext; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_mmxext; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_mmxext; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_mmxext; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmxext; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmxext; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmxext; +#endif + } + + if (EXTERNAL_SSE(cpu_flags)) { + c->vp8_idct_add = ff_vp8_idct_add_sse; + c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_sse; + } + + if (EXTERNAL_SSE2(cpu_flags) || EXTERNAL_SSE2_SLOW(cpu_flags)) { + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_sse2; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_sse2; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_sse2; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_sse2; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_sse2; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse2; + c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_sse2; + + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse2; + + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_sse2; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_sse2; + + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse2; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse2; + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_ssse3; + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_ssse3; + + c->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16y_inner_ssse3; + c->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16y_inner_ssse3; + c->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_ssse3; + c->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_ssse3; + + c->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16y_mbedge_ssse3; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_ssse3; + c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_ssse3; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_ssse3; + } + + if (EXTERNAL_SSE4(cpu_flags)) { + c->vp8_idct_dc_add = ff_vp8_idct_dc_add_sse4; + + c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_sse4; + c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_sse4; + c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_sse4; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp_loopfilter.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp_loopfilter.asm new file mode 100644 index 00000000..caeb4052 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp8dsp_loopfilter.asm @@ -0,0 +1,1584 @@ +;****************************************************************************** +;* VP8 MMXEXT optimizations +;* Copyright (c) 2010 Ronald S. Bultje +;* Copyright (c) 2010 Fiona Glaser +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pw_27: times 8 dw 27 +pw_63: times 8 dw 63 + +pb_4: times 16 db 4 +pb_F8: times 16 db 0xF8 +pb_FE: times 16 db 0xFE +pb_27_63: times 8 db 27, 63 +pb_18_63: times 8 db 18, 63 +pb_9_63: times 8 db 9, 63 + +cextern pb_1 +cextern pb_3 +cextern pw_9 +cextern pw_18 +cextern pb_80 + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_vp8_h/v_loop_filter_simple_(uint8_t *dst, ptrdiff_t stride, int flim); +;----------------------------------------------------------------------------- + +; macro called with 7 mm register indexes as argument, and 4 regular registers +; +; first 4 mm registers will carry the transposed pixel data +; the other three are scratchspace (one would be sufficient, but this allows +; for more spreading/pipelining and thus faster execution on OOE CPUs) +; +; first two regular registers are buf+4*stride and buf+5*stride +; third is -stride, fourth is +stride +%macro READ_8x4_INTERLEAVED 11 + ; interleave 8 (A-H) rows of 4 pixels each + movd m%1, [%8+%10*4] ; A0-3 + movd m%5, [%9+%10*4] ; B0-3 + movd m%2, [%8+%10*2] ; C0-3 + movd m%6, [%8+%10] ; D0-3 + movd m%3, [%8] ; E0-3 + movd m%7, [%9] ; F0-3 + movd m%4, [%9+%11] ; G0-3 + punpcklbw m%1, m%5 ; A/B interleaved + movd m%5, [%9+%11*2] ; H0-3 + punpcklbw m%2, m%6 ; C/D interleaved + punpcklbw m%3, m%7 ; E/F interleaved + punpcklbw m%4, m%5 ; G/H interleaved +%endmacro + +; macro called with 7 mm register indexes as argument, and 5 regular registers +; first 11 mean the same as READ_8x4_TRANSPOSED above +; fifth regular register is scratchspace to reach the bottom 8 rows, it +; will be set to second regular register + 8*stride at the end +%macro READ_16x4_INTERLEAVED 12 + ; transpose 16 (A-P) rows of 4 pixels each + lea %12, [r0+8*r2] + + ; read (and interleave) those addressable by %8 (=r0), A/C/D/E/I/K/L/M + movd m%1, [%8+%10*4] ; A0-3 + movd m%3, [%12+%10*4] ; I0-3 + movd m%2, [%8+%10*2] ; C0-3 + movd m%4, [%12+%10*2] ; K0-3 + movd m%6, [%8+%10] ; D0-3 + movd m%5, [%12+%10] ; L0-3 + movd m%7, [%12] ; M0-3 + add %12, %11 + punpcklbw m%1, m%3 ; A/I + movd m%3, [%8] ; E0-3 + punpcklbw m%2, m%4 ; C/K + punpcklbw m%6, m%5 ; D/L + punpcklbw m%3, m%7 ; E/M + punpcklbw m%2, m%6 ; C/D/K/L interleaved + + ; read (and interleave) those addressable by %9 (=r4), B/F/G/H/J/N/O/P + movd m%5, [%9+%10*4] ; B0-3 + movd m%4, [%12+%10*4] ; J0-3 + movd m%7, [%9] ; F0-3 + movd m%6, [%12] ; N0-3 + punpcklbw m%5, m%4 ; B/J + punpcklbw m%7, m%6 ; F/N + punpcklbw m%1, m%5 ; A/B/I/J interleaved + punpcklbw m%3, m%7 ; E/F/M/N interleaved + movd m%4, [%9+%11] ; G0-3 + movd m%6, [%12+%11] ; O0-3 + movd m%5, [%9+%11*2] ; H0-3 + movd m%7, [%12+%11*2] ; P0-3 + punpcklbw m%4, m%6 ; G/O + punpcklbw m%5, m%7 ; H/P + punpcklbw m%4, m%5 ; G/H/O/P interleaved +%endmacro + +; write 4 mm registers of 2 dwords each +; first four arguments are mm register indexes containing source data +; last four are registers containing buf+4*stride, buf+5*stride, +; -stride and +stride +%macro WRITE_4x2D 8 + ; write out (2 dwords per register) + movd [%5+%7*4], m%1 + movd [%5+%7*2], m%2 + movd [%5], m%3 + movd [%6+%8], m%4 + punpckhdq m%1, m%1 + punpckhdq m%2, m%2 + punpckhdq m%3, m%3 + punpckhdq m%4, m%4 + movd [%6+%7*4], m%1 + movd [%5+%7], m%2 + movd [%6], m%3 + movd [%6+%8*2], m%4 +%endmacro + +; write 4 xmm registers of 4 dwords each +; arguments same as WRITE_2x4D, but with an extra register, so that the 5 regular +; registers contain buf+4*stride, buf+5*stride, buf+12*stride, -stride and +stride +; we add 1*stride to the third regular registry in the process +; the 10th argument is 16 if it's a Y filter (i.e. all regular registers cover the +; same memory region), or 8 if they cover two separate buffers (third one points to +; a different memory region than the first two), allowing for more optimal code for +; the 16-width case +%macro WRITE_4x4D 10 + ; write out (4 dwords per register), start with dwords zero + movd [%5+%8*4], m%1 + movd [%5], m%2 + movd [%7+%8*4], m%3 + movd [%7], m%4 + + ; store dwords 1 + psrldq m%1, 4 + psrldq m%2, 4 + psrldq m%3, 4 + psrldq m%4, 4 + movd [%6+%8*4], m%1 + movd [%6], m%2 +%if %10 == 16 + movd [%6+%9*4], m%3 +%endif + movd [%7+%9], m%4 + + ; write dwords 2 + psrldq m%1, 4 + psrldq m%2, 4 +%if %10 == 8 + movd [%5+%8*2], m%1 + movd %5d, m%3 +%endif + psrldq m%3, 4 + psrldq m%4, 4 +%if %10 == 16 + movd [%5+%8*2], m%1 +%endif + movd [%6+%9], m%2 + movd [%7+%8*2], m%3 + movd [%7+%9*2], m%4 + add %7, %9 + + ; store dwords 3 + psrldq m%1, 4 + psrldq m%2, 4 + psrldq m%3, 4 + psrldq m%4, 4 +%if %10 == 8 + mov [%7+%8*4], %5d + movd [%6+%8*2], m%1 +%else + movd [%5+%8], m%1 +%endif + movd [%6+%9*2], m%2 + movd [%7+%8*2], m%3 + movd [%7+%9*2], m%4 +%endmacro + +; write 4 or 8 words in the mmx/xmm registers as 8 lines +; 1 and 2 are the registers to write, this can be the same (for SSE2) +; for pre-SSE4: +; 3 is a general-purpose register that we will clobber +; for SSE4: +; 3 is a pointer to the destination's 5th line +; 4 is a pointer to the destination's 4th line +; 5/6 is -stride and +stride +%macro WRITE_2x4W 6 + movd %3d, %1 + punpckhdq %1, %1 + mov [%4+%5*4], %3w + shr %3, 16 + add %4, %6 + mov [%4+%5*4], %3w + + movd %3d, %1 + add %4, %5 + mov [%4+%5*2], %3w + shr %3, 16 + mov [%4+%5 ], %3w + + movd %3d, %2 + punpckhdq %2, %2 + mov [%4 ], %3w + shr %3, 16 + mov [%4+%6 ], %3w + + movd %3d, %2 + add %4, %6 + mov [%4+%6 ], %3w + shr %3, 16 + mov [%4+%6*2], %3w + add %4, %5 +%endmacro + +%macro WRITE_8W 5 +%if cpuflag(sse4) + pextrw [%3+%4*4], %1, 0 + pextrw [%2+%4*4], %1, 1 + pextrw [%3+%4*2], %1, 2 + pextrw [%3+%4 ], %1, 3 + pextrw [%3 ], %1, 4 + pextrw [%2 ], %1, 5 + pextrw [%2+%5 ], %1, 6 + pextrw [%2+%5*2], %1, 7 +%else + movd %2d, %1 + psrldq %1, 4 + mov [%3+%4*4], %2w + shr %2, 16 + add %3, %5 + mov [%3+%4*4], %2w + + movd %2d, %1 + psrldq %1, 4 + add %3, %4 + mov [%3+%4*2], %2w + shr %2, 16 + mov [%3+%4 ], %2w + + movd %2d, %1 + psrldq %1, 4 + mov [%3 ], %2w + shr %2, 16 + mov [%3+%5 ], %2w + + movd %2d, %1 + add %3, %5 + mov [%3+%5 ], %2w + shr %2, 16 + mov [%3+%5*2], %2w +%endif +%endmacro + +%macro SIMPLE_LOOPFILTER 2 +cglobal vp8_%1_loop_filter_simple, 3, %2, 8, dst, stride, flim, cntr +%if mmsize == 8 ; mmx/mmxext + mov cntrq, 2 +%endif +%if cpuflag(ssse3) + pxor m0, m0 +%endif + SPLATB_REG m7, flim, m0 ; splat "flim" into register + + ; set up indexes to address 4 rows +%if mmsize == 8 + DEFINE_ARGS dst1, mstride, stride, cntr, dst2 +%else + DEFINE_ARGS dst1, mstride, stride, dst3, dst2 +%endif + mov strideq, mstrideq + neg mstrideq +%ifidn %1, h + lea dst1q, [dst1q+4*strideq-2] +%endif + +%if mmsize == 8 ; mmx / mmxext +.next8px: +%endif +%ifidn %1, v + ; read 4 half/full rows of pixels + mova m0, [dst1q+mstrideq*2] ; p1 + mova m1, [dst1q+mstrideq] ; p0 + mova m2, [dst1q] ; q0 + mova m3, [dst1q+ strideq] ; q1 +%else ; h + lea dst2q, [dst1q+ strideq] + +%if mmsize == 8 ; mmx/mmxext + READ_8x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq +%else ; sse2 + READ_16x4_INTERLEAVED 0, 1, 2, 3, 4, 5, 6, dst1q, dst2q, mstrideq, strideq, dst3q +%endif + TRANSPOSE4x4W 0, 1, 2, 3, 4 +%endif + + ; simple_limit + mova m5, m2 ; m5=backup of q0 + mova m6, m1 ; m6=backup of p0 + psubusb m1, m2 ; p0-q0 + psubusb m2, m6 ; q0-p0 + por m1, m2 ; FFABS(p0-q0) + paddusb m1, m1 ; m1=FFABS(p0-q0)*2 + + mova m4, m3 + mova m2, m0 + psubusb m3, m0 ; q1-p1 + psubusb m0, m4 ; p1-q1 + por m3, m0 ; FFABS(p1-q1) + mova m0, [pb_80] + pxor m2, m0 + pxor m4, m0 + psubsb m2, m4 ; m2=p1-q1 (signed) backup for below + pand m3, [pb_FE] + psrlq m3, 1 ; m3=FFABS(p1-q1)/2, this can be used signed + paddusb m3, m1 + psubusb m3, m7 + pxor m1, m1 + pcmpeqb m3, m1 ; abs(p0-q0)*2+abs(p1-q1)/2<=flim mask(0xff/0x0) + + ; filter_common (use m2/p1-q1, m4=q0, m6=p0, m5/q0-p0 and m3/mask) + mova m4, m5 + pxor m5, m0 + pxor m0, m6 + psubsb m5, m0 ; q0-p0 (signed) + paddsb m2, m5 + paddsb m2, m5 + paddsb m2, m5 ; a=(p1-q1) + 3*(q0-p0) + pand m2, m3 ; apply filter mask (m3) + + mova m3, [pb_F8] + mova m1, m2 + paddsb m2, [pb_4] ; f1<<3=a+4 + paddsb m1, [pb_3] ; f2<<3=a+3 + pand m2, m3 + pand m1, m3 ; cache f2<<3 + + pxor m0, m0 + pxor m3, m3 + pcmpgtb m0, m2 ; which values are <0? + psubb m3, m2 ; -f1<<3 + psrlq m2, 3 ; +f1 + psrlq m3, 3 ; -f1 + pand m3, m0 + pandn m0, m2 + psubusb m4, m0 + paddusb m4, m3 ; q0-f1 + + pxor m0, m0 + pxor m3, m3 + pcmpgtb m0, m1 ; which values are <0? + psubb m3, m1 ; -f2<<3 + psrlq m1, 3 ; +f2 + psrlq m3, 3 ; -f2 + pand m3, m0 + pandn m0, m1 + paddusb m6, m0 + psubusb m6, m3 ; p0+f2 + + ; store +%ifidn %1, v + mova [dst1q], m4 + mova [dst1q+mstrideq], m6 +%else ; h + inc dst1q + SBUTTERFLY bw, 6, 4, 0 + +%if mmsize == 16 ; sse2 +%if cpuflag(sse4) + inc dst2q +%endif + WRITE_8W m6, dst2q, dst1q, mstrideq, strideq + lea dst2q, [dst3q+mstrideq+1] +%if cpuflag(sse4) + inc dst3q +%endif + WRITE_8W m4, dst3q, dst2q, mstrideq, strideq +%else ; mmx/mmxext + WRITE_2x4W m6, m4, dst2q, dst1q, mstrideq, strideq +%endif +%endif + +%if mmsize == 8 ; mmx/mmxext + ; next 8 pixels +%ifidn %1, v + add dst1q, 8 ; advance 8 cols = pixels +%else ; h + lea dst1q, [dst1q+strideq*8-1] ; advance 8 rows = lines +%endif + dec cntrq + jg .next8px + REP_RET +%else ; sse2 + RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +SIMPLE_LOOPFILTER v, 4 +SIMPLE_LOOPFILTER h, 5 +INIT_MMX mmxext +SIMPLE_LOOPFILTER v, 4 +SIMPLE_LOOPFILTER h, 5 +%endif + +INIT_XMM sse2 +SIMPLE_LOOPFILTER v, 3 +SIMPLE_LOOPFILTER h, 5 +INIT_XMM ssse3 +SIMPLE_LOOPFILTER v, 3 +SIMPLE_LOOPFILTER h, 5 +INIT_XMM sse4 +SIMPLE_LOOPFILTER h, 5 + +;----------------------------------------------------------------------------- +; void ff_vp8_h/v_loop_filter_inner_(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, +; int flimE, int flimI, int hev_thr); +;----------------------------------------------------------------------------- + +%macro INNER_LOOPFILTER 2 +%define stack_size 0 +%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr +%ifidn %1, v ; [3]=hev() result +%define stack_size mmsize * -4 +%else ; h ; extra storage space for transposes +%define stack_size mmsize * -5 +%endif +%endif + +%if %2 == 8 ; chroma +cglobal vp8_%1_loop_filter8uv_inner, 6, 6, 13, stack_size, dst, dst8, stride, flimE, flimI, hevthr +%else ; luma +cglobal vp8_%1_loop_filter16y_inner, 5, 5, 13, stack_size, dst, stride, flimE, flimI, hevthr +%endif + +%if cpuflag(ssse3) + pxor m7, m7 +%endif + +%ifndef m8 + ; splat function arguments + SPLATB_REG m0, flimEq, m7 ; E + SPLATB_REG m1, flimIq, m7 ; I + SPLATB_REG m2, hevthrq, m7 ; hev_thresh + +%define m_flimE [rsp] +%define m_flimI [rsp+mmsize] +%define m_hevthr [rsp+mmsize*2] +%define m_maskres [rsp+mmsize*3] +%define m_p0backup [rsp+mmsize*3] +%define m_q0backup [rsp+mmsize*4] + + mova m_flimE, m0 + mova m_flimI, m1 + mova m_hevthr, m2 +%else +%define m_flimE m9 +%define m_flimI m10 +%define m_hevthr m11 +%define m_maskres m12 +%define m_p0backup m12 +%define m_q0backup m8 + + ; splat function arguments + SPLATB_REG m_flimE, flimEq, m7 ; E + SPLATB_REG m_flimI, flimIq, m7 ; I + SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh +%endif + +%if %2 == 8 ; chroma + DEFINE_ARGS dst1, dst8, mstride, stride, dst2 +%elif mmsize == 8 + DEFINE_ARGS dst1, mstride, stride, dst2, cntr + mov cntrq, 2 +%else + DEFINE_ARGS dst1, mstride, stride, dst2, dst8 +%endif + mov strideq, mstrideq + neg mstrideq +%ifidn %1, h + lea dst1q, [dst1q+strideq*4-4] +%if %2 == 8 ; chroma + lea dst8q, [dst8q+strideq*4-4] +%endif +%endif + +%if mmsize == 8 +.next8px: +%endif + ; read + lea dst2q, [dst1q+strideq] +%ifidn %1, v +%if %2 == 8 && mmsize == 16 +%define movrow movh +%else +%define movrow mova +%endif + movrow m0, [dst1q+mstrideq*4] ; p3 + movrow m1, [dst2q+mstrideq*4] ; p2 + movrow m2, [dst1q+mstrideq*2] ; p1 + movrow m5, [dst2q] ; q1 + movrow m6, [dst2q+ strideq*1] ; q2 + movrow m7, [dst2q+ strideq*2] ; q3 +%if mmsize == 16 && %2 == 8 + movhps m0, [dst8q+mstrideq*4] + movhps m2, [dst8q+mstrideq*2] + add dst8q, strideq + movhps m1, [dst8q+mstrideq*4] + movhps m5, [dst8q] + movhps m6, [dst8q+ strideq ] + movhps m7, [dst8q+ strideq*2] + add dst8q, mstrideq +%endif +%elif mmsize == 8 ; mmx/mmxext (h) + ; read 8 rows of 8px each + movu m0, [dst1q+mstrideq*4] + movu m1, [dst2q+mstrideq*4] + movu m2, [dst1q+mstrideq*2] + movu m3, [dst1q+mstrideq ] + movu m4, [dst1q] + movu m5, [dst2q] + movu m6, [dst2q+ strideq ] + + ; 8x8 transpose + TRANSPOSE4x4B 0, 1, 2, 3, 7 + mova m_q0backup, m1 + movu m7, [dst2q+ strideq*2] + TRANSPOSE4x4B 4, 5, 6, 7, 1 + SBUTTERFLY dq, 0, 4, 1 ; p3/p2 + SBUTTERFLY dq, 2, 6, 1 ; q0/q1 + SBUTTERFLY dq, 3, 7, 1 ; q2/q3 + mova m1, m_q0backup + mova m_q0backup, m2 ; store q0 + SBUTTERFLY dq, 1, 5, 2 ; p1/p0 + mova m_p0backup, m5 ; store p0 + SWAP 1, 4 + SWAP 2, 4 + SWAP 6, 3 + SWAP 5, 3 +%else ; sse2 (h) +%if %2 == 16 + lea dst8q, [dst1q+ strideq*8] +%endif + + ; read 16 rows of 8px each, interleave + movh m0, [dst1q+mstrideq*4] + movh m1, [dst8q+mstrideq*4] + movh m2, [dst1q+mstrideq*2] + movh m5, [dst8q+mstrideq*2] + movh m3, [dst1q+mstrideq ] + movh m6, [dst8q+mstrideq ] + movh m4, [dst1q] + movh m7, [dst8q] + punpcklbw m0, m1 ; A/I + punpcklbw m2, m5 ; C/K + punpcklbw m3, m6 ; D/L + punpcklbw m4, m7 ; E/M + + add dst8q, strideq + movh m1, [dst2q+mstrideq*4] + movh m6, [dst8q+mstrideq*4] + movh m5, [dst2q] + movh m7, [dst8q] + punpcklbw m1, m6 ; B/J + punpcklbw m5, m7 ; F/N + movh m6, [dst2q+ strideq ] + movh m7, [dst8q+ strideq ] + punpcklbw m6, m7 ; G/O + + ; 8x16 transpose + TRANSPOSE4x4B 0, 1, 2, 3, 7 +%ifdef m8 + SWAP 1, 8 +%else + mova m_q0backup, m1 +%endif + movh m7, [dst2q+ strideq*2] + movh m1, [dst8q+ strideq*2] + punpcklbw m7, m1 ; H/P + TRANSPOSE4x4B 4, 5, 6, 7, 1 + SBUTTERFLY dq, 0, 4, 1 ; p3/p2 + SBUTTERFLY dq, 2, 6, 1 ; q0/q1 + SBUTTERFLY dq, 3, 7, 1 ; q2/q3 +%ifdef m8 + SWAP 1, 8 + SWAP 2, 8 +%else + mova m1, m_q0backup + mova m_q0backup, m2 ; store q0 +%endif + SBUTTERFLY dq, 1, 5, 2 ; p1/p0 +%ifdef m12 + SWAP 5, 12 +%else + mova m_p0backup, m5 ; store p0 +%endif + SWAP 1, 4 + SWAP 2, 4 + SWAP 6, 3 + SWAP 5, 3 +%endif + + ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1 + mova m4, m1 + SWAP 4, 1 + psubusb m4, m0 ; p2-p3 + psubusb m0, m1 ; p3-p2 + por m0, m4 ; abs(p3-p2) + + mova m4, m2 + SWAP 4, 2 + psubusb m4, m1 ; p1-p2 + psubusb m1, m2 ; p2-p1 + por m1, m4 ; abs(p2-p1) + + mova m4, m6 + SWAP 4, 6 + psubusb m4, m7 ; q2-q3 + psubusb m7, m6 ; q3-q2 + por m7, m4 ; abs(q3-q2) + + mova m4, m5 + SWAP 4, 5 + psubusb m4, m6 ; q1-q2 + psubusb m6, m5 ; q2-q1 + por m6, m4 ; abs(q2-q1) + +%if notcpuflag(mmxext) + mova m4, m_flimI + pxor m3, m3 + psubusb m0, m4 + psubusb m1, m4 + psubusb m7, m4 + psubusb m6, m4 + pcmpeqb m0, m3 ; abs(p3-p2) <= I + pcmpeqb m1, m3 ; abs(p2-p1) <= I + pcmpeqb m7, m3 ; abs(q3-q2) <= I + pcmpeqb m6, m3 ; abs(q2-q1) <= I + pand m0, m1 + pand m7, m6 + pand m0, m7 +%else ; mmxext/sse2 + pmaxub m0, m1 + pmaxub m6, m7 + pmaxub m0, m6 +%endif + + ; normal_limit and high_edge_variance for p1-p0, q1-q0 + SWAP 7, 3 ; now m7 is zero +%ifidn %1, v + movrow m3, [dst1q+mstrideq ] ; p0 +%if mmsize == 16 && %2 == 8 + movhps m3, [dst8q+mstrideq ] +%endif +%elifdef m12 + SWAP 3, 12 +%else + mova m3, m_p0backup +%endif + + mova m1, m2 + SWAP 1, 2 + mova m6, m3 + SWAP 3, 6 + psubusb m1, m3 ; p1-p0 + psubusb m6, m2 ; p0-p1 + por m1, m6 ; abs(p1-p0) +%if notcpuflag(mmxext) + mova m6, m1 + psubusb m1, m4 + psubusb m6, m_hevthr + pcmpeqb m1, m7 ; abs(p1-p0) <= I + pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh + pand m0, m1 + mova m_maskres, m6 +%else ; mmxext/sse2 + pmaxub m0, m1 ; max_I + SWAP 1, 4 ; max_hev_thresh +%endif + + SWAP 6, 4 ; now m6 is I +%ifidn %1, v + movrow m4, [dst1q] ; q0 +%if mmsize == 16 && %2 == 8 + movhps m4, [dst8q] +%endif +%elifdef m8 + SWAP 4, 8 +%else + mova m4, m_q0backup +%endif + mova m1, m4 + SWAP 1, 4 + mova m7, m5 + SWAP 7, 5 + psubusb m1, m5 ; q0-q1 + psubusb m7, m4 ; q1-q0 + por m1, m7 ; abs(q1-q0) +%if notcpuflag(mmxext) + mova m7, m1 + psubusb m1, m6 + psubusb m7, m_hevthr + pxor m6, m6 + pcmpeqb m1, m6 ; abs(q1-q0) <= I + pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh + mova m6, m_maskres + pand m0, m1 ; abs([pq][321]-[pq][210]) <= I + pand m6, m7 +%else ; mmxext/sse2 + pxor m7, m7 + pmaxub m0, m1 + pmaxub m6, m1 + psubusb m0, m_flimI + psubusb m6, m_hevthr + pcmpeqb m0, m7 ; max(abs(..)) <= I + pcmpeqb m6, m7 ; !(max(abs..) > thresh) +%endif +%ifdef m12 + SWAP 6, 12 +%else + mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t) +%endif + + ; simple_limit + mova m1, m3 + SWAP 1, 3 + mova m6, m4 ; keep copies of p0/q0 around for later use + SWAP 6, 4 + psubusb m1, m4 ; p0-q0 + psubusb m6, m3 ; q0-p0 + por m1, m6 ; abs(q0-p0) + paddusb m1, m1 ; m1=2*abs(q0-p0) + + mova m7, m2 + SWAP 7, 2 + mova m6, m5 + SWAP 6, 5 + psubusb m7, m5 ; p1-q1 + psubusb m6, m2 ; q1-p1 + por m7, m6 ; abs(q1-p1) + pxor m6, m6 + pand m7, [pb_FE] + psrlq m7, 1 ; abs(q1-p1)/2 + paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2 + psubusb m7, m_flimE + pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E + pand m0, m7 ; normal_limit result + + ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask +%ifdef m8 ; x86-64 && sse2 + mova m8, [pb_80] +%define m_pb_80 m8 +%else ; x86-32 or mmx/mmxext +%define m_pb_80 [pb_80] +%endif + mova m1, m4 + mova m7, m3 + pxor m1, m_pb_80 + pxor m7, m_pb_80 + psubsb m1, m7 ; (signed) q0-p0 + mova m6, m2 + mova m7, m5 + pxor m6, m_pb_80 + pxor m7, m_pb_80 + psubsb m6, m7 ; (signed) p1-q1 + mova m7, m_maskres + pandn m7, m6 + paddsb m7, m1 + paddsb m7, m1 + paddsb m7, m1 ; 3*(q0-p0)+is4tap?(p1-q1) + + pand m7, m0 + mova m1, [pb_F8] + mova m6, m7 + paddsb m7, [pb_3] + paddsb m6, [pb_4] + pand m7, m1 + pand m6, m1 + + pxor m1, m1 + pxor m0, m0 + pcmpgtb m1, m7 + psubb m0, m7 + psrlq m7, 3 ; +f2 + psrlq m0, 3 ; -f2 + pand m0, m1 + pandn m1, m7 + psubusb m3, m0 + paddusb m3, m1 ; p0+f2 + + pxor m1, m1 + pxor m0, m0 + pcmpgtb m0, m6 + psubb m1, m6 + psrlq m6, 3 ; +f1 + psrlq m1, 3 ; -f1 + pand m1, m0 + pandn m0, m6 + psubusb m4, m0 + paddusb m4, m1 ; q0-f1 + +%ifdef m12 + SWAP 6, 12 +%else + mova m6, m_maskres +%endif +%if notcpuflag(mmxext) + mova m7, [pb_1] +%else ; mmxext/sse2 + pxor m7, m7 +%endif + pand m0, m6 + pand m1, m6 +%if notcpuflag(mmxext) + paddusb m0, m7 + pand m1, [pb_FE] + pandn m7, m0 + psrlq m1, 1 + psrlq m7, 1 + SWAP 0, 7 +%else ; mmxext/sse2 + psubusb m1, [pb_1] + pavgb m0, m7 ; a + pavgb m1, m7 ; -a +%endif + psubusb m5, m0 + psubusb m2, m1 + paddusb m5, m1 ; q1-a + paddusb m2, m0 ; p1+a + + ; store +%ifidn %1, v + movrow [dst1q+mstrideq*2], m2 + movrow [dst1q+mstrideq ], m3 + movrow [dst1q], m4 + movrow [dst1q+ strideq ], m5 +%if mmsize == 16 && %2 == 8 + movhps [dst8q+mstrideq*2], m2 + movhps [dst8q+mstrideq ], m3 + movhps [dst8q], m4 + movhps [dst8q+ strideq ], m5 +%endif +%else ; h + add dst1q, 2 + add dst2q, 2 + + ; 4x8/16 transpose + TRANSPOSE4x4B 2, 3, 4, 5, 6 + +%if mmsize == 8 ; mmx/mmxext (h) + WRITE_4x2D 2, 3, 4, 5, dst1q, dst2q, mstrideq, strideq +%else ; sse2 (h) + lea dst8q, [dst8q+mstrideq +2] + WRITE_4x4D 2, 3, 4, 5, dst1q, dst2q, dst8q, mstrideq, strideq, %2 +%endif +%endif + +%if mmsize == 8 +%if %2 == 8 ; chroma +%ifidn %1, h + sub dst1q, 2 +%endif + cmp dst1q, dst8q + mov dst1q, dst8q + jnz .next8px +%else +%ifidn %1, h + lea dst1q, [dst1q+ strideq*8-2] +%else ; v + add dst1q, 8 +%endif + dec cntrq + jg .next8px +%endif + REP_RET +%else ; mmsize == 16 + RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +INNER_LOOPFILTER v, 16 +INNER_LOOPFILTER h, 16 +INNER_LOOPFILTER v, 8 +INNER_LOOPFILTER h, 8 + +INIT_MMX mmxext +INNER_LOOPFILTER v, 16 +INNER_LOOPFILTER h, 16 +INNER_LOOPFILTER v, 8 +INNER_LOOPFILTER h, 8 +%endif + +INIT_XMM sse2 +INNER_LOOPFILTER v, 16 +INNER_LOOPFILTER h, 16 +INNER_LOOPFILTER v, 8 +INNER_LOOPFILTER h, 8 + +INIT_XMM ssse3 +INNER_LOOPFILTER v, 16 +INNER_LOOPFILTER h, 16 +INNER_LOOPFILTER v, 8 +INNER_LOOPFILTER h, 8 + +;----------------------------------------------------------------------------- +; void ff_vp8_h/v_loop_filter_mbedge_(uint8_t *dst, [uint8_t *v,] ptrdiff_t stride, +; int flimE, int flimI, int hev_thr); +;----------------------------------------------------------------------------- + +%macro MBEDGE_LOOPFILTER 2 +%define stack_size 0 +%ifndef m8 ; stack layout: [0]=E, [1]=I, [2]=hev_thr +%if mmsize == 16 ; [3]=hev() result + ; [4]=filter tmp result + ; [5]/[6] = p2/q2 backup + ; [7]=lim_res sign result +%define stack_size mmsize * -7 +%else ; 8 ; extra storage space for transposes +%define stack_size mmsize * -8 +%endif +%endif + +%if %2 == 8 ; chroma +cglobal vp8_%1_loop_filter8uv_mbedge, 6, 6, 15, stack_size, dst1, dst8, stride, flimE, flimI, hevthr +%else ; luma +cglobal vp8_%1_loop_filter16y_mbedge, 5, 5, 15, stack_size, dst1, stride, flimE, flimI, hevthr +%endif + +%if cpuflag(ssse3) + pxor m7, m7 +%endif + +%ifndef m8 + ; splat function arguments + SPLATB_REG m0, flimEq, m7 ; E + SPLATB_REG m1, flimIq, m7 ; I + SPLATB_REG m2, hevthrq, m7 ; hev_thresh + +%define m_flimE [rsp] +%define m_flimI [rsp+mmsize] +%define m_hevthr [rsp+mmsize*2] +%define m_maskres [rsp+mmsize*3] +%define m_limres [rsp+mmsize*4] +%define m_p0backup [rsp+mmsize*3] +%define m_q0backup [rsp+mmsize*4] +%define m_p2backup [rsp+mmsize*5] +%define m_q2backup [rsp+mmsize*6] +%if mmsize == 16 +%define m_limsign [rsp] +%else +%define m_limsign [rsp+mmsize*7] +%endif + + mova m_flimE, m0 + mova m_flimI, m1 + mova m_hevthr, m2 +%else ; sse2 on x86-64 +%define m_flimE m9 +%define m_flimI m10 +%define m_hevthr m11 +%define m_maskres m12 +%define m_limres m8 +%define m_p0backup m12 +%define m_q0backup m8 +%define m_p2backup m13 +%define m_q2backup m14 +%define m_limsign m9 + + ; splat function arguments + SPLATB_REG m_flimE, flimEq, m7 ; E + SPLATB_REG m_flimI, flimIq, m7 ; I + SPLATB_REG m_hevthr, hevthrq, m7 ; hev_thresh +%endif + +%if %2 == 8 ; chroma + DEFINE_ARGS dst1, dst8, mstride, stride, dst2 +%elif mmsize == 8 + DEFINE_ARGS dst1, mstride, stride, dst2, cntr + mov cntrq, 2 +%else + DEFINE_ARGS dst1, mstride, stride, dst2, dst8 +%endif + mov strideq, mstrideq + neg mstrideq +%ifidn %1, h + lea dst1q, [dst1q+strideq*4-4] +%if %2 == 8 ; chroma + lea dst8q, [dst8q+strideq*4-4] +%endif +%endif + +%if mmsize == 8 +.next8px: +%endif + ; read + lea dst2q, [dst1q+ strideq ] +%ifidn %1, v +%if %2 == 8 && mmsize == 16 +%define movrow movh +%else +%define movrow mova +%endif + movrow m0, [dst1q+mstrideq*4] ; p3 + movrow m1, [dst2q+mstrideq*4] ; p2 + movrow m2, [dst1q+mstrideq*2] ; p1 + movrow m5, [dst2q] ; q1 + movrow m6, [dst2q+ strideq ] ; q2 + movrow m7, [dst2q+ strideq*2] ; q3 +%if mmsize == 16 && %2 == 8 + movhps m0, [dst8q+mstrideq*4] + movhps m2, [dst8q+mstrideq*2] + add dst8q, strideq + movhps m1, [dst8q+mstrideq*4] + movhps m5, [dst8q] + movhps m6, [dst8q+ strideq ] + movhps m7, [dst8q+ strideq*2] + add dst8q, mstrideq +%endif +%elif mmsize == 8 ; mmx/mmxext (h) + ; read 8 rows of 8px each + movu m0, [dst1q+mstrideq*4] + movu m1, [dst2q+mstrideq*4] + movu m2, [dst1q+mstrideq*2] + movu m3, [dst1q+mstrideq ] + movu m4, [dst1q] + movu m5, [dst2q] + movu m6, [dst2q+ strideq ] + + ; 8x8 transpose + TRANSPOSE4x4B 0, 1, 2, 3, 7 + mova m_q0backup, m1 + movu m7, [dst2q+ strideq*2] + TRANSPOSE4x4B 4, 5, 6, 7, 1 + SBUTTERFLY dq, 0, 4, 1 ; p3/p2 + SBUTTERFLY dq, 2, 6, 1 ; q0/q1 + SBUTTERFLY dq, 3, 7, 1 ; q2/q3 + mova m1, m_q0backup + mova m_q0backup, m2 ; store q0 + SBUTTERFLY dq, 1, 5, 2 ; p1/p0 + mova m_p0backup, m5 ; store p0 + SWAP 1, 4 + SWAP 2, 4 + SWAP 6, 3 + SWAP 5, 3 +%else ; sse2 (h) +%if %2 == 16 + lea dst8q, [dst1q+ strideq*8 ] +%endif + + ; read 16 rows of 8px each, interleave + movh m0, [dst1q+mstrideq*4] + movh m1, [dst8q+mstrideq*4] + movh m2, [dst1q+mstrideq*2] + movh m5, [dst8q+mstrideq*2] + movh m3, [dst1q+mstrideq ] + movh m6, [dst8q+mstrideq ] + movh m4, [dst1q] + movh m7, [dst8q] + punpcklbw m0, m1 ; A/I + punpcklbw m2, m5 ; C/K + punpcklbw m3, m6 ; D/L + punpcklbw m4, m7 ; E/M + + add dst8q, strideq + movh m1, [dst2q+mstrideq*4] + movh m6, [dst8q+mstrideq*4] + movh m5, [dst2q] + movh m7, [dst8q] + punpcklbw m1, m6 ; B/J + punpcklbw m5, m7 ; F/N + movh m6, [dst2q+ strideq ] + movh m7, [dst8q+ strideq ] + punpcklbw m6, m7 ; G/O + + ; 8x16 transpose + TRANSPOSE4x4B 0, 1, 2, 3, 7 +%ifdef m8 + SWAP 1, 8 +%else + mova m_q0backup, m1 +%endif + movh m7, [dst2q+ strideq*2] + movh m1, [dst8q+ strideq*2] + punpcklbw m7, m1 ; H/P + TRANSPOSE4x4B 4, 5, 6, 7, 1 + SBUTTERFLY dq, 0, 4, 1 ; p3/p2 + SBUTTERFLY dq, 2, 6, 1 ; q0/q1 + SBUTTERFLY dq, 3, 7, 1 ; q2/q3 +%ifdef m8 + SWAP 1, 8 + SWAP 2, 8 +%else + mova m1, m_q0backup + mova m_q0backup, m2 ; store q0 +%endif + SBUTTERFLY dq, 1, 5, 2 ; p1/p0 +%ifdef m12 + SWAP 5, 12 +%else + mova m_p0backup, m5 ; store p0 +%endif + SWAP 1, 4 + SWAP 2, 4 + SWAP 6, 3 + SWAP 5, 3 +%endif + + ; normal_limit for p3-p2, p2-p1, q3-q2 and q2-q1 + mova m4, m1 + SWAP 4, 1 + psubusb m4, m0 ; p2-p3 + psubusb m0, m1 ; p3-p2 + por m0, m4 ; abs(p3-p2) + + mova m4, m2 + SWAP 4, 2 + psubusb m4, m1 ; p1-p2 + mova m_p2backup, m1 + psubusb m1, m2 ; p2-p1 + por m1, m4 ; abs(p2-p1) + + mova m4, m6 + SWAP 4, 6 + psubusb m4, m7 ; q2-q3 + psubusb m7, m6 ; q3-q2 + por m7, m4 ; abs(q3-q2) + + mova m4, m5 + SWAP 4, 5 + psubusb m4, m6 ; q1-q2 + mova m_q2backup, m6 + psubusb m6, m5 ; q2-q1 + por m6, m4 ; abs(q2-q1) + +%if notcpuflag(mmxext) + mova m4, m_flimI + pxor m3, m3 + psubusb m0, m4 + psubusb m1, m4 + psubusb m7, m4 + psubusb m6, m4 + pcmpeqb m0, m3 ; abs(p3-p2) <= I + pcmpeqb m1, m3 ; abs(p2-p1) <= I + pcmpeqb m7, m3 ; abs(q3-q2) <= I + pcmpeqb m6, m3 ; abs(q2-q1) <= I + pand m0, m1 + pand m7, m6 + pand m0, m7 +%else ; mmxext/sse2 + pmaxub m0, m1 + pmaxub m6, m7 + pmaxub m0, m6 +%endif + + ; normal_limit and high_edge_variance for p1-p0, q1-q0 + SWAP 7, 3 ; now m7 is zero +%ifidn %1, v + movrow m3, [dst1q+mstrideq ] ; p0 +%if mmsize == 16 && %2 == 8 + movhps m3, [dst8q+mstrideq ] +%endif +%elifdef m12 + SWAP 3, 12 +%else + mova m3, m_p0backup +%endif + + mova m1, m2 + SWAP 1, 2 + mova m6, m3 + SWAP 3, 6 + psubusb m1, m3 ; p1-p0 + psubusb m6, m2 ; p0-p1 + por m1, m6 ; abs(p1-p0) +%if notcpuflag(mmxext) + mova m6, m1 + psubusb m1, m4 + psubusb m6, m_hevthr + pcmpeqb m1, m7 ; abs(p1-p0) <= I + pcmpeqb m6, m7 ; abs(p1-p0) <= hev_thresh + pand m0, m1 + mova m_maskres, m6 +%else ; mmxext/sse2 + pmaxub m0, m1 ; max_I + SWAP 1, 4 ; max_hev_thresh +%endif + + SWAP 6, 4 ; now m6 is I +%ifidn %1, v + movrow m4, [dst1q] ; q0 +%if mmsize == 16 && %2 == 8 + movhps m4, [dst8q] +%endif +%elifdef m8 + SWAP 4, 8 +%else + mova m4, m_q0backup +%endif + mova m1, m4 + SWAP 1, 4 + mova m7, m5 + SWAP 7, 5 + psubusb m1, m5 ; q0-q1 + psubusb m7, m4 ; q1-q0 + por m1, m7 ; abs(q1-q0) +%if notcpuflag(mmxext) + mova m7, m1 + psubusb m1, m6 + psubusb m7, m_hevthr + pxor m6, m6 + pcmpeqb m1, m6 ; abs(q1-q0) <= I + pcmpeqb m7, m6 ; abs(q1-q0) <= hev_thresh + mova m6, m_maskres + pand m0, m1 ; abs([pq][321]-[pq][210]) <= I + pand m6, m7 +%else ; mmxext/sse2 + pxor m7, m7 + pmaxub m0, m1 + pmaxub m6, m1 + psubusb m0, m_flimI + psubusb m6, m_hevthr + pcmpeqb m0, m7 ; max(abs(..)) <= I + pcmpeqb m6, m7 ; !(max(abs..) > thresh) +%endif +%ifdef m12 + SWAP 6, 12 +%else + mova m_maskres, m6 ; !(abs(p1-p0) > hev_t || abs(q1-q0) > hev_t) +%endif + + ; simple_limit + mova m1, m3 + SWAP 1, 3 + mova m6, m4 ; keep copies of p0/q0 around for later use + SWAP 6, 4 + psubusb m1, m4 ; p0-q0 + psubusb m6, m3 ; q0-p0 + por m1, m6 ; abs(q0-p0) + paddusb m1, m1 ; m1=2*abs(q0-p0) + + mova m7, m2 + SWAP 7, 2 + mova m6, m5 + SWAP 6, 5 + psubusb m7, m5 ; p1-q1 + psubusb m6, m2 ; q1-p1 + por m7, m6 ; abs(q1-p1) + pxor m6, m6 + pand m7, [pb_FE] + psrlq m7, 1 ; abs(q1-p1)/2 + paddusb m7, m1 ; abs(q0-p0)*2+abs(q1-p1)/2 + psubusb m7, m_flimE + pcmpeqb m7, m6 ; abs(q0-p0)*2+abs(q1-p1)/2 <= E + pand m0, m7 ; normal_limit result + + ; filter_common; at this point, m2-m5=p1-q1 and m0 is filter_mask +%ifdef m8 ; x86-64 && sse2 + mova m8, [pb_80] +%define m_pb_80 m8 +%else ; x86-32 or mmx/mmxext +%define m_pb_80 [pb_80] +%endif + mova m1, m4 + mova m7, m3 + pxor m1, m_pb_80 + pxor m7, m_pb_80 + psubsb m1, m7 ; (signed) q0-p0 + mova m6, m2 + mova m7, m5 + pxor m6, m_pb_80 + pxor m7, m_pb_80 + psubsb m6, m7 ; (signed) p1-q1 + mova m7, m_maskres + paddsb m6, m1 + paddsb m6, m1 + paddsb m6, m1 + pand m6, m0 +%ifdef m8 + mova m_limres, m6 ; 3*(qp-p0)+(p1-q1) masked for filter_mbedge + pand m_limres, m7 +%else + mova m0, m6 + pand m0, m7 + mova m_limres, m0 +%endif + pandn m7, m6 ; 3*(q0-p0)+(p1-q1) masked for filter_common + + mova m1, [pb_F8] + mova m6, m7 + paddsb m7, [pb_3] + paddsb m6, [pb_4] + pand m7, m1 + pand m6, m1 + + pxor m1, m1 + pxor m0, m0 + pcmpgtb m1, m7 + psubb m0, m7 + psrlq m7, 3 ; +f2 + psrlq m0, 3 ; -f2 + pand m0, m1 + pandn m1, m7 + psubusb m3, m0 + paddusb m3, m1 ; p0+f2 + + pxor m1, m1 + pxor m0, m0 + pcmpgtb m0, m6 + psubb m1, m6 + psrlq m6, 3 ; +f1 + psrlq m1, 3 ; -f1 + pand m1, m0 + pandn m0, m6 + psubusb m4, m0 + paddusb m4, m1 ; q0-f1 + + ; filter_mbedge (m2-m5 = p1-q1; lim_res carries w) +%if cpuflag(ssse3) + mova m7, [pb_1] +%else + mova m7, [pw_63] +%endif +%ifdef m8 + SWAP 1, 8 +%else + mova m1, m_limres +%endif + pxor m0, m0 + mova m6, m1 + pcmpgtb m0, m1 ; which are negative +%if cpuflag(ssse3) + punpcklbw m6, m7 ; interleave with "1" for rounding + punpckhbw m1, m7 +%else + punpcklbw m6, m0 ; signed byte->word + punpckhbw m1, m0 +%endif + mova m_limsign, m0 +%if cpuflag(ssse3) + mova m7, [pb_27_63] +%ifndef m8 + mova m_limres, m1 +%endif +%ifdef m10 + SWAP 0, 10 ; don't lose lim_sign copy +%endif + mova m0, m7 + pmaddubsw m7, m6 + SWAP 6, 7 + pmaddubsw m0, m1 + SWAP 1, 0 +%ifdef m10 + SWAP 0, 10 +%else + mova m0, m_limsign +%endif +%else + mova m_maskres, m6 ; backup for later in filter + mova m_limres, m1 + pmullw m6, [pw_27] + pmullw m1, [pw_27] + paddw m6, m7 + paddw m1, m7 +%endif + psraw m6, 7 + psraw m1, 7 + packsswb m6, m1 ; a0 + pxor m1, m1 + psubb m1, m6 + pand m1, m0 ; -a0 + pandn m0, m6 ; +a0 +%if cpuflag(ssse3) + mova m6, [pb_18_63] ; pipelining +%endif + psubusb m3, m1 + paddusb m4, m1 + paddusb m3, m0 ; p0+a0 + psubusb m4, m0 ; q0-a0 + +%if cpuflag(ssse3) + SWAP 6, 7 +%ifdef m10 + SWAP 1, 10 +%else + mova m1, m_limres +%endif + mova m0, m7 + pmaddubsw m7, m6 + SWAP 6, 7 + pmaddubsw m0, m1 + SWAP 1, 0 +%ifdef m10 + SWAP 0, 10 +%endif + mova m0, m_limsign +%else + mova m6, m_maskres + mova m1, m_limres + pmullw m6, [pw_18] + pmullw m1, [pw_18] + paddw m6, m7 + paddw m1, m7 +%endif + mova m0, m_limsign + psraw m6, 7 + psraw m1, 7 + packsswb m6, m1 ; a1 + pxor m1, m1 + psubb m1, m6 + pand m1, m0 ; -a1 + pandn m0, m6 ; +a1 +%if cpuflag(ssse3) + mova m6, [pb_9_63] +%endif + psubusb m2, m1 + paddusb m5, m1 + paddusb m2, m0 ; p1+a1 + psubusb m5, m0 ; q1-a1 + +%if cpuflag(ssse3) + SWAP 6, 7 +%ifdef m10 + SWAP 1, 10 +%else + mova m1, m_limres +%endif + mova m0, m7 + pmaddubsw m7, m6 + SWAP 6, 7 + pmaddubsw m0, m1 + SWAP 1, 0 +%else +%ifdef m8 + SWAP 6, 12 + SWAP 1, 8 +%else + mova m6, m_maskres + mova m1, m_limres +%endif + pmullw m6, [pw_9] + pmullw m1, [pw_9] + paddw m6, m7 + paddw m1, m7 +%endif +%ifdef m9 + SWAP 7, 9 +%else + mova m7, m_limsign +%endif + psraw m6, 7 + psraw m1, 7 + packsswb m6, m1 ; a1 + pxor m0, m0 + psubb m0, m6 + pand m0, m7 ; -a1 + pandn m7, m6 ; +a1 +%ifdef m8 + SWAP 1, 13 + SWAP 6, 14 +%else + mova m1, m_p2backup + mova m6, m_q2backup +%endif + psubusb m1, m0 + paddusb m6, m0 + paddusb m1, m7 ; p1+a1 + psubusb m6, m7 ; q1-a1 + + ; store +%ifidn %1, v + movrow [dst2q+mstrideq*4], m1 + movrow [dst1q+mstrideq*2], m2 + movrow [dst1q+mstrideq ], m3 + movrow [dst1q], m4 + movrow [dst2q], m5 + movrow [dst2q+ strideq ], m6 +%if mmsize == 16 && %2 == 8 + add dst8q, mstrideq + movhps [dst8q+mstrideq*2], m1 + movhps [dst8q+mstrideq ], m2 + movhps [dst8q], m3 + add dst8q, strideq + movhps [dst8q], m4 + movhps [dst8q+ strideq ], m5 + movhps [dst8q+ strideq*2], m6 +%endif +%else ; h + inc dst1q + inc dst2q + + ; 4x8/16 transpose + TRANSPOSE4x4B 1, 2, 3, 4, 0 + SBUTTERFLY bw, 5, 6, 0 + +%if mmsize == 8 ; mmx/mmxext (h) + WRITE_4x2D 1, 2, 3, 4, dst1q, dst2q, mstrideq, strideq + add dst1q, 4 + WRITE_2x4W m5, m6, dst2q, dst1q, mstrideq, strideq +%else ; sse2 (h) + lea dst8q, [dst8q+mstrideq+1] + WRITE_4x4D 1, 2, 3, 4, dst1q, dst2q, dst8q, mstrideq, strideq, %2 + lea dst1q, [dst2q+mstrideq+4] + lea dst8q, [dst8q+mstrideq+4] +%if cpuflag(sse4) + add dst2q, 4 +%endif + WRITE_8W m5, dst2q, dst1q, mstrideq, strideq +%if cpuflag(sse4) + lea dst2q, [dst8q+ strideq ] +%endif + WRITE_8W m6, dst2q, dst8q, mstrideq, strideq +%endif +%endif + +%if mmsize == 8 +%if %2 == 8 ; chroma +%ifidn %1, h + sub dst1q, 5 +%endif + cmp dst1q, dst8q + mov dst1q, dst8q + jnz .next8px +%else +%ifidn %1, h + lea dst1q, [dst1q+ strideq*8-5] +%else ; v + add dst1q, 8 +%endif + dec cntrq + jg .next8px +%endif + REP_RET +%else ; mmsize == 16 + RET +%endif +%endmacro + +%if ARCH_X86_32 +INIT_MMX mmx +MBEDGE_LOOPFILTER v, 16 +MBEDGE_LOOPFILTER h, 16 +MBEDGE_LOOPFILTER v, 8 +MBEDGE_LOOPFILTER h, 8 + +INIT_MMX mmxext +MBEDGE_LOOPFILTER v, 16 +MBEDGE_LOOPFILTER h, 16 +MBEDGE_LOOPFILTER v, 8 +MBEDGE_LOOPFILTER h, 8 +%endif + +INIT_XMM sse2 +MBEDGE_LOOPFILTER v, 16 +MBEDGE_LOOPFILTER h, 16 +MBEDGE_LOOPFILTER v, 8 +MBEDGE_LOOPFILTER h, 8 + +INIT_XMM ssse3 +MBEDGE_LOOPFILTER v, 16 +MBEDGE_LOOPFILTER h, 16 +MBEDGE_LOOPFILTER v, 8 +MBEDGE_LOOPFILTER h, 8 + +INIT_XMM sse4 +MBEDGE_LOOPFILTER h, 16 +MBEDGE_LOOPFILTER h, 8 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init.c new file mode 100644 index 00000000..837cce85 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init.c @@ -0,0 +1,416 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "libavcodec/x86/vp9dsp_init.h" + +#if HAVE_X86ASM + +decl_fpel_func(put, 4, , mmx); +decl_fpel_func(put, 8, , mmx); +decl_fpel_func(put, 16, , sse); +decl_fpel_func(put, 32, , sse); +decl_fpel_func(put, 64, , sse); +decl_fpel_func(avg, 4, _8, mmxext); +decl_fpel_func(avg, 8, _8, mmxext); +decl_fpel_func(avg, 16, _8, sse2); +decl_fpel_func(avg, 32, _8, sse2); +decl_fpel_func(avg, 64, _8, sse2); +decl_fpel_func(put, 32, , avx); +decl_fpel_func(put, 64, , avx); +decl_fpel_func(avg, 32, _8, avx2); +decl_fpel_func(avg, 64, _8, avx2); + +decl_mc_funcs(4, mmxext, int16_t, 8, 8); +decl_mc_funcs(8, sse2, int16_t, 8, 8); +decl_mc_funcs(4, ssse3, int8_t, 32, 8); +decl_mc_funcs(8, ssse3, int8_t, 32, 8); +#if ARCH_X86_64 +decl_mc_funcs(16, ssse3, int8_t, 32, 8); +decl_mc_funcs(32, avx2, int8_t, 32, 8); +#endif + +mc_rep_funcs(16, 8, 8, sse2, int16_t, 8, 8) +#if ARCH_X86_32 +mc_rep_funcs(16, 8, 8, ssse3, int8_t, 32, 8) +#endif +mc_rep_funcs(32, 16, 16, sse2, int16_t, 8, 8) +mc_rep_funcs(32, 16, 16, ssse3, int8_t, 32, 8) +mc_rep_funcs(64, 32, 32, sse2, int16_t, 8, 8) +mc_rep_funcs(64, 32, 32, ssse3, int8_t, 32, 8) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +mc_rep_funcs(64, 32, 32, avx2, int8_t, 32, 8) +#endif + +extern const int8_t ff_filters_ssse3[3][15][4][32]; +extern const int16_t ff_filters_sse2[3][15][8][8]; + +filters_8tap_2d_fn2(put, 16, 8, 1, mmxext, sse2, sse2) +filters_8tap_2d_fn2(avg, 16, 8, 1, mmxext, sse2, sse2) +filters_8tap_2d_fn2(put, 16, 8, 1, ssse3, ssse3, ssse3) +filters_8tap_2d_fn2(avg, 16, 8, 1, ssse3, ssse3, ssse3) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +filters_8tap_2d_fn(put, 64, 32, 8, 1, avx2, ssse3) +filters_8tap_2d_fn(put, 32, 32, 8, 1, avx2, ssse3) +filters_8tap_2d_fn(avg, 64, 32, 8, 1, avx2, ssse3) +filters_8tap_2d_fn(avg, 32, 32, 8, 1, avx2, ssse3) +#endif + +filters_8tap_1d_fn3(put, 8, mmxext, sse2, sse2) +filters_8tap_1d_fn3(avg, 8, mmxext, sse2, sse2) +filters_8tap_1d_fn3(put, 8, ssse3, ssse3, ssse3) +filters_8tap_1d_fn3(avg, 8, ssse3, ssse3, ssse3) +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +filters_8tap_1d_fn2(put, 64, 8, avx2, ssse3) +filters_8tap_1d_fn2(put, 32, 8, avx2, ssse3) +filters_8tap_1d_fn2(avg, 64, 8, avx2, ssse3) +filters_8tap_1d_fn2(avg, 32, 8, avx2, ssse3) +#endif + +#define itxfm_func(typea, typeb, size, opt) \ +void ff_vp9_##typea##_##typeb##_##size##x##size##_add_##opt(uint8_t *dst, ptrdiff_t stride, \ + int16_t *block, int eob) +#define itxfm_funcs(size, opt) \ +itxfm_func(idct, idct, size, opt); \ +itxfm_func(iadst, idct, size, opt); \ +itxfm_func(idct, iadst, size, opt); \ +itxfm_func(iadst, iadst, size, opt) + +itxfm_func(idct, idct, 4, mmxext); +itxfm_func(idct, iadst, 4, sse2); +itxfm_func(iadst, idct, 4, sse2); +itxfm_func(iadst, iadst, 4, sse2); +itxfm_funcs(4, ssse3); +itxfm_funcs(8, sse2); +itxfm_funcs(8, ssse3); +itxfm_funcs(8, avx); +itxfm_funcs(16, sse2); +itxfm_funcs(16, ssse3); +itxfm_funcs(16, avx); +itxfm_func(idct, idct, 32, sse2); +itxfm_func(idct, idct, 32, ssse3); +itxfm_func(idct, idct, 32, avx); +itxfm_func(iwht, iwht, 4, mmx); +itxfm_funcs(16, avx2); +itxfm_func(idct, idct, 32, avx2); + +#undef itxfm_func +#undef itxfm_funcs + +#define lpf_funcs(size1, size2, opt) \ +void ff_vp9_loop_filter_v_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H); \ +void ff_vp9_loop_filter_h_##size1##_##size2##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) + +lpf_funcs(4, 8, mmxext); +lpf_funcs(8, 8, mmxext); +lpf_funcs(16, 16, sse2); +lpf_funcs(16, 16, ssse3); +lpf_funcs(16, 16, avx); +lpf_funcs(44, 16, sse2); +lpf_funcs(44, 16, ssse3); +lpf_funcs(44, 16, avx); +lpf_funcs(84, 16, sse2); +lpf_funcs(84, 16, ssse3); +lpf_funcs(84, 16, avx); +lpf_funcs(48, 16, sse2); +lpf_funcs(48, 16, ssse3); +lpf_funcs(48, 16, avx); +lpf_funcs(88, 16, sse2); +lpf_funcs(88, 16, ssse3); +lpf_funcs(88, 16, avx); + +#undef lpf_funcs + +#define ipred_func(size, type, opt) \ +void ff_vp9_ipred_##type##_##size##x##size##_##opt(uint8_t *dst, ptrdiff_t stride, \ + const uint8_t *l, const uint8_t *a) + +ipred_func(8, v, mmx); + +#define ipred_dc_funcs(size, opt) \ +ipred_func(size, dc, opt); \ +ipred_func(size, dc_left, opt); \ +ipred_func(size, dc_top, opt) + +ipred_dc_funcs(4, mmxext); +ipred_dc_funcs(8, mmxext); + +#define ipred_dir_tm_funcs(size, opt) \ +ipred_func(size, tm, opt); \ +ipred_func(size, dl, opt); \ +ipred_func(size, dr, opt); \ +ipred_func(size, hd, opt); \ +ipred_func(size, hu, opt); \ +ipred_func(size, vl, opt); \ +ipred_func(size, vr, opt) + +ipred_dir_tm_funcs(4, mmxext); + +ipred_func(16, v, sse); +ipred_func(32, v, sse); + +ipred_dc_funcs(16, sse2); +ipred_dc_funcs(32, sse2); + +#define ipred_dir_tm_h_funcs(size, opt) \ +ipred_dir_tm_funcs(size, opt); \ +ipred_func(size, h, opt) + +ipred_dir_tm_h_funcs(8, sse2); +ipred_dir_tm_h_funcs(16, sse2); +ipred_dir_tm_h_funcs(32, sse2); + +ipred_func(4, h, sse2); + +#define ipred_all_funcs(size, opt) \ +ipred_dc_funcs(size, opt); \ +ipred_dir_tm_h_funcs(size, opt) + +// FIXME hd/vl_4x4_ssse3 does not exist +ipred_all_funcs(4, ssse3); +ipred_all_funcs(8, ssse3); +ipred_all_funcs(16, ssse3); +ipred_all_funcs(32, ssse3); + +ipred_dir_tm_h_funcs(8, avx); +ipred_dir_tm_h_funcs(16, avx); +ipred_dir_tm_h_funcs(32, avx); + +ipred_func(32, v, avx); + +ipred_dc_funcs(32, avx2); +ipred_func(32, h, avx2); +ipred_func(32, tm, avx2); + +#undef ipred_func +#undef ipred_dir_tm_h_funcs +#undef ipred_dir_tm_funcs +#undef ipred_dc_funcs + +#endif /* HAVE_X86ASM */ + +av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp, int bitexact) +{ +#if HAVE_X86ASM + int cpu_flags; + + if (bpp == 10) { + ff_vp9dsp_init_10bpp_x86(dsp, bitexact); + return; + } else if (bpp == 12) { + ff_vp9dsp_init_12bpp_x86(dsp, bitexact); + return; + } + + cpu_flags = av_get_cpu_flags(); + +#define init_lpf(opt) do { \ + dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \ + dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \ + dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \ + dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \ + dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \ + dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \ + dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \ + dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \ + dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \ + dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \ +} while (0) + +#define init_ipred(sz, opt, t, e) \ + dsp->intra_pred[TX_##sz##X##sz][e##_PRED] = ff_vp9_ipred_##t##_##sz##x##sz##_##opt + +#define ff_vp9_ipred_hd_4x4_ssse3 ff_vp9_ipred_hd_4x4_mmxext +#define ff_vp9_ipred_vl_4x4_ssse3 ff_vp9_ipred_vl_4x4_mmxext +#define init_dir_tm_ipred(sz, opt) do { \ + init_ipred(sz, opt, dl, DIAG_DOWN_LEFT); \ + init_ipred(sz, opt, dr, DIAG_DOWN_RIGHT); \ + init_ipred(sz, opt, hd, HOR_DOWN); \ + init_ipred(sz, opt, vl, VERT_LEFT); \ + init_ipred(sz, opt, hu, HOR_UP); \ + init_ipred(sz, opt, tm, TM_VP8); \ + init_ipred(sz, opt, vr, VERT_RIGHT); \ +} while (0) +#define init_dir_tm_h_ipred(sz, opt) do { \ + init_dir_tm_ipred(sz, opt); \ + init_ipred(sz, opt, h, HOR); \ +} while (0) +#define init_dc_ipred(sz, opt) do { \ + init_ipred(sz, opt, dc, DC); \ + init_ipred(sz, opt, dc_left, LEFT_DC); \ + init_ipred(sz, opt, dc_top, TOP_DC); \ +} while (0) +#define init_all_ipred(sz, opt) do { \ + init_dc_ipred(sz, opt); \ + init_dir_tm_h_ipred(sz, opt); \ +} while (0) + + if (EXTERNAL_MMX(cpu_flags)) { + init_fpel_func(4, 0, 4, put, , mmx); + init_fpel_func(3, 0, 8, put, , mmx); + if (!bitexact) { + dsp->itxfm_add[4 /* lossless */][DCT_DCT] = + dsp->itxfm_add[4 /* lossless */][ADST_DCT] = + dsp->itxfm_add[4 /* lossless */][DCT_ADST] = + dsp->itxfm_add[4 /* lossless */][ADST_ADST] = ff_vp9_iwht_iwht_4x4_add_mmx; + } + init_ipred(8, mmx, v, VERT); + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + dsp->loop_filter_8[0][0] = ff_vp9_loop_filter_h_4_8_mmxext; + dsp->loop_filter_8[0][1] = ff_vp9_loop_filter_v_4_8_mmxext; + dsp->loop_filter_8[1][0] = ff_vp9_loop_filter_h_8_8_mmxext; + dsp->loop_filter_8[1][1] = ff_vp9_loop_filter_v_8_8_mmxext; + init_subpel2(4, 0, 4, put, 8, mmxext); + init_subpel2(4, 1, 4, avg, 8, mmxext); + init_fpel_func(4, 1, 4, avg, _8, mmxext); + init_fpel_func(3, 1, 8, avg, _8, mmxext); + dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_mmxext; + init_dc_ipred(4, mmxext); + init_dc_ipred(8, mmxext); + init_dir_tm_ipred(4, mmxext); + } + + if (EXTERNAL_SSE(cpu_flags)) { + init_fpel_func(2, 0, 16, put, , sse); + init_fpel_func(1, 0, 32, put, , sse); + init_fpel_func(0, 0, 64, put, , sse); + init_ipred(16, sse, v, VERT); + init_ipred(32, sse, v, VERT); + } + + if (EXTERNAL_SSE2(cpu_flags)) { + init_subpel3_8to64(0, put, 8, sse2); + init_subpel3_8to64(1, avg, 8, sse2); + init_fpel_func(2, 1, 16, avg, _8, sse2); + init_fpel_func(1, 1, 32, avg, _8, sse2); + init_fpel_func(0, 1, 64, avg, _8, sse2); + init_lpf(sse2); + dsp->itxfm_add[TX_4X4][ADST_DCT] = ff_vp9_idct_iadst_4x4_add_sse2; + dsp->itxfm_add[TX_4X4][DCT_ADST] = ff_vp9_iadst_idct_4x4_add_sse2; + dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_sse2; + dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_sse2; + dsp->itxfm_add[TX_8X8][ADST_DCT] = ff_vp9_idct_iadst_8x8_add_sse2; + dsp->itxfm_add[TX_8X8][DCT_ADST] = ff_vp9_iadst_idct_8x8_add_sse2; + dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_sse2; + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_sse2; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_sse2; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_sse2; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_sse2; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_sse2; + init_dc_ipred(16, sse2); + init_dc_ipred(32, sse2); + init_dir_tm_h_ipred(8, sse2); + init_dir_tm_h_ipred(16, sse2); + init_dir_tm_h_ipred(32, sse2); + init_ipred(4, sse2, h, HOR); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + init_subpel3(0, put, 8, ssse3); + init_subpel3(1, avg, 8, ssse3); + dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_ssse3; + dsp->itxfm_add[TX_4X4][ADST_DCT] = ff_vp9_idct_iadst_4x4_add_ssse3; + dsp->itxfm_add[TX_4X4][DCT_ADST] = ff_vp9_iadst_idct_4x4_add_ssse3; + dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_ssse3; + dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_ssse3; + dsp->itxfm_add[TX_8X8][ADST_DCT] = ff_vp9_idct_iadst_8x8_add_ssse3; + dsp->itxfm_add[TX_8X8][DCT_ADST] = ff_vp9_iadst_idct_8x8_add_ssse3; + dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_ssse3; + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_ssse3; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_ssse3; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_ssse3; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_ssse3; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_ssse3; + init_lpf(ssse3); + init_all_ipred(4, ssse3); + init_all_ipred(8, ssse3); + init_all_ipred(16, ssse3); + init_all_ipred(32, ssse3); + } + + if (EXTERNAL_AVX(cpu_flags)) { + dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_avx; + dsp->itxfm_add[TX_8X8][ADST_DCT] = ff_vp9_idct_iadst_8x8_add_avx; + dsp->itxfm_add[TX_8X8][DCT_ADST] = ff_vp9_iadst_idct_8x8_add_avx; + dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_avx; + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_avx; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_avx; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx; + init_lpf(avx); + init_dir_tm_h_ipred(8, avx); + init_dir_tm_h_ipred(16, avx); + init_dir_tm_h_ipred(32, avx); + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + init_fpel_func(1, 0, 32, put, , avx); + init_fpel_func(0, 0, 64, put, , avx); + init_ipred(32, avx, v, VERT); + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + init_fpel_func(1, 1, 32, avg, _8, avx2); + init_fpel_func(0, 1, 64, avg, _8, avx2); + if (ARCH_X86_64) { +#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL + dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_DCT] = ff_vp9_idct_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][DCT_ADST] = ff_vp9_iadst_idct_16x16_add_avx2; + dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx2; + dsp->itxfm_add[TX_32X32][ADST_ADST] = + dsp->itxfm_add[TX_32X32][ADST_DCT] = + dsp->itxfm_add[TX_32X32][DCT_ADST] = + dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx2; + init_subpel3_32_64(0, put, 8, avx2); + init_subpel3_32_64(1, avg, 8, avx2); +#endif + } + init_dc_ipred(32, avx2); + init_ipred(32, avx2, h, HOR); + init_ipred(32, avx2, tm, TM_VP8); + } + +#undef init_fpel +#undef init_subpel1 +#undef init_subpel2 +#undef init_subpel3 + +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init.h new file mode 100644 index 00000000..ebe7ca8a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init.h @@ -0,0 +1,191 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * 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 + */ + +#ifndef AVCODEC_X86_VP9DSP_INIT_H +#define AVCODEC_X86_VP9DSP_INIT_H + +#include "libavutil/mem_internal.h" + +#include "libavcodec/vp9dsp.h" + +// hack to force-expand BPC +#define cat(a, bpp, b) a##bpp##b + +#define decl_fpel_func(avg, sz, bpp, opt) \ +void ff_vp9_##avg##sz##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) + +#define decl_mc_func(avg, sz, dir, opt, type, f_sz, bpp) \ +void ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, const type (*filter)[f_sz]) + +#define decl_mc_funcs(sz, opt, type, fsz, bpp) \ +decl_mc_func(put, sz, h, opt, type, fsz, bpp); \ +decl_mc_func(avg, sz, h, opt, type, fsz, bpp); \ +decl_mc_func(put, sz, v, opt, type, fsz, bpp); \ +decl_mc_func(avg, sz, v, opt, type, fsz, bpp) + +#define decl_ipred_fn(type, sz, bpp, opt) \ +void ff_vp9_ipred_##type##_##sz##x##sz##_##bpp##_##opt(uint8_t *dst, \ + ptrdiff_t stride, \ + const uint8_t *l, \ + const uint8_t *a) + +#define decl_ipred_fns(type, bpp, opt4, opt8_16_32) \ +decl_ipred_fn(type, 4, bpp, opt4); \ +decl_ipred_fn(type, 8, bpp, opt8_16_32); \ +decl_ipred_fn(type, 16, bpp, opt8_16_32); \ +decl_ipred_fn(type, 32, bpp, opt8_16_32) + +#define decl_itxfm_func(typea, typeb, size, bpp, opt) \ +void cat(ff_vp9_##typea##_##typeb##_##size##x##size##_add_, bpp, _##opt)(uint8_t *dst, \ + ptrdiff_t stride, \ + int16_t *block, \ + int eob) + +#define decl_itxfm_funcs(size, bpp, opt) \ +decl_itxfm_func(idct, idct, size, bpp, opt); \ +decl_itxfm_func(iadst, idct, size, bpp, opt); \ +decl_itxfm_func(idct, iadst, size, bpp, opt); \ +decl_itxfm_func(iadst, iadst, size, bpp, opt) + +#define mc_rep_func(avg, sz, hsz, hszb, dir, opt, type, f_sz, bpp) \ +static av_always_inline void \ +ff_vp9_##avg##_8tap_1d_##dir##_##sz##_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, const type (*filter)[f_sz]) \ +{ \ + ff_vp9_##avg##_8tap_1d_##dir##_##hsz##_##bpp##_##opt(dst, dst_stride, src, \ + src_stride, h, filter); \ + ff_vp9_##avg##_8tap_1d_##dir##_##hsz##_##bpp##_##opt(dst + hszb, dst_stride, src + hszb, \ + src_stride, h, filter); \ +} + +#define mc_rep_funcs(sz, hsz, hszb, opt, type, fsz, bpp) \ +mc_rep_func(put, sz, hsz, hszb, h, opt, type, fsz, bpp) \ +mc_rep_func(avg, sz, hsz, hszb, h, opt, type, fsz, bpp) \ +mc_rep_func(put, sz, hsz, hszb, v, opt, type, fsz, bpp) \ +mc_rep_func(avg, sz, hsz, hszb, v, opt, type, fsz, bpp) + +#define filter_8tap_1d_fn(op, sz, f, f_opt, fname, dir, dvar, bpp, opt) \ +static void op##_8tap_##fname##_##sz##dir##_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + ff_vp9_##op##_8tap_1d_##dir##_##sz##_##bpp##_##opt(dst, dst_stride, src, src_stride, \ + h, ff_filters_##f_opt[f][dvar - 1]); \ +} + +#define filters_8tap_1d_fn(op, sz, dir, dvar, bpp, opt, f_opt) \ +filter_8tap_1d_fn(op, sz, FILTER_8TAP_REGULAR, f_opt, regular, dir, dvar, bpp, opt) \ +filter_8tap_1d_fn(op, sz, FILTER_8TAP_SHARP, f_opt, sharp, dir, dvar, bpp, opt) \ +filter_8tap_1d_fn(op, sz, FILTER_8TAP_SMOOTH, f_opt, smooth, dir, dvar, bpp, opt) + +#define filters_8tap_1d_fn2(op, sz, bpp, opt, f_opt) \ +filters_8tap_1d_fn(op, sz, h, mx, bpp, opt, f_opt) \ +filters_8tap_1d_fn(op, sz, v, my, bpp, opt, f_opt) + +#define filters_8tap_1d_fn3(op, bpp, opt4, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 64, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 32, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 16, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 8, bpp, opt8, f_opt) \ +filters_8tap_1d_fn2(op, 4, bpp, opt4, f_opt) + +#define filter_8tap_2d_fn(op, sz, f, f_opt, fname, align, bpp, bytes, opt) \ +static void op##_8tap_##fname##_##sz##hv_##bpp##_##opt(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my) \ +{ \ + LOCAL_ALIGNED_##align(uint8_t, temp, [71 * 64 * bytes]); \ + ff_vp9_put_8tap_1d_h_##sz##_##bpp##_##opt(temp, 64 * bytes, src - 3 * src_stride, \ + src_stride, h + 7, \ + ff_filters_##f_opt[f][mx - 1]); \ + ff_vp9_##op##_8tap_1d_v_##sz##_##bpp##_##opt(dst, dst_stride, temp + 3 * bytes * 64, \ + 64 * bytes, h, \ + ff_filters_##f_opt[f][my - 1]); \ +} + +#define filters_8tap_2d_fn(op, sz, align, bpp, bytes, opt, f_opt) \ +filter_8tap_2d_fn(op, sz, FILTER_8TAP_REGULAR, f_opt, regular, align, bpp, bytes, opt) \ +filter_8tap_2d_fn(op, sz, FILTER_8TAP_SHARP, f_opt, sharp, align, bpp, bytes, opt) \ +filter_8tap_2d_fn(op, sz, FILTER_8TAP_SMOOTH, f_opt, smooth, align, bpp, bytes, opt) + +#define filters_8tap_2d_fn2(op, align, bpp, bytes, opt4, opt8, f_opt) \ +filters_8tap_2d_fn(op, 64, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 32, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 16, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 8, align, bpp, bytes, opt8, f_opt) \ +filters_8tap_2d_fn(op, 4, align, bpp, bytes, opt4, f_opt) + +#define init_fpel_func(idx1, idx2, sz, type, bpp, opt) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][0][0] = \ + dsp->mc[idx1][FILTER_BILINEAR ][idx2][0][0] = ff_vp9_##type##sz##bpp##_##opt + +#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, bpp, opt) \ + dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][idxh][idxv] = \ + type##_8tap_smooth_##sz##dir##_##bpp##_##opt; \ + dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = \ + type##_8tap_regular_##sz##dir##_##bpp##_##opt; \ + dsp->mc[idx1][FILTER_8TAP_SHARP ][idx2][idxh][idxv] = \ + type##_8tap_sharp_##sz##dir##_##bpp##_##opt + +#define init_subpel2(idx1, idx2, sz, type, bpp, opt) \ + init_subpel1(idx1, idx2, 1, 1, sz, hv, type, bpp, opt); \ + init_subpel1(idx1, idx2, 0, 1, sz, v, type, bpp, opt); \ + init_subpel1(idx1, idx2, 1, 0, sz, h, type, bpp, opt) + +#define init_subpel3_32_64(idx, type, bpp, opt) \ + init_subpel2(0, idx, 64, type, bpp, opt); \ + init_subpel2(1, idx, 32, type, bpp, opt) + +#define init_subpel3_8to64(idx, type, bpp, opt) \ + init_subpel3_32_64(idx, type, bpp, opt); \ + init_subpel2(2, idx, 16, type, bpp, opt); \ + init_subpel2(3, idx, 8, type, bpp, opt) + +#define init_subpel3(idx, type, bpp, opt) \ + init_subpel3_8to64(idx, type, bpp, opt); \ + init_subpel2(4, idx, 4, type, bpp, opt) + +#define init_ipred_func(type, enum, sz, bpp, opt) \ + dsp->intra_pred[TX_##sz##X##sz][enum##_PRED] = \ + cat(ff_vp9_ipred_##type##_##sz##x##sz##_, bpp, _##opt) + +#define init_8_16_32_ipred_funcs(type, enum, bpp, opt) \ + init_ipred_func(type, enum, 8, bpp, opt); \ + init_ipred_func(type, enum, 16, bpp, opt); \ + init_ipred_func(type, enum, 32, bpp, opt) + +#define init_ipred_funcs(type, enum, bpp, opt) \ + init_ipred_func(type, enum, 4, bpp, opt); \ + init_8_16_32_ipred_funcs(type, enum, bpp, opt) + +void ff_vp9dsp_init_10bpp_x86(VP9DSPContext *dsp, int bitexact); +void ff_vp9dsp_init_12bpp_x86(VP9DSPContext *dsp, int bitexact); +void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp); + +#endif /* AVCODEC_X86_VP9DSP_INIT_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_10bpp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_10bpp.c new file mode 100644 index 00000000..2694c06c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_10bpp.c @@ -0,0 +1,25 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * 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 + */ + +#define BPC 10 +#define INIT_FUNC ff_vp9dsp_init_10bpp_x86 +#include "vp9dsp_init_16bpp_template.c" diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_12bpp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_12bpp.c new file mode 100644 index 00000000..5da3bc18 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_12bpp.c @@ -0,0 +1,25 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * 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 + */ + +#define BPC 12 +#define INIT_FUNC ff_vp9dsp_init_12bpp_x86 +#include "vp9dsp_init_16bpp_template.c" diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_16bpp.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_16bpp.c new file mode 100644 index 00000000..60d10a12 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_16bpp.c @@ -0,0 +1,149 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "libavcodec/x86/vp9dsp_init.h" + +#if HAVE_X86ASM + +decl_fpel_func(put, 8, , mmx); +decl_fpel_func(avg, 8, _16, mmxext); +decl_fpel_func(put, 16, , sse); +decl_fpel_func(put, 32, , sse); +decl_fpel_func(put, 64, , sse); +decl_fpel_func(put, 128, , sse); +decl_fpel_func(avg, 16, _16, sse2); +decl_fpel_func(avg, 32, _16, sse2); +decl_fpel_func(avg, 64, _16, sse2); +decl_fpel_func(avg, 128, _16, sse2); +decl_fpel_func(put, 32, , avx); +decl_fpel_func(put, 64, , avx); +decl_fpel_func(put, 128, , avx); +decl_fpel_func(avg, 32, _16, avx2); +decl_fpel_func(avg, 64, _16, avx2); +decl_fpel_func(avg, 128, _16, avx2); + +decl_ipred_fns(v, 16, mmx, sse); +decl_ipred_fns(h, 16, mmxext, sse2); +decl_ipred_fns(dc, 16, mmxext, sse2); +decl_ipred_fns(dc_top, 16, mmxext, sse2); +decl_ipred_fns(dc_left, 16, mmxext, sse2); +decl_ipred_fn(dl, 16, 16, avx2); +decl_ipred_fn(dl, 32, 16, avx2); +decl_ipred_fn(dr, 16, 16, avx2); +decl_ipred_fn(dr, 32, 16, avx2); + +#define decl_ipred_dir_funcs(type) \ +decl_ipred_fns(type, 16, sse2, sse2); \ +decl_ipred_fns(type, 16, ssse3, ssse3); \ +decl_ipred_fns(type, 16, avx, avx) + +decl_ipred_dir_funcs(dl); +decl_ipred_dir_funcs(dr); +decl_ipred_dir_funcs(vl); +decl_ipred_dir_funcs(vr); +decl_ipred_dir_funcs(hu); +decl_ipred_dir_funcs(hd); +#endif /* HAVE_X86ASM */ + +av_cold void ff_vp9dsp_init_16bpp_x86(VP9DSPContext *dsp) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + init_fpel_func(4, 0, 8, put, , mmx); + init_ipred_func(v, VERT, 4, 16, mmx); + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + init_fpel_func(4, 1, 8, avg, _16, mmxext); + init_ipred_func(h, HOR, 4, 16, mmxext); + init_ipred_func(dc, DC, 4, 16, mmxext); + init_ipred_func(dc_top, TOP_DC, 4, 16, mmxext); + init_ipred_func(dc_left, LEFT_DC, 4, 16, mmxext); + } + + if (EXTERNAL_SSE(cpu_flags)) { + init_fpel_func(3, 0, 16, put, , sse); + init_fpel_func(2, 0, 32, put, , sse); + init_fpel_func(1, 0, 64, put, , sse); + init_fpel_func(0, 0, 128, put, , sse); + init_8_16_32_ipred_funcs(v, VERT, 16, sse); + } + + if (EXTERNAL_SSE2(cpu_flags)) { + init_fpel_func(3, 1, 16, avg, _16, sse2); + init_fpel_func(2, 1, 32, avg, _16, sse2); + init_fpel_func(1, 1, 64, avg, _16, sse2); + init_fpel_func(0, 1, 128, avg, _16, sse2); + init_8_16_32_ipred_funcs(h, HOR, 16, sse2); + init_8_16_32_ipred_funcs(dc, DC, 16, sse2); + init_8_16_32_ipred_funcs(dc_top, TOP_DC, 16, sse2); + init_8_16_32_ipred_funcs(dc_left, LEFT_DC, 16, sse2); + init_ipred_funcs(dl, DIAG_DOWN_LEFT, 16, sse2); + init_ipred_funcs(dr, DIAG_DOWN_RIGHT, 16, sse2); + init_ipred_funcs(vl, VERT_LEFT, 16, sse2); + init_ipred_funcs(vr, VERT_RIGHT, 16, sse2); + init_ipred_funcs(hu, HOR_UP, 16, sse2); + init_ipred_funcs(hd, HOR_DOWN, 16, sse2); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + init_ipred_funcs(dl, DIAG_DOWN_LEFT, 16, ssse3); + init_ipred_funcs(dr, DIAG_DOWN_RIGHT, 16, ssse3); + init_ipred_funcs(vl, VERT_LEFT, 16, ssse3); + init_ipred_funcs(vr, VERT_RIGHT, 16, ssse3); + init_ipred_funcs(hu, HOR_UP, 16, ssse3); + init_ipred_funcs(hd, HOR_DOWN, 16, ssse3); + } + + if (EXTERNAL_AVX_FAST(cpu_flags)) { + init_fpel_func(2, 0, 32, put, , avx); + init_fpel_func(1, 0, 64, put, , avx); + init_fpel_func(0, 0, 128, put, , avx); + init_ipred_funcs(dl, DIAG_DOWN_LEFT, 16, avx); + init_ipred_funcs(dr, DIAG_DOWN_RIGHT, 16, avx); + init_ipred_funcs(vl, VERT_LEFT, 16, avx); + init_ipred_funcs(vr, VERT_RIGHT, 16, avx); + init_ipred_funcs(hu, HOR_UP, 16, avx); + init_ipred_funcs(hd, HOR_DOWN, 16, avx); + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + init_fpel_func(2, 1, 32, avg, _16, avx2); + init_fpel_func(1, 1, 64, avg, _16, avx2); + init_fpel_func(0, 1, 128, avg, _16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 16, 16, avx2); + init_ipred_func(dl, DIAG_DOWN_LEFT, 32, 16, avx2); + init_ipred_func(dr, DIAG_DOWN_RIGHT, 16, 16, avx2); +#if ARCH_X86_64 + init_ipred_func(dr, DIAG_DOWN_RIGHT, 32, 16, avx2); +#endif + } + +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_16bpp_template.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_16bpp_template.c new file mode 100644 index 00000000..b56afc7f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9dsp_init_16bpp_template.c @@ -0,0 +1,240 @@ +/* + * VP9 SIMD optimizations + * + * Copyright (c) 2013 Ronald S. Bultje + * + * 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 "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/mem.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/vp9dsp.h" +#include "libavcodec/x86/vp9dsp_init.h" + +#if HAVE_X86ASM + +extern const int16_t ff_filters_16bpp[3][15][4][16]; + +decl_mc_funcs(4, sse2, int16_t, 16, BPC); +decl_mc_funcs(8, sse2, int16_t, 16, BPC); +decl_mc_funcs(16, avx2, int16_t, 16, BPC); + +mc_rep_funcs(16, 8, 16, sse2, int16_t, 16, BPC) +mc_rep_funcs(32, 16, 32, sse2, int16_t, 16, BPC) +mc_rep_funcs(64, 32, 64, sse2, int16_t, 16, BPC) +#if HAVE_AVX2_EXTERNAL +mc_rep_funcs(32, 16, 32, avx2, int16_t, 16, BPC) +mc_rep_funcs(64, 32, 64, avx2, int16_t, 16, BPC) +#endif + +filters_8tap_2d_fn2(put, 16, BPC, 2, sse2, sse2, 16bpp) +filters_8tap_2d_fn2(avg, 16, BPC, 2, sse2, sse2, 16bpp) +#if HAVE_AVX2_EXTERNAL +filters_8tap_2d_fn(put, 64, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(avg, 64, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(put, 32, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(avg, 32, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(put, 16, 32, BPC, 2, avx2, 16bpp) +filters_8tap_2d_fn(avg, 16, 32, BPC, 2, avx2, 16bpp) +#endif + +filters_8tap_1d_fn3(put, BPC, sse2, sse2, 16bpp) +filters_8tap_1d_fn3(avg, BPC, sse2, sse2, 16bpp) +#if HAVE_AVX2_EXTERNAL +filters_8tap_1d_fn2(put, 64, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(avg, 64, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(put, 32, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(avg, 32, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(put, 16, BPC, avx2, 16bpp) +filters_8tap_1d_fn2(avg, 16, BPC, avx2, 16bpp) +#endif + +#define decl_lpf_func(dir, wd, bpp, opt) \ +void ff_vp9_loop_filter_##dir##_##wd##_##bpp##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) + +#define decl_lpf_funcs(dir, wd, bpp) \ +decl_lpf_func(dir, wd, bpp, sse2); \ +decl_lpf_func(dir, wd, bpp, ssse3); \ +decl_lpf_func(dir, wd, bpp, avx) + +#define decl_lpf_funcs_wd(dir) \ +decl_lpf_funcs(dir, 4, BPC); \ +decl_lpf_funcs(dir, 8, BPC); \ +decl_lpf_funcs(dir, 16, BPC) + +decl_lpf_funcs_wd(h); +decl_lpf_funcs_wd(v); + +#define lpf_16_wrapper(dir, off, bpp, opt) \ +static void loop_filter_##dir##_16_##bpp##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) \ +{ \ + ff_vp9_loop_filter_##dir##_16_##bpp##_##opt(dst, stride, E, I, H); \ + ff_vp9_loop_filter_##dir##_16_##bpp##_##opt(dst + off, stride, E, I, H); \ +} + +#define lpf_16_wrappers(bpp, opt) \ +lpf_16_wrapper(h, 8 * stride, bpp, opt) \ +lpf_16_wrapper(v, 16, bpp, opt) + +lpf_16_wrappers(BPC, sse2) +lpf_16_wrappers(BPC, ssse3) +lpf_16_wrappers(BPC, avx) + +#define lpf_mix2_wrapper(dir, off, wd1, wd2, bpp, opt) \ +static void loop_filter_##dir##_##wd1##wd2##_##bpp##_##opt(uint8_t *dst, ptrdiff_t stride, \ + int E, int I, int H) \ +{ \ + ff_vp9_loop_filter_##dir##_##wd1##_##bpp##_##opt(dst, stride, \ + E & 0xff, I & 0xff, H & 0xff); \ + ff_vp9_loop_filter_##dir##_##wd2##_##bpp##_##opt(dst + off, stride, \ + E >> 8, I >> 8, H >> 8); \ +} + +#define lpf_mix2_wrappers(wd1, wd2, bpp, opt) \ +lpf_mix2_wrapper(h, 8 * stride, wd1, wd2, bpp, opt) \ +lpf_mix2_wrapper(v, 16, wd1, wd2, bpp, opt) + +#define lpf_mix2_wrappers_set(bpp, opt) \ +lpf_mix2_wrappers(4, 4, bpp, opt) \ +lpf_mix2_wrappers(4, 8, bpp, opt) \ +lpf_mix2_wrappers(8, 4, bpp, opt) \ +lpf_mix2_wrappers(8, 8, bpp, opt) \ + +lpf_mix2_wrappers_set(BPC, sse2) +lpf_mix2_wrappers_set(BPC, ssse3) +lpf_mix2_wrappers_set(BPC, avx) + +decl_ipred_fns(tm, BPC, mmxext, sse2); + +decl_itxfm_func(iwht, iwht, 4, BPC, mmxext); +#if BPC == 10 +decl_itxfm_func(idct, idct, 4, BPC, mmxext); +decl_itxfm_funcs(4, BPC, ssse3); +#else +decl_itxfm_func(idct, idct, 4, BPC, sse2); +#endif +decl_itxfm_func(idct, iadst, 4, BPC, sse2); +decl_itxfm_func(iadst, idct, 4, BPC, sse2); +decl_itxfm_func(iadst, iadst, 4, BPC, sse2); +decl_itxfm_funcs(8, BPC, sse2); +decl_itxfm_funcs(16, BPC, sse2); +decl_itxfm_func(idct, idct, 32, BPC, sse2); +#endif /* HAVE_X86ASM */ + +av_cold void INIT_FUNC(VP9DSPContext *dsp, int bitexact) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + +#define init_lpf_8_func(idx1, idx2, dir, wd, bpp, opt) \ + dsp->loop_filter_8[idx1][idx2] = ff_vp9_loop_filter_##dir##_##wd##_##bpp##_##opt +#define init_lpf_16_func(idx, dir, bpp, opt) \ + dsp->loop_filter_16[idx] = loop_filter_##dir##_16_##bpp##_##opt +#define init_lpf_mix2_func(idx1, idx2, idx3, dir, wd1, wd2, bpp, opt) \ + dsp->loop_filter_mix2[idx1][idx2][idx3] = loop_filter_##dir##_##wd1##wd2##_##bpp##_##opt + +#define init_lpf_funcs(bpp, opt) \ + init_lpf_8_func(0, 0, h, 4, bpp, opt); \ + init_lpf_8_func(0, 1, v, 4, bpp, opt); \ + init_lpf_8_func(1, 0, h, 8, bpp, opt); \ + init_lpf_8_func(1, 1, v, 8, bpp, opt); \ + init_lpf_8_func(2, 0, h, 16, bpp, opt); \ + init_lpf_8_func(2, 1, v, 16, bpp, opt); \ + init_lpf_16_func(0, h, bpp, opt); \ + init_lpf_16_func(1, v, bpp, opt); \ + init_lpf_mix2_func(0, 0, 0, h, 4, 4, bpp, opt); \ + init_lpf_mix2_func(0, 1, 0, h, 4, 8, bpp, opt); \ + init_lpf_mix2_func(1, 0, 0, h, 8, 4, bpp, opt); \ + init_lpf_mix2_func(1, 1, 0, h, 8, 8, bpp, opt); \ + init_lpf_mix2_func(0, 0, 1, v, 4, 4, bpp, opt); \ + init_lpf_mix2_func(0, 1, 1, v, 4, 8, bpp, opt); \ + init_lpf_mix2_func(1, 0, 1, v, 8, 4, bpp, opt); \ + init_lpf_mix2_func(1, 1, 1, v, 8, 8, bpp, opt) + +#define init_itx_func(idxa, idxb, typea, typeb, size, bpp, opt) \ + dsp->itxfm_add[idxa][idxb] = \ + cat(ff_vp9_##typea##_##typeb##_##size##x##size##_add_, bpp, _##opt); +#define init_itx_func_one(idx, typea, typeb, size, bpp, opt) \ + init_itx_func(idx, DCT_DCT, typea, typeb, size, bpp, opt); \ + init_itx_func(idx, ADST_DCT, typea, typeb, size, bpp, opt); \ + init_itx_func(idx, DCT_ADST, typea, typeb, size, bpp, opt); \ + init_itx_func(idx, ADST_ADST, typea, typeb, size, bpp, opt) +#define init_itx_funcs(idx, size, bpp, opt) \ + init_itx_func(idx, DCT_DCT, idct, idct, size, bpp, opt); \ + init_itx_func(idx, ADST_DCT, idct, iadst, size, bpp, opt); \ + init_itx_func(idx, DCT_ADST, iadst, idct, size, bpp, opt); \ + init_itx_func(idx, ADST_ADST, iadst, iadst, size, bpp, opt); \ + + if (EXTERNAL_MMXEXT(cpu_flags)) { + init_ipred_func(tm, TM_VP8, 4, BPC, mmxext); + if (!bitexact) { + init_itx_func_one(4 /* lossless */, iwht, iwht, 4, BPC, mmxext); +#if BPC == 10 + init_itx_func(TX_4X4, DCT_DCT, idct, idct, 4, 10, mmxext); +#endif + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + init_subpel3(0, put, BPC, sse2); + init_subpel3(1, avg, BPC, sse2); + init_lpf_funcs(BPC, sse2); + init_8_16_32_ipred_funcs(tm, TM_VP8, BPC, sse2); +#if BPC == 10 + if (!bitexact) { + init_itx_func(TX_4X4, ADST_DCT, idct, iadst, 4, 10, sse2); + init_itx_func(TX_4X4, DCT_ADST, iadst, idct, 4, 10, sse2); + init_itx_func(TX_4X4, ADST_ADST, iadst, iadst, 4, 10, sse2); + } +#else + init_itx_funcs(TX_4X4, 4, 12, sse2); +#endif + init_itx_funcs(TX_8X8, 8, BPC, sse2); + init_itx_funcs(TX_16X16, 16, BPC, sse2); + init_itx_func_one(TX_32X32, idct, idct, 32, BPC, sse2); + } + + if (EXTERNAL_SSSE3(cpu_flags)) { + init_lpf_funcs(BPC, ssse3); +#if BPC == 10 + if (!bitexact) { + init_itx_funcs(TX_4X4, 4, BPC, ssse3); + } +#endif + } + + if (EXTERNAL_AVX(cpu_flags)) { + init_lpf_funcs(BPC, avx); + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { +#if HAVE_AVX2_EXTERNAL + init_subpel3_32_64(0, put, BPC, avx2); + init_subpel3_32_64(1, avg, BPC, avx2); + init_subpel2(2, 0, 16, put, BPC, avx2); + init_subpel2(2, 1, 16, avg, BPC, avx2); +#endif + } + +#endif /* HAVE_X86ASM */ + + ff_vp9dsp_init_16bpp_x86(dsp); +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9intrapred.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9intrapred.asm new file mode 100644 index 00000000..31f7d449 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9intrapred.asm @@ -0,0 +1,2044 @@ +;****************************************************************************** +;* VP9 Intra prediction SIMD optimizations +;* +;* Copyright (c) 2013 Ronald S. Bultje +;* +;* Parts based on: +;* H.264 intra prediction asm optimizations +;* Copyright (c) 2010 Fiona Glaser +;* Copyright (c) 2010 Holger Lubitz +;* Copyright (c) 2010 Loren Merritt +;* Copyright (c) 2010 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pw_m256: times 16 dw -256 +pw_m255: times 16 dw -255 +pw_4096: times 8 dw 4096 + +pb_4x3_4x2_4x1_4x0: times 4 db 3 + times 4 db 2 + times 4 db 1 + times 4 db 0 +pb_8x1_8x0: times 8 db 1 + times 8 db 0 +pb_8x3_8x2: times 8 db 3 + times 8 db 2 +pb_0to5_2x7: db 0, 1, 2, 3, 4, 5, 7, 7 + times 8 db -1 +pb_0to6_9x7: db 0, 1, 2, 3, 4, 5, 6 + times 9 db 7 +pb_1to6_10x7: db 1, 2, 3, 4, 5, 6 + times 10 db 7 +pb_2to6_3x7: +pb_2to6_11x7: db 2, 3, 4, 5, 6 + times 11 db 7 +pb_1toE_2xF: db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15 +pb_2toE_3xF: db 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 +pb_13456_3xm1: db 1, 3, 4, 5, 6 + times 3 db -1 +pb_6012_4xm1: db 6, 0, 1, 2 + times 4 db -1 +pb_6xm1_246_8toE: times 6 db -1 + db 2, 4, 6, 8, 9, 10, 11, 12, 13, 14 +pb_6xm1_BDF_0to6: times 6 db -1 + db 11, 13, 15, 0, 1, 2, 3, 4, 5, 6 +pb_02468ACE_13579BDF: db 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15 + +pb_15x0_1xm1: times 15 db 0 + db -1 +pb_0to2_5x3: db 0, 1, 2 + times 5 db 3 +pb_6xm1_2x0: times 6 db -1 + times 2 db 0 +pb_6x0_2xm1: times 6 db 0 + times 2 db -1 + +cextern pb_1 +cextern pb_2 +cextern pb_3 +cextern pb_15 +cextern pw_2 +cextern pw_4 +cextern pw_8 +cextern pw_16 +cextern pw_32 +cextern pw_255 +cextern pw_512 +cextern pw_1024 +cextern pw_2048 +cextern pw_8192 + +SECTION .text + +; dc_NxN(uint8_t *dst, ptrdiff_t stride, const uint8_t *l, const uint8_t *a) + +%macro DC_4to8_FUNCS 0 +cglobal vp9_ipred_dc_4x4, 4, 4, 0, dst, stride, l, a + movd m0, [lq] + punpckldq m0, [aq] + pxor m1, m1 + psadbw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_4096] + pshufb m0, m1 +%else + paddw m0, [pw_4] + psraw m0, 3 + punpcklbw m0, m0 + pshufw m0, m0, q0000 +%endif + movd [dstq+strideq*0], m0 + movd [dstq+strideq*1], m0 + lea dstq, [dstq+strideq*2] + movd [dstq+strideq*0], m0 + movd [dstq+strideq*1], m0 + RET + +cglobal vp9_ipred_dc_8x8, 4, 4, 0, dst, stride, l, a + movq m0, [lq] + movq m1, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pxor m2, m2 + psadbw m0, m2 + psadbw m1, m2 + paddw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_2048] + pshufb m0, m2 +%else + paddw m0, [pw_8] + psraw m0, 4 + punpcklbw m0, m0 + pshufw m0, m0, q0000 +%endif + movq [dstq+strideq*0], m0 + movq [dstq+strideq*1], m0 + movq [dstq+strideq*2], m0 + movq [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + movq [dstq+strideq*0], m0 + movq [dstq+strideq*1], m0 + movq [dstq+strideq*2], m0 + movq [dstq+stride3q ], m0 + RET +%endmacro + +INIT_MMX mmxext +DC_4to8_FUNCS +INIT_MMX ssse3 +DC_4to8_FUNCS + +%macro DC_16to32_FUNCS 0 +cglobal vp9_ipred_dc_16x16, 4, 4, 3, dst, stride, l, a + mova m0, [lq] + mova m1, [aq] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + pxor m2, m2 + psadbw m0, m2 + psadbw m1, m2 + paddw m0, m1 + movhlps m1, m0 + paddw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_1024] + pshufb m0, m2 +%else + paddw m0, [pw_16] + psraw m0, 5 + punpcklbw m0, m0 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +%endif + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dc_32x32, 4, 4, 5, dst, stride, l, a + mova m0, [lq] + mova m1, [lq+16] + mova m2, [aq] + mova m3, [aq+16] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + pxor m4, m4 + psadbw m0, m4 + psadbw m1, m4 + psadbw m2, m4 + psadbw m3, m4 + paddw m0, m1 + paddw m2, m3 + paddw m0, m2 + movhlps m1, m0 + paddw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_512] + pshufb m0, m4 +%else + paddw m0, [pw_32] + psraw m0, 6 + punpcklbw m0, m0 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +%endif + mov cntd, 8 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m0 + mova [dstq+strideq*2+ 0], m0 + mova [dstq+strideq*2+16], m0 + mova [dstq+stride3q + 0], m0 + mova [dstq+stride3q +16], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +DC_16to32_FUNCS +INIT_XMM ssse3 +DC_16to32_FUNCS + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dc_32x32, 4, 4, 3, dst, stride, l, a + mova m0, [lq] + mova m1, [aq] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + pxor m2, m2 + psadbw m0, m2 + psadbw m1, m2 + paddw m0, m1 + vextracti128 xm1, m0, 1 + paddw xm0, xm1 + movhlps xm1, xm0 + paddw xm0, xm1 + pmulhrsw xm0, [pw_512] + vpbroadcastb m0, xm0 + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endif + +; dc_top/left_NxN(uint8_t *dst, ptrdiff_t stride, const uint8_t *l, const uint8_t *a) + +%macro DC_1D_4to8_FUNCS 2 ; dir (top or left), arg (a or l) +cglobal vp9_ipred_dc_%1_4x4, 4, 4, 0, dst, stride, l, a + movd m0, [%2q] + pxor m1, m1 + psadbw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_8192] + pshufb m0, m1 +%else + paddw m0, [pw_2] + psraw m0, 2 + punpcklbw m0, m0 + pshufw m0, m0, q0000 +%endif + movd [dstq+strideq*0], m0 + movd [dstq+strideq*1], m0 + lea dstq, [dstq+strideq*2] + movd [dstq+strideq*0], m0 + movd [dstq+strideq*1], m0 + RET + +cglobal vp9_ipred_dc_%1_8x8, 4, 4, 0, dst, stride, l, a + movq m0, [%2q] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pxor m1, m1 + psadbw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_4096] + pshufb m0, m1 +%else + paddw m0, [pw_4] + psraw m0, 3 + punpcklbw m0, m0 + pshufw m0, m0, q0000 +%endif + movq [dstq+strideq*0], m0 + movq [dstq+strideq*1], m0 + movq [dstq+strideq*2], m0 + movq [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + movq [dstq+strideq*0], m0 + movq [dstq+strideq*1], m0 + movq [dstq+strideq*2], m0 + movq [dstq+stride3q ], m0 + RET +%endmacro + +INIT_MMX mmxext +DC_1D_4to8_FUNCS top, a +DC_1D_4to8_FUNCS left, l +INIT_MMX ssse3 +DC_1D_4to8_FUNCS top, a +DC_1D_4to8_FUNCS left, l + +%macro DC_1D_16to32_FUNCS 2; dir (top or left), arg (a or l) +cglobal vp9_ipred_dc_%1_16x16, 4, 4, 3, dst, stride, l, a + mova m0, [%2q] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + pxor m2, m2 + psadbw m0, m2 + movhlps m1, m0 + paddw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_2048] + pshufb m0, m2 +%else + paddw m0, [pw_8] + psraw m0, 4 + punpcklbw m0, m0 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +%endif + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dc_%1_32x32, 4, 4, 3, dst, stride, l, a + mova m0, [%2q] + mova m1, [%2q+16] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + pxor m2, m2 + psadbw m0, m2 + psadbw m1, m2 + paddw m0, m1 + movhlps m1, m0 + paddw m0, m1 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_1024] + pshufb m0, m2 +%else + paddw m0, [pw_16] + psraw m0, 5 + punpcklbw m0, m0 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +%endif + mov cntd, 8 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m0 + mova [dstq+strideq*2+ 0], m0 + mova [dstq+strideq*2+16], m0 + mova [dstq+stride3q + 0], m0 + mova [dstq+stride3q +16], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +DC_1D_16to32_FUNCS top, a +DC_1D_16to32_FUNCS left, l +INIT_XMM ssse3 +DC_1D_16to32_FUNCS top, a +DC_1D_16to32_FUNCS left, l + +%macro DC_1D_AVX2_FUNCS 2 ; dir (top or left), arg (a or l) +%if HAVE_AVX2_EXTERNAL +cglobal vp9_ipred_dc_%1_32x32, 4, 4, 3, dst, stride, l, a + mova m0, [%2q] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + pxor m2, m2 + psadbw m0, m2 + vextracti128 xm1, m0, 1 + paddw xm0, xm1 + movhlps xm1, xm0 + paddw xm0, xm1 + pmulhrsw xm0, [pw_1024] + vpbroadcastb m0, xm0 + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endif +%endmacro + +INIT_YMM avx2 +DC_1D_AVX2_FUNCS top, a +DC_1D_AVX2_FUNCS left, l + +; v + +INIT_MMX mmx +cglobal vp9_ipred_v_8x8, 4, 4, 0, dst, stride, l, a + movq m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + movq [dstq+strideq*0], m0 + movq [dstq+strideq*1], m0 + movq [dstq+strideq*2], m0 + movq [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + movq [dstq+strideq*0], m0 + movq [dstq+strideq*1], m0 + movq [dstq+strideq*2], m0 + movq [dstq+stride3q ], m0 + RET + +INIT_XMM sse +cglobal vp9_ipred_v_16x16, 4, 4, 1, dst, stride, l, a + mova m0, [aq] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +INIT_XMM sse +cglobal vp9_ipred_v_32x32, 4, 4, 2, dst, stride, l, a + mova m0, [aq] + mova m1, [aq+16] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 8 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m1 + mova [dstq+strideq*2+ 0], m0 + mova [dstq+strideq*2+16], m1 + mova [dstq+stride3q + 0], m0 + mova [dstq+stride3q +16], m1 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +INIT_YMM avx +cglobal vp9_ipred_v_32x32, 4, 4, 1, dst, stride, l, a + mova m0, [aq] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +; h + +%macro H_XMM_FUNCS 2 +%if notcpuflag(avx) +cglobal vp9_ipred_h_4x4, 3, 4, 1, dst, stride, l, stride3 + movd m0, [lq] +%if cpuflag(ssse3) + pshufb m0, [pb_4x3_4x2_4x1_4x0] +%else + punpcklbw m0, m0 + pshuflw m0, m0, q0123 + punpcklwd m0, m0 +%endif + lea stride3q, [strideq*3] + movd [dstq+strideq*0], m0 + psrldq m0, 4 + movd [dstq+strideq*1], m0 + psrldq m0, 4 + movd [dstq+strideq*2], m0 + psrldq m0, 4 + movd [dstq+stride3q ], m0 + RET +%endif + +cglobal vp9_ipred_h_8x8, 3, 5, %1, dst, stride, l, stride3, cnt +%if cpuflag(ssse3) + mova m2, [pb_8x1_8x0] + mova m3, [pb_8x3_8x2] +%endif + lea stride3q, [strideq*3] + mov cntq, 1 +.loop: + movd m0, [lq+cntq*4] +%if cpuflag(ssse3) + pshufb m1, m0, m3 + pshufb m0, m2 +%else + punpcklbw m0, m0 + punpcklwd m0, m0 + pshufd m1, m0, q2233 + pshufd m0, m0, q0011 +%endif + movq [dstq+strideq*0], m1 + movhps [dstq+strideq*1], m1 + movq [dstq+strideq*2], m0 + movhps [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + dec cntq + jge .loop + RET + +cglobal vp9_ipred_h_16x16, 3, 5, %2, dst, stride, l, stride3, cnt +%if cpuflag(ssse3) + mova m5, [pb_1] + mova m6, [pb_2] + mova m7, [pb_3] + pxor m4, m4 +%endif + lea stride3q, [strideq*3] + mov cntq, 3 +.loop: + movd m3, [lq+cntq*4] +%if cpuflag(ssse3) + pshufb m0, m3, m7 + pshufb m1, m3, m6 +%else + punpcklbw m3, m3 + punpcklwd m3, m3 + pshufd m0, m3, q3333 + pshufd m1, m3, q2222 +%endif + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 +%if cpuflag(ssse3) + pshufb m2, m3, m5 + pshufb m3, m4 +%else + pshufd m2, m3, q1111 + pshufd m3, m3, q0000 +%endif + mova [dstq+strideq*2], m2 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + dec cntq + jge .loop + RET + +cglobal vp9_ipred_h_32x32, 3, 5, %2, dst, stride, l, stride3, cnt +%if cpuflag(ssse3) + mova m5, [pb_1] + mova m6, [pb_2] + mova m7, [pb_3] + pxor m4, m4 +%endif + lea stride3q, [strideq*3] + mov cntq, 7 +.loop: + movd m3, [lq+cntq*4] +%if cpuflag(ssse3) + pshufb m0, m3, m7 + pshufb m1, m3, m6 +%else + punpcklbw m3, m3 + punpcklwd m3, m3 + pshufd m0, m3, q3333 + pshufd m1, m3, q2222 +%endif + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*1+ 0], m1 + mova [dstq+strideq*1+16], m1 +%if cpuflag(ssse3) + pshufb m2, m3, m5 + pshufb m3, m4 +%else + pshufd m2, m3, q1111 + pshufd m3, m3, q0000 +%endif + mova [dstq+strideq*2+ 0], m2 + mova [dstq+strideq*2+16], m2 + mova [dstq+stride3q + 0], m3 + mova [dstq+stride3q +16], m3 + lea dstq, [dstq+strideq*4] + dec cntq + jge .loop + RET +%endmacro + +INIT_XMM sse2 +H_XMM_FUNCS 2, 4 +INIT_XMM ssse3 +H_XMM_FUNCS 4, 8 +INIT_XMM avx +H_XMM_FUNCS 4, 8 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_h_32x32, 3, 5, 8, dst, stride, l, stride3, cnt + mova m5, [pb_1] + mova m6, [pb_2] + mova m7, [pb_3] + pxor m4, m4 + lea stride3q, [strideq*3] + mov cntq, 7 +.loop: + movd xm3, [lq+cntq*4] + vinserti128 m3, m3, xm3, 1 + pshufb m0, m3, m7 + pshufb m1, m3, m6 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 + pshufb m2, m3, m5 + pshufb m3, m4 + mova [dstq+strideq*2], m2 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + dec cntq + jge .loop + RET +%endif + +; tm + +%macro TM_MMX_FUNCS 0 +cglobal vp9_ipred_tm_4x4, 4, 4, 0, dst, stride, l, a + pxor m1, m1 + movd m0, [aq] + pinsrw m2, [aq-1], 0 + punpcklbw m0, m1 + DEFINE_ARGS dst, stride, l, cnt +%if cpuflag(ssse3) + mova m3, [pw_m256] + mova m1, [pw_m255] + pshufb m2, m3 +%else + punpcklbw m2, m1 + pshufw m2, m2, q0000 +%endif + psubw m0, m2 + mov cntq, 1 +.loop: + pinsrw m2, [lq+cntq*2], 0 +%if cpuflag(ssse3) + pshufb m4, m2, m1 + pshufb m2, m3 +%else + punpcklbw m2, m1 + pshufw m4, m2, q1111 + pshufw m2, m2, q0000 +%endif + paddw m4, m0 + paddw m2, m0 + packuswb m4, m4 + packuswb m2, m2 + movd [dstq+strideq*0], m4 + movd [dstq+strideq*1], m2 + lea dstq, [dstq+strideq*2] + dec cntq + jge .loop + RET +%endmacro + +INIT_MMX mmxext +TM_MMX_FUNCS +INIT_MMX ssse3 +TM_MMX_FUNCS + +%macro TM_XMM_FUNCS 0 +cglobal vp9_ipred_tm_8x8, 4, 4, 5, dst, stride, l, a + pxor m1, m1 + movh m0, [aq] + pinsrw m2, [aq-1], 0 + punpcklbw m0, m1 + DEFINE_ARGS dst, stride, l, cnt +%if cpuflag(ssse3) + mova m3, [pw_m256] + mova m1, [pw_m255] + pshufb m2, m3 +%else + punpcklbw m2, m1 + punpcklwd m2, m2 + pshufd m2, m2, q0000 +%endif + psubw m0, m2 + mov cntq, 3 +.loop: + pinsrw m2, [lq+cntq*2], 0 +%if cpuflag(ssse3) + pshufb m4, m2, m1 + pshufb m2, m3 +%else + punpcklbw m2, m1 + punpcklwd m2, m2 + pshufd m4, m2, q1111 + pshufd m2, m2, q0000 +%endif + paddw m4, m0 + paddw m2, m0 + packuswb m4, m2 + movh [dstq+strideq*0], m4 + movhps [dstq+strideq*1], m4 + lea dstq, [dstq+strideq*2] + dec cntq + jge .loop + RET + +cglobal vp9_ipred_tm_16x16, 4, 4, 8, dst, stride, l, a + pxor m3, m3 + mova m0, [aq] + pinsrw m2, [aq-1], 0 + punpckhbw m1, m0, m3 + punpcklbw m0, m3 + DEFINE_ARGS dst, stride, l, cnt +%if cpuflag(ssse3) + mova m4, [pw_m256] + mova m3, [pw_m255] + pshufb m2, m4 +%else + punpcklbw m2, m3 + punpcklwd m2, m2 + pshufd m2, m2, q0000 +%endif + psubw m1, m2 + psubw m0, m2 + mov cntq, 7 +.loop: + pinsrw m7, [lq+cntq*2], 0 +%if cpuflag(ssse3) + pshufb m5, m7, m3 + pshufb m7, m4 +%else + punpcklbw m7, m3 + punpcklwd m7, m7 + pshufd m5, m7, q1111 + pshufd m7, m7, q0000 +%endif + paddw m2, m5, m0 + paddw m5, m1 + paddw m6, m7, m0 + paddw m7, m1 + packuswb m2, m5 + packuswb m6, m7 + mova [dstq+strideq*0], m2 + mova [dstq+strideq*1], m6 + lea dstq, [dstq+strideq*2] + dec cntq + jge .loop + RET + +%if ARCH_X86_64 +%define mem 0 +%else +%define mem 64 +%endif +cglobal vp9_ipred_tm_32x32, 4, 4, 14, mem, dst, stride, l, a + pxor m5, m5 + pinsrw m4, [aq-1], 0 + mova m0, [aq] + mova m2, [aq+16] + DEFINE_ARGS dst, stride, l, cnt +%if cpuflag(ssse3) +%if ARCH_X86_64 + mova m12, [pw_m256] + mova m13, [pw_m255] +%define pw_m256_reg m12 +%define pw_m255_reg m13 +%else +%define pw_m256_reg [pw_m256] +%define pw_m255_reg [pw_m255] +%endif + pshufb m4, pw_m256_reg +%else + punpcklbw m4, m5 + punpcklwd m4, m4 + pshufd m4, m4, q0000 +%endif + punpckhbw m1, m0, m5 + punpckhbw m3, m2, m5 + punpcklbw m0, m5 + punpcklbw m2, m5 + psubw m1, m4 + psubw m0, m4 + psubw m3, m4 + psubw m2, m4 +%if ARCH_X86_64 + SWAP 0, 8 + SWAP 1, 9 + SWAP 2, 10 + SWAP 3, 11 +%else + mova [rsp+0*16], m0 + mova [rsp+1*16], m1 + mova [rsp+2*16], m2 + mova [rsp+3*16], m3 +%endif + mov cntq, 15 +.loop: + pinsrw m3, [lq+cntq*2], 0 +%if cpuflag(ssse3) + pshufb m7, m3, pw_m255_reg + pshufb m3, pw_m256_reg +%else + pxor m7, m7 + punpcklbw m3, m7 + punpcklwd m3, m3 + pshufd m7, m3, q1111 + pshufd m3, m3, q0000 +%endif +%if ARCH_X86_64 + paddw m4, m7, m8 + paddw m5, m7, m9 + paddw m6, m7, m10 + paddw m7, m11 + paddw m0, m3, m8 + paddw m1, m3, m9 + paddw m2, m3, m10 + paddw m3, m11 +%else + paddw m4, m7, [rsp+0*16] + paddw m5, m7, [rsp+1*16] + paddw m6, m7, [rsp+2*16] + paddw m7, [rsp+3*16] + paddw m0, m3, [rsp+0*16] + paddw m1, m3, [rsp+1*16] + paddw m2, m3, [rsp+2*16] + paddw m3, [rsp+3*16] +%endif + packuswb m4, m5 + packuswb m6, m7 + packuswb m0, m1 + packuswb m2, m3 + mova [dstq+strideq*0+ 0], m4 + mova [dstq+strideq*0+16], m6 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m2 + lea dstq, [dstq+strideq*2] + dec cntq + jge .loop + RET +%undef pw_m256_reg +%undef pw_m255_reg +%undef mem +%endmacro + +INIT_XMM sse2 +TM_XMM_FUNCS +INIT_XMM ssse3 +TM_XMM_FUNCS +INIT_XMM avx +TM_XMM_FUNCS + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_tm_32x32, 4, 4, 8, dst, stride, l, a + pxor m3, m3 + pinsrw xm2, [aq-1], 0 + vinserti128 m2, m2, xm2, 1 + mova m0, [aq] + DEFINE_ARGS dst, stride, l, cnt + mova m4, [pw_m256] + mova m5, [pw_m255] + pshufb m2, m4 + punpckhbw m1, m0, m3 + punpcklbw m0, m3 + psubw m1, m2 + psubw m0, m2 + mov cntq, 15 +.loop: + pinsrw xm7, [lq+cntq*2], 0 + vinserti128 m7, m7, xm7, 1 + pshufb m3, m7, m5 + pshufb m7, m4 + paddw m2, m3, m0 + paddw m3, m1 + paddw m6, m7, m0 + paddw m7, m1 + packuswb m2, m3 + packuswb m6, m7 + mova [dstq+strideq*0], m2 + mova [dstq+strideq*1], m6 + lea dstq, [dstq+strideq*2] + dec cntq + jge .loop + RET +%endif + +; dl + +%macro LOWPASS 4 ; left [dst], center, right, tmp + pxor m%4, m%1, m%3 + pand m%4, [pb_1] + pavgb m%1, m%3 + psubusb m%1, m%4 + pavgb m%1, m%2 +%endmacro + +%macro DL_MMX_FUNCS 0 +cglobal vp9_ipred_dl_4x4, 4, 4, 0, dst, stride, l, a + movq m1, [aq] +%if cpuflag(ssse3) + pshufb m0, m1, [pb_0to5_2x7] + pshufb m2, m1, [pb_2to6_3x7] +%else + punpckhbw m3, m1, m1 ; 44556677 + pand m0, m1, [pb_6xm1_2x0] ; 012345__ + pand m3, [pb_6x0_2xm1] ; ______77 + psrlq m2, m1, 16 ; 234567__ + por m0, m3 ; 01234577 + por m2, m3 ; 23456777 +%endif + psrlq m1, 8 + LOWPASS 0, 1, 2, 3 + + pshufw m1, m0, q3321 + movd [dstq+strideq*0], m0 + movd [dstq+strideq*2], m1 + psrlq m0, 8 + psrlq m1, 8 + add dstq, strideq + movd [dstq+strideq*0], m0 + movd [dstq+strideq*2], m1 + RET +%endmacro + +INIT_MMX mmxext +DL_MMX_FUNCS +INIT_MMX ssse3 +DL_MMX_FUNCS + +%macro DL_XMM_FUNCS 0 +cglobal vp9_ipred_dl_8x8, 4, 4, 4, dst, stride, stride5, a + movq m0, [aq] + lea stride5q, [strideq*5] +%if cpuflag(ssse3) + pshufb m1, m0, [pb_1to6_10x7] +%else + punpcklbw m1, m0, m0 ; 0011223344556677 + punpckhwd m1, m1 ; 4x4,4x5,4x6,4x7 +%endif + shufps m0, m1, q3310 +%if notcpuflag(ssse3) + psrldq m1, m0, 1 + shufps m1, m0, q3210 +%endif + psrldq m2, m1, 1 + LOWPASS 0, 1, 2, 3 + + pshufd m1, m0, q3321 + movq [dstq+strideq*0], m0 + movq [dstq+strideq*4], m1 + psrldq m0, 1 + psrldq m1, 1 + movq [dstq+strideq*1], m0 + movq [dstq+stride5q ], m1 + lea dstq, [dstq+strideq*2] + psrldq m0, 1 + psrldq m1, 1 + movq [dstq+strideq*0], m0 + movq [dstq+strideq*4], m1 + psrldq m0, 1 + psrldq m1, 1 + movq [dstq+strideq*1], m0 + movq [dstq+stride5q ], m1 + RET + +cglobal vp9_ipred_dl_16x16, 4, 4, 6, dst, stride, l, a + mova m0, [aq] +%if cpuflag(ssse3) + mova m5, [pb_1toE_2xF] + pshufb m1, m0, m5 + pshufb m2, m1, m5 + pshufb m4, m0, [pb_15] +%else + pand m5, m0, [pb_15x0_1xm1] ; _______________F + psrldq m1, m0, 1 ; 123456789ABCDEF_ + por m1, m5 ; 123456789ABCDEFF + psrldq m2, m1, 1 ; 23456789ABCDEFF_ + por m2, m5 ; 23456789ABCDEFFF + pshufhw m4, m1, q3333 ; xxxxxxxxFFFFFFFF +%endif + LOWPASS 0, 1, 2, 3 + DEFINE_ARGS dst, stride, cnt, stride9 + lea stride9q, [strideq+strideq*8] + mov cntd, 4 + +.loop: + movhlps m4, m0 + mova [dstq+strideq*0], m0 +%if cpuflag(ssse3) + pshufb m0, m5 +%else + psrldq m0, 1 + por m0, m5 +%endif + mova [dstq+strideq*8], m4 + movhlps m4, m0 + mova [dstq+strideq*1], m0 +%if cpuflag(ssse3) + pshufb m0, m5 +%else + psrldq m0, 1 + por m0, m5 +%endif + mova [dstq+stride9q ], m4 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dl_32x32, 4, 5, 8, dst, stride, cnt, a, dst16 + mova m0, [aq] + mova m1, [aq+16] + PALIGNR m2, m1, m0, 1, m4 + PALIGNR m3, m1, m0, 2, m4 + LOWPASS 0, 2, 3, 4 +%if cpuflag(ssse3) + mova m5, [pb_1toE_2xF] + pshufb m2, m1, m5 + pshufb m3, m2, m5 + pshufb m6, m1, [pb_15] + mova m7, m6 +%else + pand m5, m1, [pb_15x0_1xm1] ; _______________F + psrldq m2, m1, 1 ; 123456789ABCDEF_ + por m2, m5 ; 123456789ABCDEFF + psrldq m3, m2, 1 ; 23456789ABCDEFF_ + por m3, m5 ; 23456789ABCDEFFF + pshufhw m7, m2, q3333 ; xxxxxxxxFFFFFFFF + pshufd m6, m7, q3333 +%endif + LOWPASS 1, 2, 3, 4 + lea dst16q, [dstq +strideq*8] + mov cntd, 8 + lea dst16q, [dst16q+strideq*8] +.loop: + movhlps m7, m1 + mova [dstq +strideq*0+ 0], m0 + mova [dstq +strideq*0+16], m1 + movhps [dstq+strideq*8+ 0], m0 + movq [dstq +strideq*8+ 8], m1 + mova [dstq +strideq*8+16], m7 + mova [dst16q+strideq*0+ 0], m1 + mova [dst16q+strideq*0+16], m6 + mova [dst16q+strideq*8+ 0], m7 + mova [dst16q+strideq*8+16], m6 +%if cpuflag(avx) + vpalignr m0, m1, m0, 1 + pshufb m1, m5 +%elif cpuflag(ssse3) + palignr m2, m1, m0, 1 + pshufb m1, m5 + mova m0, m2 +%else + mova m4, m1 + psrldq m0, 1 + pslldq m4, 15 + psrldq m1, 1 + por m0, m4 + por m1, m5 +%endif + add dstq, strideq + add dst16q, strideq + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +DL_XMM_FUNCS +INIT_XMM ssse3 +DL_XMM_FUNCS +INIT_XMM avx +DL_XMM_FUNCS + +; dr + +%macro DR_MMX_FUNCS 0 +cglobal vp9_ipred_dr_4x4, 4, 4, 0, dst, stride, l, a + movd m0, [lq] + punpckldq m0, [aq-1] + movd m1, [aq+3] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + PALIGNR m1, m0, 1, m3 + psrlq m2, m1, 8 + LOWPASS 0, 1, 2, 3 + + movd [dstq+stride3q ], m0 + psrlq m0, 8 + movd [dstq+strideq*2], m0 + psrlq m0, 8 + movd [dstq+strideq*1], m0 + psrlq m0, 8 + movd [dstq+strideq*0], m0 + RET +%endmacro + +INIT_MMX mmxext +DR_MMX_FUNCS +INIT_MMX ssse3 +DR_MMX_FUNCS + +%macro DR_XMM_FUNCS 0 +cglobal vp9_ipred_dr_8x8, 4, 4, 4, dst, stride, l, a + movq m1, [lq] + movhps m1, [aq-1] + movd m2, [aq+7] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pslldq m0, m1, 1 + PALIGNR m2, m1, 1, m3 + LOWPASS 0, 1, 2, 3 + + movhps [dstq+strideq*0], m0 + pslldq m0, 1 + movhps [dstq+strideq*1], m0 + pslldq m0, 1 + movhps [dstq+strideq*2], m0 + pslldq m0, 1 + movhps [dstq+stride3q ], m0 + pslldq m0, 1 + lea dstq, [dstq+strideq*4] + movhps [dstq+strideq*0], m0 + pslldq m0, 1 + movhps [dstq+strideq*1], m0 + pslldq m0, 1 + movhps [dstq+strideq*2], m0 + pslldq m0, 1 + movhps [dstq+stride3q ], m0 + RET + +cglobal vp9_ipred_dr_16x16, 4, 4, 6, dst, stride, l, a + mova m1, [lq] + movu m2, [aq-1] + movd m4, [aq+15] + DEFINE_ARGS dst, stride, stride9, cnt + lea stride9q, [strideq *3] + mov cntd, 4 + lea stride9q, [stride9q*3] + PALIGNR m4, m2, 1, m5 + PALIGNR m3, m2, m1, 15, m5 + LOWPASS 3, 2, 4, 5 + pslldq m0, m1, 1 + PALIGNR m2, m1, 1, m4 + LOWPASS 0, 1, 2, 4 + +.loop: + mova [dstq+strideq*0 ], m3 + movhps [dstq+strideq*8+0], m0 + movq [dstq+strideq*8+8], m3 + PALIGNR m3, m0, 15, m1 + pslldq m0, 1 + mova [dstq+strideq*1 ], m3 + movhps [dstq+stride9q +0], m0 + movq [dstq+stride9q +8], m3 + PALIGNR m3, m0, 15, m1 + pslldq m0, 1 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dr_32x32, 4, 4, 8, dst, stride, l, a + mova m1, [lq] + mova m2, [lq+16] + movu m3, [aq-1] + movu m4, [aq+15] + movd m5, [aq+31] + DEFINE_ARGS dst, stride, stride8, cnt + lea stride8q, [strideq*8] + PALIGNR m5, m4, 1, m7 + PALIGNR m6, m4, m3, 15, m7 + LOWPASS 5, 4, 6, 7 + PALIGNR m4, m3, 1, m7 + PALIGNR m6, m3, m2, 15, m7 + LOWPASS 4, 3, 6, 7 + PALIGNR m3, m2, 1, m7 + PALIGNR m6, m2, m1, 15, m7 + LOWPASS 3, 2, 6, 7 + PALIGNR m2, m1, 1, m6 + pslldq m0, m1, 1 + LOWPASS 2, 1, 0, 6 + mov cntd, 16 + + ; out=m2/m3/m4/m5 +.loop: + mova [dstq+stride8q*0+ 0], m4 + mova [dstq+stride8q*0+16], m5 + mova [dstq+stride8q*2+ 0], m3 + mova [dstq+stride8q*2+16], m4 + PALIGNR m5, m4, 15, m6 + PALIGNR m4, m3, 15, m6 + PALIGNR m3, m2, 15, m6 + pslldq m2, 1 + add dstq, strideq + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +DR_XMM_FUNCS +INIT_XMM ssse3 +DR_XMM_FUNCS +INIT_XMM avx +DR_XMM_FUNCS + +; vl + +INIT_MMX mmxext +cglobal vp9_ipred_vl_4x4, 4, 4, 0, dst, stride, l, a + movq m0, [aq] + psrlq m1, m0, 8 + psrlq m2, m1, 8 + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + movd [dstq+strideq*0], m1 + movd [dstq+strideq*1], m2 + lea dstq, [dstq+strideq*2] + psrlq m1, 8 + psrlq m2, 8 + movd [dstq+strideq*0], m1 + movd [dstq+strideq*1], m2 + RET + +%macro VL_XMM_FUNCS 0 +cglobal vp9_ipred_vl_8x8, 4, 4, 4, dst, stride, l, a + movq m0, [aq] +%if cpuflag(ssse3) + pshufb m0, [pb_0to6_9x7] +%else + punpcklbw m1, m0, m0 + punpckhwd m1, m1 + shufps m0, m1, q3310 +%endif + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + psrldq m1, m0, 1 + psrldq m2, m0, 2 + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + + movq [dstq+strideq*0], m1 + movq [dstq+strideq*1], m2 + psrldq m1, 1 + psrldq m2, 1 + movq [dstq+strideq*2], m1 + movq [dstq+stride3q ], m2 + lea dstq, [dstq+strideq*4] + psrldq m1, 1 + psrldq m2, 1 + movq [dstq+strideq*0], m1 + movq [dstq+strideq*1], m2 + psrldq m1, 1 + psrldq m2, 1 + movq [dstq+strideq*2], m1 + movq [dstq+stride3q ], m2 + RET + +cglobal vp9_ipred_vl_16x16, 4, 4, 5, dst, stride, l, a + mova m0, [aq] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] +%if cpuflag(ssse3) + mova m4, [pb_1toE_2xF] + pshufb m1, m0, m4 + pshufb m2, m1, m4 +%else + pand m4, m0, [pb_15x0_1xm1] ; _______________F + psrldq m1, m0, 1 ; 123456789ABCDEF_ + por m1, m4 ; 123456789ABCDEFF + psrldq m2, m1, 1 ; 23456789ABCDEFF_ + por m2, m4 ; 23456789ABCDEFFF +%endif + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + mov cntd, 4 +.loop: + mova [dstq+strideq*0], m1 + mova [dstq+strideq*1], m2 +%if cpuflag(ssse3) + pshufb m1, m4 + pshufb m2, m4 +%else + psrldq m1, 1 + psrldq m2, 1 + por m1, m4 + por m2, m4 +%endif + mova [dstq+strideq*2], m1 + mova [dstq+stride3q ], m2 +%if cpuflag(ssse3) + pshufb m1, m4 + pshufb m2, m4 +%else + psrldq m1, 1 + psrldq m2, 1 + por m1, m4 + por m2, m4 +%endif + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +cglobal vp9_ipred_vl_32x32, 4, 4, 7, dst, stride, l, a + mova m0, [aq] + mova m5, [aq+16] + DEFINE_ARGS dst, stride, dst16, cnt + PALIGNR m2, m5, m0, 1, m4 + PALIGNR m3, m5, m0, 2, m4 + lea dst16q, [dstq +strideq*8] + LOWPASS 3, 2, 0, 6 + pavgb m2, m0 +%if cpuflag(ssse3) + mova m4, [pb_1toE_2xF] + pshufb m0, m5, m4 + pshufb m1, m0, m4 +%else + pand m4, m5, [pb_15x0_1xm1] ; _______________F + psrldq m0, m5, 1 ; 123456789ABCDEF_ + por m0, m4 ; 123456789ABCDEFF + psrldq m1, m0, 1 ; 23456789ABCDEFF_ + por m1, m4 ; 23456789ABCDEFFF +%endif + lea dst16q, [dst16q+strideq*8] + LOWPASS 1, 0, 5, 6 + pavgb m0, m5 +%if cpuflag(ssse3) + pshufb m5, [pb_15] +%else + punpckhbw m5, m4, m4 + pshufhw m5, m5, q3333 + punpckhqdq m5, m5 +%endif + mov cntd, 8 + +.loop: +%macro %%write 3 + mova [dstq+stride%1+ 0], %2 + mova [dstq+stride%1+16], %3 + movhps [dst16q+stride%1 ], %2 + movu [dst16q+stride%1+ 8], %3 + movq [dst16q+stride%1+24], m5 +%if cpuflag(avx) + palignr %2, %3, %2, 1 + pshufb %3, m4 +%elif cpuflag(ssse3) + palignr m6, %3, %2, 1 + pshufb %3, m4 + mova %2, m6 +%else + pslldq m6, %3, 15 + psrldq %3, 1 + psrldq %2, 1 + por %3, m4 + por %2, m6 +%endif +%endmacro + + %%write q*0, m2, m0 + %%write q*1, m3, m1 + lea dstq, [dstq +strideq*2] + lea dst16q, [dst16q+strideq*2] + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +VL_XMM_FUNCS +INIT_XMM ssse3 +VL_XMM_FUNCS +INIT_XMM avx +VL_XMM_FUNCS + +; vr + +%macro VR_MMX_FUNCS 0 +cglobal vp9_ipred_vr_4x4, 4, 4, 0, dst, stride, l, a + movq m1, [aq-1] + punpckldq m2, [lq] + movd m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pavgb m0, m1 + PALIGNR m1, m2, 5, m3 + psrlq m2, m1, 8 + psllq m3, m1, 8 + LOWPASS 2, 1, 3, 4 + + ; ABCD <- for the following predictor: + ; EFGH + ; IABC | m0 contains ABCDxxxx + ; JEFG | m2 contains xJIEFGHx + +%if cpuflag(ssse3) + punpckldq m0, m2 + pshufb m2, [pb_13456_3xm1] + movd [dstq+strideq*0], m0 + pshufb m0, [pb_6012_4xm1] + movd [dstq+stride3q ], m2 + psrlq m2, 8 + movd [dstq+strideq*2], m0 + movd [dstq+strideq*1], m2 +%else + psllq m1, m2, 40 + psrlq m2, 24 + movd [dstq+strideq*0], m0 + movd [dstq+strideq*1], m2 + PALIGNR m0, m1, 7, m3 + psllq m1, 8 + PALIGNR m2, m1, 7, m3 + movd [dstq+strideq*2], m0 + movd [dstq+stride3q ], m2 +%endif + RET +%endmacro + +INIT_MMX mmxext +VR_MMX_FUNCS +INIT_MMX ssse3 +VR_MMX_FUNCS + +%macro VR_XMM_FUNCS 1 ; n_xmm_regs for 16x16 +cglobal vp9_ipred_vr_8x8, 4, 4, 5, dst, stride, l, a + movu m1, [aq-1] + movhps m2, [lq] + movq m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pavgb m0, m1 + PALIGNR m1, m2, 9, m3 + pslldq m2, m1, 1 + pslldq m3, m1, 2 + LOWPASS 1, 2, 3, 4 + + ; ABCDEFGH <- for the following predictor: + ; IJKLMNOP + ; QABCDEFG | m0 contains ABCDEFGHxxxxxxxx + ; RIJKLMNO | m1 contains xxVUTSRQIJKLMNOP + ; SQABCDEF + ; TRIJKLMN + ; USQABCDE + ; VTRIJKLM + +%if cpuflag(ssse3) + punpcklqdq m0, m1 ; ABCDEFGHxxVUTSRQ +%endif + movq [dstq+strideq*0], m0 + movhps [dstq+strideq*1], m1 +%if cpuflag(ssse3) + pshufb m0, [pb_6xm1_BDF_0to6] ; xxxxxxUSQABCDEFG + pshufb m1, [pb_6xm1_246_8toE] ; xxxxxxVTRIJKLMNO +%else + psrlw m2, m1, 8 ; x_U_S_Q_xxxxxxxx + pand m3, m1, [pw_255] ; x_V_T_R_xxxxxxxx + packuswb m3, m2 ; xVTRxxxxxUSQxxxx + pslldq m3, 4 ; xxxxxVTRxxxxxUSQ + PALIGNR m0, m3, 7, m4 ; xxxxxxUSQABCDEFG + psrldq m1, 8 + pslldq m3, 8 + PALIGNR m1, m3, 7, m4 ; xxxxxxVTRIJKLMNO +%endif + movhps [dstq+strideq*2], m0 + movhps [dstq+stride3q ], m1 + lea dstq, [dstq+strideq*4] + pslldq m0, 1 + pslldq m1, 1 + movhps [dstq+strideq*0], m0 + movhps [dstq+strideq*1], m1 + pslldq m0, 1 + pslldq m1, 1 + movhps [dstq+strideq*2], m0 + movhps [dstq+stride3q ], m1 + RET + +cglobal vp9_ipred_vr_16x16, 4, 4, %1, dst, stride, l, a + mova m0, [aq] + movu m1, [aq-1] + mova m2, [lq] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + PALIGNR m3, m1, m2, 15, m6 + LOWPASS 3, 1, 0, 4 + pavgb m0, m1 + PALIGNR m1, m2, 1, m6 + pslldq m4, m2, 1 + LOWPASS 1, 2, 4, 5 +%if cpuflag(ssse3) + pshufb m1, [pb_02468ACE_13579BDF] +%else + psrlw m5, m1, 8 + pand m1, [pw_255] + packuswb m1, m5 +%endif + mov cntd, 4 + +.loop: + movlhps m2, m1 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m3 + PALIGNR m4, m0, m1, 15, m6 + PALIGNR m5, m3, m2, 15, m6 + mova [dstq+strideq*2], m4 + mova [dstq+stride3q ], m5 + lea dstq, [dstq+strideq*4] + PALIGNR m0, m1, 14, m6 + PALIGNR m3, m2, 14, m6 + pslldq m1, 2 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_vr_32x32, 4, 4, 9, dst, stride, l, a + mova m0, [aq] + mova m2, [aq+16] + movu m1, [aq-1] + PALIGNR m3, m2, m0, 15, m6 + PALIGNR m4, m2, m0, 14, m6 + LOWPASS 4, 3, 2, 5 + pavgb m3, m2 + mova m2, [lq+16] + PALIGNR m5, m1, m2, 15, m6 + LOWPASS 5, 1, 0, 6 + pavgb m0, m1 + mova m6, [lq] +%if ARCH_X86_64 + SWAP 0, 8 +%else + mova [dstq], m0 +%endif + PALIGNR m1, m2, 1, m0 + PALIGNR m7, m2, m6, 15, m0 + LOWPASS 1, 2, 7, 0 + PALIGNR m2, m6, 1, m0 + pslldq m7, m6, 1 + LOWPASS 2, 6, 7, 0 +%if cpuflag(ssse3) + pshufb m1, [pb_02468ACE_13579BDF] + pshufb m2, [pb_02468ACE_13579BDF] +%else + psrlw m0, m1, 8 + psrlw m6, m2, 8 + pand m1, [pw_255] + pand m2, [pw_255] + packuswb m1, m0 + packuswb m2, m6 +%endif + DEFINE_ARGS dst, stride, dst16, cnt + lea dst16q, [dstq +strideq*8] + lea dst16q, [dst16q+strideq*8] + SBUTTERFLY qdq, 2, 1, 6 +%if ARCH_X86_64 + SWAP 0, 8 +%else + mova m0, [dstq] +%endif + mov cntd, 8 + +.loop: + ; even lines (0, 2, 4, ...): m1 | m0, m3 + ; odd lines (1, 3, 5, ...): m2 | m5, m4 +%macro %%write 4 + mova [dstq+stride%1+ 0], %3 + mova [dstq+stride%1+16], %4 + movhps [dst16q+stride%1 ], %2 + movu [dst16q+stride%1+ 8], %3 + movq [dst16q+stride%1+24], %4 + PALIGNR %4, %3, 15, m6 + PALIGNR %3, %2, 15, m6 + pslldq %2, 1 +%endmacro + + %%write q*0, m1, m0, m3 + %%write q*1, m2, m5, m4 + lea dstq, [dstq +strideq*2] + lea dst16q, [dst16q+strideq*2] + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +VR_XMM_FUNCS 7 +INIT_XMM ssse3 +VR_XMM_FUNCS 6 +INIT_XMM avx +VR_XMM_FUNCS 6 + +; hd + +INIT_MMX mmxext +cglobal vp9_ipred_hd_4x4, 4, 4, 0, dst, stride, l, a + movd m0, [lq] + punpckldq m0, [aq-1] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + psrlq m1, m0, 8 + psrlq m2, m1, 8 + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + + ; DHIJ <- for the following predictor: + ; CGDH + ; BFCG | m1 contains ABCDxxxx + ; AEBF | m2 contains EFGHIJxx + + punpcklbw m1, m2 + punpckhdq m0, m1, m2 + + ; m1 contains AEBFCGDH + ; m0 contains CGDHIJxx + + movd [dstq+stride3q ], m1 + movd [dstq+strideq*1], m0 + psrlq m1, 16 + psrlq m0, 16 + movd [dstq+strideq*2], m1 + movd [dstq+strideq*0], m0 + RET + +%macro HD_XMM_FUNCS 0 +cglobal vp9_ipred_hd_8x8, 4, 4, 5, dst, stride, l, a + movq m0, [lq] + movhps m0, [aq-1] + DEFINE_ARGS dst, stride, stride3, dst4 + lea stride3q, [strideq*3] + lea dst4q, [dstq+strideq*4] + psrldq m1, m0, 1 + psrldq m2, m1, 1 + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + + ; HPQRSTUV <- for the following predictor + ; GOHPQRST + ; FNGOHPQR | m1 contains ABCDEFGHxxxxxxxx + ; EMFNGOHP | m2 contains IJKLMNOPQRSTUVxx + ; DLEMFNGO + ; CKDLEMFN + ; BJCKDLEM + ; AIBJCKDL + + punpcklbw m1, m2 + movhlps m2, m2 + + ; m1 contains AIBJCKDLEMFNGOHP + ; m2 contains QRSTUVxxxxxxxxxx + + movhps [dstq +stride3q ], m1 + movq [dst4q+stride3q ], m1 + PALIGNR m3, m2, m1, 2, m4 + movhps [dstq +strideq*2], m3 + movq [dst4q+strideq*2], m3 + PALIGNR m3, m2, m1, 4, m4 + movhps [dstq +strideq*1], m3 + movq [dst4q+strideq*1], m3 + PALIGNR m2, m1, 6, m4 + movhps [dstq +strideq*0], m2 + movq [dst4q+strideq*0], m2 + RET + +cglobal vp9_ipred_hd_16x16, 4, 6, 7, dst, stride, l, a + mova m0, [lq] + movu m3, [aq-1] + DEFINE_ARGS dst, stride, stride4, dst4, dst8, dst12 + lea stride4q, [strideq*4] + lea dst4q, [dstq +stride4q] + lea dst8q, [dst4q+stride4q] + lea dst12q, [dst8q+stride4q] + psrldq m4, m3, 1 + psrldq m5, m3, 2 + LOWPASS 5, 4, 3, 6 + PALIGNR m1, m3, m0, 1, m6 + PALIGNR m2, m3, m0, 2, m6 + LOWPASS 2, 1, 0, 6 + pavgb m1, m0 + SBUTTERFLY bw, 1, 2, 6 + + ; I PROBABLY INVERTED L0 ad L16 here + ; m1, m2, m5 +.loop: + sub stride4q, strideq + movhps [dstq +stride4q +0], m2 + movq [dstq +stride4q +8], m5 + mova [dst4q+stride4q ], m2 + movhps [dst8q+stride4q +0], m1 + movq [dst8q+stride4q +8], m2 + mova [dst12q+stride4q ], m1 +%if cpuflag(avx) + palignr m1, m2, m1, 2 + palignr m2, m5, m2, 2 +%elif cpuflag(ssse3) + palignr m3, m2, m1, 2 + palignr m0, m5, m2, 2 + mova m1, m3 + mova m2, m0 +%else + ; slightly modified version of PALIGNR + mova m6, m2 + mova m4, m5 + pslldq m6, 14 + pslldq m4, 14 + psrldq m1, 2 + psrldq m2, 2 + por m1, m6 + por m2, m4 +%endif + psrldq m5, 2 + jg .loop + RET + +cglobal vp9_ipred_hd_32x32, 4, 6, 8, dst, stride, l, a + mova m0, [lq] + mova m1, [lq+16] + movu m2, [aq-1] + movu m3, [aq+15] + DEFINE_ARGS dst, stride, stride8, dst8, dst16, dst24 + lea stride8q, [strideq*8] + lea dst8q, [dstq +stride8q] + lea dst16q, [dst8q +stride8q] + lea dst24q, [dst16q+stride8q] + psrldq m4, m3, 1 + psrldq m5, m3, 2 + LOWPASS 5, 4, 3, 6 + PALIGNR m4, m3, m2, 2, m6 + PALIGNR m3, m2, 1, m6 + LOWPASS 4, 3, 2, 6 + PALIGNR m3, m2, m1, 2, m6 + PALIGNR m2, m1, 1, m6 + LOWPASS 3, 2, 1, 6 + pavgb m2, m1 + PALIGNR m6, m1, m0, 1, m7 + PALIGNR m1, m0, 2, m7 + LOWPASS 1, 6, 0, 7 + pavgb m0, m6 + SBUTTERFLY bw, 2, 3, 6 + SBUTTERFLY bw, 0, 1, 6 + + ; m0, m1, m2, m3, m4, m5 +.loop: + sub stride8q, strideq + mova [dstq +stride8q+ 0], m3 + mova [dstq +stride8q+16], m4 + mova [dst8q +stride8q+ 0], m2 + mova [dst8q +stride8q+16], m3 + mova [dst16q+stride8q+ 0], m1 + mova [dst16q+stride8q+16], m2 + mova [dst24q+stride8q+ 0], m0 + mova [dst24q+stride8q+16], m1 +%if cpuflag(avx) + palignr m0, m1, m0, 2 + palignr m1, m2, m1, 2 + palignr m2, m3, m2, 2 + palignr m3, m4, m3, 2 + palignr m4, m5, m4, 2 + psrldq m5, 2 +%elif cpuflag(ssse3) + psrldq m6, m5, 2 + palignr m5, m4, 2 + palignr m4, m3, 2 + palignr m3, m2, 2 + palignr m2, m1, 2 + palignr m1, m0, 2 + mova m0, m1 + mova m1, m2 + mova m2, m3 + mova m3, m4 + mova m4, m5 + mova m5, m6 +%else + ; sort of a half-integrated version of PALIGNR + pslldq m7, m4, 14 + pslldq m6, m5, 14 + psrldq m4, 2 + psrldq m5, 2 + por m4, m6 + pslldq m6, m3, 14 + psrldq m3, 2 + por m3, m7 + pslldq m7, m2, 14 + psrldq m2, 2 + por m2, m6 + pslldq m6, m1, 14 + psrldq m1, 2 + por m1, m7 + psrldq m0, 2 + por m0, m6 +%endif + jg .loop + RET +%endmacro + +INIT_XMM sse2 +HD_XMM_FUNCS +INIT_XMM ssse3 +HD_XMM_FUNCS +INIT_XMM avx +HD_XMM_FUNCS + +%macro HU_MMX_FUNCS 0 +cglobal vp9_ipred_hu_4x4, 3, 3, 0, dst, stride, l + movd m0, [lq] +%if cpuflag(ssse3) + pshufb m0, [pb_0to2_5x3] +%else + punpcklbw m1, m0, m0 ; 00112233 + pshufw m1, m1, q3333 ; 33333333 + punpckldq m0, m1 ; 01233333 +%endif + psrlq m1, m0, 8 + psrlq m2, m1, 8 + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + SBUTTERFLY bw, 1, 2, 0 + PALIGNR m2, m1, 2, m0 + movd [dstq+strideq*0], m1 + movd [dstq+strideq*1], m2 + punpckhdq m1, m1 + punpckhdq m2, m2 + movd [dstq+strideq*2], m1 + movd [dstq+stride3q ], m2 + RET +%endmacro + +INIT_MMX mmxext +HU_MMX_FUNCS +INIT_MMX ssse3 +HU_MMX_FUNCS + +%macro HU_XMM_FUNCS 1 ; n_xmm_regs in hu_32x32 +cglobal vp9_ipred_hu_8x8, 3, 4, 4, dst, stride, l + movq m0, [lq] +%if cpuflag(ssse3) + pshufb m0, [pb_0to6_9x7] +%else + punpcklbw m1, m0, m0 ; 0011223344556677 + punpckhwd m1, m1 ; 4444555566667777 + shufps m0, m1, q3310 ; 0123456777777777 +%endif + psrldq m1, m0, 1 + psrldq m2, m1, 1 + LOWPASS 2, 1, 0, 3 + pavgb m1, m0 + DEFINE_ARGS dst, stride, stride3, dst4 + lea stride3q, [strideq*3] + lea dst4q, [dstq+strideq*4] + SBUTTERFLY bw, 1, 2, 0 + movq [dstq +strideq*0], m1 + movhps [dst4q+strideq*0], m1 + PALIGNR m0, m2, m1, 2, m3 + movq [dstq +strideq*1], m0 + movhps [dst4q+strideq*1], m0 + PALIGNR m0, m2, m1, 4, m3 + movq [dstq +strideq*2], m0 + movhps [dst4q+strideq*2], m0 + PALIGNR m2, m1, 6, m3 + movq [dstq +stride3q ], m2 + movhps [dst4q+stride3q ], m2 + RET + +cglobal vp9_ipred_hu_16x16, 3, 4, 5, dst, stride, l + mova m0, [lq] +%if cpuflag(ssse3) + mova m3, [pb_2toE_3xF] + pshufb m1, m0, [pb_1toE_2xF] + pshufb m2, m0, m3 +%else + pand m3, m0, [pb_15x0_1xm1] + psrldq m1, m0, 1 + por m1, m3 + punpckhbw m3, m3 + psrldq m2, m0, 2 + por m2, m3 +%endif + LOWPASS 2, 1, 0, 4 + pavgb m1, m0 + DEFINE_ARGS dst, stride, stride9, cnt + lea stride9q, [strideq*8+strideq] + mov cntd, 4 + SBUTTERFLY bw, 1, 2, 0 + +.loop: + mova [dstq+strideq*0], m1 + mova [dstq+strideq*8], m2 + PALIGNR m0, m2, m1, 2, m4 +%if cpuflag(ssse3) + pshufb m2, m3 +%else + psrldq m2, 2 + por m2, m3 +%endif + mova [dstq+strideq*1], m0 + mova [dstq+stride9q ], m2 + PALIGNR m1, m2, m0, 2, m4 +%if cpuflag(ssse3) + pshufb m2, m3 +%else + psrldq m2, 2 + por m2, m3 +%endif + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop + RET + +cglobal vp9_ipred_hu_32x32, 3, 7, %1, dst, stride, l + mova m1, [lq] + mova m0, [lq+16] + PALIGNR m2, m0, m1, 1, m5 + PALIGNR m3, m0, m1, 2, m5 + LOWPASS 3, 2, 1, 5 + pavgb m2, m1 +%if cpuflag(ssse3) + mova m4, [pb_2toE_3xF] + pshufb m5, m0, [pb_1toE_2xF] + pshufb m1, m0, m4 +%else + pand m4, m0, [pb_15x0_1xm1] + psrldq m5, m0, 1 + por m5, m4 + punpckhbw m4, m4 + psrldq m1, m0, 2 + por m1, m4 +%endif + LOWPASS 1, 5, 0, 6 + pavgb m0, m5 + DEFINE_ARGS dst, stride, cnt, stride0, dst8, dst16, dst24 + mov cntd, 8 + xor stride0q, stride0q + lea dst8q, [dstq +strideq*8] + lea dst16q, [dst8q +strideq*8] + lea dst24q, [dst16q+strideq*8] + SBUTTERFLY bw, 0, 1, 5 + SBUTTERFLY bw, 2, 3, 5 +%if cpuflag(ssse3) + pshufb m6, m1, [pb_15] +%else + pshufhw m6, m4, q3333 + punpckhqdq m6, m6 +%endif + +.loop: + mova [dstq +stride0q+ 0], m2 + mova [dstq +stride0q+16], m3 + mova [dst8q +stride0q+ 0], m3 + mova [dst8q +stride0q+16], m0 + mova [dst16q+stride0q+ 0], m0 + mova [dst16q+stride0q+16], m1 + mova [dst24q+stride0q+ 0], m1 + mova [dst24q+stride0q+16], m6 +%if cpuflag(avx) + palignr m2, m3, m2, 2 + palignr m3, m0, m3, 2 + palignr m0, m1, m0, 2 + pshufb m1, m4 +%elif cpuflag(ssse3) + pshufb m5, m1, m4 + palignr m1, m0, 2 + palignr m0, m3, 2 + palignr m3, m2, 2 + mova m2, m3 + mova m3, m0 + mova m0, m1 + mova m1, m5 +%else + ; half-integrated version of PALIGNR + pslldq m5, m1, 14 + pslldq m7, m0, 14 + psrldq m1, 2 + psrldq m0, 2 + por m1, m4 + por m0, m5 + pslldq m5, m3, 14 + psrldq m3, 2 + por m3, m7 + psrldq m2, 2 + por m2, m5 +%endif + add stride0q, strideq + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +HU_XMM_FUNCS 8 +INIT_XMM ssse3 +HU_XMM_FUNCS 7 +INIT_XMM avx +HU_XMM_FUNCS 7 + +; FIXME 127, 128, 129 ? diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9intrapred_16bpp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9intrapred_16bpp.asm new file mode 100644 index 00000000..32b69824 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9intrapred_16bpp.asm @@ -0,0 +1,2392 @@ +;****************************************************************************** +;* VP9 Intra prediction SIMD optimizations +;* +;* Copyright (c) 2015 Ronald S. Bultje +;* Copyright (c) 2015 Henrik Gramner +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pd_2: times 8 dd 2 +pd_4: times 8 dd 4 +pd_8: times 8 dd 8 + +pb_2to15_14_15: db 2,3,4,5,6,7,8,9,10,11,12,13,14,15,14,15 +pb_4_5_8to13_8x0: db 4,5,8,9,10,11,12,13,0,0,0,0,0,0,0,0 +pb_0to7_67x4: db 0,1,2,3,4,5,6,7,6,7,6,7,6,7,6,7 + +cextern pw_1 +cextern pw_1023 +cextern pw_4095 +cextern pd_16 +cextern pd_32 +cextern pd_65535; + +; FIXME most top-only functions (ddl, vl, v, dc_top) can be modified to take +; only 3 registers on x86-32, which would make it one cycle faster, but that +; would make the code quite a bit uglier... + +SECTION .text + +%macro SCRATCH 3-4 +%if ARCH_X86_64 + SWAP %1, %2 +%if %0 == 4 +%define reg_%4 m%2 +%endif +%else + mova [%3], m%1 +%if %0 == 4 +%define reg_%4 [%3] +%endif +%endif +%endmacro + +%macro UNSCRATCH 3-4 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova m%1, [%3] +%endif +%if %0 == 4 +%undef reg_%4 +%endif +%endmacro + +%macro PRELOAD 2-3 +%if ARCH_X86_64 + mova m%1, [%2] +%if %0 == 3 +%define reg_%3 m%1 +%endif +%elif %0 == 3 +%define reg_%3 [%2] +%endif +%endmacro + +INIT_MMX mmx +cglobal vp9_ipred_v_4x4_16, 2, 4, 1, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + RET + +INIT_XMM sse +cglobal vp9_ipred_v_8x8_16, 2, 4, 1, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + RET + +INIT_XMM sse +cglobal vp9_ipred_v_16x16_16, 2, 4, 2, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] + mova m1, [aq+mmsize] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m1 + mova [dstq+strideq*2+ 0], m0 + mova [dstq+strideq*2+16], m1 + mova [dstq+stride3q + 0], m0 + mova [dstq+stride3q +16], m1 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +INIT_XMM sse +cglobal vp9_ipred_v_32x32_16, 2, 4, 4, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq+mmsize*0] + mova m1, [aq+mmsize*1] + mova m2, [aq+mmsize*2] + mova m3, [aq+mmsize*3] + DEFINE_ARGS dst, stride, cnt + mov cntd, 16 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*0+32], m2 + mova [dstq+strideq*0+48], m3 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m1 + mova [dstq+strideq*1+32], m2 + mova [dstq+strideq*1+48], m3 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop + RET + +INIT_MMX mmxext +cglobal vp9_ipred_h_4x4_16, 3, 3, 4, dst, stride, l, a + mova m3, [lq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pshufw m0, m3, q3333 + pshufw m1, m3, q2222 + pshufw m2, m3, q1111 + pshufw m3, m3, q0000 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 + mova [dstq+strideq*2], m2 + mova [dstq+stride3q ], m3 + RET + +INIT_XMM sse2 +cglobal vp9_ipred_h_8x8_16, 3, 3, 4, dst, stride, l, a + mova m2, [lq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + punpckhwd m3, m2, m2 + pshufd m0, m3, q3333 + pshufd m1, m3, q2222 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 + pshufd m0, m3, q1111 + pshufd m1, m3, q0000 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m1 + lea dstq, [dstq+strideq*4] + punpcklwd m2, m2 + pshufd m0, m2, q3333 + pshufd m1, m2, q2222 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 + pshufd m0, m2, q1111 + pshufd m1, m2, q0000 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m1 + RET + +INIT_XMM sse2 +cglobal vp9_ipred_h_16x16_16, 3, 5, 4, dst, stride, l, stride3, cnt + mov cntd, 3 + lea stride3q, [strideq*3] +.loop: + movh m3, [lq+cntq*8] + punpcklwd m3, m3 + pshufd m0, m3, q3333 + pshufd m1, m3, q2222 + pshufd m2, m3, q1111 + pshufd m3, m3, q0000 + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*1+ 0], m1 + mova [dstq+strideq*1+16], m1 + mova [dstq+strideq*2+ 0], m2 + mova [dstq+strideq*2+16], m2 + mova [dstq+stride3q + 0], m3 + mova [dstq+stride3q +16], m3 + lea dstq, [dstq+strideq*4] + dec cntd + jge .loop + RET + +INIT_XMM sse2 +cglobal vp9_ipred_h_32x32_16, 3, 5, 4, dst, stride, l, stride3, cnt + mov cntd, 7 + lea stride3q, [strideq*3] +.loop: + movh m3, [lq+cntq*8] + punpcklwd m3, m3 + pshufd m0, m3, q3333 + pshufd m1, m3, q2222 + pshufd m2, m3, q1111 + pshufd m3, m3, q0000 + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*0+32], m0 + mova [dstq+strideq*0+48], m0 + mova [dstq+strideq*1+ 0], m1 + mova [dstq+strideq*1+16], m1 + mova [dstq+strideq*1+32], m1 + mova [dstq+strideq*1+48], m1 + mova [dstq+strideq*2+ 0], m2 + mova [dstq+strideq*2+16], m2 + mova [dstq+strideq*2+32], m2 + mova [dstq+strideq*2+48], m2 + mova [dstq+stride3q + 0], m3 + mova [dstq+stride3q +16], m3 + mova [dstq+stride3q +32], m3 + mova [dstq+stride3q +48], m3 + lea dstq, [dstq+strideq*4] + dec cntd + jge .loop + RET + +INIT_MMX mmxext +cglobal vp9_ipred_dc_4x4_16, 4, 4, 2, dst, stride, l, a + mova m0, [lq] + paddw m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pmaddwd m0, [pw_1] + pshufw m1, m0, q3232 + paddd m0, [pd_4] + paddd m0, m1 + psrad m0, 3 + pshufw m0, m0, q0000 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + RET + +INIT_XMM sse2 +cglobal vp9_ipred_dc_8x8_16, 4, 4, 2, dst, stride, l, a + mova m0, [lq] + paddw m0, [aq] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pmaddwd m0, [pw_1] + pshufd m1, m0, q3232 + paddd m0, m1 + pshufd m1, m0, q1111 + paddd m0, [pd_8] + paddd m0, m1 + psrad m0, 4 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + RET + +INIT_XMM sse2 +cglobal vp9_ipred_dc_16x16_16, 4, 4, 2, dst, stride, l, a + mova m0, [lq] + paddw m0, [lq+mmsize] + paddw m0, [aq] + paddw m0, [aq+mmsize] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 + pmaddwd m0, [pw_1] + pshufd m1, m0, q3232 + paddd m0, m1 + pshufd m1, m0, q1111 + paddd m0, [pd_16] + paddd m0, m1 + psrad m0, 5 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m0 + mova [dstq+strideq*2+ 0], m0 + mova [dstq+strideq*2+16], m0 + mova [dstq+stride3q + 0], m0 + mova [dstq+stride3q +16], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +INIT_XMM sse2 +cglobal vp9_ipred_dc_32x32_16, 4, 4, 2, dst, stride, l, a + mova m0, [lq+mmsize*0] + paddw m0, [lq+mmsize*1] + paddw m0, [lq+mmsize*2] + paddw m0, [lq+mmsize*3] + paddw m0, [aq+mmsize*0] + paddw m0, [aq+mmsize*1] + paddw m0, [aq+mmsize*2] + paddw m0, [aq+mmsize*3] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 16 + pmaddwd m0, [pw_1] + pshufd m1, m0, q3232 + paddd m0, m1 + pshufd m1, m0, q1111 + paddd m0, [pd_32] + paddd m0, m1 + psrad m0, 6 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*0+32], m0 + mova [dstq+strideq*0+48], m0 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m0 + mova [dstq+strideq*1+32], m0 + mova [dstq+strideq*1+48], m0 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop + RET + +%macro DC_1D_FNS 2 +INIT_MMX mmxext +cglobal vp9_ipred_dc_%1_4x4_16, 4, 4, 2, dst, stride, l, a + mova m0, [%2] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pmaddwd m0, [pw_1] + pshufw m1, m0, q3232 + paddd m0, [pd_2] + paddd m0, m1 + psrad m0, 2 + pshufw m0, m0, q0000 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + RET + +INIT_XMM sse2 +cglobal vp9_ipred_dc_%1_8x8_16, 4, 4, 2, dst, stride, l, a + mova m0, [%2] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pmaddwd m0, [pw_1] + pshufd m1, m0, q3232 + paddd m0, m1 + pshufd m1, m0, q1111 + paddd m0, [pd_4] + paddd m0, m1 + psrad m0, 3 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m0 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m0 + RET + +INIT_XMM sse2 +cglobal vp9_ipred_dc_%1_16x16_16, 4, 4, 2, dst, stride, l, a + mova m0, [%2] + paddw m0, [%2+mmsize] + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 + pmaddwd m0, [pw_1] + pshufd m1, m0, q3232 + paddd m0, m1 + pshufd m1, m0, q1111 + paddd m0, [pd_8] + paddd m0, m1 + psrad m0, 4 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m0 + mova [dstq+strideq*2+ 0], m0 + mova [dstq+strideq*2+16], m0 + mova [dstq+stride3q + 0], m0 + mova [dstq+stride3q +16], m0 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET + +INIT_XMM sse2 +cglobal vp9_ipred_dc_%1_32x32_16, 4, 4, 2, dst, stride, l, a + mova m0, [%2+mmsize*0] + paddw m0, [%2+mmsize*1] + paddw m0, [%2+mmsize*2] + paddw m0, [%2+mmsize*3] + DEFINE_ARGS dst, stride, cnt + mov cntd, 16 + pmaddwd m0, [pw_1] + pshufd m1, m0, q3232 + paddd m0, m1 + pshufd m1, m0, q1111 + paddd m0, [pd_16] + paddd m0, m1 + psrad m0, 5 + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m0 + mova [dstq+strideq*0+32], m0 + mova [dstq+strideq*0+48], m0 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m0 + mova [dstq+strideq*1+32], m0 + mova [dstq+strideq*1+48], m0 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop + RET +%endmacro + +DC_1D_FNS top, aq +DC_1D_FNS left, lq + +INIT_MMX mmxext +cglobal vp9_ipred_tm_4x4_10, 4, 4, 6, dst, stride, l, a + mova m5, [pw_1023] +.body: + mova m4, [aq] + mova m3, [lq] + movd m0, [aq-4] + pshufw m0, m0, q1111 + psubw m4, m0 + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + pshufw m0, m3, q3333 + pshufw m1, m3, q2222 + pshufw m2, m3, q1111 + pshufw m3, m3, q0000 + paddw m0, m4 + paddw m1, m4 + paddw m2, m4 + paddw m3, m4 + pxor m4, m4 + pmaxsw m0, m4 + pmaxsw m1, m4 + pmaxsw m2, m4 + pmaxsw m3, m4 + pminsw m0, m5 + pminsw m1, m5 + pminsw m2, m5 + pminsw m3, m5 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 + mova [dstq+strideq*2], m2 + mova [dstq+stride3q ], m3 + RET + +cglobal vp9_ipred_tm_4x4_12, 4, 4, 6, dst, stride, l, a + mova m5, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_ipred_tm_4x4_10 %+ SUFFIX).body + +INIT_XMM sse2 +cglobal vp9_ipred_tm_8x8_10, 4, 5, 7, dst, stride, l, a + mova m4, [pw_1023] +.body: + pxor m6, m6 + mova m5, [aq] + movd m0, [aq-4] + pshuflw m0, m0, q1111 + punpcklqdq m0, m0 + psubw m5, m0 + DEFINE_ARGS dst, stride, l, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 1 +.loop: + movh m3, [lq+cntq*8] + punpcklwd m3, m3 + pshufd m0, m3, q3333 + pshufd m1, m3, q2222 + pshufd m2, m3, q1111 + pshufd m3, m3, q0000 + paddw m0, m5 + paddw m1, m5 + paddw m2, m5 + paddw m3, m5 + pmaxsw m0, m6 + pmaxsw m1, m6 + pmaxsw m2, m6 + pmaxsw m3, m6 + pminsw m0, m4 + pminsw m1, m4 + pminsw m2, m4 + pminsw m3, m4 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m1 + mova [dstq+strideq*2], m2 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + dec cntd + jge .loop + RET + +cglobal vp9_ipred_tm_8x8_12, 4, 5, 7, dst, stride, l, a + mova m4, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_ipred_tm_8x8_10 %+ SUFFIX).body + +INIT_XMM sse2 +cglobal vp9_ipred_tm_16x16_10, 4, 4, 8, dst, stride, l, a + mova m7, [pw_1023] +.body: + pxor m6, m6 + mova m4, [aq] + mova m5, [aq+mmsize] + movd m0, [aq-4] + pshuflw m0, m0, q1111 + punpcklqdq m0, m0 + psubw m4, m0 + psubw m5, m0 + DEFINE_ARGS dst, stride, l, cnt + mov cntd, 7 +.loop: + movd m3, [lq+cntq*4] + punpcklwd m3, m3 + pshufd m2, m3, q1111 + pshufd m3, m3, q0000 + paddw m0, m2, m4 + paddw m2, m5 + paddw m1, m3, m4 + paddw m3, m5 + pmaxsw m0, m6 + pmaxsw m2, m6 + pmaxsw m1, m6 + pmaxsw m3, m6 + pminsw m0, m7 + pminsw m2, m7 + pminsw m1, m7 + pminsw m3, m7 + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m2 + mova [dstq+strideq*1+ 0], m1 + mova [dstq+strideq*1+16], m3 + lea dstq, [dstq+strideq*2] + dec cntd + jge .loop + RET + +cglobal vp9_ipred_tm_16x16_12, 4, 4, 8, dst, stride, l, a + mova m7, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_ipred_tm_16x16_10 %+ SUFFIX).body + +INIT_XMM sse2 +cglobal vp9_ipred_tm_32x32_10, 4, 4, 10, 32 * -ARCH_X86_32, dst, stride, l, a + mova m0, [pw_1023] +.body: + pxor m1, m1 +%if ARCH_X86_64 + SWAP 0, 8 + SWAP 1, 9 +%define reg_min m9 +%define reg_max m8 +%else + mova [rsp+ 0], m0 + mova [rsp+16], m1 +%define reg_min [rsp+16] +%define reg_max [rsp+ 0] +%endif + + mova m4, [aq+mmsize*0] + mova m5, [aq+mmsize*1] + mova m6, [aq+mmsize*2] + mova m7, [aq+mmsize*3] + movd m0, [aq-4] + pshuflw m0, m0, q1111 + punpcklqdq m0, m0 + psubw m4, m0 + psubw m5, m0 + psubw m6, m0 + psubw m7, m0 + DEFINE_ARGS dst, stride, l, cnt + mov cntd, 31 +.loop: + pinsrw m3, [lq+cntq*2], 0 + punpcklwd m3, m3 + pshufd m3, m3, q0000 + paddw m0, m3, m4 + paddw m1, m3, m5 + paddw m2, m3, m6 + paddw m3, m7 + pmaxsw m0, reg_min + pmaxsw m1, reg_min + pmaxsw m2, reg_min + pmaxsw m3, reg_min + pminsw m0, reg_max + pminsw m1, reg_max + pminsw m2, reg_max + pminsw m3, reg_max + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*0+32], m2 + mova [dstq+strideq*0+48], m3 + add dstq, strideq + dec cntd + jge .loop + RET + +cglobal vp9_ipred_tm_32x32_12, 4, 4, 10, 32 * -ARCH_X86_32, dst, stride, l, a + mova m0, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_ipred_tm_32x32_10 %+ SUFFIX).body + +; Directional intra predicion functions +; +; in the functions below, 'abcdefgh' refers to above data (sometimes simply +; abbreviated as a[N-M]). 'stuvwxyz' refers to left data (sometimes simply +; abbreviated as l[N-M]). * is top-left data. ABCDEFG or A[N-M] is filtered +; above data, STUVWXYZ or L[N-M] is filtered left data, and # is filtered +; top-left data. + +; left=(left+2*center+right+2)>>2 +%macro LOWPASS 3 ; left [dst], center, right + paddw m%1, m%3 + psraw m%1, 1 + pavgw m%1, m%2 +%endmacro + +; abcdefgh (src) -> bcdefghh (dst) +; dst/src can be the same register +%macro SHIFT_RIGHT 2-3 [pb_2to15_14_15] ; dst, src, [ssse3_shift_reg] +%if cpuflag(ssse3) + pshufb %1, %2, %3 ; abcdefgh -> bcdefghh +%else + psrldq %1, %2, 2 ; abcdefgh -> bcdefgh. + pshufhw %1, %1, q2210 ; bcdefgh. -> bcdefghh +%endif +%endmacro + +; abcdefgh (src) -> bcdefghh (dst1) and cdefghhh (dst2) +%macro SHIFT_RIGHTx2 3-4 [pb_2to15_14_15] ; dst1, dst2, src, [ssse3_shift_reg] +%if cpuflag(ssse3) + pshufb %1, %3, %4 ; abcdefgh -> bcdefghh + pshufb %2, %1, %4 ; bcdefghh -> cdefghhh +%else + psrldq %1, %3, 2 ; abcdefgh -> bcdefgh. + psrldq %2, %3, 4 ; abcdefgh -> cdefgh.. + pshufhw %1, %1, q2210 ; bcdefgh. -> bcdefghh + pshufhw %2, %2, q1110 ; cdefgh.. -> cdefghhh +%endif +%endmacro + +%macro DL_FUNCS 0 +cglobal vp9_ipred_dl_4x4_16, 2, 4, 3, dst, stride, l, a + movifnidn aq, amp + movu m1, [aq] ; abcdefgh + pshufhw m0, m1, q3310 ; abcdefhh + SHIFT_RIGHT m1, m1 ; bcdefghh + psrldq m2, m1, 2 ; cdefghh. + LOWPASS 0, 1, 2 ; BCDEFGh. + pshufd m1, m0, q3321 ; DEFGh... + movh [dstq+strideq*0], m0 + movh [dstq+strideq*2], m1 + add dstq, strideq + psrldq m0, 2 ; CDEFGh.. + psrldq m1, 2 ; EFGh.... + movh [dstq+strideq*0], m0 + movh [dstq+strideq*2], m1 + RET + +cglobal vp9_ipred_dl_8x8_16, 2, 4, 5, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefgh +%if cpuflag(ssse3) + mova m4, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m1, m2, m0, m4 ; bcdefghh/cdefghhh + LOWPASS 0, 1, 2 ; BCDEFGHh + shufps m1, m0, m2, q3332 ; FGHhhhhh + shufps m3, m0, m1, q2121 ; DEFGHhhh + DEFINE_ARGS dst, stride, stride5 + lea stride5q, [strideq*5] + + mova [dstq+strideq*0], m0 + mova [dstq+strideq*4], m1 + SHIFT_RIGHT m0, m0, m4 ; CDEFGHhh + pshuflw m1, m1, q3321 ; GHhhhhhh + pshufd m2, m0, q3321 ; EFGHhhhh + mova [dstq+strideq*1], m0 + mova [dstq+stride5q ], m1 + lea dstq, [dstq+strideq*2] + pshuflw m1, m1, q3321 ; Hhhhhhhh + mova [dstq+strideq*0], m3 + mova [dstq+strideq*4], m1 + pshuflw m1, m1, q3321 ; hhhhhhhh + mova [dstq+strideq*1], m2 + mova [dstq+stride5q ], m1 + RET + +cglobal vp9_ipred_dl_16x16_16, 2, 4, 5, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefgh + mova m3, [aq+mmsize] ; ijklmnop + PALIGNR m1, m3, m0, 2, m4 ; bcdefghi + PALIGNR m2, m3, m0, 4, m4 ; cdefghij + LOWPASS 0, 1, 2 ; BCDEFGHI +%if cpuflag(ssse3) + mova m4, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m2, m1, m3, m4 ; jklmnopp/klmnoppp + LOWPASS 1, 2, 3 ; JKLMNOPp + pshufd m2, m2, q3333 ; pppppppp + DEFINE_ARGS dst, stride, cnt + mov cntd, 8 + +.loop: + mova [dstq+strideq*0+ 0], m0 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*8+ 0], m1 + mova [dstq+strideq*8+16], m2 + add dstq, strideq +%if cpuflag(avx) + vpalignr m0, m1, m0, 2 +%else + PALIGNR m3, m1, m0, 2, m4 + mova m0, m3 +%endif + SHIFT_RIGHT m1, m1, m4 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dl_32x32_16, 2, 5, 7, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq+mmsize*0] ; abcdefgh + mova m1, [aq+mmsize*1] ; ijklmnop + mova m2, [aq+mmsize*2] ; qrstuvwx + mova m3, [aq+mmsize*3] ; yz012345 + PALIGNR m4, m1, m0, 2, m6 + PALIGNR m5, m1, m0, 4, m6 + LOWPASS 0, 4, 5 ; BCDEFGHI + PALIGNR m4, m2, m1, 2, m6 + PALIGNR m5, m2, m1, 4, m6 + LOWPASS 1, 4, 5 ; JKLMNOPQ + PALIGNR m4, m3, m2, 2, m6 + PALIGNR m5, m3, m2, 4, m6 + LOWPASS 2, 4, 5 ; RSTUVWXY +%if cpuflag(ssse3) + mova m6, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m4, m5, m3, m6 + LOWPASS 3, 4, 5 ; Z0123455 + pshufd m4, m4, q3333 ; 55555555 + DEFINE_ARGS dst, stride, stride8, stride24, cnt + mov cntd, 8 + lea stride8q, [strideq*8] + lea stride24q, [stride8q*3] + +.loop: + mova [dstq+stride8q*0+ 0], m0 + mova [dstq+stride8q*0+16], m1 + mova [dstq+stride8q*0+32], m2 + mova [dstq+stride8q*0+48], m3 + mova [dstq+stride8q*1+ 0], m1 + mova [dstq+stride8q*1+16], m2 + mova [dstq+stride8q*1+32], m3 + mova [dstq+stride8q*1+48], m4 + mova [dstq+stride8q*2+ 0], m2 + mova [dstq+stride8q*2+16], m3 + mova [dstq+stride8q*2+32], m4 + mova [dstq+stride8q*2+48], m4 + mova [dstq+stride24q + 0], m3 + mova [dstq+stride24q +16], m4 + mova [dstq+stride24q +32], m4 + mova [dstq+stride24q +48], m4 + add dstq, strideq +%if cpuflag(avx) + vpalignr m0, m1, m0, 2 + vpalignr m1, m2, m1, 2 + vpalignr m2, m3, m2, 2 +%else + PALIGNR m5, m1, m0, 2, m6 + mova m0, m5 + PALIGNR m5, m2, m1, 2, m6 + mova m1, m5 + PALIGNR m5, m3, m2, 2, m6 + mova m2, m5 +%endif + SHIFT_RIGHT m3, m3, m6 + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +DL_FUNCS +INIT_XMM ssse3 +DL_FUNCS +INIT_XMM avx +DL_FUNCS + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dl_16x16_16, 2, 4, 5, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefghijklmnop + vpbroadcastw xm1, [aq+30] ; pppppppp + vperm2i128 m2, m0, m1, q0201 ; ijklmnoppppppppp + vpalignr m3, m2, m0, 2 ; bcdefghijklmnopp + vpalignr m4, m2, m0, 4 ; cdefghijklmnoppp + LOWPASS 0, 3, 4 ; BCDEFGHIJKLMNOPp + vperm2i128 m2, m0, m1, q0201 ; JKLMNOPppppppppp + DEFINE_ARGS dst, stride, stride3, cnt + mov cntd, 2 + lea stride3q, [strideq*3] + +.loop: + mova [dstq+strideq*0], m0 + vpalignr m3, m2, m0, 2 + vpalignr m4, m2, m0, 4 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 6 + vpalignr m4, m2, m0, 8 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova [dstq+strideq*0], m4 + vpalignr m3, m2, m0, 10 + vpalignr m4, m2, m0, 12 + mova [dstq+strideq*1], m3 + mova [dstq+strideq*2], m4 + vpalignr m3, m2, m0, 14 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + mova m0, m2 + vperm2i128 m2, m2, m2, q0101 ; pppppppppppppppp + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dl_32x32_16, 2, 6, 7, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq+mmsize*0+ 0] ; abcdefghijklmnop + mova m1, [aq+mmsize*1+ 0] ; qrstuvwxyz012345 + vpbroadcastw xm4, [aq+mmsize*1+30] ; 55555555 + vperm2i128 m5, m0, m1, q0201 ; ijklmnopqrstuvwx + vpalignr m2, m5, m0, 2 ; bcdefghijklmnopq + vpalignr m3, m5, m0, 4 ; cdefghijklmnopqr + LOWPASS 0, 2, 3 ; BCDEFGHIJKLMNOPQ + vperm2i128 m5, m1, m4, q0201 ; yz01234555555555 + vpalignr m2, m5, m1, 2 ; rstuvwxyz0123455 + vpalignr m3, m5, m1, 4 ; stuvwxyz01234555 + LOWPASS 1, 2, 3 ; RSTUVWXYZ......5 + vperm2i128 m2, m1, m4, q0201 ; Z......555555555 + vperm2i128 m5, m0, m1, q0201 ; JKLMNOPQRSTUVWXY + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 + +.loop: + mova [dstq+strideq*0 + 0], m0 + mova [dstq+strideq*0 +32], m1 + vpalignr m3, m5, m0, 2 + vpalignr m4, m2, m1, 2 + mova [dstq+strideq*1 + 0], m3 + mova [dstq+strideq*1 +32], m4 + vpalignr m3, m5, m0, 4 + vpalignr m4, m2, m1, 4 + mova [dstq+strideq*2 + 0], m3 + mova [dstq+strideq*2 +32], m4 + vpalignr m3, m5, m0, 6 + vpalignr m4, m2, m1, 6 + mova [dstq+stride3q*1+ 0], m3 + mova [dstq+stride3q*1+32], m4 + lea dstq, [dstq+strideq*4] + vpalignr m3, m5, m0, 8 + vpalignr m4, m2, m1, 8 + mova [dstq+strideq*0 + 0], m3 + mova [dstq+strideq*0 +32], m4 + vpalignr m3, m5, m0, 10 + vpalignr m4, m2, m1, 10 + mova [dstq+strideq*1 + 0], m3 + mova [dstq+strideq*1 +32], m4 + vpalignr m3, m5, m0, 12 + vpalignr m4, m2, m1, 12 + mova [dstq+strideq*2+ 0], m3 + mova [dstq+strideq*2+32], m4 + vpalignr m3, m5, m0, 14 + vpalignr m4, m2, m1, 14 + mova [dstq+stride3q+ 0], m3 + mova [dstq+stride3q+ 32], m4 + vpalignr m3, m5, m0, 16 + vpalignr m4, m2, m1, 16 + vperm2i128 m5, m3, m4, q0201 + vperm2i128 m2, m4, m4, q0101 + mova m0, m3 + mova m1, m4 + lea dstq, [dstq+strideq*4] + dec cntd + jg .loop + RET +%endif + +%macro DR_FUNCS 1 ; stack_mem_for_32x32_32bit_function +cglobal vp9_ipred_dr_4x4_16, 4, 4, 3, dst, stride, l, a + movh m0, [lq] ; wxyz.... + movhps m0, [aq-2] ; wxyz*abc + movd m1, [aq+6] ; d....... + PALIGNR m1, m0, 2, m2 ; xyz*abcd + psrldq m2, m1, 2 ; yz*abcd. + LOWPASS 0, 1, 2 ; XYZ#ABC. + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + movh [dstq+stride3q ], m0 + psrldq m0, 2 ; YZ#ABC.. + movh [dstq+strideq*2], m0 + psrldq m0, 2 ; Z#ABC... + movh [dstq+strideq*1], m0 + psrldq m0, 2 ; #ABC.... + movh [dstq+strideq*0], m0 + RET + +cglobal vp9_ipred_dr_8x8_16, 4, 4, 5, dst, stride, l, a + mova m0, [lq] ; stuvwxyz + movu m1, [aq-2] ; *abcdefg + mova m2, [aq] ; abcdefgh + psrldq m3, m2, 2 ; bcdefgh. + LOWPASS 3, 2, 1 ; ABCDEFG. + PALIGNR m1, m0, 2, m4 ; tuvwxyz* + PALIGNR m2, m1, 2, m4 ; uvwxyz*a + LOWPASS 2, 1, 0 ; TUVWXYZ# + DEFINE_ARGS dst, stride, dst4, stride3 + lea stride3q, [strideq*3] + lea dst4q, [dstq+strideq*4] + + movhps [dstq +stride3q +0], m2 + movh [dstq+ stride3q +8], m3 + mova [dst4q+stride3q +0], m2 + PALIGNR m1, m3, m2, 2, m0 + psrldq m3, 2 + movhps [dstq +strideq*2+0], m1 + movh [dstq+ strideq*2+8], m3 + mova [dst4q+strideq*2+0], m1 + PALIGNR m2, m3, m1, 2, m0 + psrldq m3, 2 + movhps [dstq +strideq*1+0], m2 + movh [dstq+ strideq*1+8], m3 + mova [dst4q+strideq*1+0], m2 + PALIGNR m1, m3, m2, 2, m0 + psrldq m3, 2 + movhps [dstq +strideq*0+0], m1 + movh [dstq+ strideq*0+8], m3 + mova [dst4q+strideq*0+0], m1 + RET + +cglobal vp9_ipred_dr_16x16_16, 4, 4, 7, dst, stride, l, a + mova m0, [lq] ; klmnopqr + mova m1, [lq+mmsize] ; stuvwxyz + movu m2, [aq-2] ; *abcdefg + movu m3, [aq+mmsize-2] ; hijklmno + mova m4, [aq] ; abcdefgh + mova m5, [aq+mmsize] ; ijklmnop + psrldq m6, m5, 2 ; jklmnop. + LOWPASS 6, 5, 3 ; IJKLMNO. + PALIGNR m5, m4, 2, m3 ; bcdefghi + LOWPASS 5, 4, 2 ; ABCDEFGH + PALIGNR m2, m1, 2, m3 ; tuvwxyz* + PALIGNR m4, m2, 2, m3 ; uvwxyz*a + LOWPASS 4, 2, 1 ; TUVWXYZ# + PALIGNR m1, m0, 2, m3 ; lmnopqrs + PALIGNR m2, m1, 2, m3 ; mnopqrst + LOWPASS 2, 1, 0 ; LMNOPQRS + DEFINE_ARGS dst, stride, dst8, cnt + lea dst8q, [dstq+strideq*8] + mov cntd, 8 + +.loop: + sub dst8q, strideq + mova [dst8q+strideq*0+ 0], m4 + mova [dst8q+strideq*0+16], m5 + mova [dst8q+strideq*8+ 0], m2 + mova [dst8q+strideq*8+16], m4 +%if cpuflag(avx) + vpalignr m2, m4, m2, 2 + vpalignr m4, m5, m4, 2 + vpalignr m5, m6, m5, 2 +%else + PALIGNR m0, m4, m2, 2, m1 + mova m2, m0 + PALIGNR m0, m5, m4, 2, m1 + mova m4, m0 + PALIGNR m0, m6, m5, 2, m1 + mova m5, m0 +%endif + psrldq m6, 2 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_dr_32x32_16, 4, 5, 10 + notcpuflag(ssse3), \ + %1 * ARCH_X86_32 * -mmsize, dst, stride, l, a + mova m0, [aq+mmsize*3] ; a[24-31] + movu m1, [aq+mmsize*3-2] ; a[23-30] + psrldq m2, m0, 2 ; a[25-31]. + LOWPASS 2, 0, 1 ; A[24-30]. + mova m1, [aq+mmsize*2] ; a[16-23] + movu m3, [aq+mmsize*2-2] ; a[15-22] + PALIGNR m0, m1, 2, m4 ; a[17-24] + LOWPASS 0, 1, 3 ; A[16-23] + mova m3, [aq+mmsize*1] ; a[8-15] + movu m4, [aq+mmsize*1-2] ; a[7-14] + PALIGNR m1, m3, 2, m5 ; a[9-16] + LOWPASS 1, 3, 4 ; A[8-15] + mova m4, [aq+mmsize*0] ; a[0-7] + movu m5, [aq+mmsize*0-2] ; *a[0-6] + PALIGNR m3, m4, 2, m6 ; a[1-8] + LOWPASS 3, 4, 5 ; A[0-7] + SCRATCH 1, 8, rsp+0*mmsize + SCRATCH 3, 9, rsp+1*mmsize +%if notcpuflag(ssse3) + SCRATCH 0, 10, rsp+2*mmsize +%endif + mova m6, [lq+mmsize*3] ; l[24-31] + PALIGNR m5, m6, 2, m0 ; l[25-31]* + PALIGNR m4, m5, 2, m0 ; l[26-31]*a + LOWPASS 4, 5, 6 ; L[25-31]# + mova m7, [lq+mmsize*2] ; l[16-23] + PALIGNR m6, m7, 2, m0 ; l[17-24] + PALIGNR m5, m6, 2, m0 ; l[18-25] + LOWPASS 5, 6, 7 ; L[17-24] + mova m1, [lq+mmsize*1] ; l[8-15] + PALIGNR m7, m1, 2, m0 ; l[9-16] + PALIGNR m6, m7, 2, m0 ; l[10-17] + LOWPASS 6, 7, 1 ; L[9-16] + mova m3, [lq+mmsize*0] ; l[0-7] + PALIGNR m1, m3, 2, m0 ; l[1-8] + PALIGNR m7, m1, 2, m0 ; l[2-9] + LOWPASS 7, 1, 3 ; L[1-8] +%if cpuflag(ssse3) +%if cpuflag(avx) + UNSCRATCH 1, 8, rsp+0*mmsize +%endif + UNSCRATCH 3, 9, rsp+1*mmsize +%else + UNSCRATCH 0, 10, rsp+2*mmsize +%endif + DEFINE_ARGS dst8, stride, stride8, stride24, cnt + lea stride8q, [strideq*8] + lea stride24q, [stride8q*3] + lea dst8q, [dst8q+strideq*8] + mov cntd, 8 + +.loop: + sub dst8q, strideq +%if notcpuflag(avx) + UNSCRATCH 1, 8, rsp+0*mmsize +%if notcpuflag(ssse3) + UNSCRATCH 3, 9, rsp+1*mmsize +%endif +%endif + mova [dst8q+stride8q*0+ 0], m4 + mova [dst8q+stride8q*0+16], m3 + mova [dst8q+stride8q*0+32], m1 + mova [dst8q+stride8q*0+48], m0 + mova [dst8q+stride8q*1+ 0], m5 + mova [dst8q+stride8q*1+16], m4 + mova [dst8q+stride8q*1+32], m3 + mova [dst8q+stride8q*1+48], m1 + mova [dst8q+stride8q*2+ 0], m6 + mova [dst8q+stride8q*2+16], m5 + mova [dst8q+stride8q*2+32], m4 + mova [dst8q+stride8q*2+48], m3 + mova [dst8q+stride24q + 0], m7 + mova [dst8q+stride24q +16], m6 + mova [dst8q+stride24q +32], m5 + mova [dst8q+stride24q +48], m4 +%if cpuflag(avx) + vpalignr m7, m6, m7, 2 + vpalignr m6, m5, m6, 2 + vpalignr m5, m4, m5, 2 + vpalignr m4, m3, m4, 2 + vpalignr m3, m1, m3, 2 + vpalignr m1, m0, m1, 2 + vpalignr m0, m2, m0, 2 +%else + SCRATCH 2, 8, rsp+0*mmsize +%if notcpuflag(ssse3) + SCRATCH 0, 9, rsp+1*mmsize +%endif + PALIGNR m2, m6, m7, 2, m0 + mova m7, m2 + PALIGNR m2, m5, m6, 2, m0 + mova m6, m2 + PALIGNR m2, m4, m5, 2, m0 + mova m5, m2 + PALIGNR m2, m3, m4, 2, m0 + mova m4, m2 + PALIGNR m2, m1, m3, 2, m0 + mova m3, m2 +%if notcpuflag(ssse3) + UNSCRATCH 0, 9, rsp+1*mmsize + SCRATCH 3, 9, rsp+1*mmsize +%endif + PALIGNR m2, m0, m1, 2, m3 + mova m1, m2 + UNSCRATCH 2, 8, rsp+0*mmsize + SCRATCH 1, 8, rsp+0*mmsize + PALIGNR m1, m2, m0, 2, m3 + mova m0, m1 +%endif + psrldq m2, 2 + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +DR_FUNCS 3 +INIT_XMM ssse3 +DR_FUNCS 2 +INIT_XMM avx +DR_FUNCS 2 + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_ipred_dr_16x16_16, 4, 5, 6, dst, stride, l, a + mova m0, [lq] ; klmnopqrstuvwxyz + movu m1, [aq-2] ; *abcdefghijklmno + mova m2, [aq] ; abcdefghijklmnop + vperm2i128 m4, m2, m2, q2001 ; ijklmnop........ + vpalignr m5, m4, m2, 2 ; bcdefghijklmnop. + vperm2i128 m3, m0, m1, q0201 ; stuvwxyz*abcdefg + LOWPASS 1, 2, 5 ; ABCDEFGHIJKLMNO. + vpalignr m4, m3, m0, 2 ; lmnopqrstuvwxyz* + vpalignr m5, m3, m0, 4 ; mnopqrstuvwxyz*a + LOWPASS 0, 4, 5 ; LMNOPQRSTUVWXYZ# + vperm2i128 m5, m0, m1, q0201 ; TUVWXYZ#ABCDEFGH + DEFINE_ARGS dst, stride, stride3, stride5, dst3 + lea dst3q, [dstq+strideq*4] + lea stride3q, [strideq*3] + lea stride5q, [stride3q+strideq*2] + + vpalignr m3, m5, m0, 2 + vpalignr m4, m1, m5, 2 + mova [dst3q+stride5q*2], m3 ; 14 + mova [ dstq+stride3q*2], m4 ; 6 + vpalignr m3, m5, m0, 4 + vpalignr m4, m1, m5, 4 + sub dst3q, strideq + mova [dst3q+stride5q*2], m3 ; 13 + mova [dst3q+strideq*2 ], m4 ; 5 + mova [dst3q+stride3q*4], m0 ; 15 + vpalignr m3, m5, m0, 6 + vpalignr m4, m1, m5, 6 + mova [dstq+stride3q*4], m3 ; 12 + mova [dst3q+strideq*1], m4 ; 4 + vpalignr m3, m5, m0, 8 + vpalignr m4, m1, m5, 8 + mova [dst3q+strideq*8], m3 ; 11 + mova [dst3q+strideq*0], m4 ; 3 + vpalignr m3, m5, m0, 10 + vpalignr m4, m1, m5, 10 + mova [dstq+stride5q*2], m3 ; 10 + mova [dstq+strideq*2 ], m4 ; 2 + vpalignr m3, m5, m0, 12 + vpalignr m4, m1, m5, 12 + mova [dst3q+stride3q*2], m3 ; 9 + mova [dstq+strideq*1 ], m4 ; 1 + vpalignr m3, m5, m0, 14 + vpalignr m4, m1, m5, 14 + mova [dstq+strideq*8], m3 ; 8 + mova [dstq+strideq*0], m4 ; 0 + mova [dst3q+strideq*4], m5 ; 7 + RET + +%if ARCH_X86_64 +cglobal vp9_ipred_dr_32x32_16, 4, 7, 10, dst, stride, l, a + mova m0, [lq+mmsize*0+0] ; l[0-15] + mova m1, [lq+mmsize*1+0] ; l[16-31] + movu m2, [aq+mmsize*0-2] ; *abcdefghijklmno + mova m3, [aq+mmsize*0+0] ; abcdefghijklmnop + mova m4, [aq+mmsize*1+0] ; qrstuvwxyz012345 + vperm2i128 m5, m0, m1, q0201 ; lmnopqrstuvwxyz0 + vpalignr m6, m5, m0, 2 ; mnopqrstuvwxyz01 + vpalignr m7, m5, m0, 4 ; nopqrstuvwxyz012 + LOWPASS 0, 6, 7 ; L[0-15] + vperm2i128 m7, m1, m2, q0201 ; stuvwxyz*abcdefg + vpalignr m5, m7, m1, 2 ; lmnopqrstuvwxyz* + vpalignr m6, m7, m1, 4 ; mnopqrstuvwxyz*a + LOWPASS 1, 5, 6 ; L[16-31]# + vperm2i128 m5, m3, m4, q0201 ; ijklmnopqrstuvwx + vpalignr m6, m5, m3, 2 ; bcdefghijklmnopq + LOWPASS 2, 3, 6 ; A[0-15] + movu m3, [aq+mmsize*1-2] ; pqrstuvwxyz01234 + vperm2i128 m6, m4, m4, q2001 ; yz012345........ + vpalignr m7, m6, m4, 2 ; rstuvwxyz012345. + LOWPASS 3, 4, 7 ; A[16-31]. + vperm2i128 m4, m1, m2, q0201 ; TUVWXYZ#ABCDEFGH + vperm2i128 m5, m0, m1, q0201 ; L[7-15]L[16-23] + vperm2i128 m8, m2, m3, q0201 ; IJKLMNOPQRSTUVWX + DEFINE_ARGS dst8, stride, stride3, stride7, stride5, dst24, cnt + lea stride3q, [strideq*3] + lea stride5q, [stride3q+strideq*2] + lea stride7q, [strideq*4+stride3q] + lea dst24q, [dst8q+stride3q*8] + lea dst8q, [dst8q+strideq*8] + mov cntd, 2 + +.loop: + mova [dst24q+stride7q+0 ], m0 ; 31 23 15 7 + mova [dst24q+stride7q+32], m1 + mova [dst8q+stride7q+0], m1 + mova [dst8q+stride7q+32], m2 + vpalignr m6, m4, m1, 2 + vpalignr m7, m5, m0, 2 + vpalignr m9, m8, m2, 2 + mova [dst24q+stride3q*2+0], m7 ; 30 22 14 6 + mova [dst24q+stride3q*2+32], m6 + mova [dst8q+stride3q*2+0], m6 + mova [dst8q+stride3q*2+32], m9 + vpalignr m6, m4, m1, 4 + vpalignr m7, m5, m0, 4 + vpalignr m9, m8, m2, 4 + mova [dst24q+stride5q+0], m7 ; 29 21 13 5 + mova [dst24q+stride5q+32], m6 + mova [dst8q+stride5q+0], m6 + mova [dst8q+stride5q+32], m9 + vpalignr m6, m4, m1, 6 + vpalignr m7, m5, m0, 6 + vpalignr m9, m8, m2, 6 + mova [dst24q+strideq*4+0 ], m7 ; 28 20 12 4 + mova [dst24q+strideq*4+32], m6 + mova [dst8q+strideq*4+0], m6 + mova [dst8q+strideq*4+32], m9 + vpalignr m6, m4, m1, 8 + vpalignr m7, m5, m0, 8 + vpalignr m9, m8, m2, 8 + mova [dst24q+stride3q+0 ], m7 ; 27 19 11 3 + mova [dst24q+stride3q+32], m6 + mova [dst8q+stride3q+0], m6 + mova [dst8q+stride3q+32], m9 + vpalignr m6, m4, m1, 10 + vpalignr m7, m5, m0, 10 + vpalignr m9, m8, m2, 10 + mova [dst24q+strideq*2+0 ], m7 ; 26 18 10 2 + mova [dst24q+strideq*2+32], m6 + mova [dst8q+strideq*2+0], m6 + mova [dst8q+strideq*2+32], m9 + vpalignr m6, m4, m1, 12 + vpalignr m7, m5, m0, 12 + vpalignr m9, m8, m2, 12 + mova [dst24q+strideq+0 ], m7 ; 25 17 9 1 + mova [dst24q+strideq+32], m6 + mova [dst8q+strideq+0], m6 + mova [dst8q+strideq+32], m9 + vpalignr m6, m4, m1, 14 + vpalignr m7, m5, m0, 14 + vpalignr m9, m8, m2, 14 + mova [dst24q+strideq*0+0 ], m7 ; 24 16 8 0 + mova [dst24q+strideq*0+32], m6 + mova [dst8q+strideq*0+0], m6 + mova [dst8q+strideq*0+32], m9 + mova m0, m5 + mova m5, m1 + mova m1, m4 + mova m4, m2 + mova m2, m8 + mova m8, m3 + sub dst24q, stride7q + sub dst24q, strideq + sub dst8q, stride7q + sub dst8q, strideq + dec cntd + jg .loop + RET +%endif +%endif + +%macro VL_FUNCS 1 ; stack_mem_for_32x32_32bit_function +cglobal vp9_ipred_vl_4x4_16, 2, 4, 3, dst, stride, l, a + movifnidn aq, amp + movu m0, [aq] ; abcdefgh + psrldq m1, m0, 2 ; bcdefgh. + psrldq m2, m0, 4 ; cdefgh.. + LOWPASS 2, 1, 0 ; BCDEFGH. + pavgw m1, m0 ; ABCDEFG. + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + movh [dstq+strideq*0], m1 + movh [dstq+strideq*1], m2 + psrldq m1, 2 + psrldq m2, 2 + movh [dstq+strideq*2], m1 + movh [dstq+stride3q ], m2 + RET + +cglobal vp9_ipred_vl_8x8_16, 2, 4, 4, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] ; abcdefgh +%if cpuflag(ssse3) + mova m3, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m1, m2, m0, m3 ; bcdefghh/cdefghhh + LOWPASS 2, 1, 0 ; BCDEFGHh + pavgw m1, m0 ; ABCDEFGh + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + mova [dstq+strideq*0], m1 + mova [dstq+strideq*1], m2 + SHIFT_RIGHT m1, m1, m3 + SHIFT_RIGHT m2, m2, m3 + mova [dstq+strideq*2], m1 + mova [dstq+stride3q ], m2 + lea dstq, [dstq+strideq*4] + SHIFT_RIGHT m1, m1, m3 + SHIFT_RIGHT m2, m2, m3 + mova [dstq+strideq*0], m1 + mova [dstq+strideq*1], m2 + SHIFT_RIGHT m1, m1, m3 + SHIFT_RIGHT m2, m2, m3 + mova [dstq+strideq*2], m1 + mova [dstq+stride3q ], m2 + RET + +cglobal vp9_ipred_vl_16x16_16, 2, 4, 6, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq] + mova m1, [aq+mmsize] + PALIGNR m2, m1, m0, 2, m3 + PALIGNR m3, m1, m0, 4, m4 + LOWPASS 3, 2, 0 + pavgw m2, m0 +%if cpuflag(ssse3) + mova m4, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m5, m0, m1, m4 + LOWPASS 0, 5, 1 + pavgw m1, m5 + DEFINE_ARGS dst, stride, cnt + mov cntd, 8 + +.loop: + mova [dstq+strideq*0+ 0], m2 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*1+ 0], m3 + mova [dstq+strideq*1+16], m0 + lea dstq, [dstq+strideq*2] +%if cpuflag(avx) + vpalignr m2, m1, m2, 2 + vpalignr m3, m0, m3, 2 +%else + PALIGNR m5, m1, m2, 2, m4 + mova m2, m5 + PALIGNR m5, m0, m3, 2, m4 + mova m3, m5 +%endif + SHIFT_RIGHT m1, m1, m4 + SHIFT_RIGHT m0, m0, m4 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_vl_32x32_16, 2, 5, 11, %1 * mmsize * ARCH_X86_32, dst, stride, l, a + movifnidn aq, amp + mova m0, [aq+mmsize*0] + mova m1, [aq+mmsize*1] + mova m2, [aq+mmsize*2] + PALIGNR m6, m1, m0, 2, m5 + PALIGNR m7, m1, m0, 4, m5 + LOWPASS 7, 6, 0 + pavgw m6, m0 + SCRATCH 6, 8, rsp+0*mmsize + PALIGNR m4, m2, m1, 2, m0 + PALIGNR m5, m2, m1, 4, m0 + LOWPASS 5, 4, 1 + pavgw m4, m1 + mova m0, [aq+mmsize*3] + PALIGNR m1, m0, m2, 2, m6 + PALIGNR m3, m0, m2, 4, m6 + LOWPASS 3, 1, 2 + pavgw m2, m1 +%if cpuflag(ssse3) + PRELOAD 10, pb_2to15_14_15, shuf +%endif + SHIFT_RIGHTx2 m6, m1, m0, reg_shuf + LOWPASS 1, 6, 0 + pavgw m0, m6 +%if ARCH_X86_64 + pshufd m9, m6, q3333 +%endif +%if cpuflag(avx) + UNSCRATCH 6, 8, rsp+0*mmsize +%endif + DEFINE_ARGS dst, stride, cnt, stride16, stride17 + mov stride16q, strideq + mov cntd, 8 + shl stride16q, 4 + lea stride17q, [stride16q+strideq] + + ; FIXME m8 is unused for avx, so we could save one register here for win64 +.loop: +%if notcpuflag(avx) + UNSCRATCH 6, 8, rsp+0*mmsize +%endif + mova [dstq+strideq*0+ 0], m6 + mova [dstq+strideq*0+16], m4 + mova [dstq+strideq*0+32], m2 + mova [dstq+strideq*0+48], m0 + mova [dstq+strideq*1+ 0], m7 + mova [dstq+strideq*1+16], m5 + mova [dstq+strideq*1+32], m3 + mova [dstq+strideq*1+48], m1 + mova [dstq+stride16q+ 0], m4 + mova [dstq+stride16q+16], m2 + mova [dstq+stride16q+32], m0 +%if ARCH_X86_64 + mova [dstq+stride16q+48], m9 +%endif + mova [dstq+stride17q+ 0], m5 + mova [dstq+stride17q+16], m3 + mova [dstq+stride17q+32], m1 +%if ARCH_X86_64 + mova [dstq+stride17q+48], m9 +%endif + lea dstq, [dstq+strideq*2] +%if cpuflag(avx) + vpalignr m6, m4, m6, 2 + vpalignr m4, m2, m4, 2 + vpalignr m2, m0, m2, 2 + vpalignr m7, m5, m7, 2 + vpalignr m5, m3, m5, 2 + vpalignr m3, m1, m3, 2 +%else + SCRATCH 3, 8, rsp+0*mmsize +%if notcpuflag(ssse3) + SCRATCH 1, 10, rsp+1*mmsize +%endif + PALIGNR m3, m4, m6, 2, m1 + mova m6, m3 + PALIGNR m3, m2, m4, 2, m1 + mova m4, m3 + PALIGNR m3, m0, m2, 2, m1 + mova m2, m3 + PALIGNR m3, m5, m7, 2, m1 + mova m7, m3 + UNSCRATCH 3, 8, rsp+0*mmsize + SCRATCH 6, 8, rsp+0*mmsize +%if notcpuflag(ssse3) + UNSCRATCH 1, 10, rsp+1*mmsize + SCRATCH 7, 10, rsp+1*mmsize +%endif + PALIGNR m6, m3, m5, 2, m7 + mova m5, m6 + PALIGNR m6, m1, m3, 2, m7 + mova m3, m6 +%if notcpuflag(ssse3) + UNSCRATCH 7, 10, rsp+1*mmsize +%endif +%endif + SHIFT_RIGHT m1, m1, reg_shuf + SHIFT_RIGHT m0, m0, reg_shuf + dec cntd + jg .loop + +%if ARCH_X86_32 + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] +%assign %%n 0 +%rep 4 + mova [dstq+strideq*0+48], m0 + mova [dstq+strideq*1+48], m0 + mova [dstq+strideq*2+48], m0 + mova [dstq+stride3q +48], m0 +%if %%n < 3 + lea dstq, [dstq+strideq*4] +%endif +%assign %%n (%%n+1) +%endrep +%endif + RET +%endmacro + +INIT_XMM sse2 +VL_FUNCS 2 +INIT_XMM ssse3 +VL_FUNCS 1 +INIT_XMM avx +VL_FUNCS 1 + +%macro VR_FUNCS 0 +cglobal vp9_ipred_vr_4x4_16, 4, 4, 3, dst, stride, l, a + movu m0, [aq-2] + movhps m1, [lq] + PALIGNR m0, m1, 10, m2 ; xyz*abcd + pslldq m1, m0, 2 ; .xyz*abc + pslldq m2, m0, 4 ; ..xyz*ab + LOWPASS 2, 1, 0 ; ..YZ#ABC + pavgw m1, m0 ; ....#ABC + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + movhps [dstq+strideq*0], m1 + movhps [dstq+strideq*1], m2 + shufps m0, m2, m1, q3210 +%if cpuflag(ssse3) + pshufb m2, [pb_4_5_8to13_8x0] +%else + pshuflw m2, m2, q2222 + psrldq m2, 6 +%endif + psrldq m0, 6 + movh [dstq+strideq*2], m0 + movh [dstq+stride3q ], m2 + RET + +cglobal vp9_ipred_vr_8x8_16, 4, 4, 5, dst, stride, l, a + movu m1, [aq-2] ; *abcdefg + movu m2, [lq] ; stuvwxyz + mova m0, [aq] ; abcdefgh + PALIGNR m3, m1, m2, 14, m4 ; z*abcdef + LOWPASS 3, 1, 0 + pavgw m0, m1 + PALIGNR m1, m2, 2, m4 ; tuvwxyz* + pslldq m4, m2, 2 ; .stuvwxy + LOWPASS 4, 2, 1 + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m3 + PALIGNR m0, m4, 14, m1 + pslldq m4, 2 + PALIGNR m3, m4, 14, m1 + pslldq m4, 2 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m3 + lea dstq, [dstq+strideq*4] + PALIGNR m0, m4, 14, m1 + pslldq m4, 2 + PALIGNR m3, m4, 14, m1 + pslldq m4, 2 + mova [dstq+strideq*0], m0 + mova [dstq+strideq*1], m3 + PALIGNR m0, m4, 14, m1 + pslldq m4, 2 + PALIGNR m3, m4, 14, m4 + mova [dstq+strideq*2], m0 + mova [dstq+stride3q ], m3 + RET + +cglobal vp9_ipred_vr_16x16_16, 4, 4, 8, dst, stride, l, a + movu m1, [aq-2] ; *abcdefg + movu m2, [aq+mmsize-2] ; hijklmno + mova m3, [aq] ; abcdefgh + mova m4, [aq+mmsize] ; ijklmnop + mova m5, [lq+mmsize] ; stuvwxyz + PALIGNR m0, m1, m5, 14, m6 ; z*abcdef + movu m6, [aq+mmsize-4] ; ghijklmn + LOWPASS 6, 2, 4 + pavgw m2, m4 + LOWPASS 0, 1, 3 + pavgw m3, m1 + PALIGNR m1, m5, 2, m7 ; tuvwxyz* + movu m7, [lq+mmsize-2] ; rstuvwxy + LOWPASS 1, 5, 7 + movu m5, [lq+2] ; lmnopqrs + pslldq m4, m5, 2 ; .lmnopqr + pslldq m7, m5, 4 ; ..lmnopq + LOWPASS 5, 4, 7 + psrld m4, m1, 16 + psrld m7, m5, 16 + pand m1, [pd_65535] + pand m5, [pd_65535] + packssdw m7, m4 + packssdw m5, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 8 + +.loop: + mova [dstq+strideq*0+ 0], m3 + mova [dstq+strideq*0+16], m2 + mova [dstq+strideq*1+ 0], m0 + mova [dstq+strideq*1+16], m6 + lea dstq, [dstq+strideq*2] + PALIGNR m2, m3, 14, m4 + PALIGNR m3, m7, 14, m4 + pslldq m7, 2 + PALIGNR m6, m0, 14, m4 + PALIGNR m0, m5, 14, m4 + pslldq m5, 2 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_vr_32x32_16, 4, 5, 14, 6 * mmsize * ARCH_X86_32, dst, stride, l, a + movu m0, [aq+mmsize*0-2] ; *a[0-6] + movu m1, [aq+mmsize*1-2] ; a[7-14] + movu m2, [aq+mmsize*2-2] ; a[15-22] + movu m3, [aq+mmsize*3-2] ; a[23-30] + mova m4, [aq+mmsize*3+0] ; a[24-31] + movu m5, [aq+mmsize*3-4] ; a[22-29] + LOWPASS 5, 3, 4 ; A[23-30] + SCRATCH 5, 8, rsp+0*mmsize + pavgw m3, m4 + mova m4, [aq+mmsize*2+0] ; a[16-23] + movu m6, [aq+mmsize*2-4] ; a[14-21] + LOWPASS 6, 2, 4 ; A[15-22] + SCRATCH 6, 9, rsp+1*mmsize + pavgw m2, m4 + mova m4, [aq+mmsize*1+0] ; a[8-15] + movu m7, [aq+mmsize*1-4] ; a[6-13] + LOWPASS 7, 1, 4 ; A[7-14] + SCRATCH 7, 10, rsp+2*mmsize + pavgw m1, m4 + mova m4, [aq+mmsize*0+0] ; a[0-7] + mova m5, [lq+mmsize*3+0] ; l[24-31] + PALIGNR m6, m0, m5, 14, m7 ; l[31]*a[0-5] + LOWPASS 6, 0, 4 ; #A[0-6] + SCRATCH 6, 11, rsp+3*mmsize + pavgw m4, m0 + PALIGNR m0, m5, 2, m7 ; l[25-31]* + movu m7, [lq+mmsize*3-2] ; l[23-30] + LOWPASS 0, 5, 7 ; L[24-31] + movu m5, [lq+mmsize*2-2] ; l[15-22] + mova m7, [lq+mmsize*2+0] ; l[16-23] + movu m6, [lq+mmsize*2+2] ; l[17-24] + LOWPASS 5, 7, 6 ; L[16-23] + psrld m7, m0, 16 + psrld m6, m5, 16 + pand m0, [pd_65535] + pand m5, [pd_65535] + packssdw m6, m7 + packssdw m5, m0 + SCRATCH 5, 12, rsp+4*mmsize + SCRATCH 6, 13, rsp+5*mmsize + movu m6, [lq+mmsize*1-2] ; l[7-14] + mova m0, [lq+mmsize*1+0] ; l[8-15] + movu m5, [lq+mmsize*1+2] ; l[9-16] + LOWPASS 6, 0, 5 ; L[8-15] + movu m0, [lq+mmsize*0+2] ; l[1-8] + pslldq m5, m0, 2 ; .l[1-7] + pslldq m7, m0, 4 ; ..l[1-6] + LOWPASS 0, 5, 7 + psrld m5, m6, 16 + psrld m7, m0, 16 + pand m6, [pd_65535] + pand m0, [pd_65535] + packssdw m7, m5 + packssdw m0, m6 + UNSCRATCH 6, 13, rsp+5*mmsize + DEFINE_ARGS dst, stride, stride16, cnt, stride17 + mov stride16q, strideq + mov cntd, 8 + shl stride16q, 4 +%if ARCH_X86_64 + lea stride17q, [stride16q+strideq] +%endif + +.loop: + mova [dstq+strideq*0+ 0], m4 + mova [dstq+strideq*0+16], m1 + mova [dstq+strideq*0+32], m2 + mova [dstq+strideq*0+48], m3 +%if ARCH_X86_64 + mova [dstq+strideq*1+ 0], m11 + mova [dstq+strideq*1+16], m10 + mova [dstq+strideq*1+32], m9 + mova [dstq+strideq*1+48], m8 +%endif + mova [dstq+stride16q+ 0], m6 + mova [dstq+stride16q+16], m4 + mova [dstq+stride16q+32], m1 + mova [dstq+stride16q+48], m2 +%if ARCH_X86_64 + mova [dstq+stride17q+ 0], m12 + mova [dstq+stride17q+16], m11 + mova [dstq+stride17q+32], m10 + mova [dstq+stride17q+48], m9 +%endif + lea dstq, [dstq+strideq*2] + PALIGNR m3, m2, 14, m5 + PALIGNR m2, m1, 14, m5 + PALIGNR m1, m4, 14, m5 + PALIGNR m4, m6, 14, m5 + PALIGNR m6, m7, 14, m5 + pslldq m7, 2 +%if ARCH_X86_64 + PALIGNR m8, m9, 14, m5 + PALIGNR m9, m10, 14, m5 + PALIGNR m10, m11, 14, m5 + PALIGNR m11, m12, 14, m5 + PALIGNR m12, m0, 14, m5 + pslldq m0, 2 +%endif + dec cntd + jg .loop + +%if ARCH_X86_32 + UNSCRATCH 5, 12, rsp+4*mmsize + UNSCRATCH 4, 11, rsp+3*mmsize + UNSCRATCH 3, 10, rsp+2*mmsize + UNSCRATCH 2, 9, rsp+1*mmsize + UNSCRATCH 1, 8, rsp+0*mmsize + mov dstq, dstm + mov cntd, 8 + add dstq, strideq +.loop2: + mova [dstq+strideq*0+ 0], m4 + mova [dstq+strideq*0+16], m3 + mova [dstq+strideq*0+32], m2 + mova [dstq+strideq*0+48], m1 + mova [dstq+stride16q+ 0], m5 + mova [dstq+stride16q+16], m4 + mova [dstq+stride16q+32], m3 + mova [dstq+stride16q+48], m2 + lea dstq, [dstq+strideq*2] + PALIGNR m1, m2, 14, m6 + PALIGNR m2, m3, 14, m6 + PALIGNR m3, m4, 14, m6 + PALIGNR m4, m5, 14, m6 + PALIGNR m5, m0, 14, m6 + pslldq m0, 2 + dec cntd + jg .loop2 +%endif + RET +%endmacro + +INIT_XMM sse2 +VR_FUNCS +INIT_XMM ssse3 +VR_FUNCS +INIT_XMM avx +VR_FUNCS + +%macro HU_FUNCS 1 ; stack_mem_for_32x32_32bit_function +cglobal vp9_ipred_hu_4x4_16, 3, 3, 3, dst, stride, l, a + movh m0, [lq] ; abcd +%if cpuflag(ssse3) + pshufb m0, [pb_0to7_67x4] ; abcddddd +%else + punpcklqdq m0, m0 + pshufhw m0, m0, q3333 ; abcddddd +%endif + psrldq m1, m0, 2 ; bcddddd. + psrldq m2, m0, 4 ; cddddd.. + LOWPASS 2, 1, 0 ; BCDddd.. + pavgw m1, m0 ; abcddddd + SBUTTERFLY wd, 1, 2, 0 ; aBbCcDdd, dddddddd + PALIGNR m2, m1, 4, m0 ; bCcDdddd + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + movh [dstq+strideq*0], m1 ; aBbC + movh [dstq+strideq*1], m2 ; bCcD + movhps [dstq+strideq*2], m1 ; cDdd + movhps [dstq+stride3q ], m2 ; dddd + RET + +cglobal vp9_ipred_hu_8x8_16, 3, 3, 4, dst, stride, l, a + mova m0, [lq] +%if cpuflag(ssse3) + mova m3, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m1, m2, m0, m3 + LOWPASS 2, 1, 0 + pavgw m1, m0 + SBUTTERFLY wd, 1, 2, 0 + shufps m0, m1, m2, q1032 + pshufd m3, m2, q3332 + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + mova [dstq+strideq *0], m1 + mova [dstq+strideq *2], m0 + mova [dstq+strideq *4], m2 + mova [dstq+stride3q*2], m3 + add dstq, strideq +%if cpuflag(avx) + vpalignr m1, m2, m1, 4 +%else + PALIGNR m0, m2, m1, 4, m3 + mova m1, m0 +%endif + pshufd m2, m2, q3321 + shufps m0, m1, m2, q1032 + pshufd m3, m2, q3332 + mova [dstq+strideq *0], m1 + mova [dstq+strideq *2], m0 + mova [dstq+strideq *4], m2 + mova [dstq+stride3q*2], m3 + RET + +cglobal vp9_ipred_hu_16x16_16, 3, 4, 6 + notcpuflag(ssse3), dst, stride, l, a + mova m0, [lq] + mova m3, [lq+mmsize] + movu m1, [lq+2] + movu m2, [lq+4] + LOWPASS 2, 1, 0 + pavgw m1, m0 + SBUTTERFLY wd, 1, 2, 0 +%if cpuflag(ssse3) + mova m5, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m0, m4, m3, m5 + LOWPASS 4, 0, 3 + pavgw m3, m0 + SBUTTERFLY wd, 3, 4, 5 + pshufd m0, m0, q3333 + DEFINE_ARGS dst, stride, stride3, cnt + lea stride3q, [strideq*3] + mov cntd, 4 + +.loop: + mova [dstq+strideq *0+ 0], m1 + mova [dstq+strideq *0+16], m2 + mova [dstq+strideq *4+ 0], m2 + mova [dstq+strideq *4+16], m3 + mova [dstq+strideq *8+ 0], m3 + mova [dstq+strideq *8+16], m4 + mova [dstq+stride3q*4+ 0], m4 + mova [dstq+stride3q*4+16], m0 + add dstq, strideq +%if cpuflag(avx) + vpalignr m1, m2, m1, 4 + vpalignr m2, m3, m2, 4 + vpalignr m3, m4, m3, 4 + vpalignr m4, m0, m4, 4 +%else + PALIGNR m5, m2, m1, 4, m6 + mova m1, m5 + PALIGNR m5, m3, m2, 4, m6 + mova m2, m5 + PALIGNR m5, m4, m3, 4, m6 + mova m3, m5 + PALIGNR m5, m0, m4, 4, m6 + mova m4, m5 +%endif + dec cntd + jg .loop + RET + +cglobal vp9_ipred_hu_32x32_16, 3, 7, 10 + notcpuflag(ssse3), \ + %1 * -mmsize * ARCH_X86_32, dst, stride, l, a + mova m2, [lq+mmsize*0+0] + movu m1, [lq+mmsize*0+2] + movu m0, [lq+mmsize*0+4] + LOWPASS 0, 1, 2 + pavgw m1, m2 + SBUTTERFLY wd, 1, 0, 2 + SCRATCH 1, 8, rsp+0*mmsize + mova m4, [lq+mmsize*1+0] + movu m3, [lq+mmsize*1+2] + movu m2, [lq+mmsize*1+4] + LOWPASS 2, 3, 4 + pavgw m3, m4 + SBUTTERFLY wd, 3, 2, 4 + mova m6, [lq+mmsize*2+0] + movu m5, [lq+mmsize*2+2] + movu m4, [lq+mmsize*2+4] + LOWPASS 4, 5, 6 + pavgw m5, m6 + SBUTTERFLY wd, 5, 4, 6 + mova m7, [lq+mmsize*3+0] + SCRATCH 0, 9, rsp+1*mmsize +%if cpuflag(ssse3) + mova m0, [pb_2to15_14_15] +%endif + SHIFT_RIGHTx2 m1, m6, m7, m0 + LOWPASS 6, 1, 7 + pavgw m7, m1 + SBUTTERFLY wd, 7, 6, 0 + pshufd m1, m1, q3333 + UNSCRATCH 0, 9, rsp+1*mmsize + DEFINE_ARGS dst, stride, cnt, stride3, stride4, stride20, stride28 + lea stride3q, [strideq*3] + lea stride4q, [strideq*4] + lea stride28q, [stride4q*8] + lea stride20q, [stride4q*5] + sub stride28q, stride4q + mov cntd, 4 + +.loop: +%if ARCH_X86_64 + SWAP 1, 8 +%else + mova [rsp+1*mmsize], m1 + mova m1, [rsp+0*mmsize] +%endif + mova [dstq+strideq *0+ 0], m1 + mova [dstq+strideq *0+16], m0 + mova [dstq+strideq *0+32], m3 + mova [dstq+strideq *0+48], m2 + mova [dstq+stride4q*1+ 0], m0 + mova [dstq+stride4q*1+16], m3 + mova [dstq+stride4q*1+32], m2 + mova [dstq+stride4q*1+48], m5 + mova [dstq+stride4q*2+ 0], m3 + mova [dstq+stride4q*2+16], m2 + mova [dstq+stride4q*2+32], m5 + mova [dstq+stride4q*2+48], m4 +%if cpuflag(avx) + vpalignr m1, m0, m1, 4 + vpalignr m0, m3, m0, 4 + vpalignr m3, m2, m3, 4 +%else + SCRATCH 6, 9, rsp+2*mmsize +%if notcpuflag(ssse3) + SCRATCH 7, 10, rsp+3*mmsize +%endif + PALIGNR m6, m0, m1, 4, m7 + mova m1, m6 + PALIGNR m6, m3, m0, 4, m7 + mova m0, m6 + PALIGNR m6, m2, m3, 4, m7 + mova m3, m6 + UNSCRATCH 6, 9, rsp+2*mmsize + SCRATCH 0, 9, rsp+2*mmsize +%if notcpuflag(ssse3) + UNSCRATCH 7, 10, rsp+3*mmsize + SCRATCH 3, 10, rsp+3*mmsize +%endif +%endif +%if ARCH_X86_64 + SWAP 1, 8 +%else + mova [rsp+0*mmsize], m1 + mova m1, [rsp+1*mmsize] +%endif + mova [dstq+stride3q*4+ 0], m2 + mova [dstq+stride3q*4+16], m5 + mova [dstq+stride3q*4+32], m4 + mova [dstq+stride3q*4+48], m7 + mova [dstq+stride4q*4+ 0], m5 + mova [dstq+stride4q*4+16], m4 + mova [dstq+stride4q*4+32], m7 + mova [dstq+stride4q*4+48], m6 + mova [dstq+stride20q + 0], m4 + mova [dstq+stride20q +16], m7 + mova [dstq+stride20q +32], m6 + mova [dstq+stride20q +48], m1 + mova [dstq+stride3q*8+ 0], m7 + mova [dstq+stride3q*8+16], m6 + mova [dstq+stride3q*8+32], m1 + mova [dstq+stride3q*8+48], m1 + mova [dstq+stride28q + 0], m6 + mova [dstq+stride28q +16], m1 + mova [dstq+stride28q +32], m1 + mova [dstq+stride28q +48], m1 +%if cpuflag(avx) + vpalignr m2, m5, m2, 4 + vpalignr m5, m4, m5, 4 + vpalignr m4, m7, m4, 4 + vpalignr m7, m6, m7, 4 + vpalignr m6, m1, m6, 4 +%else + PALIGNR m0, m5, m2, 4, m3 + mova m2, m0 + PALIGNR m0, m4, m5, 4, m3 + mova m5, m0 + PALIGNR m0, m7, m4, 4, m3 + mova m4, m0 + PALIGNR m0, m6, m7, 4, m3 + mova m7, m0 + PALIGNR m0, m1, m6, 4, m3 + mova m6, m0 + UNSCRATCH 0, 9, rsp+2*mmsize +%if notcpuflag(ssse3) + UNSCRATCH 3, 10, rsp+3*mmsize +%endif +%endif + add dstq, strideq + dec cntd + jg .loop + RET +%endmacro + +INIT_XMM sse2 +HU_FUNCS 4 +INIT_XMM ssse3 +HU_FUNCS 3 +INIT_XMM avx +HU_FUNCS 2 + +%macro HD_FUNCS 0 +cglobal vp9_ipred_hd_4x4_16, 4, 4, 4, dst, stride, l, a + movh m0, [lq] + movhps m0, [aq-2] + psrldq m1, m0, 2 + psrldq m2, m0, 4 + LOWPASS 2, 1, 0 + pavgw m1, m0 + punpcklwd m1, m2 + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + + movh [dstq+stride3q ], m1 + movhps [dstq+strideq*1], m1 + movhlps m2, m2 + PALIGNR m2, m1, 4, m0 + movh [dstq+strideq*2], m2 + movhps [dstq+strideq*0], m2 + RET + +cglobal vp9_ipred_hd_8x8_16, 4, 4, 5, dst, stride, l, a + mova m0, [lq] + movu m1, [aq-2] + PALIGNR m2, m1, m0, 2, m3 + PALIGNR m3, m1, m0, 4, m4 + LOWPASS 3, 2, 0 + pavgw m2, m0 + SBUTTERFLY wd, 2, 3, 0 + psrldq m0, m1, 2 + psrldq m4, m1, 4 + LOWPASS 1, 0, 4 + DEFINE_ARGS dst8, mstride, cnt + lea dst8q, [dst8q+mstrideq*8] + neg mstrideq + mov cntd, 4 + +.loop: + add dst8q, mstrideq + mova [dst8q+mstrideq*0], m2 + mova [dst8q+mstrideq*4], m3 +%if cpuflag(avx) + vpalignr m2, m3, m2, 4 + vpalignr m3, m1, m3, 4 +%else + PALIGNR m0, m3, m2, 4, m4 + mova m2, m0 + PALIGNR m0, m1, m3, 4, m4 + mova m3, m0 +%endif + psrldq m1, 4 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_hd_16x16_16, 4, 4, 8, dst, stride, l, a + mova m2, [lq] + movu m1, [lq+2] + movu m0, [lq+4] + LOWPASS 0, 1, 2 + pavgw m1, m2 + mova m4, [lq+mmsize] + movu m5, [aq-2] + PALIGNR m3, m5, m4, 2, m6 + PALIGNR m2, m5, m4, 4, m6 + LOWPASS 2, 3, 4 + pavgw m3, m4 + SBUTTERFLY wd, 1, 0, 4 + SBUTTERFLY wd, 3, 2, 4 + mova m6, [aq] + movu m4, [aq+2] + LOWPASS 4, 6, 5 + movu m5, [aq+mmsize-2] + psrldq m6, m5, 2 + psrldq m7, m5, 4 + LOWPASS 5, 6, 7 + DEFINE_ARGS dst, mstride, mstride3, cnt + lea dstq, [dstq+mstrideq*8] + lea dstq, [dstq+mstrideq*8] + neg mstrideq + lea mstride3q, [mstrideq*3] + mov cntd, 4 + +.loop: + add dstq, mstrideq + mova [dstq+mstride3q*4+ 0], m2 + mova [dstq+mstride3q*4+16], m4 + mova [dstq+mstrideq *8+ 0], m3 + mova [dstq+mstrideq *8+16], m2 + mova [dstq+mstrideq *4+ 0], m0 + mova [dstq+mstrideq *4+16], m3 + mova [dstq+mstrideq *0+ 0], m1 + mova [dstq+mstrideq *0+16], m0 +%if cpuflag(avx) + vpalignr m1, m0, m1, 4 + vpalignr m0, m3, m0, 4 + vpalignr m3, m2, m3, 4 + vpalignr m2, m4, m2, 4 + vpalignr m4, m5, m4, 4 +%else + PALIGNR m6, m0, m1, 4, m7 + mova m1, m6 + PALIGNR m6, m3, m0, 4, m7 + mova m0, m6 + PALIGNR m6, m2, m3, 4, m7 + mova m3, m6 + PALIGNR m6, m4, m2, 4, m7 + mova m2, m6 + PALIGNR m6, m5, m4, 4, m7 + mova m4, m6 +%endif + psrldq m5, 4 + dec cntd + jg .loop + RET + +cglobal vp9_ipred_hd_32x32_16, 4, 4 + 3 * ARCH_X86_64, 14, \ + 10 * -mmsize * ARCH_X86_32, dst, stride, l, a + mova m2, [lq+mmsize*0+0] + movu m1, [lq+mmsize*0+2] + movu m0, [lq+mmsize*0+4] + LOWPASS 0, 1, 2 + pavgw m1, m2 + SBUTTERFLY wd, 1, 0, 2 + mova m4, [lq+mmsize*1+0] + movu m3, [lq+mmsize*1+2] + movu m2, [lq+mmsize*1+4] + LOWPASS 2, 3, 4 + pavgw m3, m4 + SBUTTERFLY wd, 3, 2, 4 + SCRATCH 0, 8, rsp+0*mmsize + SCRATCH 1, 9, rsp+1*mmsize + SCRATCH 2, 10, rsp+2*mmsize + SCRATCH 3, 11, rsp+3*mmsize + mova m6, [lq+mmsize*2+0] + movu m5, [lq+mmsize*2+2] + movu m4, [lq+mmsize*2+4] + LOWPASS 4, 5, 6 + pavgw m5, m6 + SBUTTERFLY wd, 5, 4, 6 + mova m0, [lq+mmsize*3+0] + movu m1, [aq+mmsize*0-2] + PALIGNR m7, m1, m0, 2, m2 + PALIGNR m6, m1, m0, 4, m2 + LOWPASS 6, 7, 0 + pavgw m7, m0 + SBUTTERFLY wd, 7, 6, 0 + mova m2, [aq+mmsize*0+0] + movu m0, [aq+mmsize*0+2] + LOWPASS 0, 2, 1 + movu m1, [aq+mmsize*1-2] + mova m2, [aq+mmsize*1+0] + movu m3, [aq+mmsize*1+2] + LOWPASS 1, 2, 3 + SCRATCH 6, 12, rsp+6*mmsize + SCRATCH 7, 13, rsp+7*mmsize + movu m2, [aq+mmsize*2-2] + mova m3, [aq+mmsize*2+0] + movu m6, [aq+mmsize*2+2] + LOWPASS 2, 3, 6 + movu m3, [aq+mmsize*3-2] + psrldq m6, m3, 2 + psrldq m7, m3, 4 + LOWPASS 3, 6, 7 + UNSCRATCH 6, 12, rsp+6*mmsize + UNSCRATCH 7, 13, rsp+7*mmsize +%if ARCH_X86_32 + mova [rsp+4*mmsize], m4 + mova [rsp+5*mmsize], m5 + ; we already backed up m6/m7 earlier on x86-32 in SCRATCH, so we don't need + ; to do it again here +%endif + DEFINE_ARGS dst, stride, cnt, stride3, stride4, stride20, stride28 + mov cntd, 4 + lea stride3q, [strideq*3] +%if ARCH_X86_64 + lea stride4q, [strideq*4] + lea stride28q, [stride4q*8] + lea stride20q, [stride4q*5] + sub stride28q, stride4q +%endif + add dstq, stride3q + + ; x86-32 doesn't have enough registers, so on that platform, we split + ; the loop in 2... Otherwise you spend most of the loop (un)scratching +.loop: +%if ARCH_X86_64 + mova [dstq+stride28q + 0], m9 + mova [dstq+stride28q +16], m8 + mova [dstq+stride28q +32], m11 + mova [dstq+stride28q +48], m10 + mova [dstq+stride3q*8+ 0], m8 + mova [dstq+stride3q*8+16], m11 + mova [dstq+stride3q*8+32], m10 + mova [dstq+stride3q*8+48], m5 + mova [dstq+stride20q + 0], m11 + mova [dstq+stride20q +16], m10 + mova [dstq+stride20q +32], m5 + mova [dstq+stride20q +48], m4 + mova [dstq+stride4q*4+ 0], m10 + mova [dstq+stride4q*4+16], m5 + mova [dstq+stride4q*4+32], m4 + mova [dstq+stride4q*4+48], m7 +%endif + mova [dstq+stride3q*4+ 0], m5 + mova [dstq+stride3q*4+16], m4 + mova [dstq+stride3q*4+32], m7 + mova [dstq+stride3q*4+48], m6 + mova [dstq+strideq* 8+ 0], m4 + mova [dstq+strideq* 8+16], m7 + mova [dstq+strideq* 8+32], m6 + mova [dstq+strideq* 8+48], m0 + mova [dstq+strideq* 4+ 0], m7 + mova [dstq+strideq* 4+16], m6 + mova [dstq+strideq* 4+32], m0 + mova [dstq+strideq* 4+48], m1 + mova [dstq+strideq* 0+ 0], m6 + mova [dstq+strideq* 0+16], m0 + mova [dstq+strideq* 0+32], m1 + mova [dstq+strideq* 0+48], m2 + sub dstq, strideq +%if cpuflag(avx) +%if ARCH_X86_64 + vpalignr m9, m8, m9, 4 + vpalignr m8, m11, m8, 4 + vpalignr m11, m10, m11, 4 + vpalignr m10, m5, m10, 4 +%endif + vpalignr m5, m4, m5, 4 + vpalignr m4, m7, m4, 4 + vpalignr m7, m6, m7, 4 + vpalignr m6, m0, m6, 4 + vpalignr m0, m1, m0, 4 + vpalignr m1, m2, m1, 4 + vpalignr m2, m3, m2, 4 +%else +%if ARCH_X86_64 + PALIGNR m12, m8, m9, 4, m13 + mova m9, m12 + PALIGNR m12, m11, m8, 4, m13 + mova m8, m12 + PALIGNR m12, m10, m11, 4, m13 + mova m11, m12 + PALIGNR m12, m5, m10, 4, m13 + mova m10, m12 +%endif + SCRATCH 3, 12, rsp+8*mmsize, sh +%if notcpuflag(ssse3) + SCRATCH 2, 13, rsp+9*mmsize +%endif + PALIGNR m3, m4, m5, 4, m2 + mova m5, m3 + PALIGNR m3, m7, m4, 4, m2 + mova m4, m3 + PALIGNR m3, m6, m7, 4, m2 + mova m7, m3 + PALIGNR m3, m0, m6, 4, m2 + mova m6, m3 + PALIGNR m3, m1, m0, 4, m2 + mova m0, m3 +%if notcpuflag(ssse3) + UNSCRATCH 2, 13, rsp+9*mmsize + SCRATCH 0, 13, rsp+9*mmsize +%endif + PALIGNR m3, m2, m1, 4, m0 + mova m1, m3 + PALIGNR m3, reg_sh, m2, 4, m0 + mova m2, m3 +%if notcpuflag(ssse3) + UNSCRATCH 0, 13, rsp+9*mmsize +%endif + UNSCRATCH 3, 12, rsp+8*mmsize, sh +%endif + psrldq m3, 4 + dec cntd + jg .loop + +%if ARCH_X86_32 + UNSCRATCH 0, 8, rsp+0*mmsize + UNSCRATCH 1, 9, rsp+1*mmsize + UNSCRATCH 2, 10, rsp+2*mmsize + UNSCRATCH 3, 11, rsp+3*mmsize + mova m4, [rsp+4*mmsize] + mova m5, [rsp+5*mmsize] + mova m6, [rsp+6*mmsize] + mova m7, [rsp+7*mmsize] + DEFINE_ARGS dst, stride, stride5, stride3 + lea stride5q, [strideq*5] + lea dstq, [dstq+stride5q*4] + DEFINE_ARGS dst, stride, cnt, stride3 + mov cntd, 4 +.loop_2: + mova [dstq+stride3q*4+ 0], m1 + mova [dstq+stride3q*4+16], m0 + mova [dstq+stride3q*4+32], m3 + mova [dstq+stride3q*4+48], m2 + mova [dstq+strideq* 8+ 0], m0 + mova [dstq+strideq* 8+16], m3 + mova [dstq+strideq* 8+32], m2 + mova [dstq+strideq* 8+48], m5 + mova [dstq+strideq* 4+ 0], m3 + mova [dstq+strideq* 4+16], m2 + mova [dstq+strideq* 4+32], m5 + mova [dstq+strideq* 4+48], m4 + mova [dstq+strideq* 0+ 0], m2 + mova [dstq+strideq* 0+16], m5 + mova [dstq+strideq* 0+32], m4 + mova [dstq+strideq* 0+48], m7 + sub dstq, strideq +%if cpuflag(avx) + vpalignr m1, m0, m1, 4 + vpalignr m0, m3, m0, 4 + vpalignr m3, m2, m3, 4 + vpalignr m2, m5, m2, 4 + vpalignr m5, m4, m5, 4 + vpalignr m4, m7, m4, 4 + vpalignr m7, m6, m7, 4 +%else + SCRATCH 6, 12, rsp+8*mmsize, sh +%if notcpuflag(ssse3) + SCRATCH 7, 13, rsp+9*mmsize +%endif + PALIGNR m6, m0, m1, 4, m7 + mova m1, m6 + PALIGNR m6, m3, m0, 4, m7 + mova m0, m6 + PALIGNR m6, m2, m3, 4, m7 + mova m3, m6 + PALIGNR m6, m5, m2, 4, m7 + mova m2, m6 + PALIGNR m6, m4, m5, 4, m7 + mova m5, m6 +%if notcpuflag(ssse3) + UNSCRATCH 7, 13, rsp+9*mmsize + SCRATCH 5, 13, rsp+9*mmsize +%endif + PALIGNR m6, m7, m4, 4, m5 + mova m4, m6 + PALIGNR m6, reg_sh, m7, 4, m5 + mova m7, m6 +%if notcpuflag(ssse3) + UNSCRATCH 5, 13, rsp+9*mmsize +%endif + UNSCRATCH 6, 12, rsp+8*mmsize, sh +%endif + psrldq m6, 4 + dec cntd + jg .loop_2 +%endif + RET +%endmacro + +INIT_XMM sse2 +HD_FUNCS +INIT_XMM ssse3 +HD_FUNCS +INIT_XMM avx +HD_FUNCS diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm.asm new file mode 100644 index 00000000..2c63fe51 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm.asm @@ -0,0 +1,3197 @@ +;****************************************************************************** +;* VP9 IDCT SIMD optimizations +;* +;* Copyright (C) 2013 Clément Bœsch +;* Copyright (C) 2013 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" +%include "vp9itxfm_template.asm" + +SECTION_RODATA 32 + +%macro VP9_IDCT_COEFFS 2-3 0 +const pw_m%1_%2 +times 8 dw -%1, %2 +const pw_%2_%1 +times 8 dw %2, %1 + +%if %3 == 1 +const pw_m%2_m%1 +times 8 dw -%2, -%1 +%if %1 != %2 +const pw_m%2_%1 +times 8 dw -%2, %1 +const pw_%1_%2 +times 8 dw %1, %2 +%endif +%endif + +%if %1 < 11585 +pw_m%1x2: times 16 dw -%1*2 +%elif %1 > 11585 +pw_%1x2: times 16 dw %1*2 +%else +const pw_%1x2 +times 16 dw %1*2 +%endif + +%if %2 != %1 +pw_%2x2: times 16 dw %2*2 +%endif +%endmacro + +VP9_IDCT_COEFFS 16364, 804 +VP9_IDCT_COEFFS 16305, 1606 +VP9_IDCT_COEFFS 16069, 3196, 1 +VP9_IDCT_COEFFS 15893, 3981 +VP9_IDCT_COEFFS 15137, 6270, 1 +VP9_IDCT_COEFFS 14811, 7005 +VP9_IDCT_COEFFS 14449, 7723 +VP9_IDCT_COEFFS 13160, 9760 +VP9_IDCT_COEFFS 11585, 11585, 1 +VP9_IDCT_COEFFS 11003, 12140 +VP9_IDCT_COEFFS 10394, 12665 +VP9_IDCT_COEFFS 9102, 13623, 1 +VP9_IDCT_COEFFS 8423, 14053 +VP9_IDCT_COEFFS 5520, 15426 +VP9_IDCT_COEFFS 4756, 15679 +VP9_IDCT_COEFFS 2404, 16207 + +const pw_5283_13377 +times 4 dw 5283, 13377 +const pw_9929_13377 +times 4 dw 9929, 13377 +const pw_15212_m13377 +times 4 dw 15212, -13377 +const pw_15212_9929 +times 4 dw 15212, 9929 +const pw_m5283_m15212 +times 4 dw -5283, -15212 +const pw_13377x2 +times 8 dw 13377*2 +const pw_m13377_13377 +times 4 dw -13377, 13377 +const pw_13377_0 +times 4 dw 13377, 0 + +cextern pw_8 +cextern pw_16 +cextern pw_32 +cextern pw_512 +cextern pw_1024 +cextern pw_2048 +cextern pw_m1 +cextern pd_8192 + +SECTION .text + +%macro VP9_UNPACK_MULSUB_2D_4X 6 ; dst1 [src1], dst2 [src2], dst3, dst4, mul1, mul2 + punpckhwd m%4, m%2, m%1 + punpcklwd m%2, m%1 + pmaddwd m%3, m%4, [pw_m%5_%6] + pmaddwd m%4, [pw_%6_%5] + pmaddwd m%1, m%2, [pw_m%5_%6] + pmaddwd m%2, [pw_%6_%5] +%endmacro + +%macro VP9_RND_SH_SUMSUB_BA 6 ; dst1 [src1], dst2 [src2], src3, src4, tmp, round + SUMSUB_BA d, %1, %2, %5 + SUMSUB_BA d, %3, %4, %5 + paddd m%1, %6 + paddd m%2, %6 + paddd m%3, %6 + paddd m%4, %6 + psrad m%1, 14 + psrad m%2, 14 + psrad m%3, 14 + psrad m%4, 14 + packssdw m%1, m%3 + packssdw m%2, m%4 +%endmacro + +%macro VP9_STORE_2X 5-6 dstq ; reg1, reg2, tmp1, tmp2, zero, dst +%if mmsize == 32 + pmovzxbw m%3, [%6] + pmovzxbw m%4, [%6+strideq] +%else + movh m%3, [%6] + movh m%4, [%6+strideq] + punpcklbw m%3, m%5 + punpcklbw m%4, m%5 +%endif + paddw m%3, m%1 + paddw m%4, m%2 +%if mmsize == 32 + packuswb m%3, m%4 + ; Intel... + vpermq m%3, m%3, q3120 + mova [%6], xm%3 + vextracti128 [%6+strideq], m%3, 1 +%elif mmsize == 16 + packuswb m%3, m%4 + movh [%6], m%3 + movhps [%6+strideq], m%3 +%else + packuswb m%3, m%5 + packuswb m%4, m%5 + movh [%6], m%3 + movh [%6+strideq], m%4 +%endif +%endmacro + +%macro ZERO_BLOCK 4 ; mem, stride, nnzcpl, zero_reg +%assign %%y 0 +%rep %3 +%assign %%x 0 +%rep %3*2/mmsize + mova [%1+%%y+%%x], %4 +%assign %%x (%%x+mmsize) +%endrep +%assign %%y (%%y+%2) +%endrep +%endmacro + +;------------------------------------------------------------------------------------------- +; void vp9_iwht_iwht_4x4_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;------------------------------------------------------------------------------------------- + +INIT_MMX mmx +cglobal vp9_iwht_iwht_4x4_add, 3, 3, 0, dst, stride, block, eob + mova m0, [blockq+0*8] + mova m1, [blockq+1*8] + mova m2, [blockq+2*8] + mova m3, [blockq+3*8] + psraw m0, 2 + psraw m1, 2 + psraw m2, 2 + psraw m3, 2 + + VP9_IWHT4_1D + TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP9_IWHT4_1D + + pxor m4, m4 + VP9_STORE_2X 0, 1, 5, 6, 4 + lea dstq, [dstq+strideq*2] + VP9_STORE_2X 2, 3, 5, 6, 4 + ZERO_BLOCK blockq, 8, 4, m4 + RET + +;------------------------------------------------------------------------------------------- +; void vp9_idct_idct_4x4_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;------------------------------------------------------------------------------------------- + +; 2x2 top left corner +%macro VP9_IDCT4_2x2_1D 0 + pmulhrsw m0, m5 ; m0=t1 + mova m2, m0 ; m2=t0 + mova m3, m1 + pmulhrsw m1, m6 ; m1=t2 + pmulhrsw m3, m7 ; m3=t3 + VP9_IDCT4_1D_FINALIZE +%endmacro + +%macro VP9_IDCT4_WRITEOUT 0 +%if cpuflag(ssse3) + mova m5, [pw_2048] + pmulhrsw m0, m5 ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4 + pmulhrsw m1, m5 +%else + mova m5, [pw_8] + paddw m0, m5 + paddw m1, m5 + psraw m0, 4 + psraw m1, 4 +%endif + VP9_STORE_2X 0, 1, 6, 7, 4 + lea dstq, [dstq+2*strideq] +%if cpuflag(ssse3) + pmulhrsw m2, m5 + pmulhrsw m3, m5 +%else + paddw m2, m5 + paddw m3, m5 + psraw m2, 4 + psraw m3, 4 +%endif + VP9_STORE_2X 2, 3, 6, 7, 4 +%endmacro + +%macro IDCT_4x4_FN 1 +INIT_MMX %1 +cglobal vp9_idct_idct_4x4_add, 4, 4, 0, dst, stride, block, eob + +%if cpuflag(ssse3) + cmp eobd, 4 ; 2x2 or smaller + jg .idctfull + + cmp eobd, 1 ; faster path for when only DC is set + jne .idct2x2 +%else + cmp eobd, 1 + jg .idctfull +%endif + +%if cpuflag(ssse3) + movd m0, [blockq] + mova m5, [pw_11585x2] + pmulhrsw m0, m5 + pmulhrsw m0, m5 +%else + DEFINE_ARGS dst, stride, block, coef + movsx coefd, word [blockq] + imul coefd, 11585 + add coefd, 8192 + sar coefd, 14 + imul coefd, 11585 + add coefd, (8 << 14) + 8192 + sar coefd, 14 + 4 + movd m0, coefd +%endif + pshufw m0, m0, 0 + pxor m4, m4 + movh [blockq], m4 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_2048] ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4 +%endif + VP9_STORE_2X 0, 0, 6, 7, 4 + lea dstq, [dstq+2*strideq] + VP9_STORE_2X 0, 0, 6, 7, 4 + RET + +%if cpuflag(ssse3) +; faster path for when only top left 2x2 block is set +.idct2x2: + movd m0, [blockq+0] + movd m1, [blockq+8] + mova m5, [pw_11585x2] + mova m6, [pw_6270x2] + mova m7, [pw_15137x2] + VP9_IDCT4_2x2_1D + ; partial 2x4 transpose + punpcklwd m0, m1 + punpcklwd m2, m3 + SBUTTERFLY dq, 0, 2, 1 + SWAP 1, 2 + VP9_IDCT4_2x2_1D + pxor m4, m4 ; used for the block reset, and VP9_STORE_2X + movh [blockq+ 0], m4 + movh [blockq+ 8], m4 + VP9_IDCT4_WRITEOUT + RET +%endif + +.idctfull: ; generic full 4x4 idct/idct + mova m0, [blockq+ 0] + mova m1, [blockq+ 8] + mova m2, [blockq+16] + mova m3, [blockq+24] +%if cpuflag(ssse3) + mova m6, [pw_11585x2] +%endif + mova m7, [pd_8192] ; rounding + VP9_IDCT4_1D + TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP9_IDCT4_1D + pxor m4, m4 ; used for the block reset, and VP9_STORE_2X + mova [blockq+ 0], m4 + mova [blockq+ 8], m4 + mova [blockq+16], m4 + mova [blockq+24], m4 + VP9_IDCT4_WRITEOUT + RET +%endmacro + +IDCT_4x4_FN mmxext +IDCT_4x4_FN ssse3 + +;------------------------------------------------------------------------------------------- +; void vp9_iadst_iadst_4x4_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;------------------------------------------------------------------------------------------- + +%macro IADST4_FN 5 +INIT_MMX %5 +cglobal vp9_%1_%3_4x4_add, 3, 3, 0, dst, stride, block, eob +%if WIN64 && notcpuflag(ssse3) + WIN64_SPILL_XMM 8 +%endif + movdqa xmm5, [pd_8192] + mova m0, [blockq+ 0] + mova m1, [blockq+ 8] + mova m2, [blockq+16] + mova m3, [blockq+24] +%if cpuflag(ssse3) + mova m6, [pw_11585x2] +%endif +%ifnidn %1%3, iadstiadst + movdq2q m7, xmm5 +%endif + VP9_%2_1D + TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP9_%4_1D + pxor m4, m4 ; used for the block reset, and VP9_STORE_2X + mova [blockq+ 0], m4 + mova [blockq+ 8], m4 + mova [blockq+16], m4 + mova [blockq+24], m4 + VP9_IDCT4_WRITEOUT + RET +%endmacro + +IADST4_FN idct, IDCT4, iadst, IADST4, sse2 +IADST4_FN iadst, IADST4, idct, IDCT4, sse2 +IADST4_FN iadst, IADST4, iadst, IADST4, sse2 + +IADST4_FN idct, IDCT4, iadst, IADST4, ssse3 +IADST4_FN iadst, IADST4, idct, IDCT4, ssse3 +IADST4_FN iadst, IADST4, iadst, IADST4, ssse3 + +%macro SCRATCH 3 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova [%3], m%1 +%endif +%endmacro + +%macro UNSCRATCH 3 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova m%1, [%3] +%endif +%endmacro + +;------------------------------------------------------------------------------------------- +; void vp9_idct_idct_8x8_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;------------------------------------------------------------------------------------------- + +%macro VP9_IDCT8_1D_FINALIZE 0 + SUMSUB_BA w, 3, 6, 5 ; m3=t0+t7, m6=t0-t7 + SUMSUB_BA w, 1, 2, 5 ; m1=t1+t6, m2=t1-t6 + SUMSUB_BA w, 7, 0, 5 ; m7=t2+t5, m0=t2-t5 + + UNSCRATCH 5, 8, blockq+ 0 + SCRATCH 2, 8, blockq+ 0 + + SUMSUB_BA w, 5, 4, 2 ; m5=t3+t4, m4=t3-t4 + SWAP 7, 6, 2 + SWAP 3, 5, 0 + +%if ARCH_X86_64 + SWAP 6, 8 +%endif +%endmacro + +; x86-32 +; - in: m0/m4 is in mem +; - out: m6 is in mem +; x86-64: +; - everything is in registers (m0-7) +%macro VP9_IDCT8_1D 0 +%if ARCH_X86_64 + SWAP 0, 8 + SWAP 4, 9 +%endif + + VP9_UNPACK_MULSUB_2W_4X 5, 3, 9102, 13623, D_8192_REG, 0, 4 ; m5=t5a, m3=t6a + VP9_UNPACK_MULSUB_2W_4X 1, 7, 16069, 3196, D_8192_REG, 0, 4 ; m1=t4a, m7=t7a + SUMSUB_BA w, 5, 1, 0 ; m5=t4a+t5a (t4), m1=t4a-t5a (t5a) + SUMSUB_BA w, 3, 7, 0 ; m3=t7a+t6a (t7), m7=t7a-t6a (t6a) +%if cpuflag(ssse3) + SUMSUB_BA w, 1, 7, 0 ; m1=t6a+t5a (t6), m7=t6a-t5a (t5) + pmulhrsw m1, W_11585x2_REG ; m1=t6 + pmulhrsw m7, W_11585x2_REG ; m7=t5 +%else + VP9_UNPACK_MULSUB_2W_4X 7, 1, 11585, 11585, D_8192_REG, 0, 4 +%endif + VP9_UNPACK_MULSUB_2W_4X 2, 6, 15137, 6270, D_8192_REG, 0, 4 ; m2=t2a, m6=t3a + + UNSCRATCH 0, 8, blockq+ 0 ; IN(0) + UNSCRATCH 4, 9, blockq+64 ; IN(4) + SCRATCH 5, 8, blockq+ 0 + +%if cpuflag(ssse3) + SUMSUB_BA w, 4, 0, 5 ; m4=IN(0)+IN(4) m0=IN(0)-IN(4) + pmulhrsw m4, W_11585x2_REG ; m4=t0a + pmulhrsw m0, W_11585x2_REG ; m0=t1a +%else + SCRATCH 7, 9, blockq+64 + VP9_UNPACK_MULSUB_2W_4X 0, 4, 11585, 11585, D_8192_REG, 5, 7 + UNSCRATCH 7, 9, blockq+64 +%endif + SUMSUB_BA w, 6, 4, 5 ; m6=t0a+t3a (t0), m4=t0a-t3a (t3) + SUMSUB_BA w, 2, 0, 5 ; m2=t1a+t2a (t1), m0=t1a-t2a (t2) + + VP9_IDCT8_1D_FINALIZE +%endmacro + +%macro VP9_IDCT8_4x4_1D 0 + pmulhrsw m0, W_11585x2_REG ; m0=t1a/t0a + pmulhrsw m6, m2, [pw_15137x2] ; m6=t3a + pmulhrsw m2, [pw_6270x2] ; m2=t2a + pmulhrsw m7, m1, [pw_16069x2] ; m7=t7a + pmulhrsw m1, [pw_3196x2] ; m1=t4a + pmulhrsw m5, m3, [pw_m9102x2] ; m5=t5a + pmulhrsw m3, [pw_13623x2] ; m3=t6a + SUMSUB_BA w, 5, 1, 4 ; m1=t4a+t5a (t4), m5=t4a-t5a (t5a) + SUMSUB_BA w, 3, 7, 4 ; m3=t7a+t6a (t7), m7=t7a-t6a (t6a) + SUMSUB_BA w, 1, 7, 4 ; m1=t6a+t5a (t6), m7=t6a-t5a (t5) + pmulhrsw m1, W_11585x2_REG ; m1=t6 + pmulhrsw m7, W_11585x2_REG ; m7=t5 + psubw m4, m0, m6 ; m4=t0a-t3a (t3) + paddw m6, m0 ; m6=t0a+t3a (t0) + SCRATCH 5, 8, blockq+ 0 + SUMSUB_BA w, 2, 0, 5 ; m2=t1a+t2a (t1), m0=t1a-t2a (t2) + VP9_IDCT8_1D_FINALIZE +%endmacro + +%macro VP9_IDCT8_2x2_1D 1 + pmulhrsw m0, W_11585x2_REG ; m0=t0 + pmulhrsw m3, m1, W_16069x2_REG ; m3=t7 + pmulhrsw m1, W_3196x2_REG ; m1=t4 + psubw m7, m3, m1 ; t5 = t7a - t4a + paddw m5, m3, m1 ; t6 = t7a + t4a + pmulhrsw m7, W_11585x2_REG ; m7=t5 + pmulhrsw m5, W_11585x2_REG ; m5=t6 + SWAP 5, 1 + ; merged VP9_IDCT8_1D_FINALIZE to make register-sharing w/ avx easier + psubw m6, m0, m3 ; m6=t0-t7 + paddw m3, m0 ; m3=t0+t7 + psubw m2, m0, m1 ; m2=t1-t6 + paddw m1, m0 ; m1=t1+t6 +%if %1 == 1 + punpcklwd m3, m1 +%define SCRATCH_REG 1 +%elif ARCH_X86_32 + mova [blockq+ 0], m2 +%define SCRATCH_REG 2 +%else +%define SCRATCH_REG 8 +%endif + psubw m4, m0, m5 ; m4=t3-t4 + paddw m5, m0 ; m5=t3+t4 + SUMSUB_BA w, 7, 0, SCRATCH_REG ; m7=t2+t5, m0=t2-t5 + SWAP 7, 6, 2 + SWAP 3, 5, 0 +%undef SCRATCH_REG +%endmacro + +%macro VP9_IDCT8_WRITEx2 6-8 5 ; line1, line2, tmp1, tmp2, zero, pw_1024/pw_16, shift +%if cpuflag(ssse3) + pmulhrsw m%1, %6 ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5 + pmulhrsw m%2, %6 +%else + paddw m%1, %6 + paddw m%2, %6 + psraw m%1, %7 + psraw m%2, %7 +%endif +%if %0 <= 7 + VP9_STORE_2X %1, %2, %3, %4, %5 +%else + VP9_STORE_2X %1, %2, %3, %4, %5, %8 +%endif +%endmacro + +; x86-32: +; - m6 is in mem +; x86-64: +; - m8 holds m6 (SWAP) +; m6 holds zero +%macro VP9_IDCT8_WRITEOUT 0 +%if ARCH_X86_64 +%if cpuflag(ssse3) + mova m9, [pw_1024] +%else + mova m9, [pw_16] +%endif +%define ROUND_REG m9 +%else +%if cpuflag(ssse3) +%define ROUND_REG [pw_1024] +%else +%define ROUND_REG [pw_16] +%endif +%endif + SCRATCH 5, 10, blockq+16 + SCRATCH 7, 11, blockq+32 + VP9_IDCT8_WRITEx2 0, 1, 5, 7, 6, ROUND_REG + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 2, 3, 5, 7, 6, ROUND_REG + lea dstq, [dstq+2*strideq] + UNSCRATCH 5, 10, blockq+16 + UNSCRATCH 7, 11, blockq+32 + VP9_IDCT8_WRITEx2 4, 5, 0, 1, 6, ROUND_REG + lea dstq, [dstq+2*strideq] + UNSCRATCH 5, 8, blockq+ 0 + VP9_IDCT8_WRITEx2 5, 7, 0, 1, 6, ROUND_REG + +%undef ROUND_REG +%endmacro + +%macro VP9_IDCT_IDCT_8x8_ADD_XMM 2 +INIT_XMM %1 +cglobal vp9_idct_idct_8x8_add, 4, 4, %2, dst, stride, block, eob + +%if cpuflag(ssse3) +%if ARCH_X86_64 + mova m12, [pw_11585x2] ; often used +%define W_11585x2_REG m12 +%else +%define W_11585x2_REG [pw_11585x2] +%endif + + cmp eobd, 12 ; top left half or less + jg .idctfull + + cmp eobd, 3 ; top left corner or less + jg .idcthalf + + cmp eobd, 1 ; faster path for when only DC is set + jne .idcttopleftcorner +%else + cmp eobd, 1 + jg .idctfull +%endif + +%if cpuflag(ssse3) + movd m0, [blockq] + pmulhrsw m0, W_11585x2_REG + pmulhrsw m0, W_11585x2_REG +%else + DEFINE_ARGS dst, stride, block, coef + movsx coefd, word [blockq] + imul coefd, 11585 + add coefd, 8192 + sar coefd, 14 + imul coefd, 11585 + add coefd, (16 << 14) + 8192 + sar coefd, 14 + 5 + movd m0, coefd +%endif + SPLATW m0, m0, 0 + pxor m4, m4 + movd [blockq], m4 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_1024] ; (x*1024 + (1<<14))>>15 <=> (x+16)>>5 +%endif +%rep 3 + VP9_STORE_2X 0, 0, 6, 7, 4 + lea dstq, [dstq+2*strideq] +%endrep + VP9_STORE_2X 0, 0, 6, 7, 4 + RET + +%if cpuflag(ssse3) +; faster path for when only left corner is set (3 input: DC, right to DC, below +; to DC). Note: also working with a 2x2 block +.idcttopleftcorner: + movd m0, [blockq+0] + movd m1, [blockq+16] +%if ARCH_X86_64 + mova m10, [pw_3196x2] + mova m11, [pw_16069x2] +%define W_3196x2_REG m10 +%define W_16069x2_REG m11 +%else +%define W_3196x2_REG [pw_3196x2] +%define W_16069x2_REG [pw_16069x2] +%endif + VP9_IDCT8_2x2_1D 1 + ; partial 2x8 transpose + ; punpcklwd m0, m1 already done inside idct + punpcklwd m2, m3 + punpcklwd m4, m5 + punpcklwd m6, m7 + punpckldq m0, m2 + punpckldq m4, m6 + SBUTTERFLY qdq, 0, 4, 1 + SWAP 1, 4 + VP9_IDCT8_2x2_1D 2 +%if ARCH_X86_64 + SWAP 6, 8 +%endif + pxor m6, m6 ; used for the block reset, and VP9_STORE_2X + VP9_IDCT8_WRITEOUT +%if ARCH_X86_64 + movd [blockq+ 0], m6 + movd [blockq+16], m6 +%else + mova [blockq+ 0], m6 + mova [blockq+16], m6 + mova [blockq+32], m6 +%endif + RET + +.idcthalf: + movh m0, [blockq + 0] + movh m1, [blockq +16] + movh m2, [blockq +32] + movh m3, [blockq +48] + VP9_IDCT8_4x4_1D + ; partial 4x8 transpose +%if ARCH_X86_32 + mova m6, [blockq+ 0] +%endif + punpcklwd m0, m1 + punpcklwd m2, m3 + punpcklwd m4, m5 + punpcklwd m6, m7 + SBUTTERFLY dq, 0, 2, 1 + SBUTTERFLY dq, 4, 6, 5 + SBUTTERFLY qdq, 0, 4, 1 + SBUTTERFLY qdq, 2, 6, 5 + SWAP 1, 4 + SWAP 3, 6 + VP9_IDCT8_4x4_1D +%if ARCH_X86_64 + SWAP 6, 8 +%endif + pxor m6, m6 + VP9_IDCT8_WRITEOUT +%if ARCH_X86_64 + movh [blockq+ 0], m6 + movh [blockq+16], m6 + movh [blockq+32], m6 +%else + mova [blockq+ 0], m6 + mova [blockq+16], m6 + mova [blockq+32], m6 +%endif + movh [blockq+48], m6 + RET +%endif + +.idctfull: ; generic full 8x8 idct/idct +%if ARCH_X86_64 + mova m0, [blockq+ 0] ; IN(0) +%endif + mova m1, [blockq+ 16] ; IN(1) + mova m2, [blockq+ 32] ; IN(2) + mova m3, [blockq+ 48] ; IN(3) +%if ARCH_X86_64 + mova m4, [blockq+ 64] ; IN(4) +%endif + mova m5, [blockq+ 80] ; IN(5) + mova m6, [blockq+ 96] ; IN(6) + mova m7, [blockq+112] ; IN(7) +%if ARCH_X86_64 + mova m11, [pd_8192] ; rounding +%define D_8192_REG m11 +%else +%define D_8192_REG [pd_8192] +%endif + VP9_IDCT8_1D +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [blockq+0], [blockq+64], 1 + mova [blockq+0], m0 +%endif + VP9_IDCT8_1D + +%if ARCH_X86_64 + SWAP 6, 8 +%endif + pxor m6, m6 ; used for the block reset, and VP9_STORE_2X + VP9_IDCT8_WRITEOUT + ZERO_BLOCK blockq, 16, 8, m6 + RET +%undef W_11585x2_REG +%endmacro + +VP9_IDCT_IDCT_8x8_ADD_XMM sse2, 12 +VP9_IDCT_IDCT_8x8_ADD_XMM ssse3, 13 +VP9_IDCT_IDCT_8x8_ADD_XMM avx, 13 + +;--------------------------------------------------------------------------------------------- +; void vp9_iadst_iadst_8x8_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;--------------------------------------------------------------------------------------------- + +; x86-32: +; - in: m0/3/4/7 are in mem [blockq+N*16] +; - out: m6 is in mem [blockq+0] +; x86-64: +; - everything is in registers +%macro VP9_IADST8_1D 0 ; input/output=m0/1/2/3/4/5/6/7 +%if ARCH_X86_64 + SWAP 0, 8 + SWAP 3, 9 + SWAP 4, 10 + SWAP 7, 11 +%endif + + VP9_UNPACK_MULSUB_2D_4X 5, 2, 0, 3, 14449, 7723 ; m5/2=t3[d], m2/4=t2[d] + VP9_UNPACK_MULSUB_2D_4X 1, 6, 4, 7, 4756, 15679 ; m1/4=t7[d], m6/7=t6[d] + SCRATCH 4, 12, blockq+1*16 + VP9_RND_SH_SUMSUB_BA 6, 2, 7, 3, 4, D_8192_REG ; m6=t2[w], m2=t6[w] + UNSCRATCH 4, 12, blockq+1*16 + VP9_RND_SH_SUMSUB_BA 1, 5, 4, 0, 3, D_8192_REG ; m1=t3[w], m5=t7[w] + + UNSCRATCH 0, 8, blockq+16*0 + UNSCRATCH 3, 9, blockq+16*3 + UNSCRATCH 4, 10, blockq+16*4 + UNSCRATCH 7, 11, blockq+16*7 + SCRATCH 1, 8, blockq+16*1 + SCRATCH 2, 9, blockq+16*2 + SCRATCH 5, 10, blockq+16*5 + SCRATCH 6, 11, blockq+16*6 + + VP9_UNPACK_MULSUB_2D_4X 7, 0, 1, 2, 16305, 1606 ; m7/1=t1[d], m0/2=t0[d] + VP9_UNPACK_MULSUB_2D_4X 3, 4, 5, 6, 10394, 12665 ; m3/5=t5[d], m4/6=t4[d] + SCRATCH 1, 12, blockq+ 0*16 + VP9_RND_SH_SUMSUB_BA 4, 0, 6, 2, 1, D_8192_REG ; m4=t0[w], m0=t4[w] + UNSCRATCH 1, 12, blockq+ 0*16 + VP9_RND_SH_SUMSUB_BA 3, 7, 5, 1, 2, D_8192_REG ; m3=t1[w], m7=t5[w] + + UNSCRATCH 2, 9, blockq+16*2 + UNSCRATCH 5, 10, blockq+16*5 + SCRATCH 3, 9, blockq+16*3 + SCRATCH 4, 10, blockq+16*4 + + ; m4=t0, m3=t1, m6=t2, m1=t3, m0=t4, m7=t5, m2=t6, m5=t7 + + VP9_UNPACK_MULSUB_2D_4X 0, 7, 1, 3, 15137, 6270 ; m0/1=t5[d], m7/3=t4[d] + VP9_UNPACK_MULSUB_2D_4X 5, 2, 4, 6, 6270, 15137 ; m5/4=t6[d], m2/6=t7[d] + SCRATCH 1, 12, blockq+ 0*16 + VP9_RND_SH_SUMSUB_BA 5, 7, 4, 3, 1, D_8192_REG + UNSCRATCH 1, 12, blockq+ 0*16 + PSIGNW m5, W_M1_REG ; m5=out1[w], m7=t6[w] + VP9_RND_SH_SUMSUB_BA 2, 0, 6, 1, 3, D_8192_REG ; m2=out6[w], m0=t7[w] + + UNSCRATCH 1, 8, blockq+16*1 + UNSCRATCH 3, 9, blockq+16*3 + UNSCRATCH 4, 10, blockq+16*4 + UNSCRATCH 6, 11, blockq+16*6 + SCRATCH 2, 8, blockq+16*0 + + SUMSUB_BA w, 6, 4, 2 ; m6=out0[w], m4=t2[w] + SUMSUB_BA w, 1, 3, 2 + PSIGNW m1, W_M1_REG ; m1=out7[w], m3=t3[w] + + ; m6=out0, m5=out1, m4=t2, m3=t3, m7=t6, m0=t7, m2=out6, m1=out7 + + ; unfortunately, the code below overflows in some cases +%if 0; cpuflag(ssse3) + SUMSUB_BA w, 3, 4, 2 + SUMSUB_BA w, 0, 7, 2 + pmulhrsw m3, W_11585x2_REG + pmulhrsw m7, W_11585x2_REG + pmulhrsw m4, W_11585x2_REG ; out4 + pmulhrsw m0, W_11585x2_REG ; out2 +%else + SCRATCH 5, 9, blockq+16*1 + VP9_UNPACK_MULSUB_2W_4X 4, 3, 11585, 11585, D_8192_REG, 2, 5 + VP9_UNPACK_MULSUB_2W_4X 7, 0, 11585, 11585, D_8192_REG, 2, 5 + UNSCRATCH 5, 9, blockq+16*1 +%endif + PSIGNW m3, W_M1_REG ; out3 + PSIGNW m7, W_M1_REG ; out5 + + ; m6=out0, m5=out1, m0=out2, m3=out3, m4=out4, m7=out5, m2=out6, m1=out7 + +%if ARCH_X86_64 + SWAP 2, 8 +%endif + SWAP 0, 6, 2 + SWAP 7, 1, 5 +%endmacro + +%macro IADST8_FN 6 +INIT_XMM %5 +cglobal vp9_%1_%3_8x8_add, 3, 3, %6, dst, stride, block, eob + +%ifidn %1, idct +%define first_is_idct 1 +%else +%define first_is_idct 0 +%endif + +%ifidn %3, idct +%define second_is_idct 1 +%else +%define second_is_idct 0 +%endif + +%if ARCH_X86_64 + mova m0, [blockq+ 0] ; IN(0) +%endif + mova m1, [blockq+ 16] ; IN(1) + mova m2, [blockq+ 32] ; IN(2) +%if ARCH_X86_64 || first_is_idct + mova m3, [blockq+ 48] ; IN(3) +%endif +%if ARCH_X86_64 + mova m4, [blockq+ 64] ; IN(4) +%endif + mova m5, [blockq+ 80] ; IN(5) + mova m6, [blockq+ 96] ; IN(6) +%if ARCH_X86_64 || first_is_idct + mova m7, [blockq+112] ; IN(7) +%endif +%if ARCH_X86_64 +%if cpuflag(ssse3) + mova m15, [pw_11585x2] ; often used +%endif + mova m13, [pd_8192] ; rounding + mova m14, [pw_m1] +%define W_11585x2_REG m15 +%define D_8192_REG m13 +%define W_M1_REG m14 +%else +%define W_11585x2_REG [pw_11585x2] +%define D_8192_REG [pd_8192] +%define W_M1_REG [pw_m1] +%endif + + ; note different calling conventions for idct8 vs. iadst8 on x86-32 + VP9_%2_1D +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [blockq+0], [blockq+64], 1 + mova [blockq+ 0], m0 +%if second_is_idct == 0 + mova [blockq+ 48], m3 + mova [blockq+112], m7 +%endif +%endif + VP9_%4_1D + +%if ARCH_X86_64 + SWAP 6, 8 +%endif + pxor m6, m6 ; used for the block reset, and VP9_STORE_2X + VP9_IDCT8_WRITEOUT + ZERO_BLOCK blockq, 16, 8, m6 + RET + +%undef W_11585x2_REG +%undef first_is_idct +%undef second_is_idct + +%endmacro + +IADST8_FN idct, IDCT8, iadst, IADST8, sse2, 15 +IADST8_FN iadst, IADST8, idct, IDCT8, sse2, 15 +IADST8_FN iadst, IADST8, iadst, IADST8, sse2, 15 +IADST8_FN idct, IDCT8, iadst, IADST8, ssse3, 16 +IADST8_FN idct, IDCT8, iadst, IADST8, avx, 16 +IADST8_FN iadst, IADST8, idct, IDCT8, ssse3, 16 +IADST8_FN iadst, IADST8, idct, IDCT8, avx, 16 +IADST8_FN iadst, IADST8, iadst, IADST8, ssse3, 16 +IADST8_FN iadst, IADST8, iadst, IADST8, avx, 16 + +;--------------------------------------------------------------------------------------------- +; void vp9_idct_idct_16x16_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;--------------------------------------------------------------------------------------------- + +; x86-64: +; at the end of this macro, m7 is stored in [%4+15*%5] +; everything else (t0-6 and t8-15) is stored in m0-6 and m8-15 +; the following sumsubs have not been done yet: +; SUMSUB_BA w, 6, 9, 15 ; t6, t9 +; SUMSUB_BA w, 7, 8, 15 ; t7, t8 +; or (x86-32) t0-t5 are in m0-m5, t10-t15 are in x11/9/7/5/3/1, +; and the following simsubs have not been done yet: +; SUMSUB_BA w, x13, x14, 7 ; t6, t9 +; SUMSUB_BA w, x15, x12, 7 ; t7, t8 + +%macro VP9_IDCT16_1D_START 6 ; src, nnzc, stride, scratch, scratch_stride, is_iadst +%if %2 <= 4 + mova m3, [%1+ 1*%3] ; IN(1) + mova m0, [%1+ 3*%3] ; IN(3) + + pmulhrsw m4, m3, [pw_16305x2] ; t14-15 + pmulhrsw m3, [pw_1606x2] ; t8-9 + pmulhrsw m7, m0, [pw_m4756x2] ; t10-11 + pmulhrsw m0, [pw_15679x2] ; t12-13 + + ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7 + ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15 + + VP9_UNPACK_MULSUB_2W_4X 2, 5, 4, 3, 15137, 6270, [pd_8192], 1, 6 ; t9, t14 + SCRATCH 4, 10, %4+ 1*%5 + SCRATCH 5, 11, %4+ 7*%5 + VP9_UNPACK_MULSUB_2W_4X 6, 1, 0, 7, 6270, m15137, [pd_8192], 4, 5 ; t10, t13 + UNSCRATCH 5, 11, %4+ 7*%5 + + ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7 + ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15 +%else + mova m5, [%1+ 1*%3] ; IN(1) + mova m4, [%1+ 7*%3] ; IN(7) +%if %2 <= 8 + pmulhrsw m2, m5, [pw_16305x2] ; t15 + pmulhrsw m5, [pw_1606x2] ; t8 + pmulhrsw m3, m4, [pw_m10394x2] ; t9 + pmulhrsw m4, [pw_12665x2] ; t14 +%else + mova m3, [%1+ 9*%3] ; IN(9) + mova m2, [%1+15*%3] ; IN(15) + + ; m10=in0, m5=in1, m14=in2, m6=in3, m9=in4, m7=in5, m15=in6, m4=in7 + ; m11=in8, m3=in9, m12=in10 m0=in11, m8=in12, m1=in13, m13=in14, m2=in15 + + VP9_UNPACK_MULSUB_2W_4X 5, 2, 16305, 1606, [pd_8192], 0, 1 ; t8, t15 + VP9_UNPACK_MULSUB_2W_4X 3, 4, 10394, 12665, [pd_8192], 0, 1 ; t9, t14 +%endif + + SUMSUB_BA w, 3, 5, 0 ; t8, t9 + SUMSUB_BA w, 4, 2, 0 ; t15, t14 + + VP9_UNPACK_MULSUB_2W_4X 2, 5, 15137, 6270, [pd_8192], 0, 1 ; t9, t14 + + SCRATCH 4, 10, %4+ 1*%5 + SCRATCH 5, 11, %4+ 7*%5 + + mova m6, [%1+ 3*%3] ; IN(3) + mova m7, [%1+ 5*%3] ; IN(5) +%if %2 <= 8 + pmulhrsw m0, m7, [pw_14449x2] ; t13 + pmulhrsw m7, [pw_7723x2] ; t10 + pmulhrsw m1, m6, [pw_m4756x2] ; t11 + pmulhrsw m6, [pw_15679x2] ; t12 +%else + mova m0, [%1+11*%3] ; IN(11) + mova m1, [%1+13*%3] ; IN(13) + + VP9_UNPACK_MULSUB_2W_4X 7, 0, 14449, 7723, [pd_8192], 4, 5 ; t10, t13 + VP9_UNPACK_MULSUB_2W_4X 1, 6, 4756, 15679, [pd_8192], 4, 5 ; t11, t12 +%endif + + ; m11=t0, m10=t1, m9=t2, m8=t3, m14=t4, m12=t5, m15=t6, m13=t7 + ; m5=t8, m3=t9, m7=t10, m1=t11, m6=t12, m0=t13, m4=t14, m2=t15 + + SUMSUB_BA w, 7, 1, 4 ; t11, t10 + SUMSUB_BA w, 0, 6, 4 ; t12, t13 + + ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m14=t5, m13=t6, m15=t7 + ; m3=t8, m5=t9, m1=t10, m7=t11, m0=t12, m6=t13, m2=t14, m4=t15 + + VP9_UNPACK_MULSUB_2W_4X 6, 1, 6270, m15137, [pd_8192], 4, 5 ; t10, t13 + + UNSCRATCH 5, 11, %4+ 7*%5 +%endif + + ; m8=t0, m9=t1, m10=t2, m11=t3, m12=t4, m13=t5, m14=t6, m15=t7 + ; m3=t8, m2=t9, m6=t10, m7=t11, m0=t12, m1=t13, m5=t14, m4=t15 + + SUMSUB_BA w, 7, 3, 4 ; t8, t11 + + ; backup first register + mova [%4+15*%5], m7 + + SUMSUB_BA w, 6, 2, 7 ; t9, t10 + UNSCRATCH 4, 10, %4+ 1*%5 + SUMSUB_BA w, 0, 4, 7 ; t15, t12 + SUMSUB_BA w, 1, 5, 7 ; t14. t13 + + ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7 + ; m7=t8, m6=t9, m2=t10, m3=t11, m4=t12, m5=t13, m1=t14, m0=t15 + +%if cpuflag(ssse3) && %6 == 0 + SUMSUB_BA w, 2, 5, 7 + SUMSUB_BA w, 3, 4, 7 + pmulhrsw m5, [pw_11585x2] ; t10 + pmulhrsw m4, [pw_11585x2] ; t11 + pmulhrsw m3, [pw_11585x2] ; t12 + pmulhrsw m2, [pw_11585x2] ; t13 +%else + SCRATCH 6, 10, %4+ 1*%5 + VP9_UNPACK_MULSUB_2W_4X 5, 2, 11585, 11585, [pd_8192], 6, 7 ; t10, t13 + VP9_UNPACK_MULSUB_2W_4X 4, 3, 11585, 11585, [pd_8192], 6, 7 ; t11, t12 + UNSCRATCH 6, 10, %4+ 1*%5 +%endif + + ; m15=t0, m14=t1, m13=t2, m12=t3, m11=t4, m10=t5, m9=t6, m8=t7 + ; m7=t8, m6=t9, m5=t10, m4=t11, m3=t12, m2=t13, m1=t14, m0=t15 + + SCRATCH 0, 8, %4+ 1*%5 + SCRATCH 1, 9, %4+ 3*%5 + SCRATCH 2, 10, %4+ 5*%5 + SCRATCH 3, 11, %4+ 7*%5 + SCRATCH 4, 12, %4+ 9*%5 + SCRATCH 5, 13, %4+11*%5 + SCRATCH 6, 14, %4+13*%5 + + ; even (tx8x8) +%if %2 <= 4 + mova m3, [%1+ 0*%3] ; IN(0) + mova m4, [%1+ 2*%3] ; IN(2) + + pmulhrsw m3, [pw_11585x2] ; t0-t3 + pmulhrsw m7, m4, [pw_16069x2] ; t6-7 + pmulhrsw m4, [pw_3196x2] ; t4-5 + +%if 0 ; overflows :( + paddw m6, m7, m4 + psubw m5, m7, m4 + pmulhrsw m5, [pw_11585x2] ; t5 + pmulhrsw m6, [pw_11585x2] ; t6 +%else + VP9_UNPACK_MULSUB_2W_4X 5, 6, 7, 4, 11585, 11585, [pd_8192], 0, 1 ; t5, t6 +%endif + + psubw m0, m3, m7 + paddw m7, m3 + psubw m1, m3, m6 + paddw m6, m3 + psubw m2, m3, m5 + paddw m5, m3 + +%if ARCH_X86_32 + SWAP 0, 7 +%endif + SCRATCH 7, 15, %4+12*%5 +%else + mova m6, [%1+ 2*%3] ; IN(2) + mova m1, [%1+ 4*%3] ; IN(4) + mova m7, [%1+ 6*%3] ; IN(6) +%if %2 <= 8 + pmulhrsw m0, m1, [pw_15137x2] ; t3 + pmulhrsw m1, [pw_6270x2] ; t2 + pmulhrsw m5, m6, [pw_16069x2] ; t7 + pmulhrsw m6, [pw_3196x2] ; t4 + pmulhrsw m4, m7, [pw_m9102x2] ; t5 + pmulhrsw m7, [pw_13623x2] ; t6 +%else + mova m4, [%1+10*%3] ; IN(10) + mova m0, [%1+12*%3] ; IN(12) + mova m5, [%1+14*%3] ; IN(14) + + VP9_UNPACK_MULSUB_2W_4X 1, 0, 15137, 6270, [pd_8192], 2, 3 ; t2, t3 + VP9_UNPACK_MULSUB_2W_4X 6, 5, 16069, 3196, [pd_8192], 2, 3 ; t4, t7 + VP9_UNPACK_MULSUB_2W_4X 4, 7, 9102, 13623, [pd_8192], 2, 3 ; t5, t6 +%endif + + SUMSUB_BA w, 4, 6, 2 ; t4, t5 + SUMSUB_BA w, 7, 5, 2 ; t7, t6 + +%if cpuflag(ssse3) && %6 == 0 + SUMSUB_BA w, 6, 5, 2 + pmulhrsw m5, [pw_11585x2] ; t5 + pmulhrsw m6, [pw_11585x2] ; t6 +%else + VP9_UNPACK_MULSUB_2W_4X 5, 6, 11585, 11585, [pd_8192], 2, 3 ; t5, t6 +%endif + + SCRATCH 5, 15, %4+10*%5 + mova m2, [%1+ 0*%3] ; IN(0) +%if %2 <= 8 + pmulhrsw m2, [pw_11585x2] ; t0 and t1 + psubw m3, m2, m0 + paddw m0, m2 + + SUMSUB_BA w, 7, 0, 5 ; t0, t7 +%else + mova m3, [%1+ 8*%3] ; IN(8) + + ; from 3 stages back +%if cpuflag(ssse3) && %6 == 0 + SUMSUB_BA w, 3, 2, 5 + pmulhrsw m3, [pw_11585x2] ; t0 + pmulhrsw m2, [pw_11585x2] ; t1 +%else + mova [%1+ 0*%3], m0 + VP9_UNPACK_MULSUB_2W_4X 2, 3, 11585, 11585, [pd_8192], 5, 0 ; t0, t1 + mova m0, [%1+ 0*%3] +%endif + + ; from 2 stages back + SUMSUB_BA w, 0, 3, 5 ; t0, t3 + + SUMSUB_BA w, 7, 0, 5 ; t0, t7 +%endif + UNSCRATCH 5, 15, %4+10*%5 +%if ARCH_X86_32 + SWAP 0, 7 +%endif + SCRATCH 7, 15, %4+12*%5 + SUMSUB_BA w, 1, 2, 7 ; t1, t2 + + ; from 1 stage back + SUMSUB_BA w, 6, 1, 7 ; t1, t6 + SUMSUB_BA w, 5, 2, 7 ; t2, t5 +%endif + SUMSUB_BA w, 4, 3, 7 ; t3, t4 + +%if ARCH_X86_64 + SWAP 0, 8 + SWAP 1, 9 + SWAP 2, 10 + SWAP 3, 11 + SWAP 4, 12 + SWAP 5, 13 + SWAP 6, 14 + + SUMSUB_BA w, 0, 15, 7 ; t0, t15 + SUMSUB_BA w, 1, 14, 7 ; t1, t14 + SUMSUB_BA w, 2, 13, 7 ; t2, t13 + SUMSUB_BA w, 3, 12, 7 ; t3, t12 + SUMSUB_BA w, 4, 11, 7 ; t4, t11 + SUMSUB_BA w, 5, 10, 7 ; t5, t10 +%else + SWAP 1, 6 + SWAP 2, 5 + SWAP 3, 4 + mova [%4+14*%5], m6 + +%macro %%SUMSUB_BA_STORE 5 ; reg, from_mem, to_mem, scratch, scratch_stride + mova m6, [%4+%2*%5] + SUMSUB_BA w, 6, %1, 7 + SWAP %1, 6 + mova [%4+%3*%5], m6 +%endmacro + + %%SUMSUB_BA_STORE 0, 1, 1, %4, %5 ; t0, t15 + %%SUMSUB_BA_STORE 1, 3, 3, %4, %5 ; t1, t14 + %%SUMSUB_BA_STORE 2, 5, 5, %4, %5 ; t2, t13 + %%SUMSUB_BA_STORE 3, 7, 7, %4, %5 ; t3, t12 + %%SUMSUB_BA_STORE 4, 9, 9, %4, %5 ; t4, t11 + %%SUMSUB_BA_STORE 5, 11, 11, %4, %5 ; t5, t10 +%endif +%endmacro + +%macro VP9_IDCT16_1D 2-4 16, 1 ; src, pass, nnzc, is_iadst +%if %2 == 1 + VP9_IDCT16_1D_START %1, %3, 32, tmpq, 16, %4 + +%if ARCH_X86_64 + ; backup a different register + mova m7, [tmpq+15*16] + mova [tmpq+ 1*16], m15 + + SUMSUB_BA w, 6, 9, 15 ; t6, t9 + SUMSUB_BA w, 7, 8, 15 ; t7, t8 + + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 15 + mova [tmpq+ 0], m0 + mova [tmpq+ 32], m1 + mova [tmpq+ 64], m2 + mova [tmpq+ 96], m3 + mova [tmpq+128], m4 + mova [tmpq+160], m5 + mova [tmpq+192], m6 + mova [tmpq+224], m7 + + mova m15, [tmpq+ 1*16] + TRANSPOSE8x8W 8, 9, 10, 11, 12, 13, 14, 15, 0 + mova [tmpq+ 16], m8 + mova [tmpq+ 48], m9 + mova [tmpq+ 80], m10 + mova [tmpq+112], m11 + mova [tmpq+144], m12 + mova [tmpq+176], m13 + mova [tmpq+208], m14 + mova [tmpq+240], m15 +%else + mova m6, [tmpq+13*16] + mova m7, [tmpq+14*16] + SUMSUB_BA w, 6, 7 ; t6, t9 + mova [tmpq+14*16], m6 + mova [tmpq+13*16], m7 + mova m7, [tmpq+15*16] + mova m6, [tmpq+12*16] + SUMSUB_BA w, 7, 6 ; t7, t8 + mova [tmpq+15*16], m6 + + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [tmpq+14*16], [tmpq+ 8*16], 1 + mova [tmpq+ 0*16], m0 + mova [tmpq+ 2*16], m1 + mova [tmpq+ 4*16], m2 + mova [tmpq+ 6*16], m3 + mova [tmpq+10*16], m5 + mova [tmpq+12*16], m6 + mova [tmpq+14*16], m7 + + mova m0, [tmpq+15*16] + mova m1, [tmpq+13*16] + mova m2, [tmpq+11*16] + mova m3, [tmpq+ 9*16] + mova m4, [tmpq+ 7*16] + mova m5, [tmpq+ 5*16] + mova m7, [tmpq+ 1*16] + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [tmpq+ 3*16], [tmpq+ 9*16], 1 + mova [tmpq+ 1*16], m0 + mova [tmpq+ 3*16], m1 + mova [tmpq+ 5*16], m2 + mova [tmpq+ 7*16], m3 + mova [tmpq+11*16], m5 + mova [tmpq+13*16], m6 + mova [tmpq+15*16], m7 +%endif +%else ; %2 == 2 + VP9_IDCT16_1D_START %1, %3, 32, %1, 32, %4 + +%if cpuflag(ssse3) +%define ROUND_REG [pw_512] +%else +%define ROUND_REG [pw_32] +%endif + + pxor m7, m7 +%if ARCH_X86_64 + ; backup more registers + mova [%1+ 2*32], m8 + mova [%1+ 3*32], m9 + + VP9_IDCT8_WRITEx2 0, 1, 8, 9, 7, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 2, 3, 8, 9, 7, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 4, 5, 8, 9, 7, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + ; restore from cache + SWAP 0, 7 ; move zero from m7 to m0 + mova m7, [%1+15*32] + mova m8, [%1+ 2*32] + mova m9, [%1+ 3*32] + + SUMSUB_BA w, 6, 9, 3 ; t6, t9 + SUMSUB_BA w, 7, 8, 3 ; t7, t8 + + VP9_IDCT8_WRITEx2 6, 7, 3, 4, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 8, 9, 3, 4, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 10, 11, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 12, 13, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 14, 15, 1, 2, 0, ROUND_REG, 6 +%else + mova [tmpq+ 0*32], m5 + + VP9_IDCT8_WRITEx2 0, 1, 5, 6, 7, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 2, 3, 5, 6, 7, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + SWAP 0, 7 ; move zero from m7 to m0 + mova m5, [tmpq+ 0*32] + + VP9_IDCT8_WRITEx2 4, 5, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + mova m4, [tmpq+13*32] + mova m7, [tmpq+14*32] + mova m5, [tmpq+15*32] + mova m6, [tmpq+12*32] + SUMSUB_BADC w, 4, 7, 5, 6, 1 + + VP9_IDCT8_WRITEx2 4, 5, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 6, 7, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + mova m4, [tmpq+11*32] + mova m5, [tmpq+ 9*32] + mova m6, [tmpq+ 7*32] + mova m7, [tmpq+ 5*32] + + VP9_IDCT8_WRITEx2 4, 5, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 6, 7, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + mova m4, [tmpq+ 3*32] + mova m5, [tmpq+ 1*32] + + VP9_IDCT8_WRITEx2 4, 5, 1, 2, 0, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] +%endif + +%undef ROUND_REG +%endif ; %2 == 1/2 +%endmacro + +%macro VP9_STORE_2XFULL 6-7 strideq; dc, tmp1, tmp2, tmp3, tmp4, zero, stride + mova m%3, [dstq] + mova m%5, [dstq+%7] + punpcklbw m%2, m%3, m%6 + punpckhbw m%3, m%6 + punpcklbw m%4, m%5, m%6 + punpckhbw m%5, m%6 + paddw m%2, m%1 + paddw m%3, m%1 + paddw m%4, m%1 + paddw m%5, m%1 + packuswb m%2, m%3 + packuswb m%4, m%5 + mova [dstq], m%2 + mova [dstq+%7], m%4 +%endmacro + +%macro VP9_IDCT_IDCT_16x16_ADD_XMM 1 +INIT_XMM %1 +cglobal vp9_idct_idct_16x16_add, 4, 6, 16, 512, dst, stride, block, eob +%if cpuflag(ssse3) + ; 2x2=eob=3, 4x4=eob=10 + cmp eobd, 38 + jg .idctfull + cmp eobd, 1 ; faster path for when only DC is set + jne .idct8x8 +%else + cmp eobd, 1 ; faster path for when only DC is set + jg .idctfull +%endif + + ; dc-only +%if cpuflag(ssse3) + movd m0, [blockq] + mova m1, [pw_11585x2] + pmulhrsw m0, m1 + pmulhrsw m0, m1 +%else + DEFINE_ARGS dst, stride, block, coef + movsx coefd, word [blockq] + imul coefd, 11585 + add coefd, 8192 + sar coefd, 14 + imul coefd, 11585 + add coefd, (32 << 14) + 8192 + sar coefd, 14 + 6 + movd m0, coefd +%endif + SPLATW m0, m0, q0000 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_512] +%endif + pxor m5, m5 + movd [blockq], m5 +%rep 7 + VP9_STORE_2XFULL 0, 1, 2, 3, 4, 5 + lea dstq, [dstq+2*strideq] +%endrep + VP9_STORE_2XFULL 0, 1, 2, 3, 4, 5 + RET + + DEFINE_ARGS dst, stride, block, cnt, dst_bak, tmp +%if cpuflag(ssse3) +.idct8x8: + mov tmpq, rsp + VP9_IDCT16_1D blockq, 1, 8, 0 + + mov cntd, 2 + mov dst_bakq, dstq +.loop2_8x8: + VP9_IDCT16_1D tmpq, 2, 8, 0 + lea dstq, [dst_bakq+8] + add tmpq, 16 + dec cntd + jg .loop2_8x8 + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + ZERO_BLOCK blockq, 32, 8, m0 + RET +%endif + +.idctfull: + mov cntd, 2 + mov tmpq, rsp +.loop1_full: + VP9_IDCT16_1D blockq, 1, 16, 0 + add blockq, 16 + add tmpq, 256 + dec cntd + jg .loop1_full + sub blockq, 32 + + mov cntd, 2 + mov tmpq, rsp + mov dst_bakq, dstq +.loop2_full: + VP9_IDCT16_1D tmpq, 2, 16, 0 + lea dstq, [dst_bakq+8] + add tmpq, 16 + dec cntd + jg .loop2_full + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + ZERO_BLOCK blockq, 32, 16, m0 + RET +%endmacro + +VP9_IDCT_IDCT_16x16_ADD_XMM sse2 +VP9_IDCT_IDCT_16x16_ADD_XMM ssse3 +VP9_IDCT_IDCT_16x16_ADD_XMM avx + +%macro VP9_IDCT16_YMM_1D 0 + VP9_UNPACK_MULSUB_2W_4X 1, 15, 16305, 1606, [pd_8192], 0, 4 ; t8, t15 + VP9_UNPACK_MULSUB_2W_4X 9, 7, 10394, 12665, [pd_8192], 0, 4 ; t9, t14 + + SUMSUB_BA w, 9, 1, 0 ; t8, t9 + SUMSUB_BA w, 7, 15, 0 ; t15, t14 + + VP9_UNPACK_MULSUB_2W_4X 15, 1, 15137, 6270, [pd_8192], 0, 4 ; t9, t14 + + VP9_UNPACK_MULSUB_2W_4X 5, 11, 14449, 7723, [pd_8192], 0, 4 ; t10, t13 + VP9_UNPACK_MULSUB_2W_4X 13, 3, 4756, 15679, [pd_8192], 0, 4 ; t11, t12 + + SUMSUB_BA w, 5, 13, 0 ; t11, t10 + SUMSUB_BA w, 11, 3, 0 ; t12, t13 + + VP9_UNPACK_MULSUB_2W_4X 3, 13, 6270, m15137, [pd_8192], 0, 4 ; t10, t13 + + SUMSUB_BA w, 5, 9, 0 ; t8, t11 + SUMSUB_BA w, 3, 15, 0 ; t9, t10 + SUMSUB_BA w, 11, 7, 0 ; t15, t12 + SUMSUB_BA w, 13, 1, 0 ; t14, t13 + + SUMSUB_BA w, 15, 1, 0 + SUMSUB_BA w, 9, 7, 0 + pmulhrsw m1, [pw_11585x2] ; t10 + pmulhrsw m7, [pw_11585x2] ; t11 + pmulhrsw m9, [pw_11585x2] ; t12 + pmulhrsw m15, [pw_11585x2] ; t13 + + ; even (tx8x8) + mova m4, [blockq+128] + mova [blockq+128], m5 + VP9_UNPACK_MULSUB_2W_4X 4, 12, 15137, 6270, [pd_8192], 0, 5 ; t2, t3 + VP9_UNPACK_MULSUB_2W_4X 2, 14, 16069, 3196, [pd_8192], 0, 5 ; t4, t7 + VP9_UNPACK_MULSUB_2W_4X 10, 6, 9102, 13623, [pd_8192], 0, 5 ; t5, t6 + mova m0, [blockq+ 0] + SUMSUB_BA w, 8, 0, 5 + pmulhrsw m8, [pw_11585x2] ; t0 + pmulhrsw m0, [pw_11585x2] ; t1 + + SUMSUB_BA w, 10, 2, 5 ; t4, t5 + SUMSUB_BA w, 6, 14, 5 ; t7, t6 + SUMSUB_BA w, 12, 8, 5 ; t0, t3 + SUMSUB_BA w, 4, 0, 5 ; t1, t2 + + SUMSUB_BA w, 2, 14, 5 + pmulhrsw m14, [pw_11585x2] ; t5 + pmulhrsw m2, [pw_11585x2] ; t6 + + SUMSUB_BA w, 6, 12, 5 ; t0, t7 + SUMSUB_BA w, 2, 4, 5 ; t1, t6 + SUMSUB_BA w, 14, 0, 5 ; t2, t5 + SUMSUB_BA w, 10, 8, 5 ; t3, t4 + + ; final stage + SUMSUB_BA w, 11, 6, 5 ; out0, out15 + SUMSUB_BA w, 13, 2, 5 ; out1, out14 + SUMSUB_BA w, 15, 14, 5 ; out2, out13 + SUMSUB_BA w, 9, 10, 5 ; out3, out12 + SUMSUB_BA w, 7, 8, 5 ; out4, out11 + SUMSUB_BA w, 1, 0, 5 ; out5, out10 + SUMSUB_BA w, 3, 4, 5 ; out6, out9 + mova m5, [blockq+128] + mova [blockq+192], m3 + SUMSUB_BA w, 5, 12, 3 ; out7, out8 + + SWAP 0, 11, 8, 12, 10 + SWAP 1, 13, 14, 2, 15, 6, 3, 9, 4, 7, 5 +%endmacro + +; this is almost identical to VP9_STORE_2X, but it does two rows +; for slightly improved interleaving, and it omits vpermq since the +; input is DC so all values are identical +%macro VP9_STORE_YMM_DC_4X 6 ; reg, tmp1, tmp2, tmp3, tmp4, zero + mova xm%2, [dstq] + mova xm%4, [dstq+strideq*2] + vinserti128 m%2, m%2, [dstq+strideq], 1 + vinserti128 m%4, m%4, [dstq+stride3q], 1 + punpckhbw m%3, m%2, m%6 + punpcklbw m%2, m%6 + punpckhbw m%5, m%4, m%6 + punpcklbw m%4, m%6 + paddw m%3, m%1 + paddw m%2, m%1 + paddw m%5, m%1 + paddw m%4, m%1 + packuswb m%2, m%3 + packuswb m%4, m%5 + mova [dstq], xm%2 + mova [dstq+strideq*2], xm%4 + vextracti128 [dstq+strideq], m%2, 1 + vextracti128 [dstq+stride3q], m%4, 1 +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_idct_idct_16x16_add, 4, 4, 16, dst, stride, block, eob + cmp eobd, 1 ; faster path for when only DC is set + jg .idctfull + + ; dc-only + mova m1, [pw_11585x2] + vpbroadcastw m0, [blockq] + pmulhrsw m0, m1 + pmulhrsw m0, m1 + pxor m5, m5 + pmulhrsw m0, [pw_512] + movd [blockq], xm5 + + DEFINE_ARGS dst, stride, stride3, cnt + mov cntd, 4 + lea stride3q, [strideq*3] +.loop_dc: + VP9_STORE_YMM_DC_4X 0, 1, 2, 3, 4, 5 + lea dstq, [dstq+4*strideq] + dec cntd + jg .loop_dc + RET + + DEFINE_ARGS dst, stride, block, eob +.idctfull: + mova m1, [blockq+ 32] + mova m2, [blockq+ 64] + mova m3, [blockq+ 96] + mova m5, [blockq+160] + mova m6, [blockq+192] + mova m7, [blockq+224] + mova m8, [blockq+256] + mova m9, [blockq+288] + mova m10, [blockq+320] + mova m11, [blockq+352] + mova m12, [blockq+384] + mova m13, [blockq+416] + mova m14, [blockq+448] + mova m15, [blockq+480] + + VP9_IDCT16_YMM_1D + TRANSPOSE16x16W 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ + [blockq+192], [blockq+128], 1 + mova [blockq+ 0], m0 + VP9_IDCT16_YMM_1D + + mova [blockq+224], m7 + + ; store + VP9_IDCT8_WRITEx2 0, 1, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 2, 3, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 4, 5, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + mova m6, [blockq+192] + mova m7, [blockq+224] + VP9_IDCT8_WRITEx2 6, 7, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 8, 9, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 10, 11, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 12, 13, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 14, 15, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + pxor m0, m0 + ZERO_BLOCK blockq, 32, 16, m0 + RET +%endif + +;--------------------------------------------------------------------------------------------- +; void vp9_iadst_iadst_16x16_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;--------------------------------------------------------------------------------------------- + +%macro VP9_IADST16_1D 2 ; src, pass +%assign %%str 16*%2 + mova m0, [%1+ 0*32] ; in0 + mova m1, [%1+15*32] ; in15 + mova m2, [%1+ 7*32] ; in7 + mova m3, [%1+ 8*32] ; in8 + + VP9_UNPACK_MULSUB_2D_4X 1, 0, 4, 5, 16364, 804 ; m1/4=t1[d], m0/5=t0[d] + VP9_UNPACK_MULSUB_2D_4X 2, 3, 7, 6, 11003, 12140 ; m2/7=t9[d], m3/6=t8[d] + SCRATCH 4, 8, tmpq+ 0*%%str + VP9_RND_SH_SUMSUB_BA 3, 0, 6, 5, 4, [pd_8192] ; m3=t0[w], m0=t8[w] + UNSCRATCH 4, 8, tmpq+ 0*%%str + VP9_RND_SH_SUMSUB_BA 2, 1, 7, 4, 5, [pd_8192] ; m2=t1[w], m1=t9[w] + + SCRATCH 0, 10, tmpq+ 0*%%str + SCRATCH 1, 11, tmpq+15*%%str + mova [tmpq+ 7*%%str], m2 + mova [tmpq+ 8*%%str], m3 + + mova m1, [%1+ 2*32] ; in2 + mova m0, [%1+13*32] ; in13 + mova m3, [%1+ 5*32] ; in5 + mova m2, [%1+10*32] ; in10 + + VP9_UNPACK_MULSUB_2D_4X 0, 1, 6, 7, 15893, 3981 ; m0/6=t3[d], m1/7=t2[d] + VP9_UNPACK_MULSUB_2D_4X 3, 2, 4, 5, 8423, 14053 ; m3/4=t11[d], m2/5=t10[d] + SCRATCH 4, 12, tmpq+ 2*%%str + VP9_RND_SH_SUMSUB_BA 2, 1, 5, 7, 4, [pd_8192] ; m2=t2[w], m1=t10[w] + UNSCRATCH 4, 12, tmpq+ 2*%%str + VP9_RND_SH_SUMSUB_BA 3, 0, 4, 6, 5, [pd_8192] ; m3=t3[w], m0=t11[w] + + SCRATCH 0, 12, tmpq+ 2*%%str + SCRATCH 1, 13, tmpq+13*%%str + mova [tmpq+ 5*%%str], m2 + mova [tmpq+10*%%str], m3 + + mova m2, [%1+ 4*32] ; in4 + mova m3, [%1+11*32] ; in11 + mova m0, [%1+ 3*32] ; in3 + mova m1, [%1+12*32] ; in12 + + VP9_UNPACK_MULSUB_2D_4X 3, 2, 7, 6, 14811, 7005 ; m3/7=t5[d], m2/6=t4[d] + VP9_UNPACK_MULSUB_2D_4X 0, 1, 4, 5, 5520, 15426 ; m0/4=t13[d], m1/5=t12[d] + SCRATCH 4, 9, tmpq+ 4*%%str + VP9_RND_SH_SUMSUB_BA 1, 2, 5, 6, 4, [pd_8192] ; m1=t4[w], m2=t12[w] + UNSCRATCH 4, 9, tmpq+ 4*%%str + VP9_RND_SH_SUMSUB_BA 0, 3, 4, 7, 6, [pd_8192] ; m0=t5[w], m3=t13[w] + + SCRATCH 0, 8, tmpq+ 4*%%str + mova [tmpq+11*%%str], m1 ; t4:m1->r11 + UNSCRATCH 0, 10, tmpq+ 0*%%str + UNSCRATCH 1, 11, tmpq+15*%%str + + ; round 2 interleaved part 1 + VP9_UNPACK_MULSUB_2D_4X 0, 1, 6, 7, 16069, 3196 ; m1/7=t8[d], m0/6=t9[d] + VP9_UNPACK_MULSUB_2D_4X 3, 2, 5, 4, 3196, 16069 ; m3/5=t12[d], m2/4=t13[d] + SCRATCH 4, 9, tmpq+ 3*%%str + VP9_RND_SH_SUMSUB_BA 3, 1, 5, 7, 4, [pd_8192] ; m3=t8[w], m1=t12[w] + UNSCRATCH 4, 9, tmpq+ 3*%%str + VP9_RND_SH_SUMSUB_BA 2, 0, 4, 6, 5, [pd_8192] ; m2=t9[w], m0=t13[w] + + SCRATCH 0, 10, tmpq+ 0*%%str + SCRATCH 1, 11, tmpq+15*%%str + SCRATCH 2, 14, tmpq+ 3*%%str + SCRATCH 3, 15, tmpq+12*%%str + + mova m2, [%1+ 6*32] ; in6 + mova m3, [%1+ 9*32] ; in9 + mova m0, [%1+ 1*32] ; in1 + mova m1, [%1+14*32] ; in14 + + VP9_UNPACK_MULSUB_2D_4X 3, 2, 7, 6, 13160, 9760 ; m3/7=t7[d], m2/6=t6[d] + VP9_UNPACK_MULSUB_2D_4X 0, 1, 4, 5, 2404, 16207 ; m0/4=t15[d], m1/5=t14[d] + SCRATCH 4, 9, tmpq+ 6*%%str + VP9_RND_SH_SUMSUB_BA 1, 2, 5, 6, 4, [pd_8192] ; m1=t6[w], m2=t14[w] + UNSCRATCH 4, 9, tmpq+ 6*%%str + VP9_RND_SH_SUMSUB_BA 0, 3, 4, 7, 6, [pd_8192] ; m0=t7[w], m3=t15[w] + + ; r8=t0, r7=t1, r5=t2, r10=t3, r11=t4, m8|r4=t5, m1=t6, m0=t7 + ; m10|r0=t8, m11|r15=t9, m13|r13=t10, m12|r2=t11, m14|r3=t12, m15|r12=t13, m2=t14, m3=t15 + + UNSCRATCH 4, 12, tmpq+ 2*%%str + UNSCRATCH 5, 13, tmpq+13*%%str + SCRATCH 0, 12, tmpq+ 1*%%str + SCRATCH 1, 13, tmpq+14*%%str + + ; remainder of round 2 (rest of t8-15) + VP9_UNPACK_MULSUB_2D_4X 5, 4, 6, 7, 9102, 13623 ; m5/6=t11[d], m4/7=t10[d] + VP9_UNPACK_MULSUB_2D_4X 3, 2, 1, 0, 13623, 9102 ; m3/1=t14[d], m2/0=t15[d] + SCRATCH 0, 9, tmpq+ 6*%%str + VP9_RND_SH_SUMSUB_BA 3, 4, 1, 7, 0, [pd_8192] ; m3=t10[w], m4=t14[w] + UNSCRATCH 0, 9, tmpq+ 6*%%str + VP9_RND_SH_SUMSUB_BA 2, 5, 0, 6, 1, [pd_8192] ; m2=t11[w], m5=t15[w] + + ; m15|r12=t8, m14|r3=t9, m3=t10, m2=t11, m11|r15=t12, m10|r0=t13, m4=t14, m5=t15 + + UNSCRATCH 6, 14, tmpq+ 3*%%str + UNSCRATCH 7, 15, tmpq+12*%%str + + SUMSUB_BA w, 3, 7, 1 + PSIGNW m3, [pw_m1] ; m3=out1[w], m7=t10[w] + SUMSUB_BA w, 2, 6, 1 ; m2=out14[w], m6=t11[w] + + ; unfortunately, the code below overflows in some cases, e.g. + ; http://downloads.webmproject.org/test_data/libvpx/vp90-2-14-resize-fp-tiles-16-8.webm +%if 0; cpuflag(ssse3) + SUMSUB_BA w, 7, 6, 1 + pmulhrsw m7, [pw_11585x2] ; m7=out6[w] + pmulhrsw m6, [pw_11585x2] ; m6=out9[w] +%else + VP9_UNPACK_MULSUB_2W_4X 6, 7, 11585, 11585, [pd_8192], 1, 0 +%endif + + mova [tmpq+ 3*%%str], m6 + mova [tmpq+ 6*%%str], m7 + UNSCRATCH 6, 10, tmpq+ 0*%%str + UNSCRATCH 7, 11, tmpq+15*%%str + mova [tmpq+13*%%str], m2 + SCRATCH 3, 11, tmpq+ 9*%%str + + VP9_UNPACK_MULSUB_2D_4X 7, 6, 2, 3, 15137, 6270 ; m6/3=t13[d], m7/2=t12[d] + VP9_UNPACK_MULSUB_2D_4X 5, 4, 1, 0, 6270, 15137 ; m5/1=t14[d], m4/0=t15[d] + SCRATCH 0, 9, tmpq+ 2*%%str + VP9_RND_SH_SUMSUB_BA 5, 6, 1, 3, 0, [pd_8192] ; m5=out2[w], m6=t14[w] + UNSCRATCH 0, 9, tmpq+ 2*%%str + VP9_RND_SH_SUMSUB_BA 4, 7, 0, 2, 1, [pd_8192] + PSIGNW m4, [pw_m1] ; m4=out13[w], m7=t15[w] + + ; unfortunately, the code below overflows in some cases +%if 0; cpuflag(ssse3) + SUMSUB_BA w, 7, 6, 1 + pmulhrsw m7, [pw_m11585x2] ; m7=out5[w] + pmulhrsw m6, [pw_11585x2] ; m6=out10[w] +%else + PSIGNW m7, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 7, 6, 11585, 11585, [pd_8192], 1, 0 +%endif + + ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, m6=out10, m4=out13, r2=out14 + + mova m2, [tmpq+ 8*%%str] + mova m3, [tmpq+ 7*%%str] + mova m1, [tmpq+11*%%str] + mova [tmpq+ 7*%%str], m6 + mova [tmpq+11*%%str], m4 + mova m4, [tmpq+ 5*%%str] + SCRATCH 5, 14, tmpq+ 5*%%str + SCRATCH 7, 15, tmpq+ 8*%%str + UNSCRATCH 6, 8, tmpq+ 4*%%str + UNSCRATCH 5, 12, tmpq+ 1*%%str + UNSCRATCH 7, 13, tmpq+14*%%str + + ; m2=t0, m3=t1, m9=t2, m0=t3, m1=t4, m8=t5, m13=t6, m12=t7 + ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, r10=out10, r11=out13, r2=out14 + + SUMSUB_BA w, 1, 2, 0 ; m1=t0[w], m2=t4[w] + mova m0, [tmpq+10*%%str] + SCRATCH 1, 12, tmpq+ 1*%%str + SUMSUB_BA w, 6, 3, 1 ; m8=t1[w], m3=t5[w] + SCRATCH 6, 13, tmpq+ 4*%%str + SUMSUB_BA w, 7, 4, 1 ; m13=t2[w], m9=t6[w] + SCRATCH 7, 8, tmpq+10*%%str + SUMSUB_BA w, 5, 0, 1 ; m12=t3[w], m0=t7[w] + SCRATCH 5, 9, tmpq+14*%%str + + VP9_UNPACK_MULSUB_2D_4X 2, 3, 7, 5, 15137, 6270 ; m2/6=t5[d], m3/10=t4[d] + VP9_UNPACK_MULSUB_2D_4X 0, 4, 1, 6, 6270, 15137 ; m0/14=t6[d], m9/15=t7[d] + SCRATCH 6, 10, tmpq+ 0*%%str + VP9_RND_SH_SUMSUB_BA 0, 3, 1, 5, 6, [pd_8192] + UNSCRATCH 6, 10, tmpq+ 0*%%str + PSIGNW m0, [pw_m1] ; m0=out3[w], m3=t6[w] + VP9_RND_SH_SUMSUB_BA 4, 2, 6, 7, 5, [pd_8192] ; m9=out12[w], m2=t7[w] + + UNSCRATCH 1, 8, tmpq+10*%%str + UNSCRATCH 5, 9, tmpq+14*%%str + UNSCRATCH 6, 12, tmpq+ 1*%%str + UNSCRATCH 7, 13, tmpq+ 4*%%str + SCRATCH 4, 9, tmpq+14*%%str + + SUMSUB_BA w, 1, 6, 4 ; m13=out0[w], m1=t2[w] + SUMSUB_BA w, 5, 7, 4 + PSIGNW m5, [pw_m1] ; m12=out15[w], m8=t3[w] + + ; unfortunately, the code below overflows in some cases, e.g. + ; http://downloads.webmproject.org/test_data/libvpx/vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm +%if 0 ; cpuflag(ssse3) + SUMSUB_BA w, 7, 6, 4 + pmulhrsw m7, [pw_m11585x2] ; m8=out7[w] + pmulhrsw m6, [pw_11585x2] ; m1=out8[w] + SWAP 6, 7 + SUMSUB_BA w, 3, 2, 4 + pmulhrsw m3, [pw_11585x2] ; m3=out4[w] + pmulhrsw m2, [pw_11585x2] ; m2=out11[w] +%else + SCRATCH 5, 8, tmpq+10*%%str + VP9_UNPACK_MULSUB_2W_4X 6, 7, 11585, m11585, [pd_8192], 5, 4 + VP9_UNPACK_MULSUB_2W_4X 2, 3, 11585, 11585, [pd_8192], 5, 4 + UNSCRATCH 5, 8, tmpq+10*%%str +%endif + + ; m13=out0, m0=out3, m3=out4, m8=out7, m1=out8, m2=out11, m9=out12, m12=out15 + ; m11|r13=out1, m5=out2, m7=out5, r15=out6, r3=out9, r10=out10, r11=out13, r2=out14 + +%if %2 == 1 +%if ARCH_X86_64 + mova m13, [tmpq+ 6*%%str] + TRANSPOSE8x8W 1, 11, 14, 0, 3, 15, 13, 6, 10 + mova [tmpq+ 0*16], m1 + mova [tmpq+ 2*16], m11 + mova [tmpq+ 4*16], m14 + mova [tmpq+ 6*16], m0 + mova m1, [tmpq+ 3*%%str] + mova m11, [tmpq+ 7*%%str] + mova m14, [tmpq+11*%%str] + mova m0, [tmpq+13*%%str] + mova [tmpq+ 8*16], m3 + mova [tmpq+10*16], m15 + mova [tmpq+12*16], m13 + mova [tmpq+14*16], m6 + + TRANSPOSE8x8W 7, 1, 11, 2, 9, 14, 0, 5, 10 + mova [tmpq+ 1*16], m7 + mova [tmpq+ 3*16], m1 + mova [tmpq+ 5*16], m11 + mova [tmpq+ 7*16], m2 + mova [tmpq+ 9*16], m9 + mova [tmpq+11*16], m14 + mova [tmpq+13*16], m0 + mova [tmpq+15*16], m5 +%else + mova [tmpq+12*%%str], m2 + mova [tmpq+ 1*%%str], m5 + mova [tmpq+15*%%str], m7 + mova m2, [tmpq+ 9*%%str] + mova m5, [tmpq+ 5*%%str] + mova m7, [tmpq+ 8*%%str] + TRANSPOSE8x8W 1, 2, 5, 0, 3, 7, 4, 6, [tmpq+ 6*%%str], [tmpq+ 8*%%str], 1 + mova [tmpq+ 0*16], m1 + mova [tmpq+ 2*16], m2 + mova [tmpq+ 4*16], m5 + mova [tmpq+ 6*16], m0 + mova [tmpq+10*16], m7 + mova m3, [tmpq+12*%%str] + mova [tmpq+12*16], m4 + mova m4, [tmpq+14*%%str] + mova [tmpq+14*16], m6 + + mova m0, [tmpq+15*%%str] + mova m1, [tmpq+ 3*%%str] + mova m2, [tmpq+ 7*%%str] + mova m5, [tmpq+11*%%str] + mova m7, [tmpq+ 1*%%str] + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [tmpq+13*%%str], [tmpq+ 9*%%str], 1 + mova [tmpq+ 1*16], m0 + mova [tmpq+ 3*16], m1 + mova [tmpq+ 5*16], m2 + mova [tmpq+ 7*16], m3 + mova [tmpq+11*16], m5 + mova [tmpq+13*16], m6 + mova [tmpq+15*16], m7 +%endif +%else + pxor m4, m4 + +%if cpuflag(ssse3) +%define ROUND_REG [pw_512] +%else +%define ROUND_REG [pw_32] +%endif + +%if ARCH_X86_64 + mova m12, [tmpq+ 6*%%str] + VP9_IDCT8_WRITEx2 1, 11, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 14, 0, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 3, 15, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 12, 6, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + mova m1, [tmpq+ 3*%%str] + mova m11, [tmpq+ 7*%%str] + mova m14, [tmpq+11*%%str] + mova m0, [tmpq+13*%%str] + + VP9_IDCT8_WRITEx2 7, 1, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 11, 2, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 9, 14, 10, 8, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + VP9_IDCT8_WRITEx2 0, 5, 10, 8, 4, ROUND_REG, 6 +%else + mova [tmpq+ 0*%%str], m2 + mova [tmpq+ 1*%%str], m5 + mova [tmpq+ 2*%%str], m7 + mova m2, [tmpq+ 9*%%str] + VP9_IDCT8_WRITEx2 1, 2, 5, 7, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + mova m5, [tmpq+ 5*%%str] + VP9_IDCT8_WRITEx2 5, 0, 1, 2, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + mova m5, [tmpq+ 8*%%str] + VP9_IDCT8_WRITEx2 3, 5, 1, 2, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + mova m5, [tmpq+ 6*%%str] + VP9_IDCT8_WRITEx2 5, 6, 1, 2, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + + mova m0, [tmpq+ 2*%%str] + mova m3, [tmpq+ 3*%%str] + VP9_IDCT8_WRITEx2 0, 3, 1, 2, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + mova m0, [tmpq+ 7*%%str] + mova m3, [tmpq+ 0*%%str] + VP9_IDCT8_WRITEx2 0, 3, 1, 2, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + mova m0, [tmpq+14*%%str] + mova m3, [tmpq+11*%%str] + VP9_IDCT8_WRITEx2 0, 3, 1, 2, 4, ROUND_REG, 6 + lea dstq, [dstq+strideq*2] + mova m0, [tmpq+13*%%str] + mova m3, [tmpq+ 1*%%str] + VP9_IDCT8_WRITEx2 0, 3, 1, 2, 4, ROUND_REG, 6 +%endif + + SWAP 0, 4 ; zero +%undef ROUND_REG +%endif +%endmacro + +%macro IADST16_FN 5 +INIT_XMM %5 +cglobal vp9_%1_%3_16x16_add, 3, 6, 16, 512, dst, stride, block, cnt, dst_bak, tmp + mov cntd, 2 + mov tmpq, rsp +.loop1_full: + VP9_%2_1D blockq, 1 + add blockq, 16 + add tmpq, 256 + dec cntd + jg .loop1_full + sub blockq, 32 + + mov cntd, 2 + mov tmpq, rsp + mov dst_bakq, dstq +.loop2_full: + VP9_%4_1D tmpq, 2 + lea dstq, [dst_bakq+8] + add tmpq, 16 + dec cntd + jg .loop2_full + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + ZERO_BLOCK blockq, 32, 16, m0 + RET +%endmacro + +IADST16_FN idct, IDCT16, iadst, IADST16, sse2 +IADST16_FN iadst, IADST16, idct, IDCT16, sse2 +IADST16_FN iadst, IADST16, iadst, IADST16, sse2 +IADST16_FN idct, IDCT16, iadst, IADST16, ssse3 +IADST16_FN iadst, IADST16, idct, IDCT16, ssse3 +IADST16_FN iadst, IADST16, iadst, IADST16, ssse3 +IADST16_FN idct, IDCT16, iadst, IADST16, avx +IADST16_FN iadst, IADST16, idct, IDCT16, avx +IADST16_FN iadst, IADST16, iadst, IADST16, avx + +; in: data in m[0-15] except m0/m4, which are in [blockq+0] and [blockq+128] +; out: m[0-15] except m6, which is in [blockq+192] +; uses blockq as scratch space +%macro VP9_IADST16_YMM_1D 0 + mova [blockq+ 32], m3 + mova [blockq+ 64], m7 + mova [blockq+ 96], m8 + + ; first half of round 1 + VP9_UNPACK_MULSUB_2D_4X 9, 6, 0, 3, 13160, 9760 ; m9/x=t7[d], m6/x=t6[d] + VP9_UNPACK_MULSUB_2D_4X 1, 14, 4, 7, 2404, 16207 ; m1/x=t15[d], m14/x=t14[d] + VP9_RND_SH_SUMSUB_BA 14, 6, 7, 3, 8, [pd_8192] ; m14=t6[w], m6=t14[w] + VP9_RND_SH_SUMSUB_BA 1, 9, 4, 0, 8, [pd_8192] ; m1=t7[w], m9=t15[w] + + VP9_UNPACK_MULSUB_2D_4X 13, 2, 4, 7, 15893, 3981 ; m13/x=t3[d], m2/x=t2[d] + VP9_UNPACK_MULSUB_2D_4X 5, 10, 0, 3, 8423, 14053 ; m5/x=t11[d], m10/x=t10[d] + VP9_RND_SH_SUMSUB_BA 10, 2, 3, 7, 8, [pd_8192] ; m10=t2[w], m2=t10[w] + VP9_RND_SH_SUMSUB_BA 5, 13, 0, 4, 8, [pd_8192] ; m5=t3[w], m13=t11[w] + + ; half of round 2 t8-15 + VP9_UNPACK_MULSUB_2D_4X 2, 13, 4, 7, 9102, 13623 ; m2/x=t11[d], m13/x=t10[d] + VP9_UNPACK_MULSUB_2D_4X 9, 6, 3, 0, 13623, 9102 ; m9/x=t14[d], m6/x=t15[d] + VP9_RND_SH_SUMSUB_BA 9, 13, 3, 7, 8, [pd_8192] ; m9=t10[w], m13=t14[w] + VP9_RND_SH_SUMSUB_BA 6, 2, 0, 4, 8, [pd_8192] ; m6=t11[w], m2=t15[w] + + SUMSUB_BA w, 14, 10, 8 ; m14=t2, m10=t6 + SUMSUB_BA w, 1, 5, 8 ; m1=t3, m5=t7 + + mova m0, [blockq+ 0] + mova m4, [blockq+128] + mova m3, [blockq+ 32] + mova m7, [blockq+ 64] + mova m8, [blockq+ 96] + mova [blockq+ 0], m1 + mova [blockq+128], m14 + mova [blockq+ 32], m6 + mova [blockq+ 64], m9 + mova [blockq+ 96], m10 + + ; second half of round 1 + VP9_UNPACK_MULSUB_2D_4X 15, 0, 1, 9, 16364, 804 ; m15/x=t1[d], m0/x=t0[d] + VP9_UNPACK_MULSUB_2D_4X 7, 8, 10, 6, 11003, 12140 ; m7/x=t9[d], m8/x=t8[d] + VP9_RND_SH_SUMSUB_BA 8, 0, 6, 9, 14, [pd_8192] ; m8=t0[w], m0=t8[w] + VP9_RND_SH_SUMSUB_BA 7, 15, 10, 1, 14, [pd_8192] ; m7=t1[w], m15=t9[w] + + VP9_UNPACK_MULSUB_2D_4X 11, 4, 10, 6, 14811, 7005 ; m11/x=t5[d], m4/x=t4[d] + VP9_UNPACK_MULSUB_2D_4X 3, 12, 1, 9, 5520, 15426 ; m3/x=t13[d], m12/x=t12[d] + VP9_RND_SH_SUMSUB_BA 12, 4, 9, 6, 14, [pd_8192] ; m12=t4[w], m4=t12[w] + VP9_RND_SH_SUMSUB_BA 3, 11, 1, 10, 14, [pd_8192] ; m3=t5[w], m11=t13[w] + + ; second half of round 2 t8-15 + VP9_UNPACK_MULSUB_2D_4X 0, 15, 6, 10, 16069, 3196 ; m15/x=t8[d], m0/x=t9[d] + VP9_UNPACK_MULSUB_2D_4X 11, 4, 9, 1, 3196, 16069 ; m11/x=t12[d], m4/x=t13[d] + VP9_RND_SH_SUMSUB_BA 11, 15, 9, 10, 14, [pd_8192] ; m11=t8[w], m15=t12[w] + VP9_RND_SH_SUMSUB_BA 4, 0, 1, 6, 14, [pd_8192] ; m4=t9[w], m0=t13[w] + + SUMSUB_BA w, 12, 8, 14 ; m12=t0, m8=t4 + SUMSUB_BA w, 3, 7, 14 ; m3=t1, m7=t5 + + mova m10, [blockq+ 96] + mova [blockq+ 96], m12 + + ; round 3 + VP9_UNPACK_MULSUB_2D_4X 15, 0, 9, 12, 15137, 6270 ; m15/x=t13[d], m0/x=t12[d] + VP9_UNPACK_MULSUB_2D_4X 2, 13, 1, 6, 6270, 15137 ; m2/x=t14[d], m13/x=t15[d] + VP9_RND_SH_SUMSUB_BA 2, 0, 1, 12, 14, [pd_8192] ; m2=out2[w], m0=t14a[w] + VP9_RND_SH_SUMSUB_BA 13, 15, 6, 9, 14, [pd_8192] + PSIGNW m13, [pw_m1] ; m13=out13[w], m15=t15a[w] + + VP9_UNPACK_MULSUB_2D_4X 8, 7, 12, 9, 15137, 6270 ; m8/x=t5[d], m7/x=t4[d] + VP9_UNPACK_MULSUB_2D_4X 5, 10, 1, 6, 6270, 15137 ; m5/x=t6[d], m10/x=t7[d] + VP9_RND_SH_SUMSUB_BA 5, 7, 1, 9, 14, [pd_8192] + PSIGNW m5, [pw_m1] ; m5=out3[w], m7=t6[w] + VP9_RND_SH_SUMSUB_BA 10, 8, 6, 12, 14, [pd_8192] ; m10=out12[w], m8=t7[w] + + mova m1, [blockq+ 0] + mova m14, [blockq+128] + mova m6, [blockq+ 32] + mova m9, [blockq+ 64] + mova m12, [blockq+ 96] + mova [blockq+ 0], m10 + mova [blockq+128], m5 + + SUMSUB_BA w, 14, 12, 5 ; m14=out0, m12=t2a + SUMSUB_BA w, 1, 3, 5 + PSIGNW m1, [pw_m1] ; m1=out15, m3=t3a + + SUMSUB_BA w, 9, 11, 5 + PSIGNW m9, [pw_m1] ; m9=out1, m11=t10 + SUMSUB_BA w, 6, 4, 5 ; m6=out14, m4=t11 + + VP9_UNPACK_MULSUB_2W_4X 4, 11, 11585, 11585, [pd_8192], 5, 10 ; m4=out9, m11=out6 + mova m5, [blockq+128] + mova [blockq+192], m11 + PSIGNW m15, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 15, 0, 11585, 11585, [pd_8192], 10, 11 ; m15=out5, m0=out10 + + PSIGNW m3, [pw_m1] + VP9_UNPACK_MULSUB_2W_4X 3, 12, 11585, 11585, [pd_8192], 10, 11 ; m3=out7,m12=out8 + VP9_UNPACK_MULSUB_2W_4X 8, 7, 11585, 11585, [pd_8192], 10, 11 ; m8=out11,m7=out4 + + mova m10, [blockq+ 0] + + SWAP 0, 14, 6, 11, 8, 12, 10 + SWAP 1, 9, 15, 4, 7, 3, 5 + SWAP 5, 9, 15 +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +%macro IADST16_YMM_FN 4 +INIT_YMM avx2 +cglobal vp9_%1_%3_16x16_add, 4, 4, 16, dst, stride, block, eob + mova m1, [blockq+ 32] + mova m2, [blockq+ 64] + mova m3, [blockq+ 96] + mova m5, [blockq+160] + mova m6, [blockq+192] + mova m7, [blockq+224] + mova m8, [blockq+256] + mova m9, [blockq+288] + mova m10, [blockq+320] + mova m11, [blockq+352] + mova m12, [blockq+384] + mova m13, [blockq+416] + mova m14, [blockq+448] + mova m15, [blockq+480] + + VP9_%2_YMM_1D + TRANSPOSE16x16W 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ + [blockq+192], [blockq+128], 1 + mova [blockq+ 0], m0 + VP9_%4_YMM_1D + + mova [blockq+224], m7 + + ; store + VP9_IDCT8_WRITEx2 0, 1, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 2, 3, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 4, 5, 6, 7, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + mova m6, [blockq+192] + mova m7, [blockq+224] + VP9_IDCT8_WRITEx2 6, 7, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 8, 9, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 10, 11, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 12, 13, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + VP9_IDCT8_WRITEx2 14, 15, 1, 2, unused, [pw_512], 6 + lea dstq, [dstq+2*strideq] + + ; at the end of the loop, m0 should still be zero + ; use that to zero out block coefficients + pxor m0, m0 + ZERO_BLOCK blockq, 32, 16, m0 + RET +%endmacro + +IADST16_YMM_FN idct, IDCT16, iadst, IADST16 +IADST16_YMM_FN iadst, IADST16, idct, IDCT16 +IADST16_YMM_FN iadst, IADST16, iadst, IADST16 +%endif + +;--------------------------------------------------------------------------------------------- +; void vp9_idct_idct_32x32_add_(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob); +;--------------------------------------------------------------------------------------------- + +%macro VP9_IDCT32_1D 2-3 32 ; src, pass, nnzc +%if %2 == 1 +%assign %%str mmsize +%else +%assign %%str 64 +%endif + + ; first do t0-15, this can be done identical to idct16x16 + VP9_IDCT16_1D_START %1, %3/2, 64*2, tmpq, 2*%%str, 1 + + ; store everything on stack to make space available for t16-31 + ; we store interleaved with the output of the second half (t16-31) + ; so we don't need to allocate extra stack space + mova [tmpq+ 0*%%str], m0 ; t0 + mova [tmpq+ 4*%%str], m1 ; t1 + mova [tmpq+ 8*%%str], m2 ; t2 + mova [tmpq+12*%%str], m3 ; t3 + mova [tmpq+16*%%str], m4 ; t4 + mova [tmpq+20*%%str], m5 ; t5 +%if ARCH_X86_64 + mova [tmpq+22*%%str], m10 ; t10 + mova [tmpq+18*%%str], m11 ; t11 + mova [tmpq+14*%%str], m12 ; t12 + mova [tmpq+10*%%str], m13 ; t13 + mova [tmpq+ 6*%%str], m14 ; t14 + mova [tmpq+ 2*%%str], m15 ; t15 +%endif + + mova m0, [tmpq+ 30*%%str] + UNSCRATCH 1, 6, tmpq+26*%%str + UNSCRATCH 2, 8, tmpq+24*%%str + UNSCRATCH 3, 9, tmpq+28*%%str + SUMSUB_BA w, 1, 3, 4 ; t6, t9 + SUMSUB_BA w, 0, 2, 4 ; t7, t8 + + mova [tmpq+24*%%str], m1 ; t6 + mova [tmpq+28*%%str], m0 ; t7 + mova [tmpq+30*%%str], m2 ; t8 + mova [tmpq+26*%%str], m3 ; t9 + + ; then, secondly, do t16-31 +%if %3 <= 8 + mova m4, [%1+ 1*64] + mova m7, [%1+ 7*64] + + pmulhrsw m1, m4, [pw_16364x2] ;t31 + pmulhrsw m4, [pw_804x2] ;t16 + + VP9_UNPACK_MULSUB_2W_4X 5, 0, 1, 4, 16069, 3196, [pd_8192], 6, 2 ; t17, t30 + + pmulhrsw m3, m7, [pw_m5520x2] ;t19 + pmulhrsw m7, [pw_15426x2] ;t28 + + SCRATCH 4, 13, tmpq+ 1*%%str + SCRATCH 5, 12, tmpq+15*%%str + + VP9_UNPACK_MULSUB_2W_4X 2, 6, 7, 3, 3196, m16069, [pd_8192], 4, 5 ; t18, t29 +%else + mova m0, [%1+ 1*64] + mova m1, [%1+15*64] +%if %3 <= 16 + pmulhrsw m5, m0, [pw_16364x2] + pmulhrsw m0, [pw_804x2] + pmulhrsw m4, m1, [pw_m11003x2] + pmulhrsw m1, [pw_12140x2] +%else + mova m4, [%1+17*64] + mova m5, [%1+31*64] + + VP9_UNPACK_MULSUB_2W_4X 0, 5, 16364, 804, [pd_8192], 2, 3 ; t16, t31 + VP9_UNPACK_MULSUB_2W_4X 4, 1, 11003, 12140, [pd_8192], 2, 3 ; t17, t30 +%endif + SUMSUB_BA w, 4, 0, 2 + SUMSUB_BA w, 1, 5, 2 + + VP9_UNPACK_MULSUB_2W_4X 5, 0, 16069, 3196, [pd_8192], 2, 3 ; t17, t30 + + SCRATCH 4, 13, tmpq+ 1*%%str + SCRATCH 5, 12, tmpq+15*%%str + + mova m2, [%1+ 7*64] + mova m3, [%1+ 9*64] +%if %3 <= 16 + pmulhrsw m7, m3, [pw_14811x2] + pmulhrsw m3, [pw_7005x2] + pmulhrsw m6, m2, [pw_m5520x2] + pmulhrsw m2, [pw_15426x2] +%else + mova m7, [%1+23*64] + mova m6, [%1+25*64] + + VP9_UNPACK_MULSUB_2W_4X 3, 7, 14811, 7005, [pd_8192], 4, 5 ; t18, t29 + VP9_UNPACK_MULSUB_2W_4X 6, 2, 5520, 15426, [pd_8192], 4, 5 ; t19, t28 +%endif + SUMSUB_BA w, 3, 6, 4 + SUMSUB_BA w, 7, 2, 4 + + VP9_UNPACK_MULSUB_2W_4X 2, 6, 3196, m16069, [pd_8192], 4, 5 ; t18, t29 +%endif + + UNSCRATCH 5, 12, tmpq+15*%%str + SUMSUB_BA w, 6, 0, 4 + mova [tmpq+25*%%str], m6 ; t19 + UNSCRATCH 4, 13, tmpq+ 1*%%str + SUMSUB_BA w, 7, 1, 6 + SUMSUB_BA w, 3, 4, 6 + mova [tmpq+23*%%str], m3 ; t16 + SUMSUB_BA w, 2, 5, 6 + + VP9_UNPACK_MULSUB_2W_4X 0, 5, 15137, 6270, [pd_8192], 6, 3 ; t18, t29 + VP9_UNPACK_MULSUB_2W_4X 1, 4, 15137, 6270, [pd_8192], 6, 3 ; t19, t28 + + SCRATCH 0, 10, tmpq+ 1*%%str + SCRATCH 1, 11, tmpq+ 7*%%str + SCRATCH 2, 9, tmpq+ 9*%%str + SCRATCH 4, 14, tmpq+15*%%str + SCRATCH 5, 15, tmpq+17*%%str + SCRATCH 7, 13, tmpq+31*%%str + +%if %3 <= 8 + mova m0, [%1+ 5*64] + mova m3, [%1+ 3*64] + + pmulhrsw m5, m0, [pw_15893x2] ;t27 + pmulhrsw m0, [pw_3981x2] ;t20 + + VP9_UNPACK_MULSUB_2W_4X 1, 4, 5, 0, 9102, 13623, [pd_8192], 7, 2 ; t21, t26 + + pmulhrsw m6, m3, [pw_m2404x2] ;t23 + pmulhrsw m3, [pw_16207x2] ;t24 + + SCRATCH 5, 8, tmpq+ 5*%%str + SCRATCH 4, 12, tmpq+11*%%str + + VP9_UNPACK_MULSUB_2W_4X 7, 2, 3, 6, 13623, m9102, [pd_8192], 4, 5 ; t22, t25 +%else + mova m4, [%1+ 5*64] + mova m5, [%1+11*64] +%if %3 <= 16 + pmulhrsw m1, m4, [pw_15893x2] + pmulhrsw m4, [pw_3981x2] + pmulhrsw m0, m5, [pw_m8423x2] + pmulhrsw m5, [pw_14053x2] +%else + mova m0, [%1+21*64] + mova m1, [%1+27*64] + + VP9_UNPACK_MULSUB_2W_4X 4, 1, 15893, 3981, [pd_8192], 2, 3 ; t20, t27 + VP9_UNPACK_MULSUB_2W_4X 0, 5, 8423, 14053, [pd_8192], 2, 3 ; t21, t26 +%endif + SUMSUB_BA w, 0, 4, 2 + SUMSUB_BA w, 5, 1, 2 + + VP9_UNPACK_MULSUB_2W_4X 1, 4, 9102, 13623, [pd_8192], 2, 3 ; t21, t26 + + SCRATCH 5, 8, tmpq+ 5*%%str + SCRATCH 4, 12, tmpq+11*%%str + + mova m7, [%1+ 3*64] + mova m6, [%1+13*64] +%if %3 <= 16 + pmulhrsw m3, m6, [pw_13160x2] + pmulhrsw m6, [pw_9760x2] + pmulhrsw m2, m7, [pw_m2404x2] + pmulhrsw m7, [pw_16207x2] +%else + mova m2, [%1+29*64] + mova m3, [%1+19*64] + VP9_UNPACK_MULSUB_2W_4X 6, 3, 13160, 9760, [pd_8192], 4, 5 ; t22, t25 + VP9_UNPACK_MULSUB_2W_4X 2, 7, 2404, 16207, [pd_8192], 4, 5 ; t23, t24 +%endif + SUMSUB_BA w, 6, 2, 4 + SUMSUB_BA w, 3, 7, 4 + + VP9_UNPACK_MULSUB_2W_4X 7, 2, 13623, m9102, [pd_8192], 4, 5 ; t22, t25 +%endif + + ; m4=t16, m5=t17, m9=t18, m8=t19, m0=t20, m1=t21, m13=t22, m12=t23, + ; m3=t24, m2=t25, m14=t26, m15=t27, m7=t28, m6=t29, m10=t30, m11=t31 + + UNSCRATCH 4, 12, tmpq+11*%%str + SUMSUB_BA w, 0, 6, 5 + SUMSUB_BA w, 4, 2, 5 + UNSCRATCH 5, 8, tmpq+ 5*%%str + SCRATCH 4, 8, tmpq+11*%%str + SUMSUB_BA w, 1, 7, 4 + SUMSUB_BA w, 5, 3, 4 + SCRATCH 5, 12, tmpq+ 5*%%str + + VP9_UNPACK_MULSUB_2W_4X 3, 6, 6270, m15137, [pd_8192], 4, 5 ; t20, t27 + VP9_UNPACK_MULSUB_2W_4X 2, 7, 6270, m15137, [pd_8192], 4, 5 ; t21, t26 + + ; m8[s]=t16, m9=t17, m5=t18, m4[s]=t19, m12=t20, m13=t21, m1=t22, m0=t23, + ; m15=t24, m14=t25, m2=t26, m3=t27, m11=t28, m10=t29, m6=t30, m7=t31 + + UNSCRATCH 5, 9, tmpq+ 9*%%str + mova m4, [tmpq+23*%%str] ; t16 +%if ARCH_X86_64 + SUMSUB_BA w, 1, 5, 9 + SUMSUB_BA w, 0, 4, 9 +%else + SUMSUB_BADC w, 1, 5, 0, 4 +%endif + mova [tmpq+29*%%str], m1 ; t17 + mova [tmpq+21*%%str], m0 ; t16 + UNSCRATCH 0, 10, tmpq+ 1*%%str + UNSCRATCH 1, 11, tmpq+ 7*%%str +%if ARCH_X86_64 + SUMSUB_BA w, 2, 0, 9 + SUMSUB_BA w, 3, 1, 9 +%else + SUMSUB_BADC w, 2, 0, 3, 1 +%endif + mova [tmpq+ 9*%%str], m2 ; t18 + mova [tmpq+13*%%str], m3 ; t19 + SCRATCH 0, 10, tmpq+23*%%str + SCRATCH 1, 11, tmpq+27*%%str + + UNSCRATCH 2, 14, tmpq+15*%%str + UNSCRATCH 3, 15, tmpq+17*%%str + SUMSUB_BA w, 6, 2, 0 + SUMSUB_BA w, 7, 3, 0 + SCRATCH 6, 14, tmpq+ 3*%%str + SCRATCH 7, 15, tmpq+ 7*%%str + + UNSCRATCH 0, 8, tmpq+11*%%str + mova m1, [tmpq+25*%%str] ; t19 + UNSCRATCH 6, 12, tmpq+ 5*%%str + UNSCRATCH 7, 13, tmpq+31*%%str +%if ARCH_X86_64 + SUMSUB_BA w, 0, 1, 9 + SUMSUB_BA w, 6, 7, 9 +%else + SUMSUB_BADC w, 0, 1, 6, 7 +%endif + + ; m0=t16, m1=t17, m2=t18, m3=t19, m11=t20, m10=t21, m9=t22, m8=t23, + ; m7=t24, m6=t25, m5=t26, m4=t27, m12=t28, m13=t29, m14=t30, m15=t31 + +%if 0; cpuflag(ssse3) +%if ARCH_X86_64 + SUMSUB_BA w, 4, 7, 8 + SUMSUB_BA w, 5, 1, 8 +%else + SUMSUB_BADC w, 4, 7, 5, 1 +%endif + + pmulhrsw m7, [pw_11585x2] + pmulhrsw m4, [pw_11585x2] + pmulhrsw m1, [pw_11585x2] + pmulhrsw m5, [pw_11585x2] + + mova [tmpq+ 5*%%str], m7 ; t23 + SCRATCH 1, 13, tmpq+25*%%str + UNSCRATCH 7, 10, tmpq+23*%%str + UNSCRATCH 1, 11, tmpq+27*%%str + +%if ARCH_X86_64 + SUMSUB_BA w, 7, 3, 10 + SUMSUB_BA w, 1, 2, 10 +%else + SUMSUB_BADC w, 7, 3, 1, 2 +%endif + + pmulhrsw m3, [pw_11585x2] + pmulhrsw m7, [pw_11585x2] + pmulhrsw m2, [pw_11585x2] + pmulhrsw m1, [pw_11585x2] +%else + SCRATCH 0, 8, tmpq+15*%%str + SCRATCH 6, 9, tmpq+17*%%str + VP9_UNPACK_MULSUB_2W_4X 7, 4, 11585, 11585, [pd_8192], 0, 6 + mova [tmpq+ 5*%%str], m7 ; t23 + UNSCRATCH 7, 10, tmpq+23*%%str + VP9_UNPACK_MULSUB_2W_4X 1, 5, 11585, 11585, [pd_8192], 0, 6 + SCRATCH 1, 13, tmpq+25*%%str + UNSCRATCH 1, 11, tmpq+27*%%str + VP9_UNPACK_MULSUB_2W_4X 3, 7, 11585, 11585, [pd_8192], 0, 6 + VP9_UNPACK_MULSUB_2W_4X 2, 1, 11585, 11585, [pd_8192], 0, 6 + UNSCRATCH 0, 8, tmpq+15*%%str + UNSCRATCH 6, 9, tmpq+17*%%str +%endif + + ; m0=t16, m1=t17, m2=t18, m3=t19, m4=t20, m5=t21, m6=t22, m7=t23, + ; m8=t24, m9=t25, m10=t26, m11=t27, m12=t28, m13=t29, m14=t30, m15=t31 + + ; then do final pass to sumsub+store the two halves +%if %2 == 1 + mova [tmpq+17*%%str], m2 ; t20 + mova [tmpq+ 1*%%str], m3 ; t21 +%if ARCH_X86_64 + mova [tmpq+25*%%str], m13 ; t22 + + mova m8, [tmpq+ 0*%%str] ; t0 + mova m9, [tmpq+ 4*%%str] ; t1 + mova m12, [tmpq+ 8*%%str] ; t2 + mova m11, [tmpq+12*%%str] ; t3 + mova m2, [tmpq+16*%%str] ; t4 + mova m3, [tmpq+20*%%str] ; t5 + mova m13, [tmpq+24*%%str] ; t6 + + SUMSUB_BA w, 6, 8, 10 + mova [tmpq+ 3*%%str], m8 ; t15 + SUMSUB_BA w, 0, 9, 8 + SUMSUB_BA w, 15, 12, 8 + SUMSUB_BA w, 14, 11, 8 + SUMSUB_BA w, 1, 2, 8 + SUMSUB_BA w, 7, 3, 8 + SUMSUB_BA w, 5, 13, 8 + mova m10, [tmpq+28*%%str] ; t7 + SUMSUB_BA w, 4, 10, 8 +%if cpuflag(avx2) + ; the "shitty" about this idct is that the final pass does the outermost + ; interleave sumsubs (t0/31, t1/30, etc) but the tN for the 16x16 need + ; to be sequential, which means I need to load/store half of the sumsub + ; intermediates back to/from memory to get a 16x16 transpose going... + ; This would be easier if we had more (e.g. 32) YMM regs here. + mova [tmpq+ 7*%%str], m9 + mova [tmpq+11*%%str], m12 + mova [tmpq+15*%%str], m11 + mova [tmpq+19*%%str], m2 + mova [tmpq+23*%%str], m3 + mova [tmpq+27*%%str], m13 + mova [tmpq+31*%%str], m10 + mova [tmpq+12*%%str], m5 + + mova m13, [tmpq+30*%%str] ; t8 + mova m12, [tmpq+26*%%str] ; t9 + mova m11, [tmpq+22*%%str] ; t10 + mova m10, [tmpq+18*%%str] ; t11 + mova m9, [tmpq+17*%%str] ; t20 + mova m8, [tmpq+ 1*%%str] ; t21 + mova m3, [tmpq+25*%%str] ; t22 + mova m2, [tmpq+ 5*%%str] ; t23 + + SUMSUB_BA w, 9, 10, 5 + SUMSUB_BA w, 8, 11, 5 + SUMSUB_BA w, 3, 12, 5 + SUMSUB_BA w, 2, 13, 5 + mova [tmpq+ 1*%%str], m10 + mova [tmpq+ 5*%%str], m11 + mova [tmpq+17*%%str], m12 + mova [tmpq+25*%%str], m13 + + mova m13, [tmpq+14*%%str] ; t12 + mova m12, [tmpq+10*%%str] ; t13 + mova m11, [tmpq+ 9*%%str] ; t18 + mova m10, [tmpq+13*%%str] ; t19 + + SUMSUB_BA w, 11, 12, 5 + SUMSUB_BA w, 10, 13, 5 + mova [tmpq+ 9*%%str], m13 + mova [tmpq+13*%%str], m12 + mova [tmpq+10*%%str], m10 + mova [tmpq+14*%%str], m11 + + mova m13, [tmpq+ 6*%%str] ; t14 + mova m12, [tmpq+ 2*%%str] ; t15 + mova m11, [tmpq+21*%%str] ; t16 + mova m10, [tmpq+29*%%str] ; t17 + SUMSUB_BA w, 11, 12, 5 + SUMSUB_BA w, 10, 13, 5 + mova [tmpq+21*%%str], m12 + mova [tmpq+29*%%str], m13 + mova m12, [tmpq+10*%%str] + mova m13, [tmpq+14*%%str] + + TRANSPOSE16x16W 6, 0, 15, 14, 1, 7, 5, 4, \ + 2, 3, 8, 9, 12, 13, 10, 11, \ + [tmpq+12*%%str], [tmpq+ 8*%%str], 1 + mova [tmpq+ 0*%%str], m6 + mova [tmpq+ 2*%%str], m0 + mova [tmpq+ 4*%%str], m15 + mova [tmpq+ 6*%%str], m14 + mova [tmpq+10*%%str], m7 + mova [tmpq+12*%%str], m5 + mova [tmpq+14*%%str], m4 + mova [tmpq+16*%%str], m2 + mova [tmpq+18*%%str], m3 + mova [tmpq+20*%%str], m8 + mova [tmpq+22*%%str], m9 + mova [tmpq+24*%%str], m12 + mova [tmpq+26*%%str], m13 + mova [tmpq+28*%%str], m10 + mova [tmpq+30*%%str], m11 + + mova m0, [tmpq+21*%%str] + mova m1, [tmpq+29*%%str] + mova m2, [tmpq+13*%%str] + mova m3, [tmpq+ 9*%%str] + mova m4, [tmpq+ 1*%%str] + mova m5, [tmpq+ 5*%%str] + mova m7, [tmpq+25*%%str] + mova m8, [tmpq+31*%%str] + mova m9, [tmpq+27*%%str] + mova m10, [tmpq+23*%%str] + mova m11, [tmpq+19*%%str] + mova m12, [tmpq+15*%%str] + mova m13, [tmpq+11*%%str] + mova m14, [tmpq+ 7*%%str] + mova m15, [tmpq+ 3*%%str] + TRANSPOSE16x16W 0, 1, 2, 3, 4, 5, 6, 7, \ + 8, 9, 10, 11, 12, 13, 14, 15, \ + [tmpq+17*%%str], [tmpq+ 9*%%str], 1 + mova [tmpq+ 1*%%str], m0 + mova [tmpq+ 3*%%str], m1 + mova [tmpq+ 5*%%str], m2 + mova [tmpq+ 7*%%str], m3 + mova [tmpq+11*%%str], m5 + mova [tmpq+13*%%str], m6 + mova [tmpq+15*%%str], m7 + mova [tmpq+17*%%str], m8 + mova [tmpq+19*%%str], m9 + mova [tmpq+21*%%str], m10 + mova [tmpq+23*%%str], m11 + mova [tmpq+25*%%str], m12 + mova [tmpq+27*%%str], m13 + mova [tmpq+29*%%str], m14 + mova [tmpq+31*%%str], m15 +%else ; !avx2 + TRANSPOSE8x8W 6, 0, 15, 14, 1, 7, 5, 4, 8 + mova [tmpq+ 0*%%str], m6 + mova [tmpq+ 4*%%str], m0 + mova [tmpq+ 8*%%str], m15 + mova [tmpq+12*%%str], m14 + mova [tmpq+16*%%str], m1 + mova [tmpq+20*%%str], m7 + mova [tmpq+24*%%str], m5 + mova [tmpq+28*%%str], m4 + + mova m8, [tmpq+ 3*%%str] ; t15 + TRANSPOSE8x8W 10, 13, 3, 2, 11, 12, 9, 8, 0 + mova [tmpq+ 3*%%str], m10 + mova [tmpq+ 7*%%str], m13 + mova [tmpq+11*%%str], m3 + mova [tmpq+15*%%str], m2 + mova [tmpq+19*%%str], m11 + mova [tmpq+23*%%str], m12 + mova [tmpq+27*%%str], m9 + mova [tmpq+31*%%str], m8 + + mova m15, [tmpq+30*%%str] ; t8 + mova m14, [tmpq+26*%%str] ; t9 + mova m13, [tmpq+22*%%str] ; t10 + mova m12, [tmpq+18*%%str] ; t11 + mova m11, [tmpq+14*%%str] ; t12 + mova m10, [tmpq+10*%%str] ; t13 + mova m9, [tmpq+ 6*%%str] ; t14 + mova m8, [tmpq+ 2*%%str] ; t15 + mova m7, [tmpq+21*%%str] ; t16 + mova m6, [tmpq+29*%%str] ; t17 + mova m5, [tmpq+ 9*%%str] ; t18 + mova m4, [tmpq+13*%%str] ; t19 + mova m3, [tmpq+17*%%str] ; t20 + mova m2, [tmpq+ 1*%%str] ; t21 + mova m1, [tmpq+25*%%str] ; t22 + + SUMSUB_BA w, 7, 8, 0 + mova [tmpq+ 2*%%str], m8 + mova m0, [tmpq+ 5*%%str] ; t23 + SUMSUB_BA w, 6, 9, 8 + SUMSUB_BA w, 5, 10, 8 + SUMSUB_BA w, 4, 11, 8 + SUMSUB_BA w, 3, 12, 8 + SUMSUB_BA w, 2, 13, 8 + SUMSUB_BA w, 1, 14, 8 + SUMSUB_BA w, 0, 15, 8 + + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8 + mova [tmpq+ 1*%%str], m0 + mova [tmpq+ 5*%%str], m1 + mova [tmpq+ 9*%%str], m2 + mova [tmpq+13*%%str], m3 + mova [tmpq+17*%%str], m4 + mova [tmpq+21*%%str], m5 + mova [tmpq+25*%%str], m6 + mova [tmpq+29*%%str], m7 + + mova m8, [tmpq+ 2*%%str] + TRANSPOSE8x8W 8, 9, 10, 11, 12, 13, 14, 15, 0 + mova [tmpq+ 2*%%str], m8 + mova [tmpq+ 6*%%str], m9 + mova [tmpq+10*%%str], m10 + mova [tmpq+14*%%str], m11 + mova [tmpq+18*%%str], m12 + mova [tmpq+22*%%str], m13 + mova [tmpq+26*%%str], m14 + mova [tmpq+30*%%str], m15 +%endif ; avx2 +%else + mova m2, [tmpq+24*%%str] ; t6 + mova m3, [tmpq+28*%%str] ; t7 + SUMSUB_BADC w, 5, 2, 4, 3 + mova [tmpq+24*%%str], m5 + mova [tmpq+23*%%str], m2 + mova [tmpq+28*%%str], m4 + mova [tmpq+19*%%str], m3 + + mova m2, [tmpq+16*%%str] ; t4 + mova m3, [tmpq+20*%%str] ; t5 + SUMSUB_BA w, 1, 2, 5 + SUMSUB_BA w, 7, 3, 5 + mova [tmpq+15*%%str], m2 + mova [tmpq+11*%%str], m3 + + mova m2, [tmpq+ 0*%%str] ; t0 + mova m3, [tmpq+ 4*%%str] ; t1 + SUMSUB_BA w, 6, 2, 5 + SUMSUB_BA w, 0, 3, 5 + mova [tmpq+31*%%str], m2 + mova [tmpq+27*%%str], m3 + + mova m2, [tmpq+ 8*%%str] ; t2 + mova m3, [tmpq+12*%%str] ; t3 + mova m5, [tmpq+ 7*%%str] + mova m4, [tmpq+ 3*%%str] + SUMSUB_BADC w, 5, 2, 4, 3 + mova [tmpq+ 7*%%str], m2 + mova [tmpq+ 3*%%str], m3 + + mova m3, [tmpq+28*%%str] + TRANSPOSE8x8W 6, 0, 5, 4, 1, 7, 2, 3, [tmpq+24*%%str], [tmpq+16*%%str], 1 + mova [tmpq+ 0*%%str], m6 + mova [tmpq+ 4*%%str], m0 + mova [tmpq+ 8*%%str], m5 + mova [tmpq+12*%%str], m4 + mova [tmpq+20*%%str], m7 + mova [tmpq+24*%%str], m2 + mova [tmpq+28*%%str], m3 + + mova m6, [tmpq+19*%%str] + mova m0, [tmpq+23*%%str] + mova m5, [tmpq+11*%%str] + mova m4, [tmpq+15*%%str] + mova m1, [tmpq+ 3*%%str] + mova m7, [tmpq+ 7*%%str] + mova m3, [tmpq+31*%%str] + TRANSPOSE8x8W 6, 0, 5, 4, 1, 7, 2, 3, [tmpq+27*%%str], [tmpq+19*%%str], 1 + mova [tmpq+ 3*%%str], m6 + mova [tmpq+ 7*%%str], m0 + mova [tmpq+11*%%str], m5 + mova [tmpq+15*%%str], m4 + mova [tmpq+23*%%str], m7 + mova [tmpq+27*%%str], m2 + mova [tmpq+31*%%str], m3 + + mova m1, [tmpq+ 6*%%str] ; t14 + mova m0, [tmpq+ 2*%%str] ; t15 + mova m7, [tmpq+21*%%str] ; t16 + mova m6, [tmpq+29*%%str] ; t17 + SUMSUB_BA w, 7, 0, 2 + SUMSUB_BA w, 6, 1, 2 + mova [tmpq+29*%%str], m7 + mova [tmpq+ 2*%%str], m0 + mova [tmpq+21*%%str], m6 + mova [tmpq+ 6*%%str], m1 + + mova m1, [tmpq+14*%%str] ; t12 + mova m0, [tmpq+10*%%str] ; t13 + mova m5, [tmpq+ 9*%%str] ; t18 + mova m4, [tmpq+13*%%str] ; t19 + SUMSUB_BA w, 5, 0, 2 + SUMSUB_BA w, 4, 1, 2 + mova [tmpq+10*%%str], m0 + mova [tmpq+14*%%str], m1 + + mova m1, [tmpq+22*%%str] ; t10 + mova m0, [tmpq+18*%%str] ; t11 + mova m3, [tmpq+17*%%str] ; t20 + mova m2, [tmpq+ 1*%%str] ; t21 + SUMSUB_BA w, 3, 0, 6 + SUMSUB_BA w, 2, 1, 6 + mova [tmpq+18*%%str], m0 + mova [tmpq+22*%%str], m1 + + mova m7, [tmpq+30*%%str] ; t8 + mova m6, [tmpq+26*%%str] ; t9 + mova m1, [tmpq+25*%%str] ; t22 + mova m0, [tmpq+ 5*%%str] ; t23 + SUMSUB_BADC w, 1, 6, 0, 7 + mova [tmpq+26*%%str], m6 + mova [tmpq+30*%%str], m7 + + mova m7, [tmpq+29*%%str] + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [tmpq+21*%%str], [tmpq+17*%%str], 1 + mova [tmpq+ 1*%%str], m0 + mova [tmpq+ 5*%%str], m1 + mova [tmpq+ 9*%%str], m2 + mova [tmpq+13*%%str], m3 + mova [tmpq+21*%%str], m5 + mova [tmpq+25*%%str], m6 + mova [tmpq+29*%%str], m7 + + mova m0, [tmpq+ 2*%%str] + mova m1, [tmpq+ 6*%%str] + mova m2, [tmpq+10*%%str] + mova m3, [tmpq+14*%%str] + mova m4, [tmpq+18*%%str] + mova m5, [tmpq+22*%%str] + mova m7, [tmpq+30*%%str] + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [tmpq+26*%%str], [tmpq+18*%%str], 1 + mova [tmpq+ 2*%%str], m0 + mova [tmpq+ 6*%%str], m1 + mova [tmpq+10*%%str], m2 + mova [tmpq+14*%%str], m3 + mova [tmpq+22*%%str], m5 + mova [tmpq+26*%%str], m6 + mova [tmpq+30*%%str], m7 +%endif +%else + ; t0-7 is in [tmpq+{0,4,8,12,16,20,24,28}*%%str] + ; t8-15 is in [tmpq+{2,6,10,14,18,22,26,30}*%%str] + ; t16-19 and t23 is in [tmpq+{1,5,9,13,29}*%%str] + ; t20-22 is in m4-6 + ; t24-31 is in m8-15 + +%if cpuflag(ssse3) +%define ROUND_REG [pw_512] +%else +%define ROUND_REG [pw_32] +%endif + +%macro %%STORE_2X2 7-8 1 ; src[1-4], tmp[1-2], zero, inc_dst_ptrs + SUMSUB_BA w, %4, %1, %5 + SUMSUB_BA w, %3, %2, %5 + VP9_IDCT8_WRITEx2 %4, %3, %5, %6, %7, ROUND_REG, 6 +%if %8 == 1 + add dstq, stride2q +%endif + VP9_IDCT8_WRITEx2 %2, %1, %5, %6, %7, ROUND_REG, 6, dst_endq +%if %8 == 1 + sub dst_endq, stride2q +%endif +%endmacro + +%if ARCH_X86_64 + pxor m10, m10 + + ; store t0-1 and t30-31 + mova m8, [tmpq+ 0*%%str] + mova m9, [tmpq+ 4*%%str] + %%STORE_2X2 8, 9, 0, 6, 12, 11, 10 + + ; store t2-3 and t28-29 + mova m8, [tmpq+ 8*%%str] + mova m9, [tmpq+12*%%str] + %%STORE_2X2 8, 9, 14, 15, 12, 11, 10 + + ; store t4-5 and t26-27 + mova m8, [tmpq+16*%%str] + mova m9, [tmpq+20*%%str] + %%STORE_2X2 8, 9, 7, 1, 12, 11, 10 + + ; store t6-7 and t24-25 + mova m8, [tmpq+24*%%str] + mova m9, [tmpq+28*%%str] + %%STORE_2X2 8, 9, 4, 5, 12, 11, 10 + + ; store t8-9 and t22-23 + mova m8, [tmpq+30*%%str] + mova m9, [tmpq+26*%%str] + mova m0, [tmpq+ 5*%%str] + %%STORE_2X2 8, 9, 13, 0, 12, 11, 10 + + ; store t10-11 and t20-21 + mova m8, [tmpq+22*%%str] + mova m9, [tmpq+18*%%str] + %%STORE_2X2 8, 9, 2, 3, 12, 11, 10 + + ; store t12-13 and t18-19 + mova m8, [tmpq+14*%%str] + mova m9, [tmpq+10*%%str] + mova m5, [tmpq+13*%%str] + mova m4, [tmpq+ 9*%%str] + %%STORE_2X2 8, 9, 4, 5, 12, 11, 10 + + ; store t14-17 + mova m8, [tmpq+ 6*%%str] + mova m9, [tmpq+ 2*%%str] + mova m5, [tmpq+29*%%str] + mova m4, [tmpq+21*%%str] + %%STORE_2X2 8, 9, 4, 5, 12, 11, 10, 0 + + SWAP 1, 10 ; zero +%else + mova [tmpq+ 1*%%str], m1 + mova [tmpq+11*%%str], m2 + mova [tmpq+15*%%str], m3 + mova [tmpq+17*%%str], m4 + mova [tmpq+19*%%str], m5 + pxor m1, m1 + + ; store t0-1 and t30-31 + mova m2, [tmpq+ 0*%%str] + mova m3, [tmpq+ 4*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1 + + ; store t2-3 and t28-29 + mova m2, [tmpq+ 8*%%str] + mova m3, [tmpq+12*%%str] + mova m0, [tmpq+ 3*%%str] + mova m6, [tmpq+ 7*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1 + + ; store t4-5 and t26-27 + mova m2, [tmpq+16*%%str] + mova m3, [tmpq+20*%%str] + mova m0, [tmpq+ 1*%%str] + %%STORE_2X2 2, 3, 7, 0, 4, 5, 1 + + ; store t6-7 and t24-25 + mova m2, [tmpq+24*%%str] + mova m3, [tmpq+28*%%str] + mova m0, [tmpq+17*%%str] + mova m6, [tmpq+19*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1 + + ; store t8-9 and t22-23 + mova m2, [tmpq+30*%%str] + mova m3, [tmpq+26*%%str] + mova m0, [tmpq+25*%%str] + mova m6, [tmpq+ 5*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1 + + ; store t10-11 and t20-21 + mova m2, [tmpq+22*%%str] + mova m3, [tmpq+18*%%str] + mova m0, [tmpq+11*%%str] + mova m6, [tmpq+15*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1 + + ; store t12-13 and t18-19 + mova m2, [tmpq+14*%%str] + mova m3, [tmpq+10*%%str] + mova m6, [tmpq+13*%%str] + mova m0, [tmpq+ 9*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1 + + ; store t14-17 + mova m2, [tmpq+ 6*%%str] + mova m3, [tmpq+ 2*%%str] + mova m6, [tmpq+29*%%str] + mova m0, [tmpq+21*%%str] + %%STORE_2X2 2, 3, 0, 6, 4, 5, 1, 0 +%endif +%undef ROUND_REG +%endif +%endmacro + +%macro VP9_IDCT_IDCT_32x32_ADD_XMM 1 +INIT_XMM %1 +cglobal vp9_idct_idct_32x32_add, 0, 6 + ARCH_X86_64 * 3, 16, 2048, dst, stride, block, eob + movifnidn eobd, dword eobm +%if cpuflag(ssse3) + cmp eobd, 135 + jg .idctfull + cmp eobd, 34 + jg .idct16x16 + cmp eobd, 1 + jg .idct8x8 +%else + cmp eobd, 1 + jg .idctfull +%endif + + ; dc-only case + movifnidn blockq, blockmp + movifnidn dstq, dstmp + movifnidn strideq, stridemp +%if cpuflag(ssse3) + movd m0, [blockq] + mova m1, [pw_11585x2] + pmulhrsw m0, m1 + pmulhrsw m0, m1 +%else + DEFINE_ARGS dst, stride, block, coef + movsx coefd, word [blockq] + imul coefd, 11585 + add coefd, 8192 + sar coefd, 14 + imul coefd, 11585 + add coefd, (32 << 14) + 8192 + sar coefd, 14 + 6 + movd m0, coefd +%endif + SPLATW m0, m0, q0000 +%if cpuflag(ssse3) + pmulhrsw m0, [pw_512] +%endif + pxor m5, m5 + movd [blockq], m5 +%rep 31 + VP9_STORE_2XFULL 0, 1, 2, 3, 4, 5, mmsize + add dstq, strideq +%endrep + VP9_STORE_2XFULL 0, 1, 2, 3, 4, 5, mmsize + RET + +%if ARCH_X86_64 + DEFINE_ARGS dst_bak, stride, block, cnt, dst, stride30, dst_end, stride2, tmp +%else +%define dst_bakq r0mp +%endif +%if cpuflag(ssse3) +.idct8x8: +%if ARCH_X86_32 + DEFINE_ARGS block, u1, u2, u3, u4, tmp + mov blockq, r2mp +%endif + mov tmpq, rsp + VP9_IDCT32_1D blockq, 1, 8 + +%if ARCH_X86_32 + DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp + mov strideq, r1mp +%define cntd dword r3m +%endif + mov stride30q, strideq ; stride + lea stride2q, [strideq*2] ; stride*2 + shl stride30q, 5 ; stride*32 + mov cntd, 4 + sub stride30q, stride2q ; stride*30 +.loop2_8x8: + mov dstq, dst_bakq + lea dst_endq, [dstq+stride30q] + VP9_IDCT32_1D tmpq, 2, 8 + add dst_bakq, 8 + add tmpq, 16 + dec cntd + jg .loop2_8x8 + + ; at the end of the loop, m7 should still be zero + ; use that to zero out block coefficients +%if ARCH_X86_32 + DEFINE_ARGS block + mov blockq, r2mp +%endif + ZERO_BLOCK blockq, 64, 8, m1 + RET + +.idct16x16: +%if ARCH_X86_32 + DEFINE_ARGS block, tmp, cnt + mov blockq, r2mp +%endif + mov cntd, 2 + mov tmpq, rsp +.loop1_16x16: + VP9_IDCT32_1D blockq, 1, 16 + add blockq, 16 + add tmpq, 512 + dec cntd + jg .loop1_16x16 + +%if ARCH_X86_64 + sub blockq, 32 +%else + DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp + mov strideq, r1mp +%define cntd dword r3m +%endif + + mov stride30q, strideq ; stride + lea stride2q, [strideq*2] ; stride*2 + shl stride30q, 5 ; stride*32 + mov cntd, 4 + mov tmpq, rsp + sub stride30q, stride2q ; stride*30 +.loop2_16x16: + mov dstq, dst_bakq + lea dst_endq, [dstq+stride30q] + VP9_IDCT32_1D tmpq, 2, 16 + add dst_bakq, 8 + add tmpq, 16 + dec cntd + jg .loop2_16x16 + + ; at the end of the loop, m7 should still be zero + ; use that to zero out block coefficients +%if ARCH_X86_32 + DEFINE_ARGS block + mov blockq, r2mp +%endif + ZERO_BLOCK blockq, 64, 16, m1 + RET +%endif + +.idctfull: +%if ARCH_X86_32 + DEFINE_ARGS block, tmp, cnt + mov blockq, r2mp +%endif + mov cntd, 4 + mov tmpq, rsp +.loop1_full: + VP9_IDCT32_1D blockq, 1 + add blockq, 16 + add tmpq, 512 + dec cntd + jg .loop1_full + +%if ARCH_X86_64 + sub blockq, 64 +%else + DEFINE_ARGS dst, stride, stride30, dst_end, stride2, tmp + mov strideq, r1mp +%define cntd dword r3m +%endif + + mov stride30q, strideq ; stride + lea stride2q, [strideq*2] ; stride*2 + shl stride30q, 5 ; stride*32 + mov cntd, 4 + mov tmpq, rsp + sub stride30q, stride2q ; stride*30 +.loop2_full: + mov dstq, dst_bakq + lea dst_endq, [dstq+stride30q] + VP9_IDCT32_1D tmpq, 2 + add dst_bakq, 8 + add tmpq, 16 + dec cntd + jg .loop2_full + + ; at the end of the loop, m7 should still be zero + ; use that to zero out block coefficients +%if ARCH_X86_32 + DEFINE_ARGS block + mov blockq, r2mp +%endif + ZERO_BLOCK blockq, 64, 32, m1 + RET +%endmacro + +VP9_IDCT_IDCT_32x32_ADD_XMM sse2 +VP9_IDCT_IDCT_32x32_ADD_XMM ssse3 +VP9_IDCT_IDCT_32x32_ADD_XMM avx + +; this is almost identical to VP9_STORE_2X, but it does two rows +; for slightly improved interleaving, and it omits vpermq since the +; input is DC so all values are identical +%macro VP9_STORE_YMM_DC_2X2 6 ; reg, tmp1, tmp2, tmp3, tmp4, zero + mova m%2, [dstq] + mova m%4, [dstq+strideq] + punpckhbw m%3, m%2, m%6 + punpcklbw m%2, m%6 + punpckhbw m%5, m%4, m%6 + punpcklbw m%4, m%6 + paddw m%3, m%1 + paddw m%2, m%1 + paddw m%5, m%1 + paddw m%4, m%1 + packuswb m%2, m%3 + packuswb m%4, m%5 + mova [dstq+strideq*0], m%2 + mova [dstq+strideq*1], m%4 +%endmacro + +%if ARCH_X86_64 && HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +cglobal vp9_idct_idct_32x32_add, 4, 9, 16, 2048, dst, stride, block, eob + cmp eobd, 135 + jg .idctfull + cmp eobd, 1 + jg .idct16x16 + + ; dc-only case + mova m1, [pw_11585x2] + vpbroadcastw m0, [blockq] + pmulhrsw m0, m1 + pmulhrsw m0, m1 + pxor m5, m5 + pmulhrsw m0, [pw_512] + movd [blockq], xm5 + + DEFINE_ARGS dst, stride, cnt + mov cntd, 16 +.loop_dc: + VP9_STORE_YMM_DC_2X2 0, 1, 2, 3, 4, 5 + lea dstq, [dstq+2*strideq] + dec cntd + jg .loop_dc + RET + + DEFINE_ARGS dst_bak, stride, block, cnt, dst, stride30, dst_end, stride2, tmp +.idct16x16: + mov tmpq, rsp + VP9_IDCT32_1D blockq, 1, 16 + + mov stride30q, strideq ; stride + lea stride2q, [strideq*2] ; stride*2 + shl stride30q, 5 ; stride*32 + mov cntd, 2 + sub stride30q, stride2q ; stride*30 +.loop2_16x16: + mov dstq, dst_bakq + lea dst_endq, [dstq+stride30q] + VP9_IDCT32_1D tmpq, 2, 16 + add dst_bakq, 16 + add tmpq, 32 + dec cntd + jg .loop2_16x16 + + ; at the end of the loop, m1 should still be zero + ; use that to zero out block coefficients + ZERO_BLOCK blockq, 64, 16, m1 + RET + +.idctfull: + mov cntd, 2 + mov tmpq, rsp +.loop1_full: + VP9_IDCT32_1D blockq, 1 + add blockq, 32 + add tmpq, 1024 + dec cntd + jg .loop1_full + + sub blockq, 64 + + mov stride30q, strideq ; stride + lea stride2q, [strideq*2] ; stride*2 + shl stride30q, 5 ; stride*32 + mov cntd, 2 + mov tmpq, rsp + sub stride30q, stride2q ; stride*30 +.loop2_full: + mov dstq, dst_bakq + lea dst_endq, [dstq+stride30q] + VP9_IDCT32_1D tmpq, 2 + add dst_bakq, 16 + add tmpq, 32 + dec cntd + jg .loop2_full + + ; at the end of the loop, m1 should still be zero + ; use that to zero out block coefficients + ZERO_BLOCK blockq, 64, 32, m1 + RET +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm_16bpp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm_16bpp.asm new file mode 100644 index 00000000..902685ed --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm_16bpp.asm @@ -0,0 +1,2044 @@ +;****************************************************************************** +;* VP9 inverse transform x86 SIMD optimizations +;* +;* Copyright (C) 2015 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" +%include "vp9itxfm_template.asm" + +SECTION_RODATA + +cextern pw_8 +cextern pw_1023 +cextern pw_2048 +cextern pw_4095 +cextern pw_m1 +cextern pd_1 +cextern pd_16 +cextern pd_32 +cextern pd_8192 + +pd_8: times 4 dd 8 +pd_3fff: times 4 dd 0x3fff + +cextern pw_11585x2 + +cextern pw_5283_13377 +cextern pw_9929_13377 +cextern pw_15212_m13377 +cextern pw_15212_9929 +cextern pw_m5283_m15212 +cextern pw_13377x2 +cextern pw_m13377_13377 +cextern pw_13377_0 + +pw_9929_m5283: times 4 dw 9929, -5283 + +%macro COEF_PAIR 2-3 +cextern pw_m%1_%2 +cextern pw_%2_%1 +%if %0 == 3 +cextern pw_m%1_m%2 +%if %1 != %2 +cextern pw_m%2_%1 +cextern pw_%1_%2 +%endif +%endif +%endmacro + +COEF_PAIR 2404, 16207 +COEF_PAIR 3196, 16069, 1 +COEF_PAIR 4756, 15679 +COEF_PAIR 5520, 15426 +COEF_PAIR 6270, 15137, 1 +COEF_PAIR 8423, 14053 +COEF_PAIR 10394, 12665 +COEF_PAIR 11003, 12140 +COEF_PAIR 11585, 11585, 1 +COEF_PAIR 13160, 9760 +COEF_PAIR 13623, 9102, 1 +COEF_PAIR 14449, 7723 +COEF_PAIR 14811, 7005 +COEF_PAIR 15893, 3981 +COEF_PAIR 16305, 1606 +COEF_PAIR 16364, 804 + +default_8x8: +times 12 db 1 +times 52 db 2 +row_8x8: +times 18 db 1 +times 46 db 2 +col_8x8: +times 6 db 1 +times 58 db 2 +default_16x16: +times 10 db 1 +times 28 db 2 +times 51 db 3 +times 167 db 4 +row_16x16: +times 21 db 1 +times 45 db 2 +times 60 db 3 +times 130 db 4 +col_16x16: +times 5 db 1 +times 12 db 2 +times 25 db 3 +times 214 db 4 +default_32x32: +times 9 db 1 +times 25 db 2 +times 36 db 3 +times 65 db 4 +times 105 db 5 +times 96 db 6 +times 112 db 7 +times 576 db 8 + +SECTION .text + +%macro VP9_STORE_2X 6-7 dstq ; reg1, reg2, tmp1, tmp2, min, max, dst + mova m%3, [%7] + mova m%4, [%7+strideq] + paddw m%3, m%1 + paddw m%4, m%2 + pmaxsw m%3, m%5 + pmaxsw m%4, m%5 + pminsw m%3, m%6 + pminsw m%4, m%6 + mova [%7], m%3 + mova [%7+strideq], m%4 +%endmacro + +%macro ZERO_BLOCK 4 ; mem, stride, nnzcpl, zero_reg +%assign %%y 0 +%rep %3 +%assign %%x 0 +%rep %3*4/mmsize + mova [%1+%%y+%%x], %4 +%assign %%x (%%x+mmsize) +%endrep +%assign %%y (%%y+%2) +%endrep +%endmacro + +; the input coefficients are scaled up by 2 bit (which we downscale immediately +; in the iwht), and is otherwise orthonormally increased by 1 bit per iwht_1d. +; therefore, a diff of 10-12+sign bit will fit in 12-14+sign bit after scaling, +; i.e. everything can be done in 15+1bpp words. Since the quant fractional bits +; add 2 bits, we need to scale before converting to word in 12bpp, since the +; input will be 16+sign bit which doesn't fit in 15+sign words, but in 10bpp +; we can scale after converting to words (which is half the instructions), +; since the input is only 14+sign bit, which fits in 15+sign words directly. + +%macro IWHT4_FN 2 ; bpp, max +cglobal vp9_iwht_iwht_4x4_add_%1, 3, 3, 8, dst, stride, block, eob + mova m7, [pw_%2] + mova m0, [blockq+0*16+0] + mova m1, [blockq+1*16+0] +%if %1 >= 12 + mova m4, [blockq+0*16+8] + mova m5, [blockq+1*16+8] + psrad m0, 2 + psrad m1, 2 + psrad m4, 2 + psrad m5, 2 + packssdw m0, m4 + packssdw m1, m5 +%else + packssdw m0, [blockq+0*16+8] + packssdw m1, [blockq+1*16+8] + psraw m0, 2 + psraw m1, 2 +%endif + mova m2, [blockq+2*16+0] + mova m3, [blockq+3*16+0] +%if %1 >= 12 + mova m4, [blockq+2*16+8] + mova m5, [blockq+3*16+8] + psrad m2, 2 + psrad m3, 2 + psrad m4, 2 + psrad m5, 2 + packssdw m2, m4 + packssdw m3, m5 +%else + packssdw m2, [blockq+2*16+8] + packssdw m3, [blockq+3*16+8] + psraw m2, 2 + psraw m3, 2 +%endif + + VP9_IWHT4_1D + TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP9_IWHT4_1D + + pxor m6, m6 + VP9_STORE_2X 0, 1, 4, 5, 6, 7 + lea dstq, [dstq+strideq*2] + VP9_STORE_2X 2, 3, 4, 5, 6, 7 + ZERO_BLOCK blockq, 16, 4, m6 + RET +%endmacro + +INIT_MMX mmxext +IWHT4_FN 10, 1023 +INIT_MMX mmxext +IWHT4_FN 12, 4095 + +%macro VP9_IDCT4_WRITEOUT 0 +%if cpuflag(ssse3) + mova m5, [pw_2048] + pmulhrsw m0, m5 + pmulhrsw m1, m5 + pmulhrsw m2, m5 + pmulhrsw m3, m5 +%else + mova m5, [pw_8] + paddw m0, m5 + paddw m1, m5 + paddw m2, m5 + paddw m3, m5 + psraw m0, 4 + psraw m1, 4 + psraw m2, 4 + psraw m3, 4 +%endif + mova m5, [pw_1023] + VP9_STORE_2X 0, 1, 6, 7, 4, 5 + lea dstq, [dstq+2*strideq] + VP9_STORE_2X 2, 3, 6, 7, 4, 5 +%endmacro + +%macro DC_ONLY 2 ; shift, zero + mov coefd, dword [blockq] + movd [blockq], %2 + imul coefd, 11585 + add coefd, 8192 + sar coefd, 14 + imul coefd, 11585 + add coefd, ((1 << (%1 - 1)) << 14) + 8192 + sar coefd, 14 + %1 +%endmacro + +; 4x4 coefficients are 5+depth+sign bits, so for 10bpp, everything still fits +; in 15+1 words without additional effort, since the coefficients are 15bpp. + +%macro IDCT4_10_FN 0 +cglobal vp9_idct_idct_4x4_add_10, 4, 4, 8, dst, stride, block, eob + cmp eobd, 1 + jg .idctfull + + ; dc-only + pxor m4, m4 +%if cpuflag(ssse3) + movd m0, [blockq] + movd [blockq], m4 + mova m5, [pw_11585x2] + pmulhrsw m0, m5 + pmulhrsw m0, m5 +%else + DEFINE_ARGS dst, stride, block, coef + DC_ONLY 4, m4 + movd m0, coefd +%endif + pshufw m0, m0, 0 + mova m5, [pw_1023] +%if cpuflag(ssse3) + pmulhrsw m0, [pw_2048] ; (x*2048 + (1<<14))>>15 <=> (x+8)>>4 +%endif + VP9_STORE_2X 0, 0, 6, 7, 4, 5 + lea dstq, [dstq+2*strideq] + VP9_STORE_2X 0, 0, 6, 7, 4, 5 + RET + +.idctfull: + mova m0, [blockq+0*16+0] + mova m1, [blockq+1*16+0] + packssdw m0, [blockq+0*16+8] + packssdw m1, [blockq+1*16+8] + mova m2, [blockq+2*16+0] + mova m3, [blockq+3*16+0] + packssdw m2, [blockq+2*16+8] + packssdw m3, [blockq+3*16+8] + +%if cpuflag(ssse3) + mova m6, [pw_11585x2] +%endif + mova m7, [pd_8192] ; rounding + VP9_IDCT4_1D + TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP9_IDCT4_1D + + pxor m4, m4 + ZERO_BLOCK blockq, 16, 4, m4 + VP9_IDCT4_WRITEOUT + RET +%endmacro + +INIT_MMX mmxext +IDCT4_10_FN +INIT_MMX ssse3 +IDCT4_10_FN + +%macro IADST4_FN 4 +cglobal vp9_%1_%3_4x4_add_10, 3, 3, 0, dst, stride, block, eob +%if WIN64 && notcpuflag(ssse3) + WIN64_SPILL_XMM 8 +%endif + movdqa xmm5, [pd_8192] + mova m0, [blockq+0*16+0] + mova m1, [blockq+1*16+0] + packssdw m0, [blockq+0*16+8] + packssdw m1, [blockq+1*16+8] + mova m2, [blockq+2*16+0] + mova m3, [blockq+3*16+0] + packssdw m2, [blockq+2*16+8] + packssdw m3, [blockq+3*16+8] + +%if cpuflag(ssse3) + mova m6, [pw_11585x2] +%endif +%ifnidn %1%3, iadstiadst + movdq2q m7, xmm5 +%endif + VP9_%2_1D + TRANSPOSE4x4W 0, 1, 2, 3, 4 + VP9_%4_1D + + pxor m4, m4 + ZERO_BLOCK blockq, 16, 4, m4 + VP9_IDCT4_WRITEOUT + RET +%endmacro + +INIT_MMX sse2 +IADST4_FN idct, IDCT4, iadst, IADST4 +IADST4_FN iadst, IADST4, idct, IDCT4 +IADST4_FN iadst, IADST4, iadst, IADST4 + +INIT_MMX ssse3 +IADST4_FN idct, IDCT4, iadst, IADST4 +IADST4_FN iadst, IADST4, idct, IDCT4 +IADST4_FN iadst, IADST4, iadst, IADST4 + +; inputs and outputs are dwords, coefficients are words +; +; dst1 = src1 * coef1 + src2 * coef2 + rnd >> 14 +; dst2 = src1 * coef2 - src2 * coef1 + rnd >> 14 +%macro SUMSUB_MUL 6-8 [pd_8192], [pd_3fff] ; src/dst 1-2, tmp1-2, coef1-2, rnd, mask + pand m%3, m%1, %8 + pand m%4, m%2, %8 + psrad m%1, 14 + psrad m%2, 14 + packssdw m%4, m%2 + packssdw m%3, m%1 + punpckhwd m%2, m%4, m%3 + punpcklwd m%4, m%3 + pmaddwd m%3, m%4, [pw_%6_%5] + pmaddwd m%1, m%2, [pw_%6_%5] + pmaddwd m%4, [pw_m%5_%6] + pmaddwd m%2, [pw_m%5_%6] + paddd m%3, %7 + paddd m%4, %7 + psrad m%3, 14 + psrad m%4, 14 + paddd m%1, m%3 + paddd m%2, m%4 +%endmacro + +%macro IDCT4_12BPP_1D 0-8 [pd_8192], [pd_3fff], 0, 1, 2, 3, 4, 5 ; rnd, mask, in/out0-3, tmp0-1 + SUMSUB_MUL %3, %5, %7, %8, 11585, 11585, %1, %2 + SUMSUB_MUL %4, %6, %7, %8, 15137, 6270, %1, %2 + SUMSUB_BA d, %4, %3, %7 + SUMSUB_BA d, %6, %5, %7 + SWAP %4, %6, %3 +%endmacro + +%macro STORE_4x4 6 ; tmp1-2, reg1-2, min, max + movh m%1, [dstq+strideq*0] + movh m%2, [dstq+strideq*2] + movhps m%1, [dstq+strideq*1] + movhps m%2, [dstq+stride3q ] + paddw m%1, m%3 + paddw m%2, m%4 + pmaxsw m%1, %5 + pmaxsw m%2, %5 + pminsw m%1, %6 + pminsw m%2, %6 + movh [dstq+strideq*0], m%1 + movhps [dstq+strideq*1], m%1 + movh [dstq+strideq*2], m%2 + movhps [dstq+stride3q ], m%2 +%endmacro + +%macro ROUND_AND_STORE_4x4 8 ; reg1-4, min, max, rnd, shift + paddd m%1, %7 + paddd m%2, %7 + paddd m%3, %7 + paddd m%4, %7 + psrad m%1, %8 + psrad m%2, %8 + psrad m%3, %8 + psrad m%4, %8 + packssdw m%1, m%2 + packssdw m%3, m%4 + STORE_4x4 %2, %4, %1, %3, %5, %6 +%endmacro + +INIT_XMM sse2 +cglobal vp9_idct_idct_4x4_add_12, 4, 4, 8, dst, stride, block, eob + cmp eobd, 1 + jg .idctfull + + ; dc-only - this is special, since for 4x4 12bpp, the max coef size is + ; 17+sign bpp. Since the multiply is with 11585, which is 14bpp, the + ; result of each multiply is 31+sign bit, i.e. it _exactly_ fits in a + ; dword. After the final shift (4), the result is 13+sign bits, so we + ; don't need any additional processing to fit it in a word + DEFINE_ARGS dst, stride, block, coef + pxor m4, m4 + DC_ONLY 4, m4 + movd m0, coefd + pshuflw m0, m0, q0000 + punpcklqdq m0, m0 + mova m5, [pw_4095] + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + STORE_4x4 1, 3, 0, 0, m4, m5 + RET + +.idctfull: + DEFINE_ARGS dst, stride, block, eob + mova m0, [blockq+0*16] + mova m1, [blockq+1*16] + mova m2, [blockq+2*16] + mova m3, [blockq+3*16] + mova m6, [pd_8192] + mova m7, [pd_3fff] + + IDCT4_12BPP_1D m6, m7 + TRANSPOSE4x4D 0, 1, 2, 3, 4 + IDCT4_12BPP_1D m6, m7 + + pxor m4, m4 + ZERO_BLOCK blockq, 16, 4, m4 + + ; writeout + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + mova m5, [pw_4095] + mova m6, [pd_8] + ROUND_AND_STORE_4x4 0, 1, 2, 3, m4, m5, m6, 4 + RET + +%macro SCRATCH 3-4 +%if ARCH_X86_64 + SWAP %1, %2 +%if %0 == 4 +%define reg_%4 m%2 +%endif +%else + mova [%3], m%1 +%if %0 == 4 +%define reg_%4 [%3] +%endif +%endif +%endmacro + +%macro UNSCRATCH 3-4 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova m%1, [%3] +%endif +%if %0 == 4 +%undef reg_%4 +%endif +%endmacro + +%macro PRELOAD 2-3 +%if ARCH_X86_64 + mova m%1, [%2] +%if %0 == 3 +%define reg_%3 m%1 +%endif +%elif %0 == 3 +%define reg_%3 [%2] +%endif +%endmacro + +; out0 = 5283 * in0 + 13377 + in1 + 15212 * in2 + 9929 * in3 + rnd >> 14 +; out1 = 9929 * in0 + 13377 * in1 - 5283 * in2 - 15282 * in3 + rnd >> 14 +; out2 = 13377 * in0 - 13377 * in2 + 13377 * in3 + rnd >> 14 +; out3 = 15212 * in0 - 13377 * in1 + 9929 * in2 - 5283 * in3 + rnd >> 14 +%macro IADST4_12BPP_1D 0-2 [pd_8192], [pd_3fff] ; rnd, mask + pand m4, m0, %2 + pand m5, m1, %2 + psrad m0, 14 + psrad m1, 14 + packssdw m5, m1 + packssdw m4, m0 + punpckhwd m1, m4, m5 + punpcklwd m4, m5 + pand m5, m2, %2 + pand m6, m3, %2 + psrad m2, 14 + psrad m3, 14 + packssdw m6, m3 + packssdw m5, m2 + punpckhwd m3, m5, m6 + punpcklwd m5, m6 + SCRATCH 1, 8, rsp+0*mmsize, a + SCRATCH 5, 9, rsp+1*mmsize, b + + ; m1/3 have the high bits of 0,1,2,3 + ; m4/5 have the low bits of 0,1,2,3 + ; m0/2/6/7 are free + + mova m2, [pw_15212_9929] + mova m0, [pw_5283_13377] + pmaddwd m7, m2, reg_b + pmaddwd m6, m4, m0 + pmaddwd m2, m3 + pmaddwd m0, reg_a + paddd m6, m7 + paddd m0, m2 + mova m1, [pw_m13377_13377] + mova m5, [pw_13377_0] + pmaddwd m7, m1, reg_b + pmaddwd m2, m4, m5 + pmaddwd m1, m3 + pmaddwd m5, reg_a + paddd m2, m7 + paddd m1, m5 + paddd m6, %1 + paddd m2, %1 + psrad m6, 14 + psrad m2, 14 + paddd m0, m6 ; t0 + paddd m2, m1 ; t2 + + mova m7, [pw_m5283_m15212] + mova m5, [pw_9929_13377] + pmaddwd m1, m7, reg_b + pmaddwd m6, m4, m5 + pmaddwd m7, m3 + pmaddwd m5, reg_a + paddd m6, m1 + paddd m7, m5 + UNSCRATCH 5, 9, rsp+1*mmsize, b + pmaddwd m5, [pw_9929_m5283] + pmaddwd m4, [pw_15212_m13377] + pmaddwd m3, [pw_9929_m5283] + UNSCRATCH 1, 8, rsp+0*mmsize, a + pmaddwd m1, [pw_15212_m13377] + paddd m4, m5 + paddd m3, m1 + paddd m6, %1 + paddd m4, %1 + psrad m6, 14 + psrad m4, 14 + paddd m7, m6 ; t1 + paddd m3, m4 ; t3 + + SWAP 1, 7 +%endmacro + +%macro IADST4_12BPP_FN 4 +cglobal vp9_%1_%3_4x4_add_12, 3, 3, 12, 2 * ARCH_X86_32 * mmsize, dst, stride, block, eob + mova m0, [blockq+0*16] + mova m1, [blockq+1*16] + mova m2, [blockq+2*16] + mova m3, [blockq+3*16] + + PRELOAD 10, pd_8192, rnd + PRELOAD 11, pd_3fff, mask + %2_12BPP_1D reg_rnd, reg_mask + TRANSPOSE4x4D 0, 1, 2, 3, 4 + %4_12BPP_1D reg_rnd, reg_mask + + pxor m4, m4 + ZERO_BLOCK blockq, 16, 4, m4 + + ; writeout + DEFINE_ARGS dst, stride, stride3 + lea stride3q, [strideq*3] + mova m5, [pw_4095] + mova m6, [pd_8] + ROUND_AND_STORE_4x4 0, 1, 2, 3, m4, m5, m6, 4 + RET +%endmacro + +INIT_XMM sse2 +IADST4_12BPP_FN idct, IDCT4, iadst, IADST4 +IADST4_12BPP_FN iadst, IADST4, idct, IDCT4 +IADST4_12BPP_FN iadst, IADST4, iadst, IADST4 + +; the following line has not been executed at the end of this macro: +; UNSCRATCH 6, 8, rsp+%3*mmsize +%macro IDCT8_1D 1-5 [pd_8192], [pd_3fff], 2 * mmsize, 17 ; src, rnd, mask, src_stride, stack_offset + mova m0, [%1+0*%4] + mova m2, [%1+2*%4] + mova m4, [%1+4*%4] + mova m6, [%1+6*%4] + IDCT4_12BPP_1D %2, %3, 0, 2, 4, 6, 1, 3 ; m0/2/4/6 have t0/1/2/3 + SCRATCH 4, 8, rsp+(%5+0)*mmsize + SCRATCH 6, 9, rsp+(%5+1)*mmsize + mova m1, [%1+1*%4] + mova m3, [%1+3*%4] + mova m5, [%1+5*%4] + mova m7, [%1+7*%4] + SUMSUB_MUL 1, 7, 4, 6, 16069, 3196, %2, %3 ; m1=t7a, m7=t4a + SUMSUB_MUL 5, 3, 4, 6, 9102, 13623, %2, %3 ; m5=t6a, m3=t5a + SUMSUB_BA d, 3, 7, 4 ; m3=t4, m7=t5a + SUMSUB_BA d, 5, 1, 4 ; m5=t7, m1=t6a + SUMSUB_MUL 1, 7, 4, 6, 11585, 11585, %2, %3 ; m1=t6, m7=t5 + SUMSUB_BA d, 5, 0, 4 ; m5=out0, m0=out7 + SUMSUB_BA d, 1, 2, 4 ; m1=out1, m2=out6 + UNSCRATCH 4, 8, rsp+(%5+0)*mmsize + UNSCRATCH 6, 9, rsp+(%5+1)*mmsize + SCRATCH 2, 8, rsp+(%5+0)*mmsize + SUMSUB_BA d, 7, 4, 2 ; m7=out2, m4=out5 + SUMSUB_BA d, 3, 6, 2 ; m3=out3, m6=out4 + SWAP 0, 5, 4, 6, 2, 7 +%endmacro + +%macro STORE_2x8 5-7 dstq, strideq ; tmp1-2, reg, min, max + mova m%1, [%6+%7*0] + mova m%2, [%6+%7*1] + paddw m%1, m%3 + paddw m%2, m%3 + pmaxsw m%1, %4 + pmaxsw m%2, %4 + pminsw m%1, %5 + pminsw m%2, %5 + mova [%6+%7*0], m%1 + mova [%6+%7*1], m%2 +%endmacro + +; FIXME we can use the intermediate storage (rsp[0-15]) on x86-32 for temp +; storage also instead of allocating two more stack spaces. This doesn't +; matter much but it's something... +INIT_XMM sse2 +cglobal vp9_idct_idct_8x8_add_10, 4, 6 + ARCH_X86_64, 14, \ + 16 * mmsize + 3 * ARCH_X86_32 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_1023] + cmp eobd, 1 + jg .idctfull + + ; dc-only - the 10bit version can be done entirely in 32bit, since the max + ; coef values are 16+sign bit, and the coef is 14bit, so 30+sign easily + ; fits in 32bit + DEFINE_ARGS dst, stride, block, coef + pxor m2, m2 + DC_ONLY 5, m2 + movd m1, coefd + pshuflw m1, m1, q0000 + punpcklqdq m1, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 4 +.loop_dc: + STORE_2x8 3, 4, 1, m2, m0 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop_dc + RET + +.idctfull: + SCRATCH 0, 12, rsp+16*mmsize, max + DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak +%if ARCH_X86_64 + mov dstbakq, dstq + movsxd cntq, cntd +%endif +%ifdef PIC + lea ptrq, [default_8x8] + movzx cntd, byte [ptrq+cntq-1] +%else + movzx cntd, byte [default_8x8+cntq-1] +%endif + mov skipd, 2 + sub skipd, cntd + mov ptrq, rsp + PRELOAD 10, pd_8192, rnd + PRELOAD 11, pd_3fff, mask + PRELOAD 13, pd_16, srnd +.loop_1: + IDCT8_1D blockq, reg_rnd, reg_mask + + TRANSPOSE4x4D 0, 1, 2, 3, 6 + mova [ptrq+ 0*mmsize], m0 + mova [ptrq+ 2*mmsize], m1 + mova [ptrq+ 4*mmsize], m2 + mova [ptrq+ 6*mmsize], m3 + UNSCRATCH 6, 8, rsp+17*mmsize + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 1*mmsize], m4 + mova [ptrq+ 3*mmsize], m5 + mova [ptrq+ 5*mmsize], m6 + mova [ptrq+ 7*mmsize], m7 + add ptrq, 8 * mmsize + add blockq, mmsize + dec cntd + jg .loop_1 + + ; zero-pad the remainder (skipped cols) + test skipd, skipd + jz .end + add skipd, skipd + lea blockq, [blockq+skipq*(mmsize/2)] + pxor m0, m0 +.loop_z: + mova [ptrq+mmsize*0], m0 + mova [ptrq+mmsize*1], m0 + mova [ptrq+mmsize*2], m0 + mova [ptrq+mmsize*3], m0 + add ptrq, 4 * mmsize + dec skipd + jg .loop_z +.end: + + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea stride3q, [strideq*3] + mov cntd, 2 + mov ptrq, rsp +.loop_2: + IDCT8_1D ptrq, reg_rnd, reg_mask + + pxor m6, m6 + ROUND_AND_STORE_4x4 0, 1, 2, 3, m6, reg_max, reg_srnd, 5 + lea dstq, [dstq+strideq*4] + UNSCRATCH 0, 8, rsp+17*mmsize + UNSCRATCH 1, 12, rsp+16*mmsize, max + UNSCRATCH 2, 13, pd_16, srnd + ROUND_AND_STORE_4x4 4, 5, 0, 7, m6, m1, m2, 5 + add ptrq, 16 +%if ARCH_X86_64 + lea dstq, [dstbakq+8] +%else + mov dstq, dstm + add dstq, 8 +%endif + dec cntd + jg .loop_2 + + ; m6 is still zero + ZERO_BLOCK blockq-2*mmsize, 32, 8, m6 + RET + +%macro DC_ONLY_64BIT 2 ; shift, zero +%if ARCH_X86_64 + movsxd coefq, dword [blockq] + movd [blockq], %2 + imul coefq, 11585 + add coefq, 8192 + sar coefq, 14 + imul coefq, 11585 + add coefq, ((1 << (%1 - 1)) << 14) + 8192 + sar coefq, 14 + %1 +%else + mov coefd, dword [blockq] + movd [blockq], %2 + DEFINE_ARGS dst, stride, cnt, coef, coefl + mov cntd, 2 +.loop_dc_calc: + mov coefld, coefd + sar coefd, 14 + and coefld, 0x3fff + imul coefd, 11585 + imul coefld, 11585 + add coefld, 8192 + sar coefld, 14 + add coefd, coefld + dec cntd + jg .loop_dc_calc + add coefd, 1 << (%1 - 1) + sar coefd, %1 +%endif +%endmacro + +INIT_XMM sse2 +cglobal vp9_idct_idct_8x8_add_12, 4, 6 + ARCH_X86_64, 14, \ + 16 * mmsize + 3 * ARCH_X86_32 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_4095] + cmp eobd, 1 + jg mangle(private_prefix %+ _ %+ vp9_idct_idct_8x8_add_10 %+ SUFFIX).idctfull + + ; dc-only - unfortunately, this one can overflow, since coefs are 18+sign + ; bpp, and 18+14+sign does not fit in 32bit, so we do 2-stage multiplies + DEFINE_ARGS dst, stride, block, coef, coefl + pxor m2, m2 + DC_ONLY_64BIT 5, m2 + movd m1, coefd + pshuflw m1, m1, q0000 + punpcklqdq m1, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 4 +.loop_dc: + STORE_2x8 3, 4, 1, m2, m0 + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop_dc + RET + +; inputs and outputs are dwords, coefficients are words +; +; dst1[hi]:dst3[lo] = src1 * coef1 + src2 * coef2 +; dst2[hi]:dst4[lo] = src1 * coef2 - src2 * coef1 +%macro SUMSUB_MUL_D 6-7 [pd_3fff] ; src/dst 1-2, dst3-4, coef1-2, mask + pand m%3, m%1, %7 + pand m%4, m%2, %7 + psrad m%1, 14 + psrad m%2, 14 + packssdw m%4, m%2 + packssdw m%3, m%1 + punpckhwd m%2, m%4, m%3 + punpcklwd m%4, m%3 + pmaddwd m%3, m%4, [pw_%6_%5] + pmaddwd m%1, m%2, [pw_%6_%5] + pmaddwd m%4, [pw_m%5_%6] + pmaddwd m%2, [pw_m%5_%6] +%endmacro + +; dst1 = src2[hi]:src4[lo] + src1[hi]:src3[lo] + rnd >> 14 +; dst2 = src2[hi]:src4[lo] - src1[hi]:src3[lo] + rnd >> 14 +%macro SUMSUB_PACK_D 5-6 [pd_8192] ; src/dst 1-2, src3-4, tmp, rnd + SUMSUB_BA d, %1, %2, %5 + SUMSUB_BA d, %3, %4, %5 + paddd m%3, %6 + paddd m%4, %6 + psrad m%3, 14 + psrad m%4, 14 + paddd m%1, m%3 + paddd m%2, m%4 +%endmacro + +%macro NEGD 1 +%if cpuflag(ssse3) + psignd %1, [pw_m1] +%else + pxor %1, [pw_m1] + paddd %1, [pd_1] +%endif +%endmacro + +; the following line has not been executed at the end of this macro: +; UNSCRATCH 6, 8, rsp+17*mmsize +%macro IADST8_1D 1-3 [pd_8192], [pd_3fff] ; src, rnd, mask + mova m0, [%1+ 0*mmsize] + mova m3, [%1+ 6*mmsize] + mova m4, [%1+ 8*mmsize] + mova m7, [%1+14*mmsize] + SUMSUB_MUL_D 7, 0, 1, 2, 16305, 1606, %3 ; m7/1=t0a, m0/2=t1a + SUMSUB_MUL_D 3, 4, 5, 6, 10394, 12665, %3 ; m3/5=t4a, m4/6=t5a + SCRATCH 0, 8, rsp+17*mmsize + SUMSUB_PACK_D 3, 7, 5, 1, 0, %2 ; m3=t0, m7=t4 + UNSCRATCH 0, 8, rsp+17*mmsize + SUMSUB_PACK_D 4, 0, 6, 2, 1, %2 ; m4=t1, m0=t5 + + SCRATCH 3, 8, rsp+17*mmsize + SCRATCH 4, 9, rsp+18*mmsize + SCRATCH 7, 10, rsp+19*mmsize + SCRATCH 0, 11, rsp+20*mmsize + + mova m1, [%1+ 2*mmsize] + mova m2, [%1+ 4*mmsize] + mova m5, [%1+10*mmsize] + mova m6, [%1+12*mmsize] + SUMSUB_MUL_D 5, 2, 3, 4, 14449, 7723, %3 ; m5/8=t2a, m2/9=t3a + SUMSUB_MUL_D 1, 6, 7, 0, 4756, 15679, %3 ; m1/10=t6a, m6/11=t7a + SCRATCH 2, 12, rsp+21*mmsize + SUMSUB_PACK_D 1, 5, 7, 3, 2, %2 ; m1=t2, m5=t6 + UNSCRATCH 2, 12, rsp+21*mmsize + SUMSUB_PACK_D 6, 2, 0, 4, 3, %2 ; m6=t3, m2=t7 + + UNSCRATCH 7, 10, rsp+19*mmsize + UNSCRATCH 0, 11, rsp+20*mmsize + SCRATCH 1, 10, rsp+19*mmsize + SCRATCH 6, 11, rsp+20*mmsize + + SUMSUB_MUL_D 7, 0, 3, 4, 15137, 6270, %3 ; m7/8=t4a, m0/9=t5a + SUMSUB_MUL_D 2, 5, 1, 6, 6270, 15137, %3 ; m2/10=t7a, m5/11=t6a + SCRATCH 2, 12, rsp+21*mmsize + SUMSUB_PACK_D 5, 7, 6, 3, 2, %2 ; m5=-out1, m7=t6 + UNSCRATCH 2, 12, rsp+21*mmsize + NEGD m5 ; m5=out1 + SUMSUB_PACK_D 2, 0, 1, 4, 3, %2 ; m2=out6, m0=t7 + SUMSUB_MUL 7, 0, 3, 4, 11585, 11585, %2, %3 ; m7=out2, m0=-out5 + NEGD m0 ; m0=out5 + + UNSCRATCH 3, 8, rsp+17*mmsize + UNSCRATCH 4, 9, rsp+18*mmsize + UNSCRATCH 1, 10, rsp+19*mmsize + UNSCRATCH 6, 11, rsp+20*mmsize + SCRATCH 2, 8, rsp+17*mmsize + SCRATCH 0, 9, rsp+18*mmsize + + SUMSUB_BA d, 1, 3, 2 ; m1=out0, m3=t2 + SUMSUB_BA d, 6, 4, 2 ; m6=-out7, m4=t3 + NEGD m6 ; m6=out7 + SUMSUB_MUL 3, 4, 2, 0, 11585, 11585, %2, %3 ; m3=-out3, m4=out4 + NEGD m3 ; m3=out3 + + UNSCRATCH 0, 9, rsp+18*mmsize + + SWAP 0, 1, 5 + SWAP 2, 7, 6 +%endmacro + +%macro IADST8_FN 5 +cglobal vp9_%1_%3_8x8_add_10, 4, 6 + ARCH_X86_64, 16, \ + 16 * mmsize + ARCH_X86_32 * 6 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_1023] + +.body: + SCRATCH 0, 13, rsp+16*mmsize, max + DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak +%if ARCH_X86_64 + mov dstbakq, dstq + movsxd cntq, cntd +%endif +%ifdef PIC + lea ptrq, [%5_8x8] + movzx cntd, byte [ptrq+cntq-1] +%else + movzx cntd, byte [%5_8x8+cntq-1] +%endif + mov skipd, 2 + sub skipd, cntd + mov ptrq, rsp + PRELOAD 14, pd_8192, rnd + PRELOAD 15, pd_3fff, mask +.loop_1: + %2_1D blockq, reg_rnd, reg_mask + + TRANSPOSE4x4D 0, 1, 2, 3, 6 + mova [ptrq+ 0*mmsize], m0 + mova [ptrq+ 2*mmsize], m1 + mova [ptrq+ 4*mmsize], m2 + mova [ptrq+ 6*mmsize], m3 + UNSCRATCH 6, 8, rsp+17*mmsize + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 1*mmsize], m4 + mova [ptrq+ 3*mmsize], m5 + mova [ptrq+ 5*mmsize], m6 + mova [ptrq+ 7*mmsize], m7 + add ptrq, 8 * mmsize + add blockq, mmsize + dec cntd + jg .loop_1 + + ; zero-pad the remainder (skipped cols) + test skipd, skipd + jz .end + add skipd, skipd + lea blockq, [blockq+skipq*(mmsize/2)] + pxor m0, m0 +.loop_z: + mova [ptrq+mmsize*0], m0 + mova [ptrq+mmsize*1], m0 + mova [ptrq+mmsize*2], m0 + mova [ptrq+mmsize*3], m0 + add ptrq, 4 * mmsize + dec skipd + jg .loop_z +.end: + + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea stride3q, [strideq*3] + mov cntd, 2 + mov ptrq, rsp +.loop_2: + %4_1D ptrq, reg_rnd, reg_mask + + pxor m6, m6 + PRELOAD 9, pd_16, srnd + ROUND_AND_STORE_4x4 0, 1, 2, 3, m6, reg_max, reg_srnd, 5 + lea dstq, [dstq+strideq*4] + UNSCRATCH 0, 8, rsp+17*mmsize + UNSCRATCH 1, 13, rsp+16*mmsize, max + UNSCRATCH 2, 9, pd_16, srnd + ROUND_AND_STORE_4x4 4, 5, 0, 7, m6, m1, m2, 5 + add ptrq, 16 +%if ARCH_X86_64 + lea dstq, [dstbakq+8] +%else + mov dstq, dstm + add dstq, 8 +%endif + dec cntd + jg .loop_2 + + ; m6 is still zero + ZERO_BLOCK blockq-2*mmsize, 32, 8, m6 + RET + +cglobal vp9_%1_%3_8x8_add_12, 4, 6 + ARCH_X86_64, 16, \ + 16 * mmsize + ARCH_X86_32 * 6 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_%1_%3_8x8_add_10 %+ SUFFIX).body +%endmacro + +INIT_XMM sse2 +IADST8_FN idct, IDCT8, iadst, IADST8, row +IADST8_FN iadst, IADST8, idct, IDCT8, col +IADST8_FN iadst, IADST8, iadst, IADST8, default + +%macro IDCT16_1D 1-4 4 * mmsize, 65, 67 ; src, src_stride, stack_offset, mm32bit_stack_offset + IDCT8_1D %1, [pd_8192], [pd_3fff], %2 * 2, %4 ; m0-3=t0-3a, m4-5/m8|r67/m7=t4-7 + ; SCRATCH 6, 8, rsp+(%4+0)*mmsize ; t6 + SCRATCH 0, 15, rsp+(%4+7)*mmsize ; t0a + SCRATCH 1, 14, rsp+(%4+6)*mmsize ; t1a + SCRATCH 2, 13, rsp+(%4+5)*mmsize ; t2a + SCRATCH 3, 12, rsp+(%4+4)*mmsize ; t3a + SCRATCH 4, 11, rsp+(%4+3)*mmsize ; t4 + mova [rsp+(%3+0)*mmsize], m5 ; t5 + mova [rsp+(%3+1)*mmsize], m7 ; t7 + + mova m0, [%1+ 1*%2] ; in1 + mova m3, [%1+ 7*%2] ; in7 + mova m4, [%1+ 9*%2] ; in9 + mova m7, [%1+15*%2] ; in15 + + SUMSUB_MUL 0, 7, 1, 2, 16305, 1606 ; m0=t15a, m7=t8a + SUMSUB_MUL 4, 3, 1, 2, 10394, 12665 ; m4=t14a, m3=t9a + SUMSUB_BA d, 3, 7, 1 ; m3=t8, m7=t9 + SUMSUB_BA d, 4, 0, 1 ; m4=t15,m0=t14 + SUMSUB_MUL 0, 7, 1, 2, 15137, 6270 ; m0=t14a, m7=t9a + + mova m1, [%1+ 3*%2] ; in3 + mova m2, [%1+ 5*%2] ; in5 + mova m5, [%1+11*%2] ; in11 + mova m6, [%1+13*%2] ; in13 + + SCRATCH 0, 9, rsp+(%4+1)*mmsize + SCRATCH 7, 10, rsp+(%4+2)*mmsize + + SUMSUB_MUL 2, 5, 0, 7, 14449, 7723 ; m2=t13a, m5=t10a + SUMSUB_MUL 6, 1, 0, 7, 4756, 15679 ; m6=t12a, m1=t11a + SUMSUB_BA d, 5, 1, 0 ; m5=t11,m1=t10 + SUMSUB_BA d, 2, 6, 0 ; m2=t12,m6=t13 + NEGD m1 ; m1=-t10 + SUMSUB_MUL 1, 6, 0, 7, 15137, 6270 ; m1=t13a, m6=t10a + + UNSCRATCH 7, 10, rsp+(%4+2)*mmsize + SUMSUB_BA d, 5, 3, 0 ; m5=t8a, m3=t11a + SUMSUB_BA d, 6, 7, 0 ; m6=t9, m7=t10 + SUMSUB_BA d, 2, 4, 0 ; m2=t15a,m4=t12a + SCRATCH 5, 10, rsp+(%4+2)*mmsize + SUMSUB_MUL 4, 3, 0, 5, 11585, 11585 ; m4=t12, m3=t11 + UNSCRATCH 0, 9, rsp+(%4+1)*mmsize + SUMSUB_BA d, 1, 0, 5 ; m1=t14, m0=t13 + SCRATCH 6, 9, rsp+(%4+1)*mmsize + SUMSUB_MUL 0, 7, 6, 5, 11585, 11585 ; m0=t13a,m7=t10a + + ; order: 15|r74,14|r73,13|r72,12|r71,11|r70,r65,8|r67,r66,10|r69,9|r68,7,3,4,0,1,2 + ; free: 6,5 + + UNSCRATCH 5, 15, rsp+(%4+7)*mmsize + SUMSUB_BA d, 2, 5, 6 ; m2=out0, m5=out15 + SCRATCH 5, 15, rsp+(%4+7)*mmsize + UNSCRATCH 5, 14, rsp+(%4+6)*mmsize + SUMSUB_BA d, 1, 5, 6 ; m1=out1, m5=out14 + SCRATCH 5, 14, rsp+(%4+6)*mmsize + UNSCRATCH 5, 13, rsp+(%4+5)*mmsize + SUMSUB_BA d, 0, 5, 6 ; m0=out2, m5=out13 + SCRATCH 5, 13, rsp+(%4+5)*mmsize + UNSCRATCH 5, 12, rsp+(%4+4)*mmsize + SUMSUB_BA d, 4, 5, 6 ; m4=out3, m5=out12 + SCRATCH 5, 12, rsp+(%4+4)*mmsize + UNSCRATCH 5, 11, rsp+(%4+3)*mmsize + SUMSUB_BA d, 3, 5, 6 ; m3=out4, m5=out11 + SCRATCH 4, 11, rsp+(%4+3)*mmsize + mova m4, [rsp+(%3+0)*mmsize] + SUMSUB_BA d, 7, 4, 6 ; m7=out5, m4=out10 + mova [rsp+(%3+0)*mmsize], m5 + UNSCRATCH 5, 8, rsp+(%4+0)*mmsize + UNSCRATCH 6, 9, rsp+(%4+1)*mmsize + SCRATCH 2, 8, rsp+(%4+0)*mmsize + SCRATCH 1, 9, rsp+(%4+1)*mmsize + UNSCRATCH 1, 10, rsp+(%4+2)*mmsize + SCRATCH 0, 10, rsp+(%4+2)*mmsize + mova m0, [rsp+(%3+1)*mmsize] + SUMSUB_BA d, 6, 5, 2 ; m6=out6, m5=out9 + SUMSUB_BA d, 1, 0, 2 ; m1=out7, m0=out8 + + SWAP 0, 3, 1, 7, 2, 6, 4 + + ; output order: 8-11|r67-70=out0-3 + ; 0-6,r65=out4-11 + ; 12-15|r71-74=out12-15 +%endmacro + +INIT_XMM sse2 +cglobal vp9_idct_idct_16x16_add_10, 4, 6 + ARCH_X86_64, 16, \ + 67 * mmsize + ARCH_X86_32 * 8 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_1023] + cmp eobd, 1 + jg .idctfull + + ; dc-only - the 10bit version can be done entirely in 32bit, since the max + ; coef values are 17+sign bit, and the coef is 14bit, so 31+sign easily + ; fits in 32bit + DEFINE_ARGS dst, stride, block, coef + pxor m2, m2 + DC_ONLY 6, m2 + movd m1, coefd + pshuflw m1, m1, q0000 + punpcklqdq m1, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 8 +.loop_dc: + STORE_2x8 3, 4, 1, m2, m0, dstq, mmsize + STORE_2x8 3, 4, 1, m2, m0, dstq+strideq, mmsize + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop_dc + RET + +.idctfull: + mova [rsp+64*mmsize], m0 + DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak +%if ARCH_X86_64 + mov dstbakq, dstq + movsxd cntq, cntd +%endif +%ifdef PIC + lea ptrq, [default_16x16] + movzx cntd, byte [ptrq+cntq-1] +%else + movzx cntd, byte [default_16x16+cntq-1] +%endif + mov skipd, 4 + sub skipd, cntd + mov ptrq, rsp +.loop_1: + IDCT16_1D blockq + + TRANSPOSE4x4D 0, 1, 2, 3, 7 + mova [ptrq+ 1*mmsize], m0 + mova [ptrq+ 5*mmsize], m1 + mova [ptrq+ 9*mmsize], m2 + mova [ptrq+13*mmsize], m3 + mova m7, [rsp+65*mmsize] + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 2*mmsize], m4 + mova [ptrq+ 6*mmsize], m5 + mova [ptrq+10*mmsize], m6 + mova [ptrq+14*mmsize], m7 + UNSCRATCH 0, 8, rsp+67*mmsize + UNSCRATCH 1, 9, rsp+68*mmsize + UNSCRATCH 2, 10, rsp+69*mmsize + UNSCRATCH 3, 11, rsp+70*mmsize + TRANSPOSE4x4D 0, 1, 2, 3, 7 + mova [ptrq+ 0*mmsize], m0 + mova [ptrq+ 4*mmsize], m1 + mova [ptrq+ 8*mmsize], m2 + mova [ptrq+12*mmsize], m3 + UNSCRATCH 4, 12, rsp+71*mmsize + UNSCRATCH 5, 13, rsp+72*mmsize + UNSCRATCH 6, 14, rsp+73*mmsize + UNSCRATCH 7, 15, rsp+74*mmsize + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 3*mmsize], m4 + mova [ptrq+ 7*mmsize], m5 + mova [ptrq+11*mmsize], m6 + mova [ptrq+15*mmsize], m7 + add ptrq, 16 * mmsize + add blockq, mmsize + dec cntd + jg .loop_1 + + ; zero-pad the remainder (skipped cols) + test skipd, skipd + jz .end + add skipd, skipd + lea blockq, [blockq+skipq*(mmsize/2)] + pxor m0, m0 +.loop_z: + mova [ptrq+mmsize*0], m0 + mova [ptrq+mmsize*1], m0 + mova [ptrq+mmsize*2], m0 + mova [ptrq+mmsize*3], m0 + mova [ptrq+mmsize*4], m0 + mova [ptrq+mmsize*5], m0 + mova [ptrq+mmsize*6], m0 + mova [ptrq+mmsize*7], m0 + add ptrq, 8 * mmsize + dec skipd + jg .loop_z +.end: + + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea stride3q, [strideq*3] + mov cntd, 4 + mov ptrq, rsp +.loop_2: + IDCT16_1D ptrq + + pxor m7, m7 + lea dstq, [dstq+strideq*4] + ROUND_AND_STORE_4x4 0, 1, 2, 3, m7, [rsp+64*mmsize], [pd_32], 6 + lea dstq, [dstq+strideq*4] + mova m0, [rsp+65*mmsize] + mova m1, [rsp+64*mmsize] + mova m2, [pd_32] + ROUND_AND_STORE_4x4 4, 5, 6, 0, m7, m1, m2, 6 + +%if ARCH_X86_64 + DEFINE_ARGS dstbak, stride, block, cnt, ptr, stride3, dst +%else + mov dstq, dstm +%endif + UNSCRATCH 0, 8, rsp+67*mmsize + UNSCRATCH 4, 9, rsp+68*mmsize + UNSCRATCH 5, 10, rsp+69*mmsize + UNSCRATCH 3, 11, rsp+70*mmsize + ROUND_AND_STORE_4x4 0, 4, 5, 3, m7, m1, m2, 6 +%if ARCH_X86_64 + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea dstq, [dstbakq+stride3q*4] +%else + lea dstq, [dstq+stride3q*4] +%endif + UNSCRATCH 4, 12, rsp+71*mmsize + UNSCRATCH 5, 13, rsp+72*mmsize + UNSCRATCH 6, 14, rsp+73*mmsize + UNSCRATCH 0, 15, rsp+74*mmsize + ROUND_AND_STORE_4x4 4, 5, 6, 0, m7, m1, m2, 6 + + add ptrq, mmsize +%if ARCH_X86_64 + add dstbakq, 8 + mov dstq, dstbakq +%else + add dword dstm, 8 + mov dstq, dstm +%endif + dec cntd + jg .loop_2 + + ; m7 is still zero + ZERO_BLOCK blockq-4*mmsize, 64, 16, m7 + RET + +INIT_XMM sse2 +cglobal vp9_idct_idct_16x16_add_12, 4, 6 + ARCH_X86_64, 16, \ + 67 * mmsize + ARCH_X86_32 * 8 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_4095] + cmp eobd, 1 + jg mangle(private_prefix %+ _ %+ vp9_idct_idct_16x16_add_10 %+ SUFFIX).idctfull + + ; dc-only - unfortunately, this one can overflow, since coefs are 19+sign + ; bpp, and 19+14+sign does not fit in 32bit, so we do 2-stage multiplies + DEFINE_ARGS dst, stride, block, coef, coefl + pxor m2, m2 + DC_ONLY_64BIT 6, m2 + movd m1, coefd + pshuflw m1, m1, q0000 + punpcklqdq m1, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 8 +.loop_dc: + STORE_2x8 3, 4, 1, m2, m0, dstq, mmsize + STORE_2x8 3, 4, 1, m2, m0, dstq+strideq, mmsize + lea dstq, [dstq+strideq*2] + dec cntd + jg .loop_dc + RET + +; r65-69 are available for spills +; r70-77 are available on x86-32 only (x86-64 should use m8-15) +; output should be in m8-11|r70-73, m0-6,r65 and m12-15|r74-77 +%macro IADST16_1D 1 ; src + mova m0, [%1+ 0*4*mmsize] ; in0 + mova m1, [%1+ 7*4*mmsize] ; in7 + mova m2, [%1+ 8*4*mmsize] ; in8 + mova m3, [%1+15*4*mmsize] ; in15 + SUMSUB_MUL_D 3, 0, 4, 5, 16364, 804 ; m3/4=t0, m0/5=t1 + SUMSUB_MUL_D 1, 2, 6, 7, 11003, 12140 ; m1/6=t8, m2/7=t9 + SCRATCH 0, 8, rsp+70*mmsize + SUMSUB_PACK_D 1, 3, 6, 4, 0 ; m1=t0a, m3=t8a + UNSCRATCH 0, 8, rsp+70*mmsize + SUMSUB_PACK_D 2, 0, 7, 5, 4 ; m2=t1a, m0=t9a + mova [rsp+67*mmsize], m1 + SCRATCH 2, 9, rsp+71*mmsize + SCRATCH 3, 12, rsp+74*mmsize + SCRATCH 0, 13, rsp+75*mmsize + + mova m0, [%1+ 3*4*mmsize] ; in3 + mova m1, [%1+ 4*4*mmsize] ; in4 + mova m2, [%1+11*4*mmsize] ; in11 + mova m3, [%1+12*4*mmsize] ; in12 + SUMSUB_MUL_D 2, 1, 4, 5, 14811, 7005 ; m2/4=t4, m1/5=t5 + SUMSUB_MUL_D 0, 3, 6, 7, 5520, 15426 ; m0/6=t12, m3/7=t13 + SCRATCH 1, 10, rsp+72*mmsize + SUMSUB_PACK_D 0, 2, 6, 4, 1 ; m0=t4a, m2=t12a + UNSCRATCH 1, 10, rsp+72*mmsize + SUMSUB_PACK_D 3, 1, 7, 5, 4 ; m3=t5a, m1=t13a + SCRATCH 0, 15, rsp+77*mmsize + SCRATCH 3, 11, rsp+73*mmsize + + UNSCRATCH 0, 12, rsp+74*mmsize ; t8a + UNSCRATCH 3, 13, rsp+75*mmsize ; t9a + SUMSUB_MUL_D 0, 3, 4, 5, 16069, 3196 ; m0/4=t8, m3/5=t9 + SUMSUB_MUL_D 1, 2, 6, 7, 3196, 16069 ; m1/6=t13, m2/7=t12 + SCRATCH 1, 12, rsp+74*mmsize + SUMSUB_PACK_D 2, 0, 7, 4, 1 ; m2=t8a, m0=t12a + UNSCRATCH 1, 12, rsp+74*mmsize + SUMSUB_PACK_D 1, 3, 6, 5, 4 ; m1=t9a, m3=t13a + mova [rsp+65*mmsize], m2 + mova [rsp+66*mmsize], m1 + SCRATCH 0, 8, rsp+70*mmsize + SCRATCH 3, 12, rsp+74*mmsize + + mova m0, [%1+ 2*4*mmsize] ; in2 + mova m1, [%1+ 5*4*mmsize] ; in5 + mova m2, [%1+10*4*mmsize] ; in10 + mova m3, [%1+13*4*mmsize] ; in13 + SUMSUB_MUL_D 3, 0, 4, 5, 15893, 3981 ; m3/4=t2, m0/5=t3 + SUMSUB_MUL_D 1, 2, 6, 7, 8423, 14053 ; m1/6=t10, m2/7=t11 + SCRATCH 0, 10, rsp+72*mmsize + SUMSUB_PACK_D 1, 3, 6, 4, 0 ; m1=t2a, m3=t10a + UNSCRATCH 0, 10, rsp+72*mmsize + SUMSUB_PACK_D 2, 0, 7, 5, 4 ; m2=t3a, m0=t11a + mova [rsp+68*mmsize], m1 + mova [rsp+69*mmsize], m2 + SCRATCH 3, 13, rsp+75*mmsize + SCRATCH 0, 14, rsp+76*mmsize + + mova m0, [%1+ 1*4*mmsize] ; in1 + mova m1, [%1+ 6*4*mmsize] ; in6 + mova m2, [%1+ 9*4*mmsize] ; in9 + mova m3, [%1+14*4*mmsize] ; in14 + SUMSUB_MUL_D 2, 1, 4, 5, 13160, 9760 ; m2/4=t6, m1/5=t7 + SUMSUB_MUL_D 0, 3, 6, 7, 2404, 16207 ; m0/6=t14, m3/7=t15 + SCRATCH 1, 10, rsp+72*mmsize + SUMSUB_PACK_D 0, 2, 6, 4, 1 ; m0=t6a, m2=t14a + UNSCRATCH 1, 10, rsp+72*mmsize + SUMSUB_PACK_D 3, 1, 7, 5, 4 ; m3=t7a, m1=t15a + + UNSCRATCH 4, 13, rsp+75*mmsize ; t10a + UNSCRATCH 5, 14, rsp+76*mmsize ; t11a + SCRATCH 0, 13, rsp+75*mmsize + SCRATCH 3, 14, rsp+76*mmsize + SUMSUB_MUL_D 4, 5, 6, 7, 9102, 13623 ; m4/6=t10, m5/7=t11 + SUMSUB_MUL_D 1, 2, 0, 3, 13623, 9102 ; m1/0=t15, m2/3=t14 + SCRATCH 0, 10, rsp+72*mmsize + SUMSUB_PACK_D 2, 4, 3, 6, 0 ; m2=t10a, m4=t14a + UNSCRATCH 0, 10, rsp+72*mmsize + SUMSUB_PACK_D 1, 5, 0, 7, 6 ; m1=t11a, m5=t15a + + UNSCRATCH 0, 8, rsp+70*mmsize ; t12a + UNSCRATCH 3, 12, rsp+74*mmsize ; t13a + SCRATCH 2, 8, rsp+70*mmsize + SCRATCH 1, 12, rsp+74*mmsize + SUMSUB_MUL_D 0, 3, 1, 2, 15137, 6270 ; m0/1=t12, m3/2=t13 + SUMSUB_MUL_D 5, 4, 7, 6, 6270, 15137 ; m5/7=t15, m4/6=t14 + SCRATCH 2, 10, rsp+72*mmsize + SUMSUB_PACK_D 4, 0, 6, 1, 2 ; m4=out2, m0=t14a + UNSCRATCH 2, 10, rsp+72*mmsize + SUMSUB_PACK_D 5, 3, 7, 2, 1 ; m5=-out13, m3=t15a + NEGD m5 ; m5=out13 + + UNSCRATCH 1, 9, rsp+71*mmsize ; t1a + mova m2, [rsp+68*mmsize] ; t2a + UNSCRATCH 6, 13, rsp+75*mmsize ; t6a + UNSCRATCH 7, 14, rsp+76*mmsize ; t7a + SCRATCH 4, 10, rsp+72*mmsize + SCRATCH 5, 13, rsp+75*mmsize + UNSCRATCH 4, 15, rsp+77*mmsize ; t4a + UNSCRATCH 5, 11, rsp+73*mmsize ; t5a + SCRATCH 0, 14, rsp+76*mmsize + SCRATCH 3, 15, rsp+77*mmsize + mova m0, [rsp+67*mmsize] ; t0a + SUMSUB_BA d, 4, 0, 3 ; m4=t0, m0=t4 + SUMSUB_BA d, 5, 1, 3 ; m5=t1, m1=t5 + SUMSUB_BA d, 6, 2, 3 ; m6=t2, m2=t6 + SCRATCH 4, 9, rsp+71*mmsize + mova m3, [rsp+69*mmsize] ; t3a + SUMSUB_BA d, 7, 3, 4 ; m7=t3, m3=t7 + + mova [rsp+67*mmsize], m5 + mova [rsp+68*mmsize], m6 + mova [rsp+69*mmsize], m7 + SUMSUB_MUL_D 0, 1, 4, 5, 15137, 6270 ; m0/4=t4a, m1/5=t5a + SUMSUB_MUL_D 3, 2, 7, 6, 6270, 15137 ; m3/7=t7a, m2/6=t6a + SCRATCH 1, 11, rsp+73*mmsize + SUMSUB_PACK_D 2, 0, 6, 4, 1 ; m2=-out3, m0=t6 + NEGD m2 ; m2=out3 + UNSCRATCH 1, 11, rsp+73*mmsize + SUMSUB_PACK_D 3, 1, 7, 5, 4 ; m3=out12, m1=t7 + SCRATCH 2, 11, rsp+73*mmsize + UNSCRATCH 2, 12, rsp+74*mmsize ; t11a + SCRATCH 3, 12, rsp+74*mmsize + + UNSCRATCH 3, 8, rsp+70*mmsize ; t10a + mova m4, [rsp+65*mmsize] ; t8a + mova m5, [rsp+66*mmsize] ; t9a + SUMSUB_BA d, 3, 4, 6 ; m3=-out1, m4=t10 + NEGD m3 ; m3=out1 + SUMSUB_BA d, 2, 5, 6 ; m2=out14, m5=t11 + UNSCRATCH 6, 9, rsp+71*mmsize ; t0 + UNSCRATCH 7, 14, rsp+76*mmsize ; t14a + SCRATCH 3, 9, rsp+71*mmsize + SCRATCH 2, 14, rsp+76*mmsize + + SUMSUB_MUL 1, 0, 2, 3, 11585, 11585 ; m1=out4, m0=out11 + mova [rsp+65*mmsize], m0 + SUMSUB_MUL 5, 4, 2, 3, 11585, 11585 ; m5=out6, m4=out9 + UNSCRATCH 0, 15, rsp+77*mmsize ; t15a + SUMSUB_MUL 7, 0, 2, 3, 11585, m11585 ; m7=out10, m0=out5 + + mova m2, [rsp+68*mmsize] ; t2 + SUMSUB_BA d, 2, 6, 3 ; m2=out0, m6=t2a + SCRATCH 2, 8, rsp+70*mmsize + mova m2, [rsp+67*mmsize] ; t1 + mova m3, [rsp+69*mmsize] ; t3 + mova [rsp+67*mmsize], m7 + SUMSUB_BA d, 3, 2, 7 ; m3=-out15, m2=t3a + NEGD m3 ; m3=out15 + SCRATCH 3, 15, rsp+77*mmsize + SUMSUB_MUL 6, 2, 7, 3, 11585, m11585 ; m6=out8, m2=out7 + mova m7, [rsp+67*mmsize] + + SWAP 0, 1 + SWAP 2, 5, 4, 6, 7, 3 +%endmacro + +%macro IADST16_FN 7 +cglobal vp9_%1_%4_16x16_add_10, 4, 6 + ARCH_X86_64, 16, \ + 70 * mmsize + ARCH_X86_32 * 8 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_1023] + +.body: + mova [rsp+64*mmsize], m0 + DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak +%if ARCH_X86_64 + mov dstbakq, dstq + movsxd cntq, cntd +%endif +%ifdef PIC + lea ptrq, [%7_16x16] + movzx cntd, byte [ptrq+cntq-1] +%else + movzx cntd, byte [%7_16x16+cntq-1] +%endif + mov skipd, 4 + sub skipd, cntd + mov ptrq, rsp +.loop_1: + %2_1D blockq + + TRANSPOSE4x4D 0, 1, 2, 3, 7 + mova [ptrq+ 1*mmsize], m0 + mova [ptrq+ 5*mmsize], m1 + mova [ptrq+ 9*mmsize], m2 + mova [ptrq+13*mmsize], m3 + mova m7, [rsp+65*mmsize] + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 2*mmsize], m4 + mova [ptrq+ 6*mmsize], m5 + mova [ptrq+10*mmsize], m6 + mova [ptrq+14*mmsize], m7 + UNSCRATCH 0, 8, rsp+(%3+0)*mmsize + UNSCRATCH 1, 9, rsp+(%3+1)*mmsize + UNSCRATCH 2, 10, rsp+(%3+2)*mmsize + UNSCRATCH 3, 11, rsp+(%3+3)*mmsize + TRANSPOSE4x4D 0, 1, 2, 3, 7 + mova [ptrq+ 0*mmsize], m0 + mova [ptrq+ 4*mmsize], m1 + mova [ptrq+ 8*mmsize], m2 + mova [ptrq+12*mmsize], m3 + UNSCRATCH 4, 12, rsp+(%3+4)*mmsize + UNSCRATCH 5, 13, rsp+(%3+5)*mmsize + UNSCRATCH 6, 14, rsp+(%3+6)*mmsize + UNSCRATCH 7, 15, rsp+(%3+7)*mmsize + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 3*mmsize], m4 + mova [ptrq+ 7*mmsize], m5 + mova [ptrq+11*mmsize], m6 + mova [ptrq+15*mmsize], m7 + add ptrq, 16 * mmsize + add blockq, mmsize + dec cntd + jg .loop_1 + + ; zero-pad the remainder (skipped cols) + test skipd, skipd + jz .end + add skipd, skipd + lea blockq, [blockq+skipq*(mmsize/2)] + pxor m0, m0 +.loop_z: + mova [ptrq+mmsize*0], m0 + mova [ptrq+mmsize*1], m0 + mova [ptrq+mmsize*2], m0 + mova [ptrq+mmsize*3], m0 + mova [ptrq+mmsize*4], m0 + mova [ptrq+mmsize*5], m0 + mova [ptrq+mmsize*6], m0 + mova [ptrq+mmsize*7], m0 + add ptrq, 8 * mmsize + dec skipd + jg .loop_z +.end: + + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea stride3q, [strideq*3] + mov cntd, 4 + mov ptrq, rsp +.loop_2: + %5_1D ptrq + + pxor m7, m7 + lea dstq, [dstq+strideq*4] + ROUND_AND_STORE_4x4 0, 1, 2, 3, m7, [rsp+64*mmsize], [pd_32], 6 + lea dstq, [dstq+strideq*4] + mova m0, [rsp+65*mmsize] + mova m1, [rsp+64*mmsize] + mova m2, [pd_32] + ROUND_AND_STORE_4x4 4, 5, 6, 0, m7, m1, m2, 6 + +%if ARCH_X86_64 + DEFINE_ARGS dstbak, stride, block, cnt, ptr, stride3, dst +%else + mov dstq, dstm +%endif + UNSCRATCH 0, 8, rsp+(%6+0)*mmsize + UNSCRATCH 4, 9, rsp+(%6+1)*mmsize + UNSCRATCH 5, 10, rsp+(%6+2)*mmsize + UNSCRATCH 3, 11, rsp+(%6+3)*mmsize + ROUND_AND_STORE_4x4 0, 4, 5, 3, m7, m1, m2, 6 +%if ARCH_X86_64 + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea dstq, [dstbakq+stride3q*4] +%else + lea dstq, [dstq+stride3q*4] +%endif + UNSCRATCH 4, 12, rsp+(%6+4)*mmsize + UNSCRATCH 5, 13, rsp+(%6+5)*mmsize + UNSCRATCH 6, 14, rsp+(%6+6)*mmsize + UNSCRATCH 0, 15, rsp+(%6+7)*mmsize + ROUND_AND_STORE_4x4 4, 5, 6, 0, m7, m1, m2, 6 + + add ptrq, mmsize +%if ARCH_X86_64 + add dstbakq, 8 + mov dstq, dstbakq +%else + add dword dstm, 8 + mov dstq, dstm +%endif + dec cntd + jg .loop_2 + + ; m7 is still zero + ZERO_BLOCK blockq-4*mmsize, 64, 16, m7 + RET + +cglobal vp9_%1_%4_16x16_add_12, 4, 6 + ARCH_X86_64, 16, \ + 70 * mmsize + ARCH_X86_32 * 8 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_%1_%4_16x16_add_10 %+ SUFFIX).body +%endmacro + +INIT_XMM sse2 +IADST16_FN idct, IDCT16, 67, iadst, IADST16, 70, row +IADST16_FN iadst, IADST16, 70, idct, IDCT16, 67, col +IADST16_FN iadst, IADST16, 70, iadst, IADST16, 70, default + +%macro IDCT32_1D 2-3 8 * mmsize; pass[1/2], src, src_stride + IDCT16_1D %2, 2 * %3, 272, 257 +%if ARCH_X86_64 + mova [rsp+257*mmsize], m8 + mova [rsp+258*mmsize], m9 + mova [rsp+259*mmsize], m10 + mova [rsp+260*mmsize], m11 + mova [rsp+261*mmsize], m12 + mova [rsp+262*mmsize], m13 + mova [rsp+263*mmsize], m14 + mova [rsp+264*mmsize], m15 +%endif + mova [rsp+265*mmsize], m0 + mova [rsp+266*mmsize], m1 + mova [rsp+267*mmsize], m2 + mova [rsp+268*mmsize], m3 + mova [rsp+269*mmsize], m4 + mova [rsp+270*mmsize], m5 + mova [rsp+271*mmsize], m6 + + ; r257-260: t0-3 + ; r265-272: t4/5a/6a/7/8/9a/10/11a + ; r261-264: t12a/13/14a/15 + ; r273-274 is free as scratch space, and 275-282 mirrors m8-15 on 32bit + + mova m0, [%2+ 1*%3] ; in1 + mova m1, [%2+15*%3] ; in15 + mova m2, [%2+17*%3] ; in17 + mova m3, [%2+31*%3] ; in31 + SUMSUB_MUL 0, 3, 4, 5, 16364, 804 ; m0=t31a, m3=t16a + SUMSUB_MUL 2, 1, 4, 5, 11003, 12140 ; m2=t30a, m1=t17a + SUMSUB_BA d, 1, 3, 4 ; m1=t16, m3=t17 + SUMSUB_BA d, 2, 0, 4 ; m2=t31, m0=t30 + SUMSUB_MUL 0, 3, 4, 5, 16069, 3196 ; m0=t30a, m3=t17a + SCRATCH 0, 8, rsp+275*mmsize + SCRATCH 2, 9, rsp+276*mmsize + + ; end of stage 1-3 first quart + + mova m0, [%2+ 7*%3] ; in7 + mova m2, [%2+ 9*%3] ; in9 + mova m4, [%2+23*%3] ; in23 + mova m5, [%2+25*%3] ; in25 + SUMSUB_MUL 2, 4, 6, 7, 14811, 7005 ; m2=t29a, m4=t18a + SUMSUB_MUL 5, 0, 6, 7, 5520, 15426 ; m5=t28a, m0=t19a + SUMSUB_BA d, 4, 0, 6 ; m4=t19, m0=t18 + SUMSUB_BA d, 2, 5, 6 ; m2=t28, m5=t29 + SUMSUB_MUL 5, 0, 6, 7, 3196, m16069 ; m5=t29a, m0=t18a + + ; end of stage 1-3 second quart + + SUMSUB_BA d, 4, 1, 6 ; m4=t16a, m1=t19a + SUMSUB_BA d, 0, 3, 6 ; m0=t17, m3=t18 + UNSCRATCH 6, 8, rsp+275*mmsize ; t30a + UNSCRATCH 7, 9, rsp+276*mmsize ; t31 + mova [rsp+273*mmsize], m4 + mova [rsp+274*mmsize], m0 + SUMSUB_BA d, 2, 7, 0 ; m2=t31a, m7=t28a + SUMSUB_BA d, 5, 6, 0 ; m5=t30, m6=t29 + SUMSUB_MUL 6, 3, 0, 4, 15137, 6270 ; m6=t29a, m3=t18a + SUMSUB_MUL 7, 1, 0, 4, 15137, 6270 ; m7=t28, m1=t19 + SCRATCH 3, 10, rsp+277*mmsize + SCRATCH 1, 11, rsp+278*mmsize + SCRATCH 7, 12, rsp+279*mmsize + SCRATCH 6, 13, rsp+280*mmsize + SCRATCH 5, 14, rsp+281*mmsize + SCRATCH 2, 15, rsp+282*mmsize + + ; end of stage 4-5 first half + + mova m0, [%2+ 5*%3] ; in5 + mova m1, [%2+11*%3] ; in11 + mova m2, [%2+21*%3] ; in21 + mova m3, [%2+27*%3] ; in27 + SUMSUB_MUL 0, 3, 4, 5, 15893, 3981 ; m0=t27a, m3=t20a + SUMSUB_MUL 2, 1, 4, 5, 8423, 14053 ; m2=t26a, m1=t21a + SUMSUB_BA d, 1, 3, 4 ; m1=t20, m3=t21 + SUMSUB_BA d, 2, 0, 4 ; m2=t27, m0=t26 + SUMSUB_MUL 0, 3, 4, 5, 9102, 13623 ; m0=t26a, m3=t21a + SCRATCH 0, 8, rsp+275*mmsize + SCRATCH 2, 9, rsp+276*mmsize + + ; end of stage 1-3 third quart + + mova m0, [%2+ 3*%3] ; in3 + mova m2, [%2+13*%3] ; in13 + mova m4, [%2+19*%3] ; in19 + mova m5, [%2+29*%3] ; in29 + SUMSUB_MUL 2, 4, 6, 7, 13160, 9760 ; m2=t25a, m4=t22a + SUMSUB_MUL 5, 0, 6, 7, 2404, 16207 ; m5=t24a, m0=t23a + SUMSUB_BA d, 4, 0, 6 ; m4=t23, m0=t22 + SUMSUB_BA d, 2, 5, 6 ; m2=t24, m5=t25 + SUMSUB_MUL 5, 0, 6, 7, 13623, m9102 ; m5=t25a, m0=t22a + + ; end of stage 1-3 fourth quart + + SUMSUB_BA d, 1, 4, 6 ; m1=t23a, m4=t20a + SUMSUB_BA d, 3, 0, 6 ; m3=t22, m0=t21 + UNSCRATCH 6, 8, rsp+275*mmsize ; t26a + UNSCRATCH 7, 9, rsp+276*mmsize ; t27 + SCRATCH 3, 8, rsp+275*mmsize + SCRATCH 1, 9, rsp+276*mmsize + SUMSUB_BA d, 7, 2, 1 ; m7=t24a, m2=t27a + SUMSUB_BA d, 6, 5, 1 ; m6=t25, m5=t26 + SUMSUB_MUL 2, 4, 1, 3, 6270, m15137 ; m2=t27, m4=t20 + SUMSUB_MUL 5, 0, 1, 3, 6270, m15137 ; m5=t26a, m0=t21a + + ; end of stage 4-5 second half + + UNSCRATCH 1, 12, rsp+279*mmsize ; t28 + UNSCRATCH 3, 13, rsp+280*mmsize ; t29a + SCRATCH 4, 12, rsp+279*mmsize + SCRATCH 0, 13, rsp+280*mmsize + SUMSUB_BA d, 5, 3, 0 ; m5=t29, m3=t26 + SUMSUB_BA d, 2, 1, 0 ; m2=t28a, m1=t27a + UNSCRATCH 0, 14, rsp+281*mmsize ; t30 + UNSCRATCH 4, 15, rsp+282*mmsize ; t31a + SCRATCH 2, 14, rsp+281*mmsize + SCRATCH 5, 15, rsp+282*mmsize + SUMSUB_BA d, 6, 0, 2 ; m6=t30a, m0=t25a + SUMSUB_BA d, 7, 4, 2 ; m7=t31, m4=t24 + + mova m2, [rsp+273*mmsize] ; t16a + mova m5, [rsp+274*mmsize] ; t17 + mova [rsp+273*mmsize], m6 + mova [rsp+274*mmsize], m7 + UNSCRATCH 6, 10, rsp+277*mmsize ; t18a + UNSCRATCH 7, 11, rsp+278*mmsize ; t19 + SCRATCH 4, 10, rsp+277*mmsize + SCRATCH 0, 11, rsp+278*mmsize + UNSCRATCH 4, 12, rsp+279*mmsize ; t20 + UNSCRATCH 0, 13, rsp+280*mmsize ; t21a + SCRATCH 3, 12, rsp+279*mmsize + SCRATCH 1, 13, rsp+280*mmsize + SUMSUB_BA d, 0, 6, 1 ; m0=t18, m6=t21 + SUMSUB_BA d, 4, 7, 1 ; m4=t19a, m7=t20a + UNSCRATCH 3, 8, rsp+275*mmsize ; t22 + UNSCRATCH 1, 9, rsp+276*mmsize ; t23a + SCRATCH 0, 8, rsp+275*mmsize + SCRATCH 4, 9, rsp+276*mmsize + SUMSUB_BA d, 3, 5, 0 ; m3=t17a, m5=t22a + SUMSUB_BA d, 1, 2, 0 ; m1=t16, m2=t23 + + ; end of stage 6 + + UNSCRATCH 0, 10, rsp+277*mmsize ; t24 + UNSCRATCH 4, 11, rsp+278*mmsize ; t25a + SCRATCH 1, 10, rsp+277*mmsize + SCRATCH 3, 11, rsp+278*mmsize + SUMSUB_MUL 0, 2, 1, 3, 11585, 11585 ; m0=t24a, m2=t23a + SUMSUB_MUL 4, 5, 1, 3, 11585, 11585 ; m4=t25, m5=t22 + UNSCRATCH 1, 12, rsp+279*mmsize ; t26 + UNSCRATCH 3, 13, rsp+280*mmsize ; t27a + SCRATCH 0, 12, rsp+279*mmsize + SCRATCH 4, 13, rsp+280*mmsize + SUMSUB_MUL 3, 7, 0, 4, 11585, 11585 ; m3=t27, m7=t20 + SUMSUB_MUL 1, 6, 0, 4, 11585, 11585 ; m1=t26a, m6=t21a + + ; end of stage 7 + + mova m0, [rsp+269*mmsize] ; t8 + mova m4, [rsp+270*mmsize] ; t9a + mova [rsp+269*mmsize], m1 ; t26a + mova [rsp+270*mmsize], m3 ; t27 + mova m3, [rsp+271*mmsize] ; t10 + SUMSUB_BA d, 2, 0, 1 ; m2=out8, m0=out23 + SUMSUB_BA d, 5, 4, 1 ; m5=out9, m4=out22 + SUMSUB_BA d, 6, 3, 1 ; m6=out10, m3=out21 + mova m1, [rsp+272*mmsize] ; t11a + mova [rsp+271*mmsize], m0 + SUMSUB_BA d, 7, 1, 0 ; m7=out11, m1=out20 + +%if %1 == 1 + TRANSPOSE4x4D 2, 5, 6, 7, 0 + mova [ptrq+ 2*mmsize], m2 + mova [ptrq+10*mmsize], m5 + mova [ptrq+18*mmsize], m6 + mova [ptrq+26*mmsize], m7 +%else ; %1 == 2 + pxor m0, m0 + lea dstq, [dstq+strideq*8] + ROUND_AND_STORE_4x4 2, 5, 6, 7, m0, [rsp+256*mmsize], [pd_32], 6 +%endif + mova m2, [rsp+271*mmsize] +%if %1 == 1 + TRANSPOSE4x4D 1, 3, 4, 2, 0 + mova [ptrq+ 5*mmsize], m1 + mova [ptrq+13*mmsize], m3 + mova [ptrq+21*mmsize], m4 + mova [ptrq+29*mmsize], m2 +%else ; %1 == 2 + lea dstq, [dstq+stride3q*4] + ROUND_AND_STORE_4x4 1, 3, 4, 2, m0, [rsp+256*mmsize], [pd_32], 6 +%endif + + ; end of last stage + store for out8-11 and out20-23 + + UNSCRATCH 0, 9, rsp+276*mmsize ; t19a + UNSCRATCH 1, 8, rsp+275*mmsize ; t18 + UNSCRATCH 2, 11, rsp+278*mmsize ; t17a + UNSCRATCH 3, 10, rsp+277*mmsize ; t16 + mova m7, [rsp+261*mmsize] ; t12a + mova m6, [rsp+262*mmsize] ; t13 + mova m5, [rsp+263*mmsize] ; t14a + SUMSUB_BA d, 0, 7, 4 ; m0=out12, m7=out19 + SUMSUB_BA d, 1, 6, 4 ; m1=out13, m6=out18 + SUMSUB_BA d, 2, 5, 4 ; m2=out14, m5=out17 + mova m4, [rsp+264*mmsize] ; t15 + SCRATCH 7, 8, rsp+275*mmsize + SUMSUB_BA d, 3, 4, 7 ; m3=out15, m4=out16 + +%if %1 == 1 + TRANSPOSE4x4D 0, 1, 2, 3, 7 + mova [ptrq+ 3*mmsize], m0 + mova [ptrq+11*mmsize], m1 + mova [ptrq+19*mmsize], m2 + mova [ptrq+27*mmsize], m3 +%else ; %1 == 2 +%if ARCH_X86_64 + SWAP 7, 9 + lea dstq, [dstbakq+stride3q*4] +%else ; x86-32 + pxor m7, m7 + mov dstq, dstm + lea dstq, [dstq+stride3q*4] +%endif + ROUND_AND_STORE_4x4 0, 1, 2, 3, m7, [rsp+256*mmsize], [pd_32], 6 +%endif + UNSCRATCH 0, 8, rsp+275*mmsize ; out19 +%if %1 == 1 + TRANSPOSE4x4D 4, 5, 6, 0, 7 + mova [ptrq+ 4*mmsize], m4 + mova [ptrq+12*mmsize], m5 + mova [ptrq+20*mmsize], m6 + mova [ptrq+28*mmsize], m0 +%else ; %1 == 2 + lea dstq, [dstq+strideq*4] + ROUND_AND_STORE_4x4 4, 5, 6, 0, m7, [rsp+256*mmsize], [pd_32], 6 +%endif + + ; end of last stage + store for out12-19 + +%if ARCH_X86_64 + SWAP 7, 8 +%endif + mova m7, [rsp+257*mmsize] ; t0 + mova m6, [rsp+258*mmsize] ; t1 + mova m5, [rsp+259*mmsize] ; t2 + mova m4, [rsp+260*mmsize] ; t3 + mova m0, [rsp+274*mmsize] ; t31 + mova m1, [rsp+273*mmsize] ; t30a + UNSCRATCH 2, 15, rsp+282*mmsize ; t29 + SUMSUB_BA d, 0, 7, 3 ; m0=out0, m7=out31 + SUMSUB_BA d, 1, 6, 3 ; m1=out1, m6=out30 + SUMSUB_BA d, 2, 5, 3 ; m2=out2, m5=out29 + SCRATCH 0, 9, rsp+276*mmsize + UNSCRATCH 3, 14, rsp+281*mmsize ; t28a + SUMSUB_BA d, 3, 4, 0 ; m3=out3, m4=out28 + +%if %1 == 1 + TRANSPOSE4x4D 4, 5, 6, 7, 0 + mova [ptrq+ 7*mmsize], m4 + mova [ptrq+15*mmsize], m5 + mova [ptrq+23*mmsize], m6 + mova [ptrq+31*mmsize], m7 +%else ; %1 == 2 +%if ARCH_X86_64 + SWAP 0, 8 +%else ; x86-32 + pxor m0, m0 +%endif + lea dstq, [dstq+stride3q*4] + ROUND_AND_STORE_4x4 4, 5, 6, 7, m0, [rsp+256*mmsize], [pd_32], 6 +%endif + UNSCRATCH 7, 9, rsp+276*mmsize ; out0 +%if %1 == 1 + TRANSPOSE4x4D 7, 1, 2, 3, 0 + mova [ptrq+ 0*mmsize], m7 + mova [ptrq+ 8*mmsize], m1 + mova [ptrq+16*mmsize], m2 + mova [ptrq+24*mmsize], m3 +%else ; %1 == 2 +%if ARCH_X86_64 + DEFINE_ARGS dstbak, stride, block, cnt, ptr, stride3, dst +%else ; x86-32 + mov dstq, dstm +%endif + ROUND_AND_STORE_4x4 7, 1, 2, 3, m0, [rsp+256*mmsize], [pd_32], 6 +%if ARCH_X86_64 + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak +%endif +%endif + + ; end of last stage + store for out0-3 and out28-31 + +%if ARCH_X86_64 + SWAP 0, 8 +%endif + mova m7, [rsp+265*mmsize] ; t4 + mova m6, [rsp+266*mmsize] ; t5a + mova m5, [rsp+267*mmsize] ; t6a + mova m4, [rsp+268*mmsize] ; t7 + mova m0, [rsp+270*mmsize] ; t27 + mova m1, [rsp+269*mmsize] ; t26a + UNSCRATCH 2, 13, rsp+280*mmsize ; t25 + SUMSUB_BA d, 0, 7, 3 ; m0=out4, m7=out27 + SUMSUB_BA d, 1, 6, 3 ; m1=out5, m6=out26 + SUMSUB_BA d, 2, 5, 3 ; m2=out6, m5=out25 + UNSCRATCH 3, 12, rsp+279*mmsize ; t24a + SCRATCH 7, 9, rsp+276*mmsize + SUMSUB_BA d, 3, 4, 7 ; m3=out7, m4=out24 + +%if %1 == 1 + TRANSPOSE4x4D 0, 1, 2, 3, 7 + mova [ptrq+ 1*mmsize], m0 + mova [ptrq+ 9*mmsize], m1 + mova [ptrq+17*mmsize], m2 + mova [ptrq+25*mmsize], m3 +%else ; %1 == 2 +%if ARCH_X86_64 + SWAP 7, 8 + lea dstq, [dstbakq+strideq*4] +%else ; x86-32 + pxor m7, m7 + lea dstq, [dstq+strideq*4] +%endif + ROUND_AND_STORE_4x4 0, 1, 2, 3, m7, [rsp+256*mmsize], [pd_32], 6 +%endif + UNSCRATCH 0, 9, rsp+276*mmsize ; out27 +%if %1 == 1 + TRANSPOSE4x4D 4, 5, 6, 0, 7 + mova [ptrq+ 6*mmsize], m4 + mova [ptrq+14*mmsize], m5 + mova [ptrq+22*mmsize], m6 + mova [ptrq+30*mmsize], m0 +%else ; %1 == 2 +%if ARCH_X86_64 + lea dstq, [dstbakq+stride3q*8] +%else + mov dstq, dstm + lea dstq, [dstq+stride3q*8] +%endif + ROUND_AND_STORE_4x4 4, 5, 6, 0, m7, [rsp+256*mmsize], [pd_32], 6 +%endif + + ; end of last stage + store for out4-7 and out24-27 +%endmacro + +INIT_XMM sse2 +cglobal vp9_idct_idct_32x32_add_10, 4, 6 + ARCH_X86_64, 16, \ + 275 * mmsize + ARCH_X86_32 * 8 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_1023] + cmp eobd, 1 + jg .idctfull + + ; dc-only - the 10bit version can be done entirely in 32bit, since the max + ; coef values are 17+sign bit, and the coef is 14bit, so 31+sign easily + ; fits in 32bit + DEFINE_ARGS dst, stride, block, coef + pxor m2, m2 + DC_ONLY 6, m2 + movd m1, coefd + pshuflw m1, m1, q0000 + punpcklqdq m1, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 32 +.loop_dc: + STORE_2x8 3, 4, 1, m2, m0, dstq, mmsize + STORE_2x8 3, 4, 1, m2, m0, dstq+mmsize*2, mmsize + add dstq, strideq + dec cntd + jg .loop_dc + RET + +.idctfull: + mova [rsp+256*mmsize], m0 + DEFINE_ARGS dst, stride, block, cnt, ptr, skip, dstbak +%if ARCH_X86_64 + mov dstbakq, dstq + movsxd cntq, cntd +%endif +%ifdef PIC + lea ptrq, [default_32x32] + movzx cntd, byte [ptrq+cntq-1] +%else + movzx cntd, byte [default_32x32+cntq-1] +%endif + mov skipd, 8 + sub skipd, cntd + mov ptrq, rsp +.loop_1: + IDCT32_1D 1, blockq + + add ptrq, 32 * mmsize + add blockq, mmsize + dec cntd + jg .loop_1 + + ; zero-pad the remainder (skipped cols) + test skipd, skipd + jz .end + shl skipd, 2 + lea blockq, [blockq+skipq*(mmsize/4)] + pxor m0, m0 +.loop_z: + mova [ptrq+mmsize*0], m0 + mova [ptrq+mmsize*1], m0 + mova [ptrq+mmsize*2], m0 + mova [ptrq+mmsize*3], m0 + mova [ptrq+mmsize*4], m0 + mova [ptrq+mmsize*5], m0 + mova [ptrq+mmsize*6], m0 + mova [ptrq+mmsize*7], m0 + add ptrq, 8 * mmsize + dec skipd + jg .loop_z +.end: + + DEFINE_ARGS dst, stride, block, cnt, ptr, stride3, dstbak + lea stride3q, [strideq*3] + mov cntd, 8 + mov ptrq, rsp +.loop_2: + IDCT32_1D 2, ptrq + + add ptrq, mmsize +%if ARCH_X86_64 + add dstbakq, 8 + mov dstq, dstbakq +%else + add dword dstm, 8 + mov dstq, dstm +%endif + dec cntd + jg .loop_2 + + ; m7 is still zero + ZERO_BLOCK blockq-8*mmsize, 128, 32, m7 + RET + +INIT_XMM sse2 +cglobal vp9_idct_idct_32x32_add_12, 4, 6 + ARCH_X86_64, 16, \ + 275 * mmsize + ARCH_X86_32 * 8 * mmsize, \ + dst, stride, block, eob + mova m0, [pw_4095] + cmp eobd, 1 + jg mangle(private_prefix %+ _ %+ vp9_idct_idct_32x32_add_10 %+ SUFFIX).idctfull + + ; dc-only - unfortunately, this one can overflow, since coefs are 19+sign + ; bpp, and 19+14+sign does not fit in 32bit, so we do 2-stage multiplies + DEFINE_ARGS dst, stride, block, coef, coefl + pxor m2, m2 + DC_ONLY_64BIT 6, m2 + movd m1, coefd + pshuflw m1, m1, q0000 + punpcklqdq m1, m1 + DEFINE_ARGS dst, stride, cnt + mov cntd, 32 +.loop_dc: + STORE_2x8 3, 4, 1, m2, m0, dstq, mmsize + STORE_2x8 3, 4, 1, m2, m0, dstq+mmsize*2, mmsize + add dstq, strideq + dec cntd + jg .loop_dc + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm_template.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm_template.asm new file mode 100644 index 00000000..d2f2257d --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9itxfm_template.asm @@ -0,0 +1,142 @@ +;****************************************************************************** +;* VP9 IDCT SIMD optimizations +;* +;* Copyright (C) 2013 Clément Bœsch +;* Copyright (C) 2013 Ronald S. Bultje +;* +;* 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 +;****************************************************************************** + +%macro VP9_IWHT4_1D 0 + SWAP 1, 2, 3 + paddw m0, m2 + psubw m3, m1 + psubw m4, m0, m3 + psraw m4, 1 + psubw m5, m4, m1 + SWAP 5, 1 + psubw m4, m2 + SWAP 4, 2 + psubw m0, m1 + paddw m3, m2 + SWAP 3, 2, 1 +%endmacro + +; (a*x + b*y + round) >> shift +%macro VP9_MULSUB_2W_2X 5 ; dst1, dst2/src, round, coefs1, coefs2 + pmaddwd m%1, m%2, %4 + pmaddwd m%2, %5 + paddd m%1, %3 + paddd m%2, %3 + psrad m%1, 14 + psrad m%2, 14 +%endmacro + +%macro VP9_MULSUB_2W_4X 7 ; dst1, dst2, coef1, coef2, rnd, tmp1/src, tmp2 + VP9_MULSUB_2W_2X %7, %6, %5, [pw_m%3_%4], [pw_%4_%3] + VP9_MULSUB_2W_2X %1, %2, %5, [pw_m%3_%4], [pw_%4_%3] + packssdw m%1, m%7 + packssdw m%2, m%6 +%endmacro + +%macro VP9_UNPACK_MULSUB_2W_4X 7-9 ; dst1, dst2, (src1, src2,) coef1, coef2, rnd, tmp1, tmp2 +%if %0 == 7 + punpckhwd m%6, m%2, m%1 + punpcklwd m%2, m%1 + VP9_MULSUB_2W_4X %1, %2, %3, %4, %5, %6, %7 +%else + punpckhwd m%8, m%4, m%3 + punpcklwd m%2, m%4, m%3 + VP9_MULSUB_2W_4X %1, %2, %5, %6, %7, %8, %9 +%endif +%endmacro + +%macro VP9_IDCT4_1D_FINALIZE 0 + SUMSUB_BA w, 3, 2, 4 ; m3=t3+t0, m2=-t3+t0 + SUMSUB_BA w, 1, 0, 4 ; m1=t2+t1, m0=-t2+t1 + SWAP 0, 3, 2 ; 3102 -> 0123 +%endmacro + +%macro VP9_IDCT4_1D 0 +%if cpuflag(ssse3) + SUMSUB_BA w, 2, 0, 4 ; m2=IN(0)+IN(2) m0=IN(0)-IN(2) + pmulhrsw m2, m6 ; m2=t0 + pmulhrsw m0, m6 ; m0=t1 +%else ; <= sse2 + VP9_UNPACK_MULSUB_2W_4X 0, 2, 11585, 11585, m7, 4, 5 ; m0=t1, m1=t0 +%endif + VP9_UNPACK_MULSUB_2W_4X 1, 3, 15137, 6270, m7, 4, 5 ; m1=t2, m3=t3 + VP9_IDCT4_1D_FINALIZE +%endmacro + +%macro VP9_IADST4_1D 0 + movq2dq xmm0, m0 + movq2dq xmm1, m1 + movq2dq xmm2, m2 + movq2dq xmm3, m3 +%if cpuflag(ssse3) + paddw m3, m0 +%endif + punpcklwd xmm0, xmm1 + punpcklwd xmm2, xmm3 + pmaddwd xmm1, xmm0, [pw_5283_13377] + pmaddwd xmm4, xmm0, [pw_9929_13377] +%if notcpuflag(ssse3) + pmaddwd xmm6, xmm0, [pw_13377_0] +%endif + pmaddwd xmm0, [pw_15212_m13377] + pmaddwd xmm3, xmm2, [pw_15212_9929] +%if notcpuflag(ssse3) + pmaddwd xmm7, xmm2, [pw_m13377_13377] +%endif + pmaddwd xmm2, [pw_m5283_m15212] +%if cpuflag(ssse3) + psubw m3, m2 +%else + paddd xmm6, xmm7 +%endif + paddd xmm0, xmm2 + paddd xmm3, xmm5 + paddd xmm2, xmm5 +%if notcpuflag(ssse3) + paddd xmm6, xmm5 +%endif + paddd xmm1, xmm3 + paddd xmm0, xmm3 + paddd xmm4, xmm2 + psrad xmm1, 14 + psrad xmm0, 14 + psrad xmm4, 14 +%if cpuflag(ssse3) + pmulhrsw m3, [pw_13377x2] ; out2 +%else + psrad xmm6, 14 +%endif + packssdw xmm0, xmm0 + packssdw xmm1, xmm1 + packssdw xmm4, xmm4 +%if notcpuflag(ssse3) + packssdw xmm6, xmm6 +%endif + movdq2q m0, xmm0 ; out3 + movdq2q m1, xmm1 ; out0 + movdq2q m2, xmm4 ; out1 +%if notcpuflag(ssse3) + movdq2q m3, xmm6 ; out2 +%endif + SWAP 0, 1, 2, 3 +%endmacro diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9lpf.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9lpf.asm new file mode 100644 index 00000000..4e7ede22 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9lpf.asm @@ -0,0 +1,1211 @@ +;****************************************************************************** +;* VP9 loop filter SIMD optimizations +;* +;* Copyright (C) 2013-2014 Clément Bœsch +;* Copyright (C) 2014 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +cextern pb_3 +cextern pb_80 + +pb_4: times 16 db 0x04 +pb_10: times 16 db 0x10 +pb_40: times 16 db 0x40 +pb_81: times 16 db 0x81 +pb_f8: times 16 db 0xf8 +pb_fe: times 16 db 0xfe +pb_ff: times 16 db 0xff + +cextern pw_4 +cextern pw_8 + +; with mix functions, two 8-bit thresholds are stored in a 16-bit storage, +; the following mask is used to splat both in the same register +mask_mix: times 8 db 0 + times 8 db 1 + +mask_mix84: times 8 db 0xff + times 8 db 0x00 +mask_mix48: times 8 db 0x00 + times 8 db 0xff + +SECTION .text + +%macro SCRATCH 3 +%ifdef m8 + SWAP %1, %2 +%else + mova [%3], m%1 +%endif +%endmacro + +%macro UNSCRATCH 3 +%ifdef m8 + SWAP %1, %2 +%else + mova m%1, [%3] +%endif +%endmacro + +; %1 = abs(%2-%3) +%macro ABSSUB 4 ; dst, src1 (RO), src2 (RO), tmp +%ifdef m8 + psubusb %1, %3, %2 + psubusb %4, %2, %3 +%else + mova %1, %3 + mova %4, %2 + psubusb %1, %2 + psubusb %4, %3 +%endif + por %1, %4 +%endmacro + +; %1 = %1>%2 +%macro CMP_GT 2-3 ; src/dst, cmp, pb_80 +%if %0 == 3 + pxor %1, %3 +%endif + pcmpgtb %1, %2 +%endmacro + +; %1 = abs(%2-%3) > %4 +%macro ABSSUB_GT 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80] + ABSSUB %1, %2, %3, %5 ; dst = abs(src1-src2) + CMP_GT %1, %4, %6 ; dst > cmp +%endmacro + +%macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp + pand %1, %3 ; new &= mask + pandn %4, %3, %2 ; tmp = ~mask & old + por %1, %4 ; new&mask | old&~mask +%endmacro + +%macro UNPACK 4 +%ifdef m8 + punpck%1bw %2, %3, %4 +%else + mova %2, %3 + punpck%1bw %2, %4 +%endif +%endmacro + +%macro FILTER_SUBx2_ADDx2 11 ; %1=dst %2=h/l %3=cache %4=stack_off %5=sub1 %6=sub2 %7=add1 + ; %8=add2 %9=rshift, [unpack], [unpack_is_mem_on_x86_32] + psubw %3, [rsp+%4+%5*mmsize*2] + psubw %3, [rsp+%4+%6*mmsize*2] + paddw %3, [rsp+%4+%7*mmsize*2] +%ifnidn %10, "" +%if %11 == 0 + punpck%2bw %1, %10, m0 +%else + UNPACK %2, %1, %10, m0 +%endif + mova [rsp+%4+%8*mmsize*2], %1 + paddw %3, %1 +%else + paddw %3, [rsp+%4+%8*mmsize*2] +%endif + psraw %1, %3, %9 +%endmacro + +; FIXME interleave l/h better (for instruction pairing) +%macro FILTER_INIT 9 ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, filterid, mask, source + FILTER%7_INIT %1, l, %3, %6 + 0 + FILTER%7_INIT %2, h, %4, %6 + mmsize + packuswb %1, %2 + MASK_APPLY %1, %9, %8, %2 + mova %5, %1 +%endmacro + + +%macro FILTER_UPDATE 12-16 "", "", "", 0 ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, -, -, +, +, rshift, + ; mask, [source], [unpack + src], [unpack_is_mem_on_x86_32] +; FIXME interleave this properly with the subx2/addx2 +%ifnidn %15, "" +%if %16 == 0 || ARCH_X86_64 + mova %14, %15 +%endif +%endif + FILTER_SUBx2_ADDx2 %1, l, %3, %6 + 0, %7, %8, %9, %10, %11, %14, %16 + FILTER_SUBx2_ADDx2 %2, h, %4, %6 + mmsize, %7, %8, %9, %10, %11, %14, %16 + packuswb %1, %2 +%ifnidn %13, "" + MASK_APPLY %1, %13, %12, %2 +%else + MASK_APPLY %1, %5, %12, %2 +%endif + mova %5, %1 +%endmacro + +%macro SRSHIFT3B_2X 4 ; reg1, reg2, [pb_10], tmp + mova %4, [pb_f8] + pand %1, %4 + pand %2, %4 + psrlq %1, 3 + psrlq %2, 3 + pxor %1, %3 + pxor %2, %3 + psubb %1, %3 + psubb %2, %3 +%endmacro + +%macro EXTRACT_POS_NEG 3 ; i8, neg, pos + pxor %3, %3 + pxor %2, %2 + pcmpgtb %3, %1 ; i8 < 0 mask + psubb %2, %1 ; neg values (only the originally - will be kept) + pand %2, %3 ; negative values of i8 (but stored as +) + pandn %3, %1 ; positive values of i8 +%endmacro + +; clip_u8(u8 + i8) +%macro SIGN_ADD 4 ; dst, u8, i8, tmp1 + EXTRACT_POS_NEG %3, %4, %1 + paddusb %1, %2 ; add the positives + psubusb %1, %4 ; sub the negatives +%endmacro + +; clip_u8(u8 - i8) +%macro SIGN_SUB 4 ; dst, u8, i8, tmp1 + EXTRACT_POS_NEG %3, %1, %4 + paddusb %1, %2 ; add the negatives + psubusb %1, %4 ; sub the positives +%endmacro + +%macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off + UNPACK %2, %1, rp3, m0 ; p3: B->W + mova [rsp+%4+0*mmsize*2], %1 + paddw %3, %1, %1 ; p3*2 + paddw %3, %1 ; p3*3 + punpck%2bw %1, m1, m0 ; p2: B->W + mova [rsp+%4+1*mmsize*2], %1 + paddw %3, %1 ; p3*3 + p2 + paddw %3, %1 ; p3*3 + p2*2 + UNPACK %2, %1, rp1, m0 ; p1: B->W + mova [rsp+%4+2*mmsize*2], %1 + paddw %3, %1 ; p3*3 + p2*2 + p1 + UNPACK %2, %1, rp0, m0 ; p0: B->W + mova [rsp+%4+3*mmsize*2], %1 + paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 + UNPACK %2, %1, rq0, m0 ; q0: B->W + mova [rsp+%4+4*mmsize*2], %1 + paddw %3, %1 ; p3*3 + p2*2 + p1 + p0 + q0 + paddw %3, [pw_4] ; p3*3 + p2*2 + p1 + p0 + q0 + 4 + psraw %1, %3, 3 ; (p3*3 + p2*2 + p1 + p0 + q0 + 4) >> 3 +%endmacro + +%macro FILTER14_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off + punpck%2bw %1, m2, m0 ; p7: B->W + mova [rsp+%4+ 8*mmsize*2], %1 + psllw %3, %1, 3 ; p7*8 + psubw %3, %1 ; p7*7 + punpck%2bw %1, m3, m0 ; p6: B->W + mova [rsp+%4+ 9*mmsize*2], %1 + paddw %3, %1 ; p7*7 + p6 + paddw %3, %1 ; p7*7 + p6*2 + UNPACK %2, %1, rp5, m0 ; p5: B->W + mova [rsp+%4+10*mmsize*2], %1 + paddw %3, %1 ; p7*7 + p6*2 + p5 + UNPACK %2, %1, rp4, m0 ; p4: B->W + mova [rsp+%4+11*mmsize*2], %1 + paddw %3, %1 ; p7*7 + p6*2 + p5 + p4 + paddw %3, [rsp+%4+ 0*mmsize*2] ; p7*7 + p6*2 + p5 + p4 + p3 + paddw %3, [rsp+%4+ 1*mmsize*2] ; p7*7 + p6*2 + p5 + .. + p2 + paddw %3, [rsp+%4+ 2*mmsize*2] ; p7*7 + p6*2 + p5 + .. + p1 + paddw %3, [rsp+%4+ 3*mmsize*2] ; p7*7 + p6*2 + p5 + .. + p0 + paddw %3, [rsp+%4+ 4*mmsize*2] ; p7*7 + p6*2 + p5 + .. + p0 + q0 + paddw %3, [pw_8] ; p7*7 + p6*2 + p5 + .. + p0 + q0 + 8 + psraw %1, %3, 4 ; (p7*7 + p6*2 + p5 + .. + p0 + q0 + 8) >> 4 +%endmacro + +%macro TRANSPOSE16x16B 17 + mova %17, m%16 + SBUTTERFLY bw, %1, %2, %16 + SBUTTERFLY bw, %3, %4, %16 + SBUTTERFLY bw, %5, %6, %16 + SBUTTERFLY bw, %7, %8, %16 + SBUTTERFLY bw, %9, %10, %16 + SBUTTERFLY bw, %11, %12, %16 + SBUTTERFLY bw, %13, %14, %16 + mova m%16, %17 + mova %17, m%14 + SBUTTERFLY bw, %15, %16, %14 + SBUTTERFLY wd, %1, %3, %14 + SBUTTERFLY wd, %2, %4, %14 + SBUTTERFLY wd, %5, %7, %14 + SBUTTERFLY wd, %6, %8, %14 + SBUTTERFLY wd, %9, %11, %14 + SBUTTERFLY wd, %10, %12, %14 + SBUTTERFLY wd, %13, %15, %14 + mova m%14, %17 + mova %17, m%12 + SBUTTERFLY wd, %14, %16, %12 + SBUTTERFLY dq, %1, %5, %12 + SBUTTERFLY dq, %2, %6, %12 + SBUTTERFLY dq, %3, %7, %12 + SBUTTERFLY dq, %4, %8, %12 + SBUTTERFLY dq, %9, %13, %12 + SBUTTERFLY dq, %10, %14, %12 + SBUTTERFLY dq, %11, %15, %12 + mova m%12, %17 + mova %17, m%8 + SBUTTERFLY dq, %12, %16, %8 + SBUTTERFLY qdq, %1, %9, %8 + SBUTTERFLY qdq, %2, %10, %8 + SBUTTERFLY qdq, %3, %11, %8 + SBUTTERFLY qdq, %4, %12, %8 + SBUTTERFLY qdq, %5, %13, %8 + SBUTTERFLY qdq, %6, %14, %8 + SBUTTERFLY qdq, %7, %15, %8 + mova m%8, %17 + mova %17, m%1 + SBUTTERFLY qdq, %8, %16, %1 + mova m%1, %17 + SWAP %2, %9 + SWAP %3, %5 + SWAP %4, %13 + SWAP %6, %11 + SWAP %8, %15 + SWAP %12, %14 +%endmacro + +%macro TRANSPOSE8x8B 13 + SBUTTERFLY bw, %1, %2, %7 + movdq%10 m%7, %9 + movdqa %11, m%2 + SBUTTERFLY bw, %3, %4, %2 + SBUTTERFLY bw, %5, %6, %2 + SBUTTERFLY bw, %7, %8, %2 + SBUTTERFLY wd, %1, %3, %2 + movdqa m%2, %11 + movdqa %11, m%3 + SBUTTERFLY wd, %2, %4, %3 + SBUTTERFLY wd, %5, %7, %3 + SBUTTERFLY wd, %6, %8, %3 + SBUTTERFLY dq, %1, %5, %3 + SBUTTERFLY dq, %2, %6, %3 + movdqa m%3, %11 + movh %12, m%2 + movhps %13, m%2 + SBUTTERFLY dq, %3, %7, %2 + SBUTTERFLY dq, %4, %8, %2 + SWAP %2, %5 + SWAP %4, %7 +%endmacro + +%macro DEFINE_REAL_P7_TO_Q7 0-1 0 +%define P7 dstq + 4*mstrideq + %1 +%define P6 dstq + mstride3q + %1 +%define P5 dstq + 2*mstrideq + %1 +%define P4 dstq + mstrideq + %1 +%define P3 dstq + %1 +%define P2 dstq + strideq + %1 +%define P1 dstq + 2* strideq + %1 +%define P0 dstq + stride3q + %1 +%define Q0 dstq + 4* strideq + %1 +%define Q1 dst2q + mstride3q + %1 +%define Q2 dst2q + 2*mstrideq + %1 +%define Q3 dst2q + mstrideq + %1 +%define Q4 dst2q + %1 +%define Q5 dst2q + strideq + %1 +%define Q6 dst2q + 2* strideq + %1 +%define Q7 dst2q + stride3q + %1 +%endmacro + +%macro DEFINE_TRANSPOSED_P7_TO_Q7 0-1 0 +%define P3 rsp + 0*mmsize + %1 +%define P2 rsp + 1*mmsize + %1 +%define P1 rsp + 2*mmsize + %1 +%define P0 rsp + 3*mmsize + %1 +%define Q0 rsp + 4*mmsize + %1 +%define Q1 rsp + 5*mmsize + %1 +%define Q2 rsp + 6*mmsize + %1 +%define Q3 rsp + 7*mmsize + %1 +%if mmsize == 16 +%define P7 rsp + 8*mmsize + %1 +%define P6 rsp + 9*mmsize + %1 +%define P5 rsp + 10*mmsize + %1 +%define P4 rsp + 11*mmsize + %1 +%define Q4 rsp + 12*mmsize + %1 +%define Q5 rsp + 13*mmsize + %1 +%define Q6 rsp + 14*mmsize + %1 +%define Q7 rsp + 15*mmsize + %1 +%endif +%endmacro + +; ..............AB -> AAAAAAAABBBBBBBB +%macro SPLATB_MIX 1-2 [mask_mix] +%if cpuflag(ssse3) + pshufb %1, %2 +%else + punpcklbw %1, %1 + punpcklwd %1, %1 + punpckldq %1, %1 +%endif +%endmacro + +%macro LOOPFILTER 5 ; %1=v/h %2=size1 %3+%4=stack, %5=mmx/32bit stack only +%assign %%ext 0 +%if ARCH_X86_32 || mmsize == 8 +%assign %%ext %5 +%endif + +%if UNIX64 +cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 5, 9, 16, %3 + %4 + %%ext, dst, stride, E, I, H, mstride, dst2, stride3, mstride3 +%else +%if WIN64 +cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 4, 8, 16, %3 + %4 + %%ext, dst, stride, E, I, mstride, dst2, stride3, mstride3 +%else +cglobal vp9_loop_filter_%1_%2_ %+ mmsize, 2, 6, 16, %3 + %4 + %%ext, dst, stride, mstride, dst2, stride3, mstride3 +%define Ed dword r2m +%define Id dword r3m +%endif +%define Hd dword r4m +%endif + + mov mstrideq, strideq + neg mstrideq + + lea stride3q, [strideq*3] + lea mstride3q, [mstrideq*3] + +%ifidn %1, h +%if %2 != 16 +%if mmsize == 16 +%define movx movh +%else +%define movx mova +%endif + lea dstq, [dstq + 4*strideq - 4] +%else +%define movx movu + lea dstq, [dstq + 4*strideq - 8] ; go from top center (h pos) to center left (v pos) +%endif +%else + lea dstq, [dstq + 4*mstrideq] +%endif + ; FIXME we shouldn't need two dts registers if mmsize == 8 + lea dst2q, [dstq + 8*strideq] + + DEFINE_REAL_P7_TO_Q7 + +%ifidn %1, h + movx m0, [P7] + movx m1, [P6] + movx m2, [P5] + movx m3, [P4] + movx m4, [P3] + movx m5, [P2] +%if (ARCH_X86_64 && mmsize == 16) || %2 > 16 + movx m6, [P1] +%endif + movx m7, [P0] +%ifdef m8 + movx m8, [Q0] + movx m9, [Q1] + movx m10, [Q2] + movx m11, [Q3] + movx m12, [Q4] + movx m13, [Q5] + movx m14, [Q6] + movx m15, [Q7] + DEFINE_TRANSPOSED_P7_TO_Q7 +%if %2 == 16 + TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] + mova [P7], m0 + mova [P6], m1 + mova [P5], m2 + mova [P4], m3 +%else ; %2 == 44/48/84/88 + ; 8x16 transpose + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 + punpcklbw m8, m9 + punpcklbw m10, m11 + punpcklbw m12, m13 + punpcklbw m14, m15 + TRANSPOSE8x8W 0, 2, 4, 6, 8, 10, 12, 14, 15 + SWAP 0, 4 + SWAP 2, 5 + SWAP 0, 6 + SWAP 0, 7 + SWAP 10, 9 + SWAP 12, 10 + SWAP 14, 11 +%endif ; %2 + mova [P3], m4 + mova [P2], m5 + mova [P1], m6 + mova [P0], m7 + mova [Q0], m8 + mova [Q1], m9 + mova [Q2], m10 + mova [Q3], m11 +%if %2 == 16 + mova [Q4], m12 + mova [Q5], m13 + mova [Q6], m14 + mova [Q7], m15 +%endif ; %2 +%else ; x86-32 +%if %2 == 16 + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [P1], u, [rsp+%3+%4], [rsp+64], [rsp+80] + DEFINE_TRANSPOSED_P7_TO_Q7 + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 + DEFINE_REAL_P7_TO_Q7 + movx m0, [Q0] + movx m1, [Q1] + movx m2, [Q2] + movx m3, [Q3] + movx m4, [Q4] + movx m5, [Q5] + movx m7, [Q7] + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [Q6], u, [rsp+%3+%4], [rsp+72], [rsp+88] + DEFINE_TRANSPOSED_P7_TO_Q7 8 + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 + DEFINE_TRANSPOSED_P7_TO_Q7 +%elif %2 > 16 ; %2 == 44/48/84/88 + punpcklbw m0, m1 + punpcklbw m2, m3 + punpcklbw m4, m5 + punpcklbw m6, m7 + movx m1, [Q0] + movx m3, [Q1] + movx m5, [Q2] + movx m7, [Q3] + punpcklbw m1, m3 + punpcklbw m5, m7 + movx m3, [Q4] + movx m7, [Q5] + punpcklbw m3, m7 + mova [rsp], m3 + movx m3, [Q6] + movx m7, [Q7] + punpcklbw m3, m7 + DEFINE_TRANSPOSED_P7_TO_Q7 + TRANSPOSE8x8W 0, 2, 4, 6, 1, 5, 7, 3, [rsp], [Q0], 1 + mova [P3], m0 + mova [P2], m2 + mova [P1], m4 + mova [P0], m6 + mova [Q1], m5 + mova [Q2], m7 + mova [Q3], m3 +%else ; %2 == 4 || %2 == 8 + SBUTTERFLY bw, 0, 1, 6 + SBUTTERFLY bw, 2, 3, 6 + SBUTTERFLY bw, 4, 5, 6 + mova [rsp+4*mmsize], m5 + mova m6, [P1] + SBUTTERFLY bw, 6, 7, 5 + DEFINE_TRANSPOSED_P7_TO_Q7 + TRANSPOSE4x4W 0, 2, 4, 6, 5 + mova [P3], m0 + mova [P2], m2 + mova [P1], m4 + mova [P0], m6 + mova m5, [rsp+4*mmsize] + TRANSPOSE4x4W 1, 3, 5, 7, 0 + mova [Q0], m1 + mova [Q1], m3 + mova [Q2], m5 + mova [Q3], m7 +%endif ; %2 +%endif ; x86-32/64 +%endif ; %1 == h + + ; calc fm mask +%if %2 == 16 || mmsize == 8 +%if cpuflag(ssse3) + pxor m0, m0 +%endif + SPLATB_REG m2, I, m0 ; I I I I ... + SPLATB_REG m3, E, m0 ; E E E E ... +%else +%if cpuflag(ssse3) + mova m0, [mask_mix] +%endif + movd m2, Id + movd m3, Ed + SPLATB_MIX m2, m0 + SPLATB_MIX m3, m0 +%endif + mova m0, [pb_80] + pxor m2, m0 + pxor m3, m0 +%ifdef m8 +%ifidn %1, v + mova m8, [P3] + mova m9, [P2] + mova m10, [P1] + mova m11, [P0] + mova m12, [Q0] + mova m13, [Q1] + mova m14, [Q2] + mova m15, [Q3] +%else + ; In case of horizontal, P3..Q3 are already present in some registers due + ; to the previous transpose, so we just swap registers. + SWAP 8, 4, 12 + SWAP 9, 5, 13 + SWAP 10, 6, 14 + SWAP 11, 7, 15 +%endif +%define rp3 m8 +%define rp2 m9 +%define rp1 m10 +%define rp0 m11 +%define rq0 m12 +%define rq1 m13 +%define rq2 m14 +%define rq3 m15 +%else +%define rp3 [P3] +%define rp2 [P2] +%define rp1 [P1] +%define rp0 [P0] +%define rq0 [Q0] +%define rq1 [Q1] +%define rq2 [Q2] +%define rq3 [Q3] +%endif + ABSSUB_GT m5, rp3, rp2, m2, m7, m0 ; m5 = abs(p3-p2) <= I + ABSSUB_GT m1, rp2, rp1, m2, m7, m0 ; m1 = abs(p2-p1) <= I + por m5, m1 + ABSSUB_GT m1, rp1, rp0, m2, m7, m0 ; m1 = abs(p1-p0) <= I + por m5, m1 + ABSSUB_GT m1, rq0, rq1, m2, m7, m0 ; m1 = abs(q1-q0) <= I + por m5, m1 + ABSSUB_GT m1, rq1, rq2, m2, m7, m0 ; m1 = abs(q2-q1) <= I + por m5, m1 + ABSSUB_GT m1, rq2, rq3, m2, m7, m0 ; m1 = abs(q3-q2) <= I + por m5, m1 + ABSSUB m1, rp0, rq0, m7 ; abs(p0-q0) + paddusb m1, m1 ; abs(p0-q0) * 2 + ABSSUB m2, rp1, rq1, m7 ; abs(p1-q1) + pand m2, [pb_fe] ; drop lsb so shift can work + psrlq m2, 1 ; abs(p1-q1)/2 + paddusb m1, m2 ; abs(p0-q0)*2 + abs(p1-q1)/2 + pxor m1, m0 + pcmpgtb m1, m3 + por m1, m5 ; fm final value + SWAP 1, 3 + pxor m3, [pb_ff] + + ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3) + ; calc flat8in (if not 44_16) and hev masks +%if %2 != 44 && %2 != 4 + mova m6, [pb_81] ; [1 1 1 1 ...] ^ 0x80 + ABSSUB_GT m2, rp3, rp0, m6, m5 ; abs(p3 - p0) <= 1 +%ifdef m8 + mova m8, [pb_80] +%define rb80 m8 +%else +%define rb80 [pb_80] +%endif + ABSSUB_GT m1, rp2, rp0, m6, m5, rb80 ; abs(p2 - p0) <= 1 + por m2, m1 + ABSSUB m4, rp1, rp0, m5 ; abs(p1 - p0) +%if %2 <= 16 +%if cpuflag(ssse3) + pxor m0, m0 +%endif + SPLATB_REG m7, H, m0 ; H H H H ... +%else + movd m7, Hd + SPLATB_MIX m7 +%endif + pxor m7, rb80 + pxor m4, rb80 + pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) + CMP_GT m4, m6 ; abs(p1 - p0) <= 1 + por m2, m4 ; (flat8in) + ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) + pxor m4, rb80 + pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) + por m0, m5 ; hev final value + CMP_GT m4, m6 ; abs(q1 - q0) <= 1 + por m2, m4 ; (flat8in) + ABSSUB_GT m1, rq2, rq0, m6, m5, rb80 ; abs(q2 - q0) <= 1 + por m2, m1 + ABSSUB_GT m1, rq3, rq0, m6, m5, rb80 ; abs(q3 - q0) <= 1 + por m2, m1 ; flat8in final value + pxor m2, [pb_ff] +%if %2 == 84 || %2 == 48 + pand m2, [mask_mix%2] +%endif +%else + mova m6, [pb_80] +%if %2 == 44 + movd m7, Hd + SPLATB_MIX m7 +%else +%if cpuflag(ssse3) + pxor m0, m0 +%endif + SPLATB_REG m7, H, m0 ; H H H H ... +%endif + pxor m7, m6 + ABSSUB m4, rp1, rp0, m1 ; abs(p1 - p0) + pxor m4, m6 + pcmpgtb m0, m4, m7 ; abs(p1 - p0) > H (1/2 hev condition) + ABSSUB m4, rq1, rq0, m1 ; abs(q1 - q0) + pxor m4, m6 + pcmpgtb m5, m4, m7 ; abs(q1 - q0) > H (2/2 hev condition) + por m0, m5 ; hev final value +%endif + +%if %2 == 16 + ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3) + ; calc flat8out mask +%ifdef m8 + mova m8, [P7] + mova m9, [P6] +%define rp7 m8 +%define rp6 m9 +%else +%define rp7 [P7] +%define rp6 [P6] +%endif + ABSSUB_GT m1, rp7, rp0, m6, m5 ; abs(p7 - p0) <= 1 + ABSSUB_GT m7, rp6, rp0, m6, m5 ; abs(p6 - p0) <= 1 + por m1, m7 +%ifdef m8 + mova m8, [P5] + mova m9, [P4] +%define rp5 m8 +%define rp4 m9 +%else +%define rp5 [P5] +%define rp4 [P4] +%endif + ABSSUB_GT m7, rp5, rp0, m6, m5 ; abs(p5 - p0) <= 1 + por m1, m7 + ABSSUB_GT m7, rp4, rp0, m6, m5 ; abs(p4 - p0) <= 1 + por m1, m7 +%ifdef m8 + mova m14, [Q4] + mova m15, [Q5] +%define rq4 m14 +%define rq5 m15 +%else +%define rq4 [Q4] +%define rq5 [Q5] +%endif + ABSSUB_GT m7, rq4, rq0, m6, m5 ; abs(q4 - q0) <= 1 + por m1, m7 + ABSSUB_GT m7, rq5, rq0, m6, m5 ; abs(q5 - q0) <= 1 + por m1, m7 +%ifdef m8 + mova m14, [Q6] + mova m15, [Q7] +%define rq6 m14 +%define rq7 m15 +%else +%define rq6 [Q6] +%define rq7 [Q7] +%endif + ABSSUB_GT m7, rq6, rq0, m6, m5 ; abs(q4 - q0) <= 1 + por m1, m7 + ABSSUB_GT m7, rq7, rq0, m6, m5 ; abs(q5 - q0) <= 1 + por m1, m7 ; flat8out final value + pxor m1, [pb_ff] +%endif + + ; if (fm) { + ; if (out && in) filter_14() + ; else if (in) filter_6() + ; else if (hev) filter_2() + ; else filter_4() + ; } + ; + ; f14: fm & out & in + ; f6: fm & ~f14 & in => fm & ~(out & in) & in => fm & ~out & in + ; f2: fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev => fm & ~in & hev + ; f4: fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm & ~in & ~hev + + ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7) + ; filter2() +%if %2 != 44 && %2 != 4 + mova m6, [pb_80] ; already in m6 if 44_16 + SCRATCH 2, 15, rsp+%3+%4 +%if %2 == 16 + SCRATCH 1, 8, rsp+%3+%4+16 +%endif +%endif + pxor m2, m6, rq0 ; q0 ^ 0x80 + pxor m4, m6, rp0 ; p0 ^ 0x80 + psubsb m2, m4 ; (signed) q0 - p0 + pxor m4, m6, rp1 ; p1 ^ 0x80 + pxor m5, m6, rq1 ; q1 ^ 0x80 + psubsb m4, m5 ; (signed) p1 - q1 + paddsb m4, m2 ; (q0 - p0) + (p1 - q1) + paddsb m4, m2 ; 2*(q0 - p0) + (p1 - q1) + paddsb m4, m2 ; 3*(q0 - p0) + (p1 - q1) + paddsb m6, m4, [pb_4] ; m6: f1 = clip(f + 4, 127) + paddsb m4, [pb_3] ; m4: f2 = clip(f + 3, 127) +%ifdef m8 + mova m14, [pb_10] ; will be reused in filter4() +%define rb10 m14 +%else +%define rb10 [pb_10] +%endif + SRSHIFT3B_2X m6, m4, rb10, m7 ; f1 and f2 sign byte shift by 3 + SIGN_SUB m7, rq0, m6, m5 ; m7 = q0 - f1 + SIGN_ADD m1, rp0, m4, m5 ; m1 = p0 + f2 +%if %2 != 44 && %2 != 4 +%ifdef m8 + pandn m6, m15, m3 ; ~mask(in) & mask(fm) +%else + mova m6, [rsp+%3+%4] + pandn m6, m3 +%endif + pand m6, m0 ; (~mask(in) & mask(fm)) & mask(hev) +%else + pand m6, m3, m0 +%endif + MASK_APPLY m7, rq0, m6, m5 ; m7 = filter2(q0) & mask / we write it in filter4() + MASK_APPLY m1, rp0, m6, m5 ; m1 = filter2(p0) & mask / we write it in filter4() + + ; (m0: hev, m1: p0', m2: q0-p0, m3: fm, m7: q0', [m8: flat8out], m10..13: p1 p0 q0 q1, m14: pb_10, [m15: flat8in], ) + ; filter4() + mova m4, m2 + paddsb m2, m4 ; 2 * (q0 - p0) + paddsb m2, m4 ; 3 * (q0 - p0) + paddsb m6, m2, [pb_4] ; m6: f1 = clip(f + 4, 127) + paddsb m2, [pb_3] ; m2: f2 = clip(f + 3, 127) + SRSHIFT3B_2X m6, m2, rb10, m4 ; f1 and f2 sign byte shift by 3 +%if %2 != 44 && %2 != 4 +%ifdef m8 + pandn m5, m15, m3 ; ~mask(in) & mask(fm) +%else + mova m5, [rsp+%3+%4] + pandn m5, m3 +%endif + pandn m0, m5 ; ~mask(hev) & (~mask(in) & mask(fm)) +%else + pandn m0, m3 +%endif + SIGN_SUB m5, rq0, m6, m4 ; q0 - f1 + MASK_APPLY m5, m7, m0, m4 ; filter4(q0) & mask + mova [Q0], m5 + SIGN_ADD m7, rp0, m2, m4 ; p0 + f2 + MASK_APPLY m7, m1, m0, m4 ; filter4(p0) & mask + mova [P0], m7 + paddb m6, [pb_80] ; + pxor m1, m1 ; f=(f1+1)>>1 + pavgb m6, m1 ; + psubb m6, [pb_40] ; + SIGN_ADD m1, rp1, m6, m2 ; p1 + f + SIGN_SUB m4, rq1, m6, m2 ; q1 - f + MASK_APPLY m1, rp1, m0, m2 ; m1 = filter4(p1) + MASK_APPLY m4, rq1, m0, m2 ; m4 = filter4(q1) + mova [P1], m1 + mova [Q1], m4 + +%if %2 != 44 && %2 != 4 + UNSCRATCH 2, 15, rsp+%3+%4 +%endif + + ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1) + ; filter6() +%if %2 != 44 && %2 != 4 + pxor m0, m0 +%if %2 != 16 + pand m3, m2 +%else + pand m2, m3 ; mask(fm) & mask(in) +%ifdef m8 + pandn m3, m8, m2 ; ~mask(out) & (mask(fm) & mask(in)) +%else + mova m3, [rsp+%3+%4+16] + pandn m3, m2 +%endif +%endif +%ifdef m8 + mova m14, [P3] + mova m9, [Q3] +%define rp3 m14 +%define rq3 m9 +%else +%define rp3 [P3] +%define rq3 [Q3] +%endif + mova m1, [P2] + FILTER_INIT m4, m5, m6, m7, [P2], %4, 6, m3, m1 ; [p2] + mova m1, [Q2] + FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 0, 1, 2, 5, 3, m3, "", rq1, "", 1 ; [p1] -p3 -p2 +p1 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3, "", m1 ; [p0] -p3 -p1 +p0 +q2 + FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 0, 3, 4, 7, 3, m3, "", rq3, "", 1 ; [q0] -p3 -p0 +q0 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 1, 4, 5, 7, 3, m3, "" ; [q1] -p2 -q0 +q1 +q3 + FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3, m1 ; [q2] -p1 -q1 +q2 +q3 +%endif + +%if %2 == 16 + UNSCRATCH 1, 8, rsp+%3+%4+16 +%endif + + ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2) + ; filter14() + ; + ; m2 m3 m8 m9 m14 m15 m10 m11 m12 m13 + ; + ; q2 q3 p3 p2 p1 p0 q0 q1 + ; p6 -7 p7 p6 p5 p4 . . . . . + ; p5 -6 -p7 -p6 +p5 +q1 . . . . + ; p4 -5 -p7 -p5 +p4 +q2 . . . q2 + ; p3 -4 -p7 -p4 +p3 +q3 . . . q3 + ; p2 -3 -p7 -p3 +p2 +q4 . . . q4 + ; p1 -2 -p7 -p2 +p1 +q5 . . . q5 + ; p0 -1 -p7 -p1 +p0 +q6 . . . q6 + ; q0 +0 -p7 -p0 +q0 +q7 . . . q7 + ; q1 +1 -p6 -q0 +q1 +q7 q1 . . . + ; q2 +2 -p5 -q1 +q2 +q7 . q2 . . + ; q3 +3 -p4 -q2 +q3 +q7 . q3 . . + ; q4 +4 -p3 -q3 +q4 +q7 . q4 . . + ; q5 +5 -p2 -q4 +q5 +q7 . q5 . . + ; q6 +6 -p1 -q5 +q6 +q7 . q6 . . + +%if %2 == 16 + pand m1, m2 ; mask(out) & (mask(fm) & mask(in)) + mova m2, [P7] + mova m3, [P6] +%ifdef m8 + mova m8, [P5] + mova m9, [P4] +%define rp5 m8 +%define rp4 m9 +%define rp5s m8 +%define rp4s m9 +%define rp3s m14 +%define rq4 m8 +%define rq5 m9 +%define rq6 m14 +%define rq7 m15 +%define rq4s m8 +%define rq5s m9 +%define rq6s m14 +%else +%define rp5 [P5] +%define rp4 [P4] +%define rp5s "" +%define rp4s "" +%define rp3s "" +%define rq4 [Q4] +%define rq5 [Q5] +%define rq6 [Q6] +%define rq7 [Q7] +%define rq4s "" +%define rq5s "" +%define rq6s "" +%endif + FILTER_INIT m4, m5, m6, m7, [P6], %4, 14, m1, m3 ; [p6] + FILTER_UPDATE m4, m5, m6, m7, [P5], %4, 8, 9, 10, 5, 4, m1, rp5s ; [p5] -p7 -p6 +p5 +q1 + FILTER_UPDATE m4, m5, m6, m7, [P4], %4, 8, 10, 11, 6, 4, m1, rp4s ; [p4] -p7 -p5 +p4 +q2 + FILTER_UPDATE m4, m5, m6, m7, [P3], %4, 8, 11, 0, 7, 4, m1, rp3s ; [p3] -p7 -p4 +p3 +q3 + FILTER_UPDATE m4, m5, m6, m7, [P2], %4, 8, 0, 1, 12, 4, m1, "", rq4, [Q4], 1 ; [p2] -p7 -p3 +p2 +q4 + FILTER_UPDATE m4, m5, m6, m7, [P1], %4, 8, 1, 2, 13, 4, m1, "", rq5, [Q5], 1 ; [p1] -p7 -p2 +p1 +q5 + FILTER_UPDATE m4, m5, m6, m7, [P0], %4, 8, 2, 3, 14, 4, m1, "", rq6, [Q6], 1 ; [p0] -p7 -p1 +p0 +q6 + FILTER_UPDATE m4, m5, m6, m7, [Q0], %4, 8, 3, 4, 15, 4, m1, "", rq7, [Q7], 1 ; [q0] -p7 -p0 +q0 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q1], %4, 9, 4, 5, 15, 4, m1, "" ; [q1] -p6 -q0 +q1 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q2], %4, 10, 5, 6, 15, 4, m1, "" ; [q2] -p5 -q1 +q2 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q3], %4, 11, 6, 7, 15, 4, m1, "" ; [q3] -p4 -q2 +q3 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q4], %4, 0, 7, 12, 15, 4, m1, rq4s ; [q4] -p3 -q3 +q4 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q5], %4, 1, 12, 13, 15, 4, m1, rq5s ; [q5] -p2 -q4 +q5 +q7 + FILTER_UPDATE m4, m5, m6, m7, [Q6], %4, 2, 13, 14, 15, 4, m1, rq6s ; [q6] -p1 -q5 +q6 +q7 +%endif + +%ifidn %1, h +%if %2 == 16 + mova m0, [P7] + mova m1, [P6] + mova m2, [P5] + mova m3, [P4] + mova m4, [P3] + mova m5, [P2] +%if ARCH_X86_64 + mova m6, [P1] +%endif + mova m7, [P0] +%if ARCH_X86_64 + mova m8, [Q0] + mova m9, [Q1] + mova m10, [Q2] + mova m11, [Q3] + mova m12, [Q4] + mova m13, [Q5] + mova m14, [Q6] + mova m15, [Q7] + TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp] + DEFINE_REAL_P7_TO_Q7 + movu [P7], m0 + movu [P6], m1 + movu [P5], m2 + movu [P4], m3 + movu [P3], m4 + movu [P2], m5 + movu [P1], m6 + movu [P0], m7 + movu [Q0], m8 + movu [Q1], m9 + movu [Q2], m10 + movu [Q3], m11 + movu [Q4], m12 + movu [Q5], m13 + movu [Q6], m14 + movu [Q7], m15 +%else + DEFINE_REAL_P7_TO_Q7 + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [rsp+32], a, [rsp+%3+%4], [Q0], [Q1] + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 + DEFINE_TRANSPOSED_P7_TO_Q7 + mova m0, [Q0] + mova m1, [Q1] + mova m2, [Q2] + mova m3, [Q3] + mova m4, [Q4] + mova m5, [Q5] + mova m7, [Q7] + DEFINE_REAL_P7_TO_Q7 8 + TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [rsp+224], a, [rsp+%3+%4], [Q0], [Q1] + movh [P7], m0 + movh [P5], m1 + movh [P3], m2 + movh [P1], m3 + movh [Q2], m5 + movh [Q4], m6 + movh [Q6], m7 + movhps [P6], m0 + movhps [P4], m1 + movhps [P2], m2 + movhps [P0], m3 + movhps [Q3], m5 + movhps [Q5], m6 + movhps [Q7], m7 +%endif +%elif %2 == 44 || %2 == 4 + SWAP 0, 1 ; m0 = p1 + SWAP 1, 7 ; m1 = p0 + SWAP 2, 5 ; m2 = q0 + SWAP 3, 4 ; m3 = q1 + DEFINE_REAL_P7_TO_Q7 2 + SBUTTERFLY bw, 0, 1, 4 + SBUTTERFLY bw, 2, 3, 4 + SBUTTERFLY wd, 0, 2, 4 + SBUTTERFLY wd, 1, 3, 4 +%if mmsize == 16 + movd [P7], m0 + movd [P3], m2 + movd [Q0], m1 + movd [Q4], m3 + psrldq m0, 4 + psrldq m1, 4 + psrldq m2, 4 + psrldq m3, 4 + movd [P6], m0 + movd [P2], m2 + movd [Q1], m1 + movd [Q5], m3 + psrldq m0, 4 + psrldq m1, 4 + psrldq m2, 4 + psrldq m3, 4 + movd [P5], m0 + movd [P1], m2 + movd [Q2], m1 + movd [Q6], m3 + psrldq m0, 4 + psrldq m1, 4 + psrldq m2, 4 + psrldq m3, 4 + movd [P4], m0 + movd [P0], m2 + movd [Q3], m1 + movd [Q7], m3 +%else + movd [P7], m0 + movd [P5], m2 + movd [P3], m1 + movd [P1], m3 + psrlq m0, 32 + psrlq m2, 32 + psrlq m1, 32 + psrlq m3, 32 + movd [P6], m0 + movd [P4], m2 + movd [P2], m1 + movd [P0], m3 +%endif +%else + ; the following code do a transpose of 8 full lines to 16 half + ; lines (high part). It is inlined to avoid the need of a staging area + mova m0, [P3] + mova m1, [P2] + mova m2, [P1] + mova m3, [P0] + mova m4, [Q0] + mova m5, [Q1] +%ifdef m8 + mova m6, [Q2] +%endif + mova m7, [Q3] + DEFINE_REAL_P7_TO_Q7 +%ifdef m8 + SBUTTERFLY bw, 0, 1, 8 + SBUTTERFLY bw, 2, 3, 8 + SBUTTERFLY bw, 4, 5, 8 + SBUTTERFLY bw, 6, 7, 8 + SBUTTERFLY wd, 0, 2, 8 + SBUTTERFLY wd, 1, 3, 8 + SBUTTERFLY wd, 4, 6, 8 + SBUTTERFLY wd, 5, 7, 8 + SBUTTERFLY dq, 0, 4, 8 + SBUTTERFLY dq, 1, 5, 8 + SBUTTERFLY dq, 2, 6, 8 + SBUTTERFLY dq, 3, 7, 8 +%else + SBUTTERFLY bw, 0, 1, 6 + mova [rsp+mmsize*4], m1 + mova m6, [rsp+mmsize*6] + SBUTTERFLY bw, 2, 3, 1 + SBUTTERFLY bw, 4, 5, 1 + SBUTTERFLY bw, 6, 7, 1 + SBUTTERFLY wd, 0, 2, 1 + mova [rsp+mmsize*6], m2 + mova m1, [rsp+mmsize*4] + SBUTTERFLY wd, 1, 3, 2 + SBUTTERFLY wd, 4, 6, 2 + SBUTTERFLY wd, 5, 7, 2 + SBUTTERFLY dq, 0, 4, 2 + SBUTTERFLY dq, 1, 5, 2 +%if mmsize == 16 + movh [Q0], m1 + movhps [Q1], m1 +%else + mova [P3], m1 +%endif + mova m2, [rsp+mmsize*6] + SBUTTERFLY dq, 2, 6, 1 + SBUTTERFLY dq, 3, 7, 1 +%endif + SWAP 3, 6 + SWAP 1, 4 +%if mmsize == 16 + movh [P7], m0 + movhps [P6], m0 + movh [P5], m1 + movhps [P4], m1 + movh [P3], m2 + movhps [P2], m2 + movh [P1], m3 + movhps [P0], m3 +%ifdef m8 + movh [Q0], m4 + movhps [Q1], m4 +%endif + movh [Q2], m5 + movhps [Q3], m5 + movh [Q4], m6 + movhps [Q5], m6 + movh [Q6], m7 + movhps [Q7], m7 +%else + mova [P7], m0 + mova [P6], m1 + mova [P5], m2 + mova [P4], m3 + mova [P2], m5 + mova [P1], m6 + mova [P0], m7 +%endif +%endif +%endif + + RET +%endmacro + +%macro LPF_16_VH 5 +INIT_XMM %5 +LOOPFILTER v, %1, %2, 0, %4 +LOOPFILTER h, %1, %2, %3, %4 +%endmacro + +%macro LPF_16_VH_ALL_OPTS 4 +LPF_16_VH %1, %2, %3, %4, sse2 +LPF_16_VH %1, %2, %3, %4, ssse3 +LPF_16_VH %1, %2, %3, %4, avx +%endmacro + +LPF_16_VH_ALL_OPTS 16, 512, 256, 32 +LPF_16_VH_ALL_OPTS 44, 0, 128, 0 +LPF_16_VH_ALL_OPTS 48, 256, 128, 16 +LPF_16_VH_ALL_OPTS 84, 256, 128, 16 +LPF_16_VH_ALL_OPTS 88, 256, 128, 16 + +INIT_MMX mmxext +LOOPFILTER v, 4, 0, 0, 0 +LOOPFILTER h, 4, 0, 64, 0 +LOOPFILTER v, 8, 128, 0, 8 +LOOPFILTER h, 8, 128, 64, 8 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9lpf_16bpp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9lpf_16bpp.asm new file mode 100644 index 00000000..c0888170 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9lpf_16bpp.asm @@ -0,0 +1,823 @@ +;****************************************************************************** +;* VP9 loop filter SIMD optimizations +;* +;* Copyright (C) 2015 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA + +pw_511: times 16 dw 511 +pw_2047: times 16 dw 2047 +pw_16384: times 16 dw 16384 +pw_m512: times 16 dw -512 +pw_m2048: times 16 dw -2048 + +cextern pw_1 +cextern pw_3 +cextern pw_4 +cextern pw_8 +cextern pw_16 +cextern pw_256 +cextern pw_1023 +cextern pw_4095 +cextern pw_m1 + +SECTION .text + +%macro SCRATCH 3-4 +%if ARCH_X86_64 + SWAP %1, %2 +%if %0 == 4 +%define reg_%4 m%2 +%endif +%else + mova [%3], m%1 +%if %0 == 4 +%define reg_%4 [%3] +%endif +%endif +%endmacro + +%macro UNSCRATCH 3-4 +%if ARCH_X86_64 + SWAP %1, %2 +%else + mova m%1, [%3] +%endif +%if %0 == 4 +%undef reg_%4 +%endif +%endmacro + +%macro PRELOAD 2-3 +%if ARCH_X86_64 + mova m%1, [%2] +%if %0 == 3 +%define reg_%3 m%1 +%endif +%elif %0 == 3 +%define reg_%3 [%2] +%endif +%endmacro + +; calculate p or q portion of flat8out +%macro FLAT8OUT_HALF 0 + psubw m4, m0 ; q4-q0 + psubw m5, m0 ; q5-q0 + psubw m6, m0 ; q6-q0 + psubw m7, m0 ; q7-q0 + ABS2 m4, m5, m2, m3 ; abs(q4-q0) | abs(q5-q0) + ABS2 m6, m7, m2, m3 ; abs(q6-q0) | abs(q7-q0) + pcmpgtw m4, reg_F ; abs(q4-q0) > F + pcmpgtw m5, reg_F ; abs(q5-q0) > F + pcmpgtw m6, reg_F ; abs(q6-q0) > F + pcmpgtw m7, reg_F ; abs(q7-q0) > F + por m5, m4 + por m7, m6 + por m7, m5 ; !flat8out, q portion +%endmacro + +; calculate p or q portion of flat8in/hev/fm (excluding mb_edge condition) +%macro FLAT8IN_HALF 1 +%if %1 > 4 + psubw m4, m3, m0 ; q3-q0 + psubw m5, m2, m0 ; q2-q0 + ABS2 m4, m5, m6, m7 ; abs(q3-q0) | abs(q2-q0) + pcmpgtw m4, reg_F ; abs(q3-q0) > F + pcmpgtw m5, reg_F ; abs(q2-q0) > F +%endif + psubw m3, m2 ; q3-q2 + psubw m2, m1 ; q2-q1 + ABS2 m3, m2, m6, m7 ; abs(q3-q2) | abs(q2-q1) + pcmpgtw m3, reg_I ; abs(q3-q2) > I + pcmpgtw m2, reg_I ; abs(q2-q1) > I +%if %1 > 4 + por m4, m5 +%endif + por m2, m3 + psubw m3, m1, m0 ; q1-q0 + ABS1 m3, m5 ; abs(q1-q0) +%if %1 > 4 + pcmpgtw m6, m3, reg_F ; abs(q1-q0) > F +%endif + pcmpgtw m7, m3, reg_H ; abs(q1-q0) > H + pcmpgtw m3, reg_I ; abs(q1-q0) > I +%if %1 > 4 + por m4, m6 +%endif + por m2, m3 +%endmacro + +; one step in filter_14/filter_6 +; +; take sum $reg, downshift, apply mask and write into dst +; +; if sub2/add1-2 are present, add/sub as appropriate to prepare for the next +; step's sum $reg. This is omitted for the last row in each filter. +; +; if dont_store is set, don't write the result into memory, instead keep the +; values in register so we can write it out later +%macro FILTER_STEP 6-10 "", "", "", 0 ; tmp, reg, mask, shift, dst, \ + ; src/sub1, sub2, add1, add2, dont_store + psrlw %1, %2, %4 + psubw %1, %6 ; abs->delta +%ifnidn %7, "" + psubw %2, %6 + psubw %2, %7 + paddw %2, %8 + paddw %2, %9 +%endif + pand %1, reg_%3 ; apply mask +%if %10 == 1 + paddw %6, %1 ; delta->abs +%else + paddw %1, %6 ; delta->abs + mova [%5], %1 +%endif +%endmacro + +; FIXME avx2 versions for 16_16 and mix2_{4,8}{4,8} + +%macro LOOP_FILTER 3 ; dir[h/v], wd[4/8/16], bpp[10/12] + +%if ARCH_X86_64 +%if %2 == 16 +%assign %%num_xmm_regs 16 +%elif %2 == 8 +%assign %%num_xmm_regs 15 +%else ; %2 == 4 +%assign %%num_xmm_regs 14 +%endif ; %2 +%assign %%bak_mem 0 +%else ; ARCH_X86_32 +%assign %%num_xmm_regs 8 +%if %2 == 16 +%assign %%bak_mem 7 +%elif %2 == 8 +%assign %%bak_mem 6 +%else ; %2 == 4 +%assign %%bak_mem 5 +%endif ; %2 +%endif ; ARCH_X86_64/32 + +%if %2 == 16 +%ifidn %1, v +%assign %%num_gpr_regs 6 +%else ; %1 == h +%assign %%num_gpr_regs 5 +%endif ; %1 +%assign %%wd_mem 6 +%else ; %2 == 8/4 +%assign %%num_gpr_regs 5 +%if ARCH_X86_32 && %2 == 8 +%assign %%wd_mem 2 +%else ; ARCH_X86_64 || %2 == 4 +%assign %%wd_mem 0 +%endif ; ARCH_X86_64/32 etc. +%endif ; %2 + +%ifidn %1, v +%assign %%tsp_mem 0 +%elif %2 == 16 ; && %1 == h +%assign %%tsp_mem 16 +%else ; %1 == h && %1 == 8/4 +%assign %%tsp_mem 8 +%endif ; %1/%2 + +%assign %%off %%wd_mem +%assign %%tspoff %%bak_mem+%%wd_mem +%assign %%stack_mem ((%%bak_mem+%%wd_mem+%%tsp_mem)*mmsize) + +%if %3 == 10 +%define %%maxsgn 511 +%define %%minsgn m512 +%define %%maxusgn 1023 +%define %%maxf 4 +%else ; %3 == 12 +%define %%maxsgn 2047 +%define %%minsgn m2048 +%define %%maxusgn 4095 +%define %%maxf 16 +%endif ; %3 + +cglobal vp9_loop_filter_%1_%2_%3, 5, %%num_gpr_regs, %%num_xmm_regs, %%stack_mem, dst, stride, E, I, H + ; prepare E, I and H masks + shl Ed, %3-8 + shl Id, %3-8 + shl Hd, %3-8 +%if cpuflag(ssse3) + mova m0, [pw_256] +%endif + movd m1, Ed + movd m2, Id + movd m3, Hd +%if cpuflag(ssse3) + pshufb m1, m0 ; E << (bit_depth - 8) + pshufb m2, m0 ; I << (bit_depth - 8) + pshufb m3, m0 ; H << (bit_depth - 8) +%else + punpcklwd m1, m1 + punpcklwd m2, m2 + punpcklwd m3, m3 + pshufd m1, m1, q0000 + pshufd m2, m2, q0000 + pshufd m3, m3, q0000 +%endif + SCRATCH 1, 8, rsp+(%%off+0)*mmsize, E + SCRATCH 2, 9, rsp+(%%off+1)*mmsize, I + SCRATCH 3, 10, rsp+(%%off+2)*mmsize, H +%if %2 > 4 + PRELOAD 11, pw_ %+ %%maxf, F +%endif + + ; set up variables to load data +%ifidn %1, v + DEFINE_ARGS dst8, stride, stride3, dst0, dst4, dst12 + lea stride3q, [strideq*3] + neg strideq +%if %2 == 16 + lea dst0q, [dst8q+strideq*8] +%else + lea dst4q, [dst8q+strideq*4] +%endif + neg strideq +%if %2 == 16 + lea dst12q, [dst8q+strideq*4] + lea dst4q, [dst0q+strideq*4] +%endif + +%if %2 == 16 +%define %%p7 dst0q +%define %%p6 dst0q+strideq +%define %%p5 dst0q+strideq*2 +%define %%p4 dst0q+stride3q +%endif +%define %%p3 dst4q +%define %%p2 dst4q+strideq +%define %%p1 dst4q+strideq*2 +%define %%p0 dst4q+stride3q +%define %%q0 dst8q +%define %%q1 dst8q+strideq +%define %%q2 dst8q+strideq*2 +%define %%q3 dst8q+stride3q +%if %2 == 16 +%define %%q4 dst12q +%define %%q5 dst12q+strideq +%define %%q6 dst12q+strideq*2 +%define %%q7 dst12q+stride3q +%endif +%else ; %1 == h + DEFINE_ARGS dst0, stride, stride3, dst4 + lea stride3q, [strideq*3] + lea dst4q, [dst0q+strideq*4] + +%define %%p3 rsp+(%%tspoff+0)*mmsize +%define %%p2 rsp+(%%tspoff+1)*mmsize +%define %%p1 rsp+(%%tspoff+2)*mmsize +%define %%p0 rsp+(%%tspoff+3)*mmsize +%define %%q0 rsp+(%%tspoff+4)*mmsize +%define %%q1 rsp+(%%tspoff+5)*mmsize +%define %%q2 rsp+(%%tspoff+6)*mmsize +%define %%q3 rsp+(%%tspoff+7)*mmsize + +%if %2 < 16 + movu m0, [dst0q+strideq*0-8] + movu m1, [dst0q+strideq*1-8] + movu m2, [dst0q+strideq*2-8] + movu m3, [dst0q+stride3q -8] + movu m4, [dst4q+strideq*0-8] + movu m5, [dst4q+strideq*1-8] + movu m6, [dst4q+strideq*2-8] + movu m7, [dst4q+stride3q -8] + +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 12 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%%p0], [%%q0] +%endif + + mova [%%p3], m0 + mova [%%p2], m1 + mova [%%p1], m2 + mova [%%p0], m3 +%if ARCH_X86_64 + mova [%%q0], m4 +%endif + mova [%%q1], m5 + mova [%%q2], m6 + mova [%%q3], m7 + + ; FIXME investigate if we can _not_ load q0-3 below if h, and adjust register + ; order here accordingly +%else ; %2 == 16 + +%define %%p7 rsp+(%%tspoff+ 8)*mmsize +%define %%p6 rsp+(%%tspoff+ 9)*mmsize +%define %%p5 rsp+(%%tspoff+10)*mmsize +%define %%p4 rsp+(%%tspoff+11)*mmsize +%define %%q4 rsp+(%%tspoff+12)*mmsize +%define %%q5 rsp+(%%tspoff+13)*mmsize +%define %%q6 rsp+(%%tspoff+14)*mmsize +%define %%q7 rsp+(%%tspoff+15)*mmsize + + mova m0, [dst0q+strideq*0-16] + mova m1, [dst0q+strideq*1-16] + mova m2, [dst0q+strideq*2-16] + mova m3, [dst0q+stride3q -16] + mova m4, [dst4q+strideq*0-16] + mova m5, [dst4q+strideq*1-16] +%if ARCH_X86_64 + mova m6, [dst4q+strideq*2-16] +%endif + mova m7, [dst4q+stride3q -16] + +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 12 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [dst4q+strideq*2-16], [%%p3], 1 +%endif + + mova [%%p7], m0 + mova [%%p6], m1 + mova [%%p5], m2 + mova [%%p4], m3 +%if ARCH_X86_64 + mova [%%p3], m4 +%endif + mova [%%p2], m5 + mova [%%p1], m6 + mova [%%p0], m7 + + mova m0, [dst0q+strideq*0] + mova m1, [dst0q+strideq*1] + mova m2, [dst0q+strideq*2] + mova m3, [dst0q+stride3q ] + mova m4, [dst4q+strideq*0] + mova m5, [dst4q+strideq*1] +%if ARCH_X86_64 + mova m6, [dst4q+strideq*2] +%endif + mova m7, [dst4q+stride3q ] + +%if ARCH_X86_64 + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 12 +%else + TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [dst4q+strideq*2], [%%q4], 1 +%endif + + mova [%%q0], m0 + mova [%%q1], m1 + mova [%%q2], m2 + mova [%%q3], m3 +%if ARCH_X86_64 + mova [%%q4], m4 +%endif + mova [%%q5], m5 + mova [%%q6], m6 + mova [%%q7], m7 + + ; FIXME investigate if we can _not_ load q0|q4-7 below if h, and adjust register + ; order here accordingly +%endif ; %2 +%endif ; %1 + + ; load q0|q4-7 data + mova m0, [%%q0] +%if %2 == 16 + mova m4, [%%q4] + mova m5, [%%q5] + mova m6, [%%q6] + mova m7, [%%q7] + + ; flat8out q portion + FLAT8OUT_HALF + SCRATCH 7, 15, rsp+(%%off+6)*mmsize, F8O +%endif + + ; load q1-3 data + mova m1, [%%q1] + mova m2, [%%q2] + mova m3, [%%q3] + + ; r6-8|pw_4[m8-11]=reg_E/I/H/F + ; r9[m15]=!flatout[q] + ; m12-14=free + ; m0-3=q0-q3 + ; m4-7=free + + ; flat8in|fm|hev q portion + FLAT8IN_HALF %2 + SCRATCH 7, 13, rsp+(%%off+4)*mmsize, HEV +%if %2 > 4 + SCRATCH 4, 14, rsp+(%%off+5)*mmsize, F8I +%endif + + ; r6-8|pw_4[m8-11]=reg_E/I/H/F + ; r9[m15]=!flat8out[q] + ; r10[m13]=hev[q] + ; r11[m14]=!flat8in[q] + ; m2=!fm[q] + ; m0,1=q0-q1 + ; m2-7=free + ; m12=free + + ; load p0-1 + mova m3, [%%p0] + mova m4, [%%p1] + + ; fm mb_edge portion + psubw m5, m3, m0 ; q0-p0 + psubw m6, m4, m1 ; q1-p1 +%if ARCH_X86_64 + ABS2 m5, m6, m7, m12 ; abs(q0-p0) | abs(q1-p1) +%else + ABS1 m5, m7 ; abs(q0-p0) + ABS1 m6, m7 ; abs(q1-p1) +%endif + paddw m5, m5 + psraw m6, 1 + paddw m6, m5 ; abs(q0-p0)*2+(abs(q1-p1)>>1) + pcmpgtw m6, reg_E + por m2, m6 + SCRATCH 2, 12, rsp+(%%off+3)*mmsize, FM + + ; r6-8|pw_4[m8-11]=reg_E/I/H/F + ; r9[m15]=!flat8out[q] + ; r10[m13]=hev[q] + ; r11[m14]=!flat8in[q] + ; r12[m12]=!fm[q] + ; m3-4=q0-1 + ; m0-2/5-7=free + + ; load p4-7 data + SWAP 3, 0 ; p0 + SWAP 4, 1 ; p1 +%if %2 == 16 + mova m7, [%%p7] + mova m6, [%%p6] + mova m5, [%%p5] + mova m4, [%%p4] + + ; flat8out p portion + FLAT8OUT_HALF + por m7, reg_F8O + SCRATCH 7, 15, rsp+(%%off+6)*mmsize, F8O +%endif + + ; r6-8|pw_4[m8-11]=reg_E/I/H/F + ; r9[m15]=!flat8out + ; r10[m13]=hev[q] + ; r11[m14]=!flat8in[q] + ; r12[m12]=!fm[q] + ; m0=p0 + ; m1-7=free + + ; load p2-3 data + mova m2, [%%p2] + mova m3, [%%p3] + + ; flat8in|fm|hev p portion + FLAT8IN_HALF %2 + por m7, reg_HEV +%if %2 > 4 + por m4, reg_F8I +%endif + por m2, reg_FM +%if %2 > 4 + por m4, m2 ; !flat8|!fm +%if %2 == 16 + por m5, m4, reg_F8O ; !flat16|!fm + pandn m2, m4 ; filter4_mask + pandn m4, m5 ; filter8_mask + pxor m5, [pw_m1] ; filter16_mask + SCRATCH 5, 15, rsp+(%%off+6)*mmsize, F16M +%else + pandn m2, m4 ; filter4_mask + pxor m4, [pw_m1] ; filter8_mask +%endif + SCRATCH 4, 14, rsp+(%%off+5)*mmsize, F8M +%else + pxor m2, [pw_m1] ; filter4_mask +%endif + SCRATCH 7, 13, rsp+(%%off+4)*mmsize, HEV + SCRATCH 2, 12, rsp+(%%off+3)*mmsize, F4M + + ; r9[m15]=filter16_mask + ; r10[m13]=hev + ; r11[m14]=filter8_mask + ; r12[m12]=filter4_mask + ; m0,1=p0-p1 + ; m2-7=free + ; m8-11=free + +%if %2 > 4 +%if %2 == 16 + ; filter_14 + mova m2, [%%p7] + mova m3, [%%p6] + mova m6, [%%p5] + mova m7, [%%p4] + PRELOAD 8, %%p3, P3 + PRELOAD 9, %%p2, P2 +%endif + PRELOAD 10, %%q0, Q0 + PRELOAD 11, %%q1, Q1 +%if %2 == 16 + psllw m4, m2, 3 + paddw m5, m3, m3 + paddw m4, m6 + paddw m5, m7 + paddw m4, reg_P3 + paddw m5, reg_P2 + paddw m4, m1 + paddw m5, m0 + paddw m4, reg_Q0 ; q0+p1+p3+p5+p7*8 + psubw m5, m2 ; p0+p2+p4+p6*2-p7 + paddw m4, [pw_8] + paddw m5, m4 ; q0+p0+p1+p2+p3+p4+p5+p6*2+p7*7+8 + + ; below, we use r0-5 for storing pre-filter pixels for subsequent subtraction + ; at the end of the filter + + mova [rsp+0*mmsize], m3 + FILTER_STEP m4, m5, F16M, 4, %%p6, m3, m2, m6, reg_Q1 +%endif + mova m3, [%%q2] +%if %2 == 16 + mova [rsp+1*mmsize], m6 + FILTER_STEP m4, m5, F16M, 4, %%p5, m6, m2, m7, m3 +%endif + mova m6, [%%q3] +%if %2 == 16 + mova [rsp+2*mmsize], m7 + FILTER_STEP m4, m5, F16M, 4, %%p4, m7, m2, reg_P3, m6 + mova m7, [%%q4] +%if ARCH_X86_64 + mova [rsp+3*mmsize], reg_P3 +%else + mova m4, reg_P3 + mova [rsp+3*mmsize], m4 +%endif + FILTER_STEP m4, m5, F16M, 4, %%p3, reg_P3, m2, reg_P2, m7 + PRELOAD 8, %%q5, Q5 +%if ARCH_X86_64 + mova [rsp+4*mmsize], reg_P2 +%else + mova m4, reg_P2 + mova [rsp+4*mmsize], m4 +%endif + FILTER_STEP m4, m5, F16M, 4, %%p2, reg_P2, m2, m1, reg_Q5 + PRELOAD 9, %%q6, Q6 + mova [rsp+5*mmsize], m1 + FILTER_STEP m4, m5, F16M, 4, %%p1, m1, m2, m0, reg_Q6 + mova m1, [%%q7] + FILTER_STEP m4, m5, F16M, 4, %%p0, m0, m2, reg_Q0, m1, 1 + FILTER_STEP m4, m5, F16M, 4, %%q0, reg_Q0, [rsp+0*mmsize], reg_Q1, m1, ARCH_X86_64 + FILTER_STEP m4, m5, F16M, 4, %%q1, reg_Q1, [rsp+1*mmsize], m3, m1, ARCH_X86_64 + FILTER_STEP m4, m5, F16M, 4, %%q2, m3, [rsp+2*mmsize], m6, m1, 1 + FILTER_STEP m4, m5, F16M, 4, %%q3, m6, [rsp+3*mmsize], m7, m1 + FILTER_STEP m4, m5, F16M, 4, %%q4, m7, [rsp+4*mmsize], reg_Q5, m1 + FILTER_STEP m4, m5, F16M, 4, %%q5, reg_Q5, [rsp+5*mmsize], reg_Q6, m1 + FILTER_STEP m4, m5, F16M, 4, %%q6, reg_Q6 + + mova m7, [%%p1] +%else + SWAP 1, 7 +%endif + + mova m2, [%%p3] + mova m1, [%%p2] + + ; reg_Q0-1 (m10-m11) + ; m0=p0 + ; m1=p2 + ; m2=p3 + ; m3=q2 + ; m4-5=free + ; m6=q3 + ; m7=p1 + ; m8-9 unused + + ; filter_6 + psllw m4, m2, 2 + paddw m5, m1, m1 + paddw m4, m7 + psubw m5, m2 + paddw m4, m0 + paddw m5, reg_Q0 + paddw m4, [pw_4] + paddw m5, m4 + +%if ARCH_X86_64 + mova m8, m1 + mova m9, m7 +%else + mova [rsp+0*mmsize], m1 + mova [rsp+1*mmsize], m7 +%endif +%ifidn %1, v + FILTER_STEP m4, m5, F8M, 3, %%p2, m1, m2, m7, reg_Q1 +%else + FILTER_STEP m4, m5, F8M, 3, %%p2, m1, m2, m7, reg_Q1, 1 +%endif + FILTER_STEP m4, m5, F8M, 3, %%p1, m7, m2, m0, m3, 1 + FILTER_STEP m4, m5, F8M, 3, %%p0, m0, m2, reg_Q0, m6, 1 +%if ARCH_X86_64 + FILTER_STEP m4, m5, F8M, 3, %%q0, reg_Q0, m8, reg_Q1, m6, ARCH_X86_64 + FILTER_STEP m4, m5, F8M, 3, %%q1, reg_Q1, m9, m3, m6, ARCH_X86_64 +%else + FILTER_STEP m4, m5, F8M, 3, %%q0, reg_Q0, [rsp+0*mmsize], reg_Q1, m6, ARCH_X86_64 + FILTER_STEP m4, m5, F8M, 3, %%q1, reg_Q1, [rsp+1*mmsize], m3, m6, ARCH_X86_64 +%endif + FILTER_STEP m4, m5, F8M, 3, %%q2, m3 + + UNSCRATCH 2, 10, %%q0 + UNSCRATCH 6, 11, %%q1 +%else + SWAP 1, 7 + mova m2, [%%q0] + mova m6, [%%q1] +%endif + UNSCRATCH 3, 13, rsp+(%%off+4)*mmsize, HEV + + ; m0=p0 + ; m1=p2 + ; m2=q0 + ; m3=hev_mask + ; m4-5=free + ; m6=q1 + ; m7=p1 + + ; filter_4 + psubw m4, m7, m6 ; p1-q1 + psubw m5, m2, m0 ; q0-p0 + pand m4, m3 + pminsw m4, [pw_ %+ %%maxsgn] + pmaxsw m4, [pw_ %+ %%minsgn] ; clip_intp2(p1-q1, 9) -> f + paddw m4, m5 + paddw m5, m5 + paddw m4, m5 ; 3*(q0-p0)+f + pminsw m4, [pw_ %+ %%maxsgn] + pmaxsw m4, [pw_ %+ %%minsgn] ; clip_intp2(3*(q0-p0)+f, 9) -> f + pand m4, reg_F4M + paddw m5, m4, [pw_4] + paddw m4, [pw_3] + pminsw m5, [pw_ %+ %%maxsgn] + pminsw m4, [pw_ %+ %%maxsgn] + psraw m5, 3 ; min_intp2(f+4, 9)>>3 -> f1 + psraw m4, 3 ; min_intp2(f+3, 9)>>3 -> f2 + psubw m2, m5 ; q0-f1 + paddw m0, m4 ; p0+f2 + pandn m3, m5 ; f1 & !hev (for p1/q1 adj) + pxor m4, m4 + mova m5, [pw_ %+ %%maxusgn] + pmaxsw m2, m4 + pmaxsw m0, m4 + pminsw m2, m5 + pminsw m0, m5 +%if cpuflag(ssse3) + pmulhrsw m3, [pw_16384] ; (f1+1)>>1 +%else + paddw m3, [pw_1] + psraw m3, 1 +%endif + paddw m7, m3 ; p1+f + psubw m6, m3 ; q1-f + pmaxsw m7, m4 + pmaxsw m6, m4 + pminsw m7, m5 + pminsw m6, m5 + + ; store +%ifidn %1, v + mova [%%p1], m7 + mova [%%p0], m0 + mova [%%q0], m2 + mova [%%q1], m6 +%else ; %1 == h +%if %2 == 4 + TRANSPOSE4x4W 7, 0, 2, 6, 1 + movh [dst0q+strideq*0-4], m7 + movhps [dst0q+strideq*1-4], m7 + movh [dst0q+strideq*2-4], m0 + movhps [dst0q+stride3q -4], m0 + movh [dst4q+strideq*0-4], m2 + movhps [dst4q+strideq*1-4], m2 + movh [dst4q+strideq*2-4], m6 + movhps [dst4q+stride3q -4], m6 +%elif %2 == 8 + mova m3, [%%p3] + mova m4, [%%q2] + mova m5, [%%q3] + +%if ARCH_X86_64 + TRANSPOSE8x8W 3, 1, 7, 0, 2, 6, 4, 5, 8 +%else + TRANSPOSE8x8W 3, 1, 7, 0, 2, 6, 4, 5, [%%q2], [%%q0], 1 + mova m2, [%%q0] +%endif + + movu [dst0q+strideq*0-8], m3 + movu [dst0q+strideq*1-8], m1 + movu [dst0q+strideq*2-8], m7 + movu [dst0q+stride3q -8], m0 + movu [dst4q+strideq*0-8], m2 + movu [dst4q+strideq*1-8], m6 + movu [dst4q+strideq*2-8], m4 + movu [dst4q+stride3q -8], m5 +%else ; %2 == 16 + SCRATCH 2, 8, %%q0 + SCRATCH 6, 9, %%q1 + mova m2, [%%p7] + mova m3, [%%p6] + mova m4, [%%p5] + mova m5, [%%p4] + mova m6, [%%p3] + +%if ARCH_X86_64 + TRANSPOSE8x8W 2, 3, 4, 5, 6, 1, 7, 0, 10 +%else + mova [%%p1], m7 + TRANSPOSE8x8W 2, 3, 4, 5, 6, 1, 7, 0, [%%p1], [dst4q+strideq*0-16], 1 +%endif + + mova [dst0q+strideq*0-16], m2 + mova [dst0q+strideq*1-16], m3 + mova [dst0q+strideq*2-16], m4 + mova [dst0q+stride3q -16], m5 +%if ARCH_X86_64 + mova [dst4q+strideq*0-16], m6 +%endif + mova [dst4q+strideq*1-16], m1 + mova [dst4q+strideq*2-16], m7 + mova [dst4q+stride3q -16], m0 + + UNSCRATCH 2, 8, %%q0 + UNSCRATCH 6, 9, %%q1 + mova m0, [%%q2] + mova m1, [%%q3] + mova m3, [%%q4] + mova m4, [%%q5] +%if ARCH_X86_64 + mova m5, [%%q6] +%endif + mova m7, [%%q7] + +%if ARCH_X86_64 + TRANSPOSE8x8W 2, 6, 0, 1, 3, 4, 5, 7, 8 +%else + TRANSPOSE8x8W 2, 6, 0, 1, 3, 4, 5, 7, [%%q6], [dst4q+strideq*0], 1 +%endif + + mova [dst0q+strideq*0], m2 + mova [dst0q+strideq*1], m6 + mova [dst0q+strideq*2], m0 + mova [dst0q+stride3q ], m1 +%if ARCH_X86_64 + mova [dst4q+strideq*0], m3 +%endif + mova [dst4q+strideq*1], m4 + mova [dst4q+strideq*2], m5 + mova [dst4q+stride3q ], m7 +%endif ; %2 +%endif ; %1 + RET +%endmacro + +%macro LOOP_FILTER_CPUSETS 3 +INIT_XMM sse2 +LOOP_FILTER %1, %2, %3 +INIT_XMM ssse3 +LOOP_FILTER %1, %2, %3 +INIT_XMM avx +LOOP_FILTER %1, %2, %3 +%endmacro + +%macro LOOP_FILTER_WDSETS 2 +LOOP_FILTER_CPUSETS %1, 4, %2 +LOOP_FILTER_CPUSETS %1, 8, %2 +LOOP_FILTER_CPUSETS %1, 16, %2 +%endmacro + +LOOP_FILTER_WDSETS h, 10 +LOOP_FILTER_WDSETS v, 10 +LOOP_FILTER_WDSETS h, 12 +LOOP_FILTER_WDSETS v, 12 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9mc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9mc.asm new file mode 100644 index 00000000..f64161b2 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9mc.asm @@ -0,0 +1,675 @@ +;****************************************************************************** +;* VP9 motion compensation SIMD optimizations +;* +;* Copyright (c) 2013 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +cextern pw_256 +cextern pw_64 + +%macro F8_SSSE3_TAPS 8 +times 16 db %1, %2 +times 16 db %3, %4 +times 16 db %5, %6 +times 16 db %7, %8 +%endmacro + +%macro F8_SSE2_TAPS 8 +times 8 dw %1 +times 8 dw %2 +times 8 dw %3 +times 8 dw %4 +times 8 dw %5 +times 8 dw %6 +times 8 dw %7 +times 8 dw %8 +%endmacro + +%macro F8_16BPP_TAPS 8 +times 8 dw %1, %2 +times 8 dw %3, %4 +times 8 dw %5, %6 +times 8 dw %7, %8 +%endmacro + +%macro FILTER 1 +const filters_%1 ; smooth + F8_TAPS -3, -1, 32, 64, 38, 1, -3, 0 + F8_TAPS -2, -2, 29, 63, 41, 2, -3, 0 + F8_TAPS -2, -2, 26, 63, 43, 4, -4, 0 + F8_TAPS -2, -3, 24, 62, 46, 5, -4, 0 + F8_TAPS -2, -3, 21, 60, 49, 7, -4, 0 + F8_TAPS -1, -4, 18, 59, 51, 9, -4, 0 + F8_TAPS -1, -4, 16, 57, 53, 12, -4, -1 + F8_TAPS -1, -4, 14, 55, 55, 14, -4, -1 + F8_TAPS -1, -4, 12, 53, 57, 16, -4, -1 + F8_TAPS 0, -4, 9, 51, 59, 18, -4, -1 + F8_TAPS 0, -4, 7, 49, 60, 21, -3, -2 + F8_TAPS 0, -4, 5, 46, 62, 24, -3, -2 + F8_TAPS 0, -4, 4, 43, 63, 26, -2, -2 + F8_TAPS 0, -3, 2, 41, 63, 29, -2, -2 + F8_TAPS 0, -3, 1, 38, 64, 32, -1, -3 + ; regular + F8_TAPS 0, 1, -5, 126, 8, -3, 1, 0 + F8_TAPS -1, 3, -10, 122, 18, -6, 2, 0 + F8_TAPS -1, 4, -13, 118, 27, -9, 3, -1 + F8_TAPS -1, 4, -16, 112, 37, -11, 4, -1 + F8_TAPS -1, 5, -18, 105, 48, -14, 4, -1 + F8_TAPS -1, 5, -19, 97, 58, -16, 5, -1 + F8_TAPS -1, 6, -19, 88, 68, -18, 5, -1 + F8_TAPS -1, 6, -19, 78, 78, -19, 6, -1 + F8_TAPS -1, 5, -18, 68, 88, -19, 6, -1 + F8_TAPS -1, 5, -16, 58, 97, -19, 5, -1 + F8_TAPS -1, 4, -14, 48, 105, -18, 5, -1 + F8_TAPS -1, 4, -11, 37, 112, -16, 4, -1 + F8_TAPS -1, 3, -9, 27, 118, -13, 4, -1 + F8_TAPS 0, 2, -6, 18, 122, -10, 3, -1 + F8_TAPS 0, 1, -3, 8, 126, -5, 1, 0 + ; sharp + F8_TAPS -1, 3, -7, 127, 8, -3, 1, 0 + F8_TAPS -2, 5, -13, 125, 17, -6, 3, -1 + F8_TAPS -3, 7, -17, 121, 27, -10, 5, -2 + F8_TAPS -4, 9, -20, 115, 37, -13, 6, -2 + F8_TAPS -4, 10, -23, 108, 48, -16, 8, -3 + F8_TAPS -4, 10, -24, 100, 59, -19, 9, -3 + F8_TAPS -4, 11, -24, 90, 70, -21, 10, -4 + F8_TAPS -4, 11, -23, 80, 80, -23, 11, -4 + F8_TAPS -4, 10, -21, 70, 90, -24, 11, -4 + F8_TAPS -3, 9, -19, 59, 100, -24, 10, -4 + F8_TAPS -3, 8, -16, 48, 108, -23, 10, -4 + F8_TAPS -2, 6, -13, 37, 115, -20, 9, -4 + F8_TAPS -2, 5, -10, 27, 121, -17, 7, -3 + F8_TAPS -1, 3, -6, 17, 125, -13, 5, -2 + F8_TAPS 0, 1, -3, 8, 127, -7, 3, -1 +%endmacro + +%define F8_TAPS F8_SSSE3_TAPS +; int8_t ff_filters_ssse3[3][15][4][32] +FILTER ssse3 +%define F8_TAPS F8_SSE2_TAPS +; int16_t ff_filters_sse2[3][15][8][8] +FILTER sse2 +%define F8_TAPS F8_16BPP_TAPS +; int16_t ff_filters_16bpp[3][15][4][16] +FILTER 16bpp + +SECTION .text + +%macro filter_sse2_h_fn 1 +%assign %%px mmsize/2 +cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _8, 6, 6, 15, dst, dstride, src, sstride, h, filtery + pxor m5, m5 + mova m6, [pw_64] + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+ 16] + mova m9, [filteryq+ 32] + mova m10, [filteryq+ 48] + mova m11, [filteryq+ 64] + mova m12, [filteryq+ 80] + mova m13, [filteryq+ 96] + mova m14, [filteryq+112] +%endif +.loop: + movh m0, [srcq-3] + movh m1, [srcq-2] + movh m2, [srcq-1] + movh m3, [srcq+0] + movh m4, [srcq+1] + punpcklbw m0, m5 + punpcklbw m1, m5 + punpcklbw m2, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 + pmullw m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m8 + pmullw m2, m9 + pmullw m3, m10 + pmullw m4, m11 +%else + pmullw m1, [filteryq+ 16] + pmullw m2, [filteryq+ 32] + pmullw m3, [filteryq+ 48] + pmullw m4, [filteryq+ 64] +%endif + paddw m0, m1 + paddw m2, m3 + paddw m0, m4 + movh m1, [srcq+2] + movh m3, [srcq+3] + movh m4, [srcq+4] + add srcq, sstrideq + punpcklbw m1, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m12 + pmullw m3, m13 + pmullw m4, m14 +%else + pmullw m1, [filteryq+ 80] + pmullw m3, [filteryq+ 96] + pmullw m4, [filteryq+112] +%endif + paddw m0, m1 + paddw m3, m4 + paddw m0, m6 + paddw m2, m3 + paddsw m0, m2 + psraw m0, 7 +%ifidn %1, avg + movh m1, [dstq] +%endif + packuswb m0, m0 +%ifidn %1, avg + pavgb m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_MMX mmxext +filter_sse2_h_fn put +filter_sse2_h_fn avg + +INIT_XMM sse2 +filter_sse2_h_fn put +filter_sse2_h_fn avg + +%macro filter_h_fn 1 +%assign %%px mmsize/2 +cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _8, 6, 6, 11, dst, dstride, src, sstride, h, filtery + mova m6, [pw_256] + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+32] + mova m9, [filteryq+64] + mova m10, [filteryq+96] +%endif +.loop: + movh m0, [srcq-3] + movh m1, [srcq-2] + movh m2, [srcq-1] + movh m3, [srcq+0] + movh m4, [srcq+1] + movh m5, [srcq+2] + punpcklbw m0, m1 + punpcklbw m2, m3 + movh m1, [srcq+3] + movh m3, [srcq+4] + add srcq, sstrideq + punpcklbw m4, m5 + punpcklbw m1, m3 + pmaddubsw m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmaddubsw m2, m8 + pmaddubsw m4, m9 + pmaddubsw m1, m10 +%else + pmaddubsw m2, [filteryq+32] + pmaddubsw m4, [filteryq+64] + pmaddubsw m1, [filteryq+96] +%endif + paddw m0, m4 + paddw m2, m1 + paddsw m0, m2 + pmulhrsw m0, m6 +%ifidn %1, avg + movh m1, [dstq] +%endif + packuswb m0, m0 +%ifidn %1, avg + pavgb m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_MMX ssse3 +filter_h_fn put +filter_h_fn avg + +INIT_XMM ssse3 +filter_h_fn put +filter_h_fn avg + +%if ARCH_X86_64 +%macro filter_hx2_fn 1 +%assign %%px mmsize +cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _8, 6, 6, 14, dst, dstride, src, sstride, h, filtery + mova m13, [pw_256] + mova m8, [filteryq+ 0] + mova m9, [filteryq+32] + mova m10, [filteryq+64] + mova m11, [filteryq+96] +.loop: + movu m0, [srcq-3] + movu m1, [srcq-2] + movu m2, [srcq-1] + movu m3, [srcq+0] + movu m4, [srcq+1] + movu m5, [srcq+2] + movu m6, [srcq+3] + movu m7, [srcq+4] + add srcq, sstrideq + SBUTTERFLY bw, 0, 1, 12 + SBUTTERFLY bw, 2, 3, 12 + SBUTTERFLY bw, 4, 5, 12 + SBUTTERFLY bw, 6, 7, 12 + pmaddubsw m0, m8 + pmaddubsw m1, m8 + pmaddubsw m2, m9 + pmaddubsw m3, m9 + pmaddubsw m4, m10 + pmaddubsw m5, m10 + pmaddubsw m6, m11 + pmaddubsw m7, m11 + paddw m0, m4 + paddw m1, m5 + paddw m2, m6 + paddw m3, m7 + paddsw m0, m2 + paddsw m1, m3 + pmulhrsw m0, m13 + pmulhrsw m1, m13 + packuswb m0, m1 +%ifidn %1, avg + pavgb m0, [dstq] +%endif + mova [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_XMM ssse3 +filter_hx2_fn put +filter_hx2_fn avg + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +filter_hx2_fn put +filter_hx2_fn avg +%endif + +%endif ; ARCH_X86_64 + +%macro filter_sse2_v_fn 1 +%assign %%px mmsize/2 +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 6, 8, 15, dst, dstride, src, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 4, 7, 15, dst, dstride, src, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%define hd r4mp +%endif + pxor m5, m5 + mova m6, [pw_64] + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+ 16] + mova m9, [filteryq+ 32] + mova m10, [filteryq+ 48] + mova m11, [filteryq+ 64] + mova m12, [filteryq+ 80] + mova m13, [filteryq+ 96] + mova m14, [filteryq+112] +%endif +.loop: + ; FIXME maybe reuse loads from previous rows, or just + ; more generally unroll this to prevent multiple loads of + ; the same data? + movh m0, [srcq] + movh m1, [srcq+sstrideq] + movh m2, [srcq+sstrideq*2] + movh m3, [srcq+sstride3q] + add srcq, sstrideq + movh m4, [src4q] + punpcklbw m0, m5 + punpcklbw m1, m5 + punpcklbw m2, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 + pmullw m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m8 + pmullw m2, m9 + pmullw m3, m10 + pmullw m4, m11 +%else + pmullw m1, [filteryq+ 16] + pmullw m2, [filteryq+ 32] + pmullw m3, [filteryq+ 48] + pmullw m4, [filteryq+ 64] +%endif + paddw m0, m1 + paddw m2, m3 + paddw m0, m4 + movh m1, [src4q+sstrideq] + movh m3, [src4q+sstrideq*2] + movh m4, [src4q+sstride3q] + add src4q, sstrideq + punpcklbw m1, m5 + punpcklbw m3, m5 + punpcklbw m4, m5 +%if ARCH_X86_64 && mmsize > 8 + pmullw m1, m12 + pmullw m3, m13 + pmullw m4, m14 +%else + pmullw m1, [filteryq+ 80] + pmullw m3, [filteryq+ 96] + pmullw m4, [filteryq+112] +%endif + paddw m0, m1 + paddw m3, m4 + paddw m0, m6 + paddw m2, m3 + paddsw m0, m2 + psraw m0, 7 +%ifidn %1, avg + movh m1, [dstq] +%endif + packuswb m0, m0 +%ifidn %1, avg + pavgb m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_MMX mmxext +filter_sse2_v_fn put +filter_sse2_v_fn avg + +INIT_XMM sse2 +filter_sse2_v_fn put +filter_sse2_v_fn avg + +%macro filter_v_fn 1 +%assign %%px mmsize/2 +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 6, 8, 11, dst, dstride, src, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 4, 7, 11, dst, dstride, src, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%define hd r4mp +%endif + mova m6, [pw_256] + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+32] + mova m9, [filteryq+64] + mova m10, [filteryq+96] +%endif +.loop: + ; FIXME maybe reuse loads from previous rows, or just more generally + ; unroll this to prevent multiple loads of the same data? + movh m0, [srcq] + movh m1, [srcq+sstrideq] + movh m2, [srcq+sstrideq*2] + movh m3, [srcq+sstride3q] + movh m4, [src4q] + movh m5, [src4q+sstrideq] + punpcklbw m0, m1 + punpcklbw m2, m3 + movh m1, [src4q+sstrideq*2] + movh m3, [src4q+sstride3q] + add srcq, sstrideq + add src4q, sstrideq + punpcklbw m4, m5 + punpcklbw m1, m3 + pmaddubsw m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmaddubsw m2, m8 + pmaddubsw m4, m9 + pmaddubsw m1, m10 +%else + pmaddubsw m2, [filteryq+32] + pmaddubsw m4, [filteryq+64] + pmaddubsw m1, [filteryq+96] +%endif + paddw m0, m4 + paddw m2, m1 + paddsw m0, m2 + pmulhrsw m0, m6 +%ifidn %1, avg + movh m1, [dstq] +%endif + packuswb m0, m0 +%ifidn %1, avg + pavgb m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_MMX ssse3 +filter_v_fn put +filter_v_fn avg + +INIT_XMM ssse3 +filter_v_fn put +filter_v_fn avg + +%if ARCH_X86_64 + +%macro filter_vx2_fn 1 +%assign %%px mmsize +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _8, 6, 8, 14, dst, dstride, src, sstride, h, filtery, src4, sstride3 + mova m13, [pw_256] + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q + mova m8, [filteryq+ 0] + mova m9, [filteryq+32] + mova m10, [filteryq+64] + mova m11, [filteryq+96] +.loop: + ; FIXME maybe reuse loads from previous rows, or just + ; more generally unroll this to prevent multiple loads of + ; the same data? + movu m0, [srcq] + movu m1, [srcq+sstrideq] + movu m2, [srcq+sstrideq*2] + movu m3, [srcq+sstride3q] + movu m4, [src4q] + movu m5, [src4q+sstrideq] + movu m6, [src4q+sstrideq*2] + movu m7, [src4q+sstride3q] + add srcq, sstrideq + add src4q, sstrideq + SBUTTERFLY bw, 0, 1, 12 + SBUTTERFLY bw, 2, 3, 12 + SBUTTERFLY bw, 4, 5, 12 + SBUTTERFLY bw, 6, 7, 12 + pmaddubsw m0, m8 + pmaddubsw m1, m8 + pmaddubsw m2, m9 + pmaddubsw m3, m9 + pmaddubsw m4, m10 + pmaddubsw m5, m10 + pmaddubsw m6, m11 + pmaddubsw m7, m11 + paddw m0, m4 + paddw m1, m5 + paddw m2, m6 + paddw m3, m7 + paddsw m0, m2 + paddsw m1, m3 + pmulhrsw m0, m13 + pmulhrsw m1, m13 + packuswb m0, m1 +%ifidn %1, avg + pavgb m0, [dstq] +%endif + mova [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET +%endmacro + +INIT_XMM ssse3 +filter_vx2_fn put +filter_vx2_fn avg + +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +filter_vx2_fn put +filter_vx2_fn avg +%endif + +%endif ; ARCH_X86_64 + +%macro fpel_fn 6-8 0, 4 +%if %2 == 4 +%define %%srcfn movh +%define %%dstfn movh +%else +%define %%srcfn movu +%define %%dstfn mova +%endif + +%if %7 == 8 +%define %%pavg pavgb +%define %%szsuf _8 +%elif %7 == 16 +%define %%pavg pavgw +%define %%szsuf _16 +%else +%define %%szsuf +%endif + +%if %2 <= mmsize +cglobal vp9_%1%2 %+ %%szsuf, 5, 7, 4, dst, dstride, src, sstride, h, dstride3, sstride3 + lea sstride3q, [sstrideq*3] + lea dstride3q, [dstrideq*3] +%else +cglobal vp9_%1%2 %+ %%szsuf, 5, 5, %8, dst, dstride, src, sstride, h +%endif +.loop: + %%srcfn m0, [srcq] + %%srcfn m1, [srcq+s%3] + %%srcfn m2, [srcq+s%4] + %%srcfn m3, [srcq+s%5] +%if %2/mmsize == 8 + %%srcfn m4, [srcq+mmsize*4] + %%srcfn m5, [srcq+mmsize*5] + %%srcfn m6, [srcq+mmsize*6] + %%srcfn m7, [srcq+mmsize*7] +%endif + lea srcq, [srcq+sstrideq*%6] +%ifidn %1, avg + %%pavg m0, [dstq] + %%pavg m1, [dstq+d%3] + %%pavg m2, [dstq+d%4] + %%pavg m3, [dstq+d%5] +%if %2/mmsize == 8 + %%pavg m4, [dstq+mmsize*4] + %%pavg m5, [dstq+mmsize*5] + %%pavg m6, [dstq+mmsize*6] + %%pavg m7, [dstq+mmsize*7] +%endif +%endif + %%dstfn [dstq], m0 + %%dstfn [dstq+d%3], m1 + %%dstfn [dstq+d%4], m2 + %%dstfn [dstq+d%5], m3 +%if %2/mmsize == 8 + %%dstfn [dstq+mmsize*4], m4 + %%dstfn [dstq+mmsize*5], m5 + %%dstfn [dstq+mmsize*6], m6 + %%dstfn [dstq+mmsize*7], m7 +%endif + lea dstq, [dstq+dstrideq*%6] + sub hd, %6 + jnz .loop + RET +%endmacro + +%define d16 16 +%define s16 16 +%define d32 32 +%define s32 32 +INIT_MMX mmx +fpel_fn put, 4, strideq, strideq*2, stride3q, 4 +fpel_fn put, 8, strideq, strideq*2, stride3q, 4 +INIT_MMX mmxext +fpel_fn avg, 4, strideq, strideq*2, stride3q, 4, 8 +fpel_fn avg, 8, strideq, strideq*2, stride3q, 4, 8 +INIT_XMM sse +fpel_fn put, 16, strideq, strideq*2, stride3q, 4 +fpel_fn put, 32, mmsize, strideq, strideq+mmsize, 2 +fpel_fn put, 64, mmsize, mmsize*2, mmsize*3, 1 +fpel_fn put, 128, mmsize, mmsize*2, mmsize*3, 1, 0, 8 +INIT_XMM sse2 +fpel_fn avg, 16, strideq, strideq*2, stride3q, 4, 8 +fpel_fn avg, 32, mmsize, strideq, strideq+mmsize, 2, 8 +fpel_fn avg, 64, mmsize, mmsize*2, mmsize*3, 1, 8 +INIT_YMM avx +fpel_fn put, 32, strideq, strideq*2, stride3q, 4 +fpel_fn put, 64, mmsize, strideq, strideq+mmsize, 2 +fpel_fn put, 128, mmsize, mmsize*2, mmsize*3, 1 +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +fpel_fn avg, 32, strideq, strideq*2, stride3q, 4, 8 +fpel_fn avg, 64, mmsize, strideq, strideq+mmsize, 2, 8 +%endif +INIT_MMX mmxext +fpel_fn avg, 8, strideq, strideq*2, stride3q, 4, 16 +INIT_XMM sse2 +fpel_fn avg, 16, strideq, strideq*2, stride3q, 4, 16 +fpel_fn avg, 32, mmsize, strideq, strideq+mmsize, 2, 16 +fpel_fn avg, 64, mmsize, mmsize*2, mmsize*3, 1, 16 +fpel_fn avg, 128, mmsize, mmsize*2, mmsize*3, 1, 16, 8 +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +fpel_fn avg, 32, strideq, strideq*2, stride3q, 4, 16 +fpel_fn avg, 64, mmsize, strideq, strideq+mmsize, 2, 16 +fpel_fn avg, 128, mmsize, mmsize*2, mmsize*3, 1, 16 +%endif +%undef s16 +%undef d16 +%undef s32 +%undef d32 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9mc_16bpp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9mc_16bpp.asm new file mode 100644 index 00000000..9a462eaf --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/vp9mc_16bpp.asm @@ -0,0 +1,431 @@ +;****************************************************************************** +;* VP9 MC SIMD optimizations +;* +;* Copyright (c) 2015 Ronald S. Bultje +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA 32 + +pd_64: times 8 dd 64 + +cextern pw_1023 +cextern pw_4095 + +SECTION .text + +%macro filter_h4_fn 1-2 12 +cglobal vp9_%1_8tap_1d_h_4_10, 6, 6, %2, dst, dstride, src, sstride, h, filtery + mova m5, [pw_1023] +.body: +%if notcpuflag(sse4) && ARCH_X86_64 + pxor m11, m11 +%endif + mova m6, [pd_64] + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+32] + mova m9, [filteryq+64] + mova m10, [filteryq+96] +%endif +.loop: + movh m0, [srcq-6] + movh m1, [srcq-4] + movh m2, [srcq-2] + movh m3, [srcq+0] + movh m4, [srcq+2] + punpcklwd m0, m1 + punpcklwd m2, m3 + pmaddwd m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m2, m8 +%else + pmaddwd m2, [filteryq+32] +%endif + movu m1, [srcq+4] + movu m3, [srcq+6] + paddd m0, m2 + movu m2, [srcq+8] + add srcq, sstrideq + punpcklwd m4, m1 + punpcklwd m3, m2 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m4, m9 + pmaddwd m3, m10 +%else + pmaddwd m4, [filteryq+64] + pmaddwd m3, [filteryq+96] +%endif + paddd m0, m4 + paddd m0, m3 + paddd m0, m6 + psrad m0, 7 +%if cpuflag(sse4) + packusdw m0, m0 +%else + packssdw m0, m0 +%endif +%ifidn %1, avg + movh m1, [dstq] +%endif + pminsw m0, m5 +%if notcpuflag(sse4) +%if ARCH_X86_64 + pmaxsw m0, m11 +%else + pxor m2, m2 + pmaxsw m0, m2 +%endif +%endif +%ifidn %1, avg + pavgw m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET + +cglobal vp9_%1_8tap_1d_h_4_12, 6, 6, %2, dst, dstride, src, sstride, h, filtery + mova m5, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_h_4_10 %+ SUFFIX).body +%endmacro + +INIT_XMM sse2 +filter_h4_fn put +filter_h4_fn avg + +%macro filter_h_fn 1-2 12 +%assign %%px mmsize/2 +cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _10, 6, 6, %2, dst, dstride, src, sstride, h, filtery + mova m5, [pw_1023] +.body: +%if notcpuflag(sse4) && ARCH_X86_64 + pxor m11, m11 +%endif + mova m6, [pd_64] + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+32] + mova m9, [filteryq+64] + mova m10, [filteryq+96] +%endif +.loop: + movu m0, [srcq-6] + movu m1, [srcq-4] + movu m2, [srcq-2] + movu m3, [srcq+0] + movu m4, [srcq+2] + pmaddwd m0, m7 + pmaddwd m1, m7 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m2, m8 + pmaddwd m3, m8 + pmaddwd m4, m9 +%else + pmaddwd m2, [filteryq+32] + pmaddwd m3, [filteryq+32] + pmaddwd m4, [filteryq+64] +%endif + paddd m0, m2 + paddd m1, m3 + paddd m0, m4 + movu m2, [srcq+4] + movu m3, [srcq+6] + movu m4, [srcq+8] + add srcq, sstrideq +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m2, m9 + pmaddwd m3, m10 + pmaddwd m4, m10 +%else + pmaddwd m2, [filteryq+64] + pmaddwd m3, [filteryq+96] + pmaddwd m4, [filteryq+96] +%endif + paddd m1, m2 + paddd m0, m3 + paddd m1, m4 + paddd m0, m6 + paddd m1, m6 + psrad m0, 7 + psrad m1, 7 +%if cpuflag(sse4) + packusdw m0, m0 + packusdw m1, m1 +%else + packssdw m0, m0 + packssdw m1, m1 +%endif + punpcklwd m0, m1 + pminsw m0, m5 +%if notcpuflag(sse4) +%if ARCH_X86_64 + pmaxsw m0, m11 +%else + pxor m2, m2 + pmaxsw m0, m2 +%endif +%endif +%ifidn %1, avg + pavgw m0, [dstq] +%endif + mova [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET + +cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _12, 6, 6, %2, dst, dstride, src, sstride, h, filtery + mova m5, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_h_ %+ %%px %+ _10 %+ SUFFIX).body +%endmacro + +INIT_XMM sse2 +filter_h_fn put +filter_h_fn avg +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +filter_h_fn put +filter_h_fn avg +%endif + +%macro filter_v4_fn 1-2 12 +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_4_10, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_4_10, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%define hd r4mp +%endif + mova m5, [pw_1023] +.body: +%if notcpuflag(sse4) && ARCH_X86_64 + pxor m11, m11 +%endif + mova m6, [pd_64] + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+ 32] + mova m9, [filteryq+ 64] + mova m10, [filteryq+ 96] +%endif +.loop: + ; FIXME maybe reuse loads from previous rows, or just + ; more generally unroll this to prevent multiple loads of + ; the same data? + movh m0, [srcq] + movh m1, [srcq+sstrideq] + movh m2, [srcq+sstrideq*2] + movh m3, [srcq+sstride3q] + add srcq, sstrideq + movh m4, [src4q] + punpcklwd m0, m1 + punpcklwd m2, m3 + pmaddwd m0, m7 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m2, m8 +%else + pmaddwd m2, [filteryq+ 32] +%endif + movh m1, [src4q+sstrideq] + movh m3, [src4q+sstrideq*2] + paddd m0, m2 + movh m2, [src4q+sstride3q] + add src4q, sstrideq + punpcklwd m4, m1 + punpcklwd m3, m2 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m4, m9 + pmaddwd m3, m10 +%else + pmaddwd m4, [filteryq+ 64] + pmaddwd m3, [filteryq+ 96] +%endif + paddd m0, m4 + paddd m0, m3 + paddd m0, m6 + psrad m0, 7 +%if cpuflag(sse4) + packusdw m0, m0 +%else + packssdw m0, m0 +%endif +%ifidn %1, avg + movh m1, [dstq] +%endif + pminsw m0, m5 +%if notcpuflag(sse4) +%if ARCH_X86_64 + pmaxsw m0, m11 +%else + pxor m2, m2 + pmaxsw m0, m2 +%endif +%endif +%ifidn %1, avg + pavgw m0, m1 +%endif + movh [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET + +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_4_12, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_4_12, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%endif + mova m5, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_v_4_10 %+ SUFFIX).body +%endmacro + +INIT_XMM sse2 +filter_v4_fn put +filter_v4_fn avg + +%macro filter_v_fn 1-2 13 +%assign %%px mmsize/2 +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _10, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _10, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%define hd r4mp +%endif + mova m5, [pw_1023] +.body: +%if notcpuflag(sse4) && ARCH_X86_64 + pxor m12, m12 +%endif +%if ARCH_X86_64 + mova m11, [pd_64] +%endif + lea sstride3q, [sstrideq*3] + lea src4q, [srcq+sstrideq] + sub srcq, sstride3q + mova m7, [filteryq+ 0] +%if ARCH_X86_64 && mmsize > 8 + mova m8, [filteryq+ 32] + mova m9, [filteryq+ 64] + mova m10, [filteryq+ 96] +%endif +.loop: + ; FIXME maybe reuse loads from previous rows, or just + ; more generally unroll this to prevent multiple loads of + ; the same data? + movu m0, [srcq] + movu m1, [srcq+sstrideq] + movu m2, [srcq+sstrideq*2] + movu m3, [srcq+sstride3q] + add srcq, sstrideq + movu m4, [src4q] + SBUTTERFLY wd, 0, 1, 6 + SBUTTERFLY wd, 2, 3, 6 + pmaddwd m0, m7 + pmaddwd m1, m7 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m2, m8 + pmaddwd m3, m8 +%else + pmaddwd m2, [filteryq+ 32] + pmaddwd m3, [filteryq+ 32] +%endif + paddd m0, m2 + paddd m1, m3 + movu m2, [src4q+sstrideq] + movu m3, [src4q+sstrideq*2] + SBUTTERFLY wd, 4, 2, 6 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m4, m9 + pmaddwd m2, m9 +%else + pmaddwd m4, [filteryq+ 64] + pmaddwd m2, [filteryq+ 64] +%endif + paddd m0, m4 + paddd m1, m2 + movu m4, [src4q+sstride3q] + add src4q, sstrideq + SBUTTERFLY wd, 3, 4, 6 +%if ARCH_X86_64 && mmsize > 8 + pmaddwd m3, m10 + pmaddwd m4, m10 +%else + pmaddwd m3, [filteryq+ 96] + pmaddwd m4, [filteryq+ 96] +%endif + paddd m0, m3 + paddd m1, m4 +%if ARCH_X86_64 + paddd m0, m11 + paddd m1, m11 +%else + paddd m0, [pd_64] + paddd m1, [pd_64] +%endif + psrad m0, 7 + psrad m1, 7 +%if cpuflag(sse4) + packusdw m0, m1 +%else + packssdw m0, m1 +%endif + pminsw m0, m5 +%if notcpuflag(sse4) +%if ARCH_X86_64 + pmaxsw m0, m12 +%else + pxor m2, m2 + pmaxsw m0, m2 +%endif +%endif +%ifidn %1, avg + pavgw m0, [dstq] +%endif + mova [dstq], m0 + add dstq, dstrideq + dec hd + jg .loop + RET + +%if ARCH_X86_64 +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _12, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3 +%else +cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _12, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3 + mov filteryq, r5mp +%endif + mova m5, [pw_4095] + jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_v_ %+ %%px %+ _10 %+ SUFFIX).body +%endmacro + +INIT_XMM sse2 +filter_v_fn put +filter_v_fn avg +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +filter_v_fn put +filter_v_fn avg +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/w64xmmtest.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/w64xmmtest.c new file mode 100644 index 00000000..d0782b94 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/w64xmmtest.c @@ -0,0 +1,101 @@ +/* + * check XMM registers for clobbers on Win64 + * Copyright (c) 2012 Ronald S. Bultje + * + * 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 "libavcodec/avcodec.h" +#include "libavutil/x86/w64xmmtest.h" + +wrap(avcodec_open2(AVCodecContext *avctx, + const AVCodec *codec, + AVDictionary **options)) +{ + testxmmclobbers(avcodec_open2, avctx, codec, options); +} + +#if FF_API_OLD_ENCDEC +wrap(avcodec_decode_audio4(AVCodecContext *avctx, + AVFrame *frame, + int *got_frame_ptr, + AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_decode_audio4, avctx, frame, + got_frame_ptr, avpkt); +} + +wrap(avcodec_decode_video2(AVCodecContext *avctx, + AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_decode_video2, avctx, picture, + got_picture_ptr, avpkt); +} + +wrap(avcodec_encode_audio2(AVCodecContext *avctx, + AVPacket *avpkt, + const AVFrame *frame, + int *got_packet_ptr)) +{ + testxmmclobbers(avcodec_encode_audio2, avctx, avpkt, frame, + got_packet_ptr); +} + +wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr)) +{ + testxmmclobbers(avcodec_encode_video2, avctx, avpkt, frame, got_packet_ptr); +} +#endif + +wrap(avcodec_decode_subtitle2(AVCodecContext *avctx, + AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_decode_subtitle2, avctx, sub, + got_sub_ptr, avpkt); +} + +wrap(avcodec_encode_subtitle(AVCodecContext *avctx, + uint8_t *buf, int buf_size, + const AVSubtitle *sub)) +{ + testxmmclobbers(avcodec_encode_subtitle, avctx, buf, buf_size, sub); +} + +wrap(avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_send_packet, avctx, avpkt); +} + +wrap(avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)) +{ + testxmmclobbers(avcodec_receive_packet, avctx, avpkt); +} + +wrap(avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)) +{ + testxmmclobbers(avcodec_send_frame, avctx, frame); +} + +wrap(avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)) +{ + testxmmclobbers(avcodec_receive_frame, avctx, frame); +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct.asm new file mode 100644 index 00000000..0220885d --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct.asm @@ -0,0 +1,983 @@ +; XVID MPEG-4 VIDEO CODEC +; +; Conversion from gcc syntax to x264asm syntax with modifications +; by Christophe Gisquet +; +; =========== SSE2 inverse discrete cosine transform =========== +; +; Copyright(C) 2003 Pascal Massimino +; +; Conversion to gcc syntax with modifications +; by Alexander Strange +; +; Originally from dct/x86_asm/fdct_sse2_skal.asm in Xvid. +; +; Vertical pass is an implementation of the scheme: +; Loeffler C., Ligtenberg A., and Moschytz C.S.: +; Practical Fast 1D DCT Algorithm with Eleven Multiplications, +; Proc. ICASSP 1989, 988-991. +; +; Horizontal pass is a double 4x4 vector/matrix multiplication, +; (see also Intel's Application Note 922: +; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm +; Copyright (C) 1999 Intel Corporation) +; +; More details at http://skal.planet-d.net/coding/dct.html +; +; ======= MMX and XMM forward discrete cosine transform ======= +; +; Copyright(C) 2001 Peter Ross +; +; Originally provided by Intel at AP-922 +; http://developer.intel.com/vtune/cbts/strmsimd/922down.htm +; (See more app notes at http://developer.intel.com/vtune/cbts/strmsimd/appnotes.htm) +; but in a limited edition. +; New macro implements a column part for precise iDCT +; The routine precision now satisfies IEEE standard 1180-1990. +; +; Copyright(C) 2000-2001 Peter Gubanov +; Rounding trick Copyright(C) 2000 Michel Lespinasse +; +; http://www.elecard.com/peter/idct.html +; http://www.linuxvideo.org/mpeg2dec/ +; +; These examples contain code fragments for first stage iDCT 8x8 +; (for rows) and first stage DCT 8x8 (for columns) +; +; conversion to gcc syntax by Michael Niedermayer +; +; ====================================================================== +; +; 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 "libavutil/x86/x86util.asm" + +SECTION_RODATA +; Similar to tg_1_16 in MMX code +tan1: times 8 dw 13036 +tan2: times 8 dw 27146 +tan3: times 8 dw 43790 +sqrt2: times 8 dw 23170 + +; SSE2 tables +iTab1: dw 0x4000, 0x539f, 0xc000, 0xac61, 0x4000, 0xdd5d, 0x4000, 0xdd5d + dw 0x4000, 0x22a3, 0x4000, 0x22a3, 0xc000, 0x539f, 0x4000, 0xac61 + dw 0x3249, 0x11a8, 0x4b42, 0xee58, 0x11a8, 0x4b42, 0x11a8, 0xcdb7 + dw 0x58c5, 0x4b42, 0xa73b, 0xcdb7, 0x3249, 0xa73b, 0x4b42, 0xa73b +iTab2: dw 0x58c5, 0x73fc, 0xa73b, 0x8c04, 0x58c5, 0xcff5, 0x58c5, 0xcff5 + dw 0x58c5, 0x300b, 0x58c5, 0x300b, 0xa73b, 0x73fc, 0x58c5, 0x8c04 + dw 0x45bf, 0x187e, 0x6862, 0xe782, 0x187e, 0x6862, 0x187e, 0xba41 + dw 0x7b21, 0x6862, 0x84df, 0xba41, 0x45bf, 0x84df, 0x6862, 0x84df +iTab3: dw 0x539f, 0x6d41, 0xac61, 0x92bf, 0x539f, 0xd2bf, 0x539f, 0xd2bf + dw 0x539f, 0x2d41, 0x539f, 0x2d41, 0xac61, 0x6d41, 0x539f, 0x92bf + dw 0x41b3, 0x1712, 0x6254, 0xe8ee, 0x1712, 0x6254, 0x1712, 0xbe4d + dw 0x73fc, 0x6254, 0x8c04, 0xbe4d, 0x41b3, 0x8c04, 0x6254, 0x8c04 +iTab4: dw 0x4b42, 0x6254, 0xb4be, 0x9dac, 0x4b42, 0xd746, 0x4b42, 0xd746 + dw 0x4b42, 0x28ba, 0x4b42, 0x28ba, 0xb4be, 0x6254, 0x4b42, 0x9dac + dw 0x3b21, 0x14c3, 0x587e, 0xeb3d, 0x14c3, 0x587e, 0x14c3, 0xc4df + dw 0x6862, 0x587e, 0x979e, 0xc4df, 0x3b21, 0x979e, 0x587e, 0x979e + +%if ARCH_X86_32 +; ----------------------------------------------------------------------------- +; +; The first stage iDCT 8x8 - inverse DCTs of rows +; +; ----------------------------------------------------------------------------- +; The 8-point inverse DCT direct algorithm +; ----------------------------------------------------------------------------- +; +; static const short w[32] = { +; FIX(cos_4_16), FIX(cos_2_16), FIX(cos_4_16), FIX(cos_6_16), +; FIX(cos_4_16), FIX(cos_6_16), -FIX(cos_4_16), -FIX(cos_2_16), +; FIX(cos_4_16), -FIX(cos_6_16), -FIX(cos_4_16), FIX(cos_2_16), +; FIX(cos_4_16), -FIX(cos_2_16), FIX(cos_4_16), -FIX(cos_6_16), +; FIX(cos_1_16), FIX(cos_3_16), FIX(cos_5_16), FIX(cos_7_16), +; FIX(cos_3_16), -FIX(cos_7_16), -FIX(cos_1_16), -FIX(cos_5_16), +; FIX(cos_5_16), -FIX(cos_1_16), FIX(cos_7_16), FIX(cos_3_16), +; FIX(cos_7_16), -FIX(cos_5_16), FIX(cos_3_16), -FIX(cos_1_16) }; +; +; #define DCT_8_INV_ROW(x, y) +; { +; int a0, a1, a2, a3, b0, b1, b2, b3; +; +; a0 = x[0] * w[0] + x[2] * w[1] + x[4] * w[2] + x[6] * w[3]; +; a1 = x[0] * w[4] + x[2] * w[5] + x[4] * w[6] + x[6] * w[7]; +; a2 = x[0] * w[8] + x[2] * w[9] + x[4] * w[10] + x[6] * w[11]; +; a3 = x[0] * w[12] + x[2] * w[13] + x[4] * w[14] + x[6] * w[15]; +; b0 = x[1] * w[16] + x[3] * w[17] + x[5] * w[18] + x[7] * w[19]; +; b1 = x[1] * w[20] + x[3] * w[21] + x[5] * w[22] + x[7] * w[23]; +; b2 = x[1] * w[24] + x[3] * w[25] + x[5] * w[26] + x[7] * w[27]; +; b3 = x[1] * w[28] + x[3] * w[29] + x[5] * w[30] + x[7] * w[31]; +; +; y[0] = SHIFT_ROUND(a0 + b0); +; y[1] = SHIFT_ROUND(a1 + b1); +; y[2] = SHIFT_ROUND(a2 + b2); +; y[3] = SHIFT_ROUND(a3 + b3); +; y[4] = SHIFT_ROUND(a3 - b3); +; y[5] = SHIFT_ROUND(a2 - b2); +; y[6] = SHIFT_ROUND(a1 - b1); +; y[7] = SHIFT_ROUND(a0 - b0); +; } +; +; ----------------------------------------------------------------------------- +; +; In this implementation the outputs of the iDCT-1D are multiplied +; for rows 0,4 - by cos_4_16, +; for rows 1,7 - by cos_1_16, +; for rows 2,6 - by cos_2_16, +; for rows 3,5 - by cos_3_16 +; and are shifted to the left for better accuracy. +; +; For the constants used, +; FIX(float_const) = (short) (float_const * (1 << 15) + 0.5) +; +; ----------------------------------------------------------------------------- + +; ----------------------------------------------------------------------------- +; Tables for mmx processors +; ----------------------------------------------------------------------------- + +; Table for rows 0,4 - constants are multiplied by cos_4_16 +tab_i_04_mmx: dw 16384, 16384, 16384, -16384 + dw 21407, 8867, 8867, -21407 ; w07 w05 w03 w01 + dw 16384, -16384, 16384, 16384 ; w14 w12 w10 w08 + dw -8867, 21407, -21407, -8867 ; w15 w13 w11 w09 + dw 22725, 12873, 19266, -22725 ; w22 w20 w18 w16 + dw 19266, 4520, -4520, -12873 ; w23 w21 w19 w17 + dw 12873, 4520, 4520, 19266 ; w30 w28 w26 w24 + dw -22725, 19266, -12873, -22725 ; w31 w29 w27 w25 +; Table for rows 1,7 - constants are multiplied by cos_1_16 + dw 22725, 22725, 22725, -22725 ; movq-> w06 w04 w02 w00 + dw 29692, 12299, 12299, -29692 ; w07 w05 w03 w01 + dw 22725, -22725, 22725, 22725 ; w14 w12 w10 w08 + dw -12299, 29692, -29692, -12299 ; w15 w13 w11 w09 + dw 31521, 17855, 26722, -31521 ; w22 w20 w18 w16 + dw 26722, 6270, -6270, -17855 ; w23 w21 w19 w17 + dw 17855, 6270, 6270, 26722 ; w30 w28 w26 w24 + dw -31521, 26722, -17855, -31521 ; w31 w29 w27 w25 +; Table for rows 2,6 - constants are multiplied by cos_2_16 + dw 21407, 21407, 21407, -21407 ; movq-> w06 w04 w02 w00 + dw 27969, 11585, 11585, -27969 ; w07 w05 w03 w01 + dw 21407, -21407, 21407, 21407 ; w14 w12 w10 w08 + dw -11585, 27969, -27969, -11585 ; w15 w13 w11 w09 + dw 29692, 16819, 25172, -29692 ; w22 w20 w18 w16 + dw 25172, 5906, -5906, -16819 ; w23 w21 w19 w17 + dw 16819, 5906, 5906, 25172 ; w30 w28 w26 w24 + dw -29692, 25172, -16819, -29692 ; w31 w29 w27 w25 +; Table for rows 3,5 - constants are multiplied by cos_3_16 + dw 19266, 19266, 19266, -19266 ; movq-> w06 w04 w02 w00 + dw 25172, 10426, 10426, -25172 ; w07 w05 w03 w01 + dw 19266, -19266, 19266, 19266 ; w14 w12 w10 w08 + dw -10426, 25172, -25172, -10426 ; w15 w13 w11 w09 + dw 26722, 15137, 22654, -26722 ; w22 w20 w18 w16 + dw 22654, 5315, -5315, -15137 ; w23 w21 w19 w17 + dw 15137, 5315, 5315, 22654 ; w30 w28 w26 w24 + dw -26722, 22654, -15137, -26722 ; w31 w29 w27 w25 + +; ----------------------------------------------------------------------------- +; Tables for xmm processors +; ----------------------------------------------------------------------------- + +; %3 for rows 0,4 - constants are multiplied by cos_4_16 +tab_i_04_xmm: dw 16384, 21407, 16384, 8867 ; movq-> w05 w04 w01 w00 + dw 16384, 8867, -16384, -21407 ; w07 w06 w03 w02 + dw 16384, -8867, 16384, -21407 ; w13 w12 w09 w08 + dw -16384, 21407, 16384, -8867 ; w15 w14 w11 w10 + dw 22725, 19266, 19266, -4520 ; w21 w20 w17 w16 + dw 12873, 4520, -22725, -12873 ; w23 w22 w19 w18 + dw 12873, -22725, 4520, -12873 ; w29 w28 w25 w24 + dw 4520, 19266, 19266, -22725 ; w31 w30 w27 w26 +; %3 for rows 1,7 - constants are multiplied by cos_1_16 + dw 22725, 29692, 22725, 12299 ; movq-> w05 w04 w01 w00 + dw 22725, 12299, -22725, -29692 ; w07 w06 w03 w02 + dw 22725, -12299, 22725, -29692 ; w13 w12 w09 w08 + dw -22725, 29692, 22725, -12299 ; w15 w14 w11 w10 + dw 31521, 26722, 26722, -6270 ; w21 w20 w17 w16 + dw 17855, 6270, -31521, -17855 ; w23 w22 w19 w18 + dw 17855, -31521, 6270, -17855 ; w29 w28 w25 w24 + dw 6270, 26722, 26722, -31521 ; w31 w30 w27 w26 +; %3 for rows 2,6 - constants are multiplied by cos_2_16 + dw 21407, 27969, 21407, 11585 ; movq-> w05 w04 w01 w00 + dw 21407, 11585, -21407, -27969 ; w07 w06 w03 w02 + dw 21407, -11585, 21407, -27969 ; w13 w12 w09 w08 + dw -21407, 27969, 21407, -11585 ; w15 w14 w11 w10 + dw 29692, 25172, 25172, -5906 ; w21 w20 w17 w16 + dw 16819, 5906, -29692, -16819 ; w23 w22 w19 w18 + dw 16819, -29692, 5906, -16819 ; w29 w28 w25 w24 + dw 5906, 25172, 25172, -29692 ; w31 w30 w27 w26 +; %3 for rows 3,5 - constants are multiplied by cos_3_16 + dw 19266, 25172, 19266, 10426 ; movq-> w05 w04 w01 w00 + dw 19266, 10426, -19266, -25172 ; w07 w06 w03 w02 + dw 19266, -10426, 19266, -25172 ; w13 w12 w09 w08 + dw -19266, 25172, 19266, -10426 ; w15 w14 w11 w10 + dw 26722, 22654, 22654, -5315 ; w21 w20 w17 w16 + dw 15137, 5315, -26722, -15137 ; w23 w22 w19 w18 + dw 15137, -26722, 5315, -15137 ; w29 w28 w25 w24 + dw 5315, 22654, 22654, -26722 ; w31 w30 w27 w26 +%endif ; ~ARCH_X86_32 + +; Similar to rounder_0 in MMX code +; 4 first similar, then: 4*8->6*16 5*8->4*16 6/7*8->5*16 +walkenIdctRounders: times 4 dd 65536 + times 4 dd 3597 + times 4 dd 2260 + times 4 dd 1203 + times 4 dd 120 + times 4 dd 512 + times 2 dd 0 + +pb_127: times 8 db 127 + +SECTION .text + +; Temporary storage before the column pass +%define ROW1 xmm6 +%define ROW3 xmm4 +%define ROW5 xmm5 +%define ROW7 xmm7 + +%macro CLEAR_ODD 1 + pxor %1, %1 +%endmacro +%macro PUT_ODD 1 + pshufhw %1, xmm2, 0x1B +%endmacro + +%macro MOV32 2 +%if ARCH_X86_32 + movdqa %2, %1 +%endif +%endmacro + +%macro CLEAR_EVEN 1 +%if ARCH_X86_64 + CLEAR_ODD %1 +%endif +%endmacro + +%macro PUT_EVEN 1 +%if ARCH_X86_64 + PUT_ODD %1 +%else + pshufhw xmm2, xmm2, 0x1B + movdqa %1, xmm2 +%endif +%endmacro + +%if ARCH_X86_64 +%define ROW0 xmm8 +%define REG0 ROW0 +%define ROW2 xmm9 +%define REG2 ROW2 +%define ROW4 xmm10 +%define REG4 ROW4 +%define ROW6 xmm11 +%define REG6 ROW6 +%define XMMS xmm12 +%define SREG2 REG2 +%define TAN3 xmm13 +%define TAN1 xmm14 +%else +%define ROW0 [BLOCK + 0*16] +%define REG0 xmm4 +%define ROW2 [BLOCK + 2*16] +%define REG2 xmm4 +%define ROW4 [BLOCK + 4*16] +%define REG4 xmm6 +%define ROW6 [BLOCK + 6*16] +%define REG6 xmm6 +%define XMMS xmm2 +%define SREG2 xmm7 +%define TAN3 xmm0 +%define TAN1 xmm2 +%endif + +%macro JZ 2 + test %1, %1 + jz .%2 +%endmacro + +%macro JNZ 2 + test %1, %1 + jnz .%2 +%endmacro + +%macro TEST_ONE_ROW 4 ; src, reg, clear, arg + %3 %4 + movq mm1, [%1] + por mm1, [%1 + 8] + paddusb mm1, mm0 + pmovmskb %2, mm1 +%endmacro + +;row1, row2, reg1, reg2, clear1, arg1, clear2, arg2 +%macro TEST_TWO_ROWS 8 + %5 %6 + %7 %8 + movq mm1, [%1 + 0] + por mm1, [%1 + 8] + movq mm2, [%2 + 0] + por mm2, [%2 + 8] + paddusb mm1, mm0 + paddusb mm2, mm0 + pmovmskb %3, mm1 + pmovmskb %4, mm2 +%endmacro + +; IDCT pass on rows. +%macro iMTX_MULT 4-5 ; src, table, put, arg, rounder + movdqa xmm3, [%1] + movdqa xmm0, xmm3 + pshufd xmm1, xmm3, 0x11 ; 4602 + punpcklqdq xmm0, xmm0 ; 0246 + pmaddwd xmm0, [%2] + pmaddwd xmm1, [%2+16] + pshufd xmm2, xmm3, 0xBB ; 5713 + punpckhqdq xmm3, xmm3 ; 1357 + pmaddwd xmm2, [%2+32] + pmaddwd xmm3, [%2+48] + paddd xmm0, xmm1 + paddd xmm2, xmm3 +%if %0 == 5 + paddd xmm0, [walkenIdctRounders+%5] +%endif + movdqa xmm3, xmm2 + paddd xmm2, xmm0 + psubd xmm0, xmm3 + psrad xmm2, 11 + psrad xmm0, 11 + packssdw xmm2, xmm0 + %3 %4 +%endmacro + +%macro iLLM_HEAD 0 + movdqa TAN3, [tan3] + movdqa TAN1, [tan1] +%endmacro + +%macro FIRST_HALF 2 ; %1=dct %2=type(normal,add,put) + psraw xmm5, 6 + psraw REG0, 6 + psraw TAN3, 6 + psraw xmm3, 6 + ; dct coeffs must still be written for AC prediction +%if %2 == 0 + movdqa [%1+1*16], TAN3 + movdqa [%1+2*16], xmm3 + movdqa [%1+5*16], REG0 + movdqa [%1+6*16], xmm5 +%else + ; Must now load args as gprs are no longer used for masks + ; DEST is set to where address of dest was loaded + %if ARCH_X86_32 + %if %2 == 2 ; Not enough xmms, store + movdqa [%1+1*16], TAN3 + movdqa [%1+2*16], xmm3 + movdqa [%1+5*16], REG0 + movdqa [%1+6*16], xmm5 + %endif + %xdefine DEST r2q ; BLOCK is r0, stride r1 + movifnidn DEST, destm + movifnidn strideq, stridem + %else + %xdefine DEST r0q + %endif + lea r3q, [3*strideq] + %if %2 == 1 + packuswb TAN3, xmm3 + packuswb xmm5, REG0 + movq [DEST + strideq], TAN3 + movhps [DEST + 2*strideq], TAN3 + ; REG0 and TAN3 are now available (and likely used in second half) + %endif +%endif +%endmacro + +%macro SECOND_HALF 6 ; %1=dct %2=type(normal,add,put) 3-6: xmms + psraw %3, 6 + psraw %4, 6 + psraw %5, 6 + psraw %6, 6 + ; dct coeffs must still be written for AC prediction +%if %2 == 0 + movdqa [%1+0*16], %3 + movdqa [%1+3*16], %5 + movdqa [%1+4*16], %6 + movdqa [%1+7*16], %4 +%elif %2 == 1 + packuswb %3, %5 + packuswb %6, %4 + ; address of dest may have been loaded + movq [DEST], %3 + movhps [DEST + r3q], %3 + lea DEST, [DEST + 4*strideq] + movq [DEST], %6 + movhps [DEST + r3q], %6 + ; and now write remainder of first half + movq [DEST + 2*strideq], xmm5 + movhps [DEST + strideq], xmm5 +%elif %2 == 2 + pxor xmm0, xmm0 + %if ARCH_X86_32 + ; free: m3 REG0=m4 m5 + ; input: m1, m7, m2, m6 + movq xmm3, [DEST+0*strideq] + movq xmm4, [DEST+1*strideq] + punpcklbw xmm3, xmm0 + punpcklbw xmm4, xmm0 + paddsw xmm3, %3 + paddsw xmm4, [%1 + 1*16] + movq %3, [DEST+2*strideq] + movq xmm5, [DEST+ r3q] + punpcklbw %3, xmm0 + punpcklbw xmm5, xmm0 + paddsw %3, [%1 + 2*16] + paddsw xmm5, %5 + packuswb xmm3, xmm4 + packuswb %3, xmm5 + movq [DEST+0*strideq], xmm3 + movhps [DEST+1*strideq], xmm3 + movq [DEST+2*strideq], %3 + movhps [DEST+ r3q], %3 + lea DEST, [DEST+4*strideq] + movq xmm3, [DEST+0*strideq] + movq xmm4, [DEST+1*strideq] + movq %3, [DEST+2*strideq] + movq xmm5, [DEST+ r3q] + punpcklbw xmm3, xmm0 + punpcklbw xmm4, xmm0 + punpcklbw %3, xmm0 + punpcklbw xmm5, xmm0 + paddsw xmm3, %6 + paddsw xmm4, [%1 + 5*16] + paddsw %3, [%1 + 6*16] + paddsw xmm5, %4 + packuswb xmm3, xmm4 + packuswb %3, xmm5 + movq [DEST+0*strideq], xmm3 + movhps [DEST+1*strideq], xmm3 + movq [DEST+2*strideq], %3 + movhps [DEST+ r3q], %3 + %else + ; l1:TAN3=m13 l2:m3 l5:REG0=m8 l6=m5 + ; input: m1, m7/SREG2=m9, TAN1=m14, REG4=m10 + movq xmm2, [DEST+0*strideq] + movq xmm4, [DEST+1*strideq] + movq xmm12, [DEST+2*strideq] + movq xmm11, [DEST+ r3q] + punpcklbw xmm2, xmm0 + punpcklbw xmm4, xmm0 + punpcklbw xmm12, xmm0 + punpcklbw xmm11, xmm0 + paddsw xmm2, %3 + paddsw xmm4, TAN3 + paddsw xmm12, xmm3 + paddsw xmm11, %5 + packuswb xmm2, xmm4 + packuswb xmm12, xmm11 + movq [DEST+0*strideq], xmm2 + movhps [DEST+1*strideq], xmm2 + movq [DEST+2*strideq], xmm12 + movhps [DEST+ r3q], xmm12 + lea DEST, [DEST+4*strideq] + movq xmm2, [DEST+0*strideq] + movq xmm4, [DEST+1*strideq] + movq xmm12, [DEST+2*strideq] + movq xmm11, [DEST+ r3q] + punpcklbw xmm2, xmm0 + punpcklbw xmm4, xmm0 + punpcklbw xmm12, xmm0 + punpcklbw xmm11, xmm0 + paddsw xmm2, %6 + paddsw xmm4, REG0 + paddsw xmm12, xmm5 + paddsw xmm11, %4 + packuswb xmm2, xmm4 + packuswb xmm12, xmm11 + movq [DEST+0*strideq], xmm2 + movhps [DEST+1*strideq], xmm2 + movq [DEST+2*strideq], xmm12 + movhps [DEST+ r3q], xmm12 + %endif +%endif +%endmacro + + +; IDCT pass on columns. +%macro iLLM_PASS 2 ; %1=dct %2=type(normal,add,put) + movdqa xmm1, TAN3 + movdqa xmm3, TAN1 + pmulhw TAN3, xmm4 + pmulhw xmm1, xmm5 + paddsw TAN3, xmm4 + paddsw xmm1, xmm5 + psubsw TAN3, xmm5 + paddsw xmm1, xmm4 + pmulhw xmm3, xmm7 + pmulhw TAN1, xmm6 + paddsw xmm3, xmm6 + psubsw TAN1, xmm7 + movdqa xmm7, xmm3 + movdqa xmm6, TAN1 + psubsw xmm3, xmm1 + psubsw TAN1, TAN3 + paddsw xmm1, xmm7 + paddsw TAN3, xmm6 + movdqa xmm6, xmm3 + psubsw xmm3, TAN3 + paddsw TAN3, xmm6 + movdqa xmm4, [sqrt2] + pmulhw xmm3, xmm4 + pmulhw TAN3, xmm4 + paddsw TAN3, TAN3 + paddsw xmm3, xmm3 + movdqa xmm7, [tan2] + MOV32 ROW2, REG2 + MOV32 ROW6, REG6 + movdqa xmm5, xmm7 + pmulhw xmm7, REG6 + pmulhw xmm5, REG2 + paddsw xmm7, REG2 + psubsw xmm5, REG6 + MOV32 ROW0, REG0 + MOV32 ROW4, REG4 + MOV32 TAN1, [BLOCK] + movdqa XMMS, REG0 + psubsw REG0, REG4 + paddsw REG4, XMMS + movdqa XMMS, REG4 + psubsw REG4, xmm7 + paddsw xmm7, XMMS + movdqa XMMS, REG0 + psubsw REG0, xmm5 + paddsw xmm5, XMMS + movdqa XMMS, xmm5 + psubsw xmm5, TAN3 + paddsw TAN3, XMMS + movdqa XMMS, REG0 + psubsw REG0, xmm3 + paddsw xmm3, XMMS + MOV32 [BLOCK], TAN1 + + FIRST_HALF %1, %2 + + movdqa xmm0, xmm7 + movdqa xmm4, REG4 + psubsw xmm7, xmm1 + psubsw REG4, TAN1 + paddsw xmm1, xmm0 + paddsw TAN1, xmm4 + + SECOND_HALF %1, %2, xmm1, xmm7, TAN1, REG4 +%endmacro + +; IDCT pass on columns, assuming rows 4-7 are zero +%macro iLLM_PASS_SPARSE 2 ; %1=dct %2=type(normal,put,add) + pmulhw TAN3, xmm4 + paddsw TAN3, xmm4 + movdqa xmm3, xmm6 + pmulhw TAN1, xmm6 + movdqa xmm1, xmm4 + psubsw xmm3, xmm1 + paddsw xmm1, xmm6 + movdqa xmm6, TAN1 + psubsw TAN1, TAN3 + paddsw TAN3, xmm6 + movdqa xmm6, xmm3 + psubsw xmm3, TAN3 + paddsw TAN3, xmm6 + movdqa xmm4, [sqrt2] + pmulhw xmm3, xmm4 + pmulhw TAN3, xmm4 + paddsw TAN3, TAN3 + paddsw xmm3, xmm3 + movdqa xmm5, [tan2] + MOV32 ROW2, SREG2 + pmulhw xmm5, SREG2 + MOV32 ROW0, REG0 + movdqa xmm6, REG0 + psubsw xmm6, SREG2 + paddsw SREG2, REG0 + MOV32 TAN1, [BLOCK] + movdqa XMMS, REG0 + psubsw REG0, xmm5 + paddsw xmm5, XMMS + movdqa XMMS, xmm5 + psubsw xmm5, TAN3 + paddsw TAN3, XMMS + movdqa XMMS, REG0 + psubsw REG0, xmm3 + paddsw xmm3, XMMS + MOV32 [BLOCK], TAN1 + + FIRST_HALF %1, %2 + + movdqa xmm0, SREG2 + movdqa xmm4, xmm6 + psubsw SREG2, xmm1 + psubsw xmm6, TAN1 + paddsw xmm1, xmm0 + paddsw TAN1, xmm4 + + SECOND_HALF %1, %2, xmm1, SREG2, TAN1, xmm6 +%endmacro + +%macro IDCT_SSE2 1 ; 0=normal 1=put 2=add +%if %1 == 0 || ARCH_X86_32 + %define GPR0 r1d + %define GPR1 r2d + %define GPR2 r3d + %define GPR3 r4d + %define NUM_GPRS 5 +%else + %define GPR0 r3d + %define GPR1 r4d + %define GPR2 r5d + %define GPR3 r6d + %define NUM_GPRS 7 +%endif +%if %1 == 0 +cglobal xvid_idct, 1, NUM_GPRS, 8+7*ARCH_X86_64, block +%xdefine BLOCK blockq +%else + %if %1 == 1 +cglobal xvid_idct_put, 0, NUM_GPRS, 8+7*ARCH_X86_64, dest, stride, block + %else +cglobal xvid_idct_add, 0, NUM_GPRS, 8+7*ARCH_X86_64, dest, stride, block + %endif + %if ARCH_X86_64 + %xdefine BLOCK blockq + %else + mov r0q, blockm + %xdefine BLOCK r0q + %endif +%endif + movq mm0, [pb_127] + iMTX_MULT BLOCK + 0*16, iTab1, PUT_EVEN, ROW0, 0*16 + iMTX_MULT BLOCK + 1*16, iTab2, PUT_ODD, ROW1, 1*16 + iMTX_MULT BLOCK + 2*16, iTab3, PUT_EVEN, ROW2, 2*16 + + TEST_TWO_ROWS BLOCK + 3*16, BLOCK + 4*16, GPR0, GPR1, CLEAR_ODD, ROW3, CLEAR_EVEN, ROW4 ; a, c + JZ GPR0, col1 + iMTX_MULT BLOCK + 3*16, iTab4, PUT_ODD, ROW3, 3*16 +.col1: + TEST_TWO_ROWS BLOCK + 5*16, BLOCK + 6*16, GPR0, GPR2, CLEAR_ODD, ROW5, CLEAR_EVEN, ROW6 ; a, d + TEST_ONE_ROW BLOCK + 7*16, GPR3, CLEAR_ODD, ROW7 ; esi + + iLLM_HEAD + JNZ GPR1, 2 + JNZ GPR0, 3 + JNZ GPR2, 4 + JNZ GPR3, 5 + iLLM_PASS_SPARSE BLOCK, %1 + jmp .6 +.2: + iMTX_MULT BLOCK + 4*16, iTab1, PUT_EVEN, ROW4 +.3: + iMTX_MULT BLOCK + 5*16, iTab4, PUT_ODD, ROW5, 4*16 + JZ GPR2, col2 +.4: + iMTX_MULT BLOCK + 6*16, iTab3, PUT_EVEN, ROW6, 5*16 +.col2: + JZ GPR3, col3 +.5: + iMTX_MULT BLOCK + 7*16, iTab2, PUT_ODD, ROW7, 5*16 +.col3: +%if ARCH_X86_32 + iLLM_HEAD +%endif + iLLM_PASS BLOCK, %1 +.6: + RET +%endmacro + +INIT_XMM sse2 +IDCT_SSE2 0 +IDCT_SSE2 1 +IDCT_SSE2 2 + +%if ARCH_X86_32 + +; %1=offset %2=tab_offset +; %3=rnd_offset where 4*8->6*16 5*8->4*16 6/7*8->5*16 +%macro DCT_8_INV_ROW 3 + movq mm0, [r0+16*%1+0] ; 0 ; x3 x2 x1 x0 + movq mm1, [r0+16*%1+8] ; 1 ; x7 x6 x5 x4 + movq mm2, mm0 ; 2 ; x3 x2 x1 x0 + movq mm3, [%2+ 0] ; 3 ; w06 w04 w02 w00 +%if cpuflag(mmxext) + pshufw mm0, mm0, 0x88 ; x2 x0 x2 x0 + movq mm4, [%2+ 8] ; 4 ; w07 w06 w03 w02 + movq mm5, mm1 ; 5 ; x7 x6 x5 x4 + pmaddwd mm3, mm0 ; x2*w05+x0*w04 x2*w01+x0*w00 + movq mm6, [%2+32] ; 6 ; w21 w20 w17 w16 + pshufw mm1, mm1, 0x88 ; x6 x4 x6 x4 + pmaddwd mm4, mm1 ; x6*w07+x4*w06 x6*w03+x4*w02 + movq mm7, [%2+40] ; 7; w23 w22 w19 w18 + pshufw mm2, mm2, 0xdd ; x3 x1 x3 x1 + pmaddwd mm6, mm2 ; x3*w21+x1*w20 x3*w17+x1*w16 + pshufw mm5, mm5, 0xdd ; x7 x5 x7 x5 + pmaddwd mm7, mm5 ; x7*w23+x5*w22 x7*w19+x5*w18 + paddd mm3, [walkenIdctRounders + %3] ; +%3 + pmaddwd mm0, [%2+16] ; x2*w13+x0*w12 x2*w09+x0*w08 + paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) + pmaddwd mm1, [%2+24] ; x6*w15+x4*w14 x6*w11+x4*w10 + movq mm4, mm3 ; 4 ; a1 a0 + pmaddwd mm2, [%2+48] ; x3*w29+x1*w28 x3*w25+x1*w24 + paddd mm6, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) + pmaddwd mm5, [%2+56] ; x7*w31+x5*w30 x7*w27+x5*w26 + paddd mm3, mm6 ; a1+b1 a0+b0 + paddd mm0, [walkenIdctRounders + %3] ; +%3 + psrad mm3, 11 ; y1=a1+b1 y0=a0+b0 + paddd mm0, mm1 ; 1 ; a3=sum(even3) a2=sum(even2) + psubd mm4, mm6 ; 6 ; a1-b1 a0-b0 + movq mm7, mm0 ; 7 ; a3 a2 + paddd mm2, mm5 ; 5 ; b3=sum(odd3) b2=sum(odd2) + paddd mm0, mm2 ; a3+b3 a2+b2 + psrad mm4, 11 ; y6=a1-b1 y7=a0-b0 + psubd mm7, mm2 ; 2 ; a3-b3 a2-b2 + psrad mm0, 11 ; y3=a3+b3 y2=a2+b2 + psrad mm7, 11 ; y4=a3-b3 y5=a2-b2 + packssdw mm3, mm0 ; 0 ; y3 y2 y1 y0 + packssdw mm7, mm4 ; 4 ; y6 y7 y4 y5 + movq [r0+16*%1+0], mm3 ; 3 ; save y3 y2 y1 y0 + pshufw mm7, mm7, 0xb1 ; y7 y6 y5 y4 +%else + punpcklwd mm0, mm1 ; x5 x1 x4 x0 + movq mm5, mm0 ; 5 ; x5 x1 x4 x0 + punpckldq mm0, mm0 ; x4 x0 x4 x0 + movq mm4, [%2+ 8] ; 4 ; w07 w05 w03 w01 + punpckhwd mm2, mm1 ; 1 ; x7 x3 x6 x2 + pmaddwd mm3, mm0 ; x4*w06+x0*w04 x4*w02+x0*w00 + movq mm6, mm2 ; 6 ; x7 x3 x6 x2 + movq mm1, [%2+32] ; 1 ; w22 w20 w18 w16 + punpckldq mm2, mm2 ; x6 x2 x6 x2 + pmaddwd mm4, mm2 ; x6*w07+x2*w05 x6*w03+x2*w01 + punpckhdq mm5, mm5 ; x5 x1 x5 x1 + pmaddwd mm0, [%2+16] ; x4*w14+x0*w12 x4*w10+x0*w08 + punpckhdq mm6, mm6 ; x7 x3 x7 x3 + movq mm7, [%2+40] ; 7 ; w23 w21 w19 w17 + pmaddwd mm1, mm5 ; x5*w22+x1*w20 x5*w18+x1*w16 + paddd mm3, [walkenIdctRounders + %3] ; +%3 + pmaddwd mm7, mm6 ; x7*w23+x3*w21 x7*w19+x3*w17 + pmaddwd mm2, [%2+24] ; x6*w15+x2*w13 x6*w11+x2*w09 + paddd mm3, mm4 ; 4 ; a1=sum(even1) a0=sum(even0) + pmaddwd mm5, [%2+48] ; x5*w30+x1*w28 x5*w26+x1*w24 + movq mm4, mm3 ; 4 ; a1 a0 + pmaddwd mm6, [%2+56] ; x7*w31+x3*w29 x7*w27+x3*w25 + paddd mm1, mm7 ; 7 ; b1=sum(odd1) b0=sum(odd0) + paddd mm0, [walkenIdctRounders + %3] ; +%3 + psubd mm3, mm1 ; a1-b1 a0-b0 + psrad mm3, 11 ; y6=a1-b1 y7=a0-b0 + paddd mm1, mm4 ; 4 ; a1+b1 a0+b0 + paddd mm0, mm2 ; 2 ; a3=sum(even3) a2=sum(even2) + psrad mm1, 11 ; y1=a1+b1 y0=a0+b0 + paddd mm5, mm6 ; 6 ; b3=sum(odd3) b2=sum(odd2) + movq mm4, mm0 ; 4 ; a3 a2 + paddd mm0, mm5 ; a3+b3 a2+b2 + psubd mm4, mm5 ; 5 ; a3-b3 a2-b2 + psrad mm0, 11 ; y3=a3+b3 y2=a2+b2 + psrad mm4, 11 ; y4=a3-b3 y5=a2-b2 + packssdw mm1, mm0 ; 0 ; y3 y2 y1 y0 + packssdw mm4, mm3 ; 3 ; y6 y7 y4 y5 + movq mm7, mm4 ; 7 ; y6 y7 y4 y5 + psrld mm4, 16 ; 0 y6 0 y4 + pslld mm7, 16 ; y7 0 y5 0 + movq [r0+16*%1+0], mm1 ; 1 ; save y3 y2 y1 y0 + por mm7, mm4 ; 4 ; y7 y6 y5 y4 +%endif + movq [r0+16*%1+8], mm7 ; 7 ; save y7 y6 y5 y4 +%endmacro + +; ----------------------------------------------------------------------------- +; +; The first stage DCT 8x8 - forward DCTs of columns +; +; The %2puts are multiplied +; for rows 0,4 - on cos_4_16, +; for rows 1,7 - on cos_1_16, +; for rows 2,6 - on cos_2_16, +; for rows 3,5 - on cos_3_16 +; and are shifted to the left for rise of accuracy +; +; ----------------------------------------------------------------------------- +; +; The 8-point scaled forward DCT algorithm (26a8m) +; +; ----------------------------------------------------------------------------- +; +;#define DCT_8_FRW_COL(x, y) +; { +; short t0, t1, t2, t3, t4, t5, t6, t7; +; short tp03, tm03, tp12, tm12, tp65, tm65; +; short tp465, tm465, tp765, tm765; +; +; t0 = LEFT_SHIFT(x[0] + x[7]); +; t1 = LEFT_SHIFT(x[1] + x[6]); +; t2 = LEFT_SHIFT(x[2] + x[5]); +; t3 = LEFT_SHIFT(x[3] + x[4]); +; t4 = LEFT_SHIFT(x[3] - x[4]); +; t5 = LEFT_SHIFT(x[2] - x[5]); +; t6 = LEFT_SHIFT(x[1] - x[6]); +; t7 = LEFT_SHIFT(x[0] - x[7]); +; +; tp03 = t0 + t3; +; tm03 = t0 - t3; +; tp12 = t1 + t2; +; tm12 = t1 - t2; +; +; y[0] = tp03 + tp12; +; y[4] = tp03 - tp12; +; +; y[2] = tm03 + tm12 * tg_2_16; +; y[6] = tm03 * tg_2_16 - tm12; +; +; tp65 = (t6 + t5) * cos_4_16; +; tm65 = (t6 - t5) * cos_4_16; +; +; tp765 = t7 + tp65; +; tm765 = t7 - tp65; +; tp465 = t4 + tm65; +; tm465 = t4 - tm65; +; +; y[1] = tp765 + tp465 * tg_1_16; +; y[7] = tp765 * tg_1_16 - tp465; +; y[5] = tm765 * tg_3_16 + tm465; +; y[3] = tm765 - tm465 * tg_3_16; +; } +; +; ----------------------------------------------------------------------------- + +; ----------------------------------------------------------------------------- +; DCT_8_INV_COL_4 INP,OUT +; ----------------------------------------------------------------------------- +%macro DCT_8_INV_COL 1 + movq mm0, [tan3] + movq mm3, [%1+16*3] + movq mm1, mm0 ; tg_3_16 + movq mm5, [%1+16*5] + pmulhw mm0, mm3 ; x3*(tg_3_16-1) + movq mm4, [tan1] + pmulhw mm1, mm5 ; x5*(tg_3_16-1) + movq mm7, [%1+16*7] + movq mm2, mm4 ; tg_1_16 + movq mm6, [%1+16*1] + pmulhw mm4, mm7 ; x7*tg_1_16 + paddsw mm0, mm3 ; x3*tg_3_16 + pmulhw mm2, mm6 ; x1*tg_1_16 + paddsw mm1, mm3 ; x3+x5*(tg_3_16-1) + psubsw mm0, mm5 ; x3*tg_3_16-x5 = tm35 + movq mm3, [sqrt2] + paddsw mm1, mm5 ; x3+x5*tg_3_16 = tp35 + paddsw mm4, mm6 ; x1+tg_1_16*x7 = tp17 + psubsw mm2, mm7 ; x1*tg_1_16-x7 = tm17 + movq mm5, mm4 ; tp17 + movq mm6, mm2 ; tm17 + paddsw mm5, mm1 ; tp17+tp35 = b0 + psubsw mm6, mm0 ; tm17-tm35 = b3 + psubsw mm4, mm1 ; tp17-tp35 = t1 + paddsw mm2, mm0 ; tm17+tm35 = t2 + movq mm7, [tan2] + movq mm1, mm4 ; t1 + movq [%1+3*16], mm5 ; save b0 + paddsw mm1, mm2 ; t1+t2 + movq [%1+5*16], mm6 ; save b3 + psubsw mm4, mm2 ; t1-t2 + movq mm5, [%1+2*16] + movq mm0, mm7 ; tg_2_16 + movq mm6, [%1+6*16] + pmulhw mm0, mm5 ; x2*tg_2_16 + pmulhw mm7, mm6 ; x6*tg_2_16 + pmulhw mm1, mm3 ; ocos_4_16*(t1+t2) = b1/2 + movq mm2, [%1+0*16] + pmulhw mm4, mm3 ; ocos_4_16*(t1-t2) = b2/2 + psubsw mm0, mm6 ; t2*tg_2_16-x6 = tm26 + movq mm3, mm2 ; x0 + movq mm6, [%1+4*16] + paddsw mm7, mm5 ; x2+x6*tg_2_16 = tp26 + paddsw mm2, mm6 ; x0+x4 = tp04 + psubsw mm3, mm6 ; x0-x4 = tm04 + movq mm5, mm2 ; tp04 + movq mm6, mm3 ; tm04 + psubsw mm2, mm7 ; tp04-tp26 = a3 + paddsw mm3, mm0 ; tm04+tm26 = a1 + paddsw mm1, mm1 ; b1 + paddsw mm4, mm4 ; b2 + paddsw mm5, mm7 ; tp04+tp26 = a0 + psubsw mm6, mm0 ; tm04-tm26 = a2 + movq mm7, mm3 ; a1 + movq mm0, mm6 ; a2 + paddsw mm3, mm1 ; a1+b1 + paddsw mm6, mm4 ; a2+b2 + psraw mm3, 6 ; dst1 + psubsw mm7, mm1 ; a1-b1 + psraw mm6, 6 ; dst2 + psubsw mm0, mm4 ; a2-b2 + movq mm1, [%1+3*16] ; load b0 + psraw mm7, 6 ; dst6 + movq mm4, mm5 ; a0 + psraw mm0, 6 ; dst5 + movq [%1+1*16], mm3 + paddsw mm5, mm1 ; a0+b0 + movq [%1+2*16], mm6 + psubsw mm4, mm1 ; a0-b0 + movq mm3, [%1+5*16] ; load b3 + psraw mm5, 6 ; dst0 + movq mm6, mm2 ; a3 + psraw mm4, 6 ; dst7 + movq [%1+5*16], mm0 + paddsw mm2, mm3 ; a3+b3 + movq [%1+6*16], mm7 + psubsw mm6, mm3 ; a3-b3 + movq [%1+0*16], mm5 + psraw mm2, 6 ; dst3 + movq [%1+7*16], mm4 + psraw mm6, 6 ; dst4 + movq [%1+3*16], mm2 + movq [%1+4*16], mm6 +%endmacro + +%macro XVID_IDCT_MMX 0 +cglobal xvid_idct, 1, 1, 0, block +%if cpuflag(mmxext) +%define TAB tab_i_04_xmm +%else +%define TAB tab_i_04_mmx +%endif + ; Process each row - beware of rounder offset + DCT_8_INV_ROW 0, TAB + 64 * 0, 0*16 + DCT_8_INV_ROW 1, TAB + 64 * 1, 1*16 + DCT_8_INV_ROW 2, TAB + 64 * 2, 2*16 + DCT_8_INV_ROW 3, TAB + 64 * 3, 3*16 + DCT_8_INV_ROW 4, TAB + 64 * 0, 6*16 + DCT_8_INV_ROW 5, TAB + 64 * 3, 4*16 + DCT_8_INV_ROW 6, TAB + 64 * 2, 5*16 + DCT_8_INV_ROW 7, TAB + 64 * 1, 5*16 + + ; Process the columns (4 at a time) + DCT_8_INV_COL r0+0 + DCT_8_INV_COL r0+8 + + RET +%endmacro + +INIT_MMX mmx +XVID_IDCT_MMX +INIT_MMX mmxext +XVID_IDCT_MMX + +%endif ; ~ARCH_X86_32 diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct.h new file mode 100644 index 00000000..edb5ebfd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct.h @@ -0,0 +1,44 @@ +/* + * XVID MPEG-4 VIDEO CODEC + * + * 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 + */ + +/** + * @file + * header for Xvid IDCT functions + */ + +#ifndef AVCODEC_X86_XVIDIDCT_H +#define AVCODEC_X86_XVIDIDCT_H + +#include +#include + +void ff_xvid_idct_mmx(short *block); +void ff_xvid_idct_mmx_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_mmx_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_xvid_idct_mmxext(short *block); +void ff_xvid_idct_mmxext_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block); +void ff_xvid_idct_mmxext_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block); + +void ff_xvid_idct_sse2(short *block); +void ff_xvid_idct_put_sse2(uint8_t *dest, ptrdiff_t line_size, short *block); +void ff_xvid_idct_add_sse2(uint8_t *dest, ptrdiff_t line_size, short *block); + +#endif /* AVCODEC_X86_XVIDIDCT_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct_init.c new file mode 100644 index 00000000..a91b416b --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavcodec/x86/xvididct_init.c @@ -0,0 +1,89 @@ +/* + * 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.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/idctdsp.h" +#include "libavcodec/xvididct.h" + +#include "idctdsp.h" +#include "xvididct.h" + +#if ARCH_X86_32 && HAVE_X86ASM +static void xvid_idct_mmx_put(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmx(block); + ff_put_pixels_clamped_mmx(block, dest, line_size); +} + +static void xvid_idct_mmx_add(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmx(block); + ff_add_pixels_clamped_mmx(block, dest, line_size); +} + +static void xvid_idct_mmxext_put(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmxext(block); + ff_put_pixels_clamped_mmx(block, dest, line_size); +} + +static void xvid_idct_mmxext_add(uint8_t *dest, ptrdiff_t line_size, short *block) +{ + ff_xvid_idct_mmxext(block); + ff_add_pixels_clamped_mmx(block, dest, line_size); +} +#endif + +av_cold void ff_xvid_idct_init_x86(IDCTDSPContext *c, AVCodecContext *avctx, + unsigned high_bit_depth) +{ +#if HAVE_X86ASM + int cpu_flags = av_get_cpu_flags(); + + if (high_bit_depth || + !(avctx->idct_algo == FF_IDCT_AUTO || + avctx->idct_algo == FF_IDCT_XVID)) + return; + +#if ARCH_X86_32 + if (EXTERNAL_MMX(cpu_flags)) { + c->idct_put = xvid_idct_mmx_put; + c->idct_add = xvid_idct_mmx_add; + c->idct = ff_xvid_idct_mmx; + c->perm_type = FF_IDCT_PERM_NONE; + } + + if (EXTERNAL_MMXEXT(cpu_flags)) { + c->idct_put = xvid_idct_mmxext_put; + c->idct_add = xvid_idct_mmxext_add; + c->idct = ff_xvid_idct_mmxext; + c->perm_type = FF_IDCT_PERM_NONE; + } +#endif + + if (EXTERNAL_SSE2(cpu_flags)) { + c->idct_put = ff_xvid_idct_put_sse2; + c->idct_add = ff_xvid_idct_add_sse2; + c->idct = ff_xvid_idct_sse2; + c->perm_type = FF_IDCT_PERM_SSE2; + } +#endif /* HAVE_X86ASM */ +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/Makefile b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/Makefile new file mode 100644 index 00000000..5f5242b5 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/Makefile @@ -0,0 +1,18 @@ +OBJS += x86/cpu.o \ + x86/fixed_dsp_init.o \ + x86/float_dsp_init.o \ + x86/imgutils_init.o \ + x86/lls_init.o \ + +OBJS-$(CONFIG_PIXELUTILS) += x86/pixelutils_init.o \ + +EMMS_OBJS_$(HAVE_MMX_INLINE)_$(HAVE_MMX_EXTERNAL)_$(HAVE_MM_EMPTY) = x86/emms.o + +X86ASM-OBJS += x86/cpuid.o \ + $(EMMS_OBJS__yes_) \ + x86/fixed_dsp.o \ + x86/float_dsp.o \ + x86/imgutils.o \ + x86/lls.o \ + +X86ASM-OBJS-$(CONFIG_PIXELUTILS) += x86/pixelutils.o \ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/asm.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/asm.h new file mode 100644 index 00000000..9bff42d6 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/asm.h @@ -0,0 +1,154 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * 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 + */ + +#ifndef AVUTIL_X86_ASM_H +#define AVUTIL_X86_ASM_H + +#include +#include "config.h" + +typedef struct xmm_reg { uint64_t a, b; } xmm_reg; +typedef struct ymm_reg { uint64_t a, b, c, d; } ymm_reg; + +#if ARCH_X86_64 +# define FF_OPSIZE "q" +# define FF_REG_a "rax" +# define FF_REG_b "rbx" +# define FF_REG_c "rcx" +# define FF_REG_d "rdx" +# define FF_REG_D "rdi" +# define FF_REG_S "rsi" +# define FF_PTR_SIZE "8" +typedef int64_t x86_reg; + +/* FF_REG_SP is defined in Solaris sys headers, so use FF_REG_sp */ +# define FF_REG_sp "rsp" +# define FF_REG_BP "rbp" +# define FF_REGBP rbp +# define FF_REGa rax +# define FF_REGb rbx +# define FF_REGc rcx +# define FF_REGd rdx +# define FF_REGSP rsp + +#elif ARCH_X86_32 + +# define FF_OPSIZE "l" +# define FF_REG_a "eax" +# define FF_REG_b "ebx" +# define FF_REG_c "ecx" +# define FF_REG_d "edx" +# define FF_REG_D "edi" +# define FF_REG_S "esi" +# define FF_PTR_SIZE "4" +typedef int32_t x86_reg; + +# define FF_REG_sp "esp" +# define FF_REG_BP "ebp" +# define FF_REGBP ebp +# define FF_REGa eax +# define FF_REGb ebx +# define FF_REGc ecx +# define FF_REGd edx +# define FF_REGSP esp +#else +typedef int x86_reg; +#endif + +#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE)) +#define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE)) + +#if ARCH_X86_64 && defined(PIC) +# define BROKEN_RELOCATIONS 1 +#endif + +/* + * If gcc is not set to support sse (-msse) it will not accept xmm registers + * in the clobber list for inline asm. XMM_CLOBBERS takes a list of xmm + * registers to be marked as clobbered and evaluates to nothing if they are + * not supported, or to the list itself if they are supported. Since a clobber + * list may not be empty, XMM_CLOBBERS_ONLY should be used if the xmm + * registers are the only in the clobber list. + * For example a list with "eax" and "xmm0" as clobbers should become: + * : XMM_CLOBBERS("xmm0",) "eax" + * and a list with only "xmm0" should become: + * XMM_CLOBBERS_ONLY("xmm0") + */ +#if HAVE_XMM_CLOBBERS +# define XMM_CLOBBERS(...) __VA_ARGS__ +# define XMM_CLOBBERS_ONLY(...) : __VA_ARGS__ +#else +# define XMM_CLOBBERS(...) +# define XMM_CLOBBERS_ONLY(...) +#endif + +/* Use to export labels from asm. */ +#define LABEL_MANGLE(a) EXTERN_PREFIX #a + +// Use rip-relative addressing if compiling PIC code on x86-64. +#if ARCH_X86_64 && defined(PIC) +# define LOCAL_MANGLE(a) #a "(%%rip)" +#else +# define LOCAL_MANGLE(a) #a +#endif + +#if HAVE_INLINE_ASM_DIRECT_SYMBOL_REFS +# define MANGLE(a) EXTERN_PREFIX LOCAL_MANGLE(a) +# define NAMED_CONSTRAINTS_ADD(...) +# define NAMED_CONSTRAINTS(...) +# define NAMED_CONSTRAINTS_ARRAY_ADD(...) +# define NAMED_CONSTRAINTS_ARRAY(...) +#else + /* When direct symbol references are used in code passed to a compiler that does not support them + * then these references need to be converted to named asm constraints instead. + * Instead of returning a direct symbol MANGLE now returns a named constraint for that specific symbol. + * In order for this to work there must also be a corresponding entry in the asm-interface. To add this + * entry use the macro NAMED_CONSTRAINTS() and pass in a list of each symbol reference used in the + * corresponding block of code. (e.g. NAMED_CONSTRAINTS(var1,var2,var3) where var1 is the first symbol etc. ). + * If there are already existing constraints then use NAMED_CONSTRAINTS_ADD to add to the existing constraint list. + */ +# define MANGLE(a) "%["#a"]" + // Intel/MSVC does not correctly expand va-args so we need a rather ugly hack in order to get it to work +# define FE_0(P,X) P(X) +# define FE_1(P,X,X1) P(X), FE_0(P,X1) +# define FE_2(P,X,X1,X2) P(X), FE_1(P,X1,X2) +# define FE_3(P,X,X1,X2,X3) P(X), FE_2(P,X1,X2,X3) +# define FE_4(P,X,X1,X2,X3,X4) P(X), FE_3(P,X1,X2,X3,X4) +# define FE_5(P,X,X1,X2,X3,X4,X5) P(X), FE_4(P,X1,X2,X3,X4,X5) +# define FE_6(P,X,X1,X2,X3,X4,X5,X6) P(X), FE_5(P,X1,X2,X3,X4,X5,X6) +# define FE_7(P,X,X1,X2,X3,X4,X5,X6,X7) P(X), FE_6(P,X1,X2,X3,X4,X5,X6,X7) +# define FE_8(P,X,X1,X2,X3,X4,X5,X6,X7,X8) P(X), FE_7(P,X1,X2,X3,X4,X5,X6,X7,X8) +# define FE_9(P,X,X1,X2,X3,X4,X5,X6,X7,X8,X9) P(X), FE_8(P,X1,X2,X3,X4,X5,X6,X7,X8,X9) +# define GET_FE_IMPL(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,NAME,...) NAME +# define GET_FE(A) GET_FE_IMPL A +# define GET_FE_GLUE(x, y) x y +# define FOR_EACH_VA(P,...) GET_FE_GLUE(GET_FE((__VA_ARGS__,FE_9,FE_8,FE_7,FE_6,FE_5,FE_4,FE_3,FE_2,FE_1,FE_0)), (P,__VA_ARGS__)) +# define NAME_CONSTRAINT(x) [x] "m"(x) + // Parameters are a list of each symbol reference required +# define NAMED_CONSTRAINTS_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__) + // Same but without comma for when there are no previously defined constraints +# define NAMED_CONSTRAINTS(...) FOR_EACH_VA(NAME_CONSTRAINT,__VA_ARGS__) + // Same as above NAMED_CONSTRAINTS except used for passing arrays/pointers instead of normal variables +# define NAME_CONSTRAINT_ARRAY(x) [x] "m"(*x) +# define NAMED_CONSTRAINTS_ARRAY_ADD(...) , FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__) +# define NAMED_CONSTRAINTS_ARRAY(...) FOR_EACH_VA(NAME_CONSTRAINT_ARRAY,__VA_ARGS__) +#endif + +#endif /* AVUTIL_X86_ASM_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/bswap.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/bswap.h new file mode 100644 index 00000000..b2f18b6c --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/bswap.h @@ -0,0 +1,88 @@ +/* + * 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 + */ + +/** + * @file + * byte swapping routines + */ + +#ifndef AVUTIL_X86_BSWAP_H +#define AVUTIL_X86_BSWAP_H + +#include +#if defined(_MSC_VER) +#include +#include +#endif +#include "config.h" +#include "libavutil/attributes.h" + +#if defined(_MSC_VER) + +#define av_bswap16 av_bswap16 +static av_always_inline av_const uint16_t av_bswap16(uint16_t x) +{ + return _rotr16(x, 8); +} + +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + return _byteswap_ulong(x); +} + +#if ARCH_X86_64 +#define av_bswap64 av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + return _byteswap_uint64(x); +} +#endif + + +#elif HAVE_INLINE_ASM + +#if AV_GCC_VERSION_AT_MOST(4,0) +#define av_bswap16 av_bswap16 +static av_always_inline av_const unsigned av_bswap16(unsigned x) +{ + __asm__("rorw $8, %w0" : "+r"(x)); + return x; +} +#endif /* AV_GCC_VERSION_AT_MOST(4,0) */ + +#if AV_GCC_VERSION_AT_MOST(4,4) || defined(__INTEL_COMPILER) +#define av_bswap32 av_bswap32 +static av_always_inline av_const uint32_t av_bswap32(uint32_t x) +{ + __asm__("bswap %0" : "+r" (x)); + return x; +} + +#if ARCH_X86_64 +#define av_bswap64 av_bswap64 +static inline uint64_t av_const av_bswap64(uint64_t x) +{ + __asm__("bswap %0": "=r" (x) : "0" (x)); + return x; +} +#endif +#endif /* AV_GCC_VERSION_AT_MOST(4,4) */ + +#endif /* HAVE_INLINE_ASM */ +#endif /* AVUTIL_X86_BSWAP_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpu.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpu.c new file mode 100644 index 00000000..bcd41a50 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpu.c @@ -0,0 +1,272 @@ +/* + * CPU detection code, extracted from mmx.h + * (c)1997-99 by H. Dietz and R. Fisher + * Converted to C and improved by Fabrice Bellard. + * + * 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 +#include + +#include "libavutil/x86/asm.h" +#include "libavutil/x86/cpu.h" +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#if HAVE_X86ASM + +#define cpuid(index, eax, ebx, ecx, edx) \ + ff_cpu_cpuid(index, &eax, &ebx, &ecx, &edx) + +#define xgetbv(index, eax, edx) \ + ff_cpu_xgetbv(index, &eax, &edx) + +#elif HAVE_INLINE_ASM + +/* ebx saving is necessary for PIC. gcc seems unable to see it alone */ +#define cpuid(index, eax, ebx, ecx, edx) \ + __asm__ volatile ( \ + "mov %%"FF_REG_b", %%"FF_REG_S" \n\t" \ + "cpuid \n\t" \ + "xchg %%"FF_REG_b", %%"FF_REG_S \ + : "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \ + : "0" (index), "2"(0)) + +#define xgetbv(index, eax, edx) \ + __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index)) + +#define get_eflags(x) \ + __asm__ volatile ("pushfl \n" \ + "pop %0 \n" \ + : "=r"(x)) + +#define set_eflags(x) \ + __asm__ volatile ("push %0 \n" \ + "popfl \n" \ + :: "r"(x)) + +#endif /* HAVE_INLINE_ASM */ + +#if ARCH_X86_64 + +#define cpuid_test() 1 + +#elif HAVE_X86ASM + +#define cpuid_test ff_cpu_cpuid_test + +#elif HAVE_INLINE_ASM + +static int cpuid_test(void) +{ + x86_reg a, c; + + /* Check if CPUID is supported by attempting to toggle the ID bit in + * the EFLAGS register. */ + get_eflags(a); + set_eflags(a ^ 0x200000); + get_eflags(c); + + return a != c; +} +#endif + +/* Function to test if multimedia instructions are supported... */ +int ff_get_cpu_flags_x86(void) +{ + int rval = 0; + +#ifdef cpuid + + int eax, ebx, ecx, edx; + int max_std_level, max_ext_level, std_caps = 0, ext_caps = 0; + int family = 0, model = 0; + union { int i[3]; char c[12]; } vendor; + int xcr0_lo = 0, xcr0_hi = 0; + + if (!cpuid_test()) + return 0; /* CPUID not supported */ + + cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]); + + if (max_std_level >= 1) { + cpuid(1, eax, ebx, ecx, std_caps); + family = ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff); + model = ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0); + if (std_caps & (1 << 15)) + rval |= AV_CPU_FLAG_CMOV; + if (std_caps & (1 << 23)) + rval |= AV_CPU_FLAG_MMX; + if (std_caps & (1 << 25)) + rval |= AV_CPU_FLAG_MMXEXT; +#if HAVE_SSE + if (std_caps & (1 << 25)) + rval |= AV_CPU_FLAG_SSE; + if (std_caps & (1 << 26)) + rval |= AV_CPU_FLAG_SSE2; + if (ecx & 1) + rval |= AV_CPU_FLAG_SSE3; + if (ecx & 0x00000200 ) + rval |= AV_CPU_FLAG_SSSE3; + if (ecx & 0x00080000 ) + rval |= AV_CPU_FLAG_SSE4; + if (ecx & 0x00100000 ) + rval |= AV_CPU_FLAG_SSE42; + if (ecx & 0x02000000 ) + rval |= AV_CPU_FLAG_AESNI; +#if HAVE_AVX + /* Check OXSAVE and AVX bits */ + if ((ecx & 0x18000000) == 0x18000000) { + /* Check for OS support */ + xgetbv(0, xcr0_lo, xcr0_hi); + if ((xcr0_lo & 0x6) == 0x6) { + rval |= AV_CPU_FLAG_AVX; + if (ecx & 0x00001000) + rval |= AV_CPU_FLAG_FMA3; + } + } +#endif /* HAVE_AVX */ +#endif /* HAVE_SSE */ + } + if (max_std_level >= 7) { + cpuid(7, eax, ebx, ecx, edx); +#if HAVE_AVX2 + if ((rval & AV_CPU_FLAG_AVX) && (ebx & 0x00000020)) + rval |= AV_CPU_FLAG_AVX2; +#if HAVE_AVX512 /* F, CD, BW, DQ, VL */ + if ((xcr0_lo & 0xe0) == 0xe0) { /* OPMASK/ZMM state */ + if ((rval & AV_CPU_FLAG_AVX2) && (ebx & 0xd0030000) == 0xd0030000) + rval |= AV_CPU_FLAG_AVX512; + + } +#endif /* HAVE_AVX512 */ +#endif /* HAVE_AVX2 */ + /* BMI1/2 don't need OS support */ + if (ebx & 0x00000008) { + rval |= AV_CPU_FLAG_BMI1; + if (ebx & 0x00000100) + rval |= AV_CPU_FLAG_BMI2; + } + } + + cpuid(0x80000000, max_ext_level, ebx, ecx, edx); + + if (max_ext_level >= 0x80000001) { + cpuid(0x80000001, eax, ebx, ecx, ext_caps); + if (ext_caps & (1U << 31)) + rval |= AV_CPU_FLAG_3DNOW; + if (ext_caps & (1 << 30)) + rval |= AV_CPU_FLAG_3DNOWEXT; + if (ext_caps & (1 << 23)) + rval |= AV_CPU_FLAG_MMX; + if (ext_caps & (1 << 22)) + rval |= AV_CPU_FLAG_MMXEXT; + + if (!strncmp(vendor.c, "AuthenticAMD", 12)) { + /* Allow for selectively disabling SSE2 functions on AMD processors + with SSE2 support but not SSE4a. This includes Athlon64, some + Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster + than SSE2 often enough to utilize this special-case flag. + AV_CPU_FLAG_SSE2 and AV_CPU_FLAG_SSE2SLOW are both set in this case + so that SSE2 is used unless explicitly disabled by checking + AV_CPU_FLAG_SSE2SLOW. */ + if (rval & AV_CPU_FLAG_SSE2 && !(ecx & 0x00000040)) + rval |= AV_CPU_FLAG_SSE2SLOW; + + /* Similar to the above but for AVX functions on AMD processors. + This is necessary only for functions using YMM registers on Bulldozer + and Jaguar based CPUs as they lack 256-bit execution units. SSE/AVX + functions using XMM registers are always faster on them. + AV_CPU_FLAG_AVX and AV_CPU_FLAG_AVXSLOW are both set so that AVX is + used unless explicitly disabled by checking AV_CPU_FLAG_AVXSLOW. */ + if ((family == 0x15 || family == 0x16) && (rval & AV_CPU_FLAG_AVX)) + rval |= AV_CPU_FLAG_AVXSLOW; + } + + /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be + * used unless the OS has AVX support. */ + if (rval & AV_CPU_FLAG_AVX) { + if (ecx & 0x00000800) + rval |= AV_CPU_FLAG_XOP; + if (ecx & 0x00010000) + rval |= AV_CPU_FLAG_FMA4; + } + } + + if (!strncmp(vendor.c, "GenuineIntel", 12)) { + if (family == 6 && (model == 9 || model == 13 || model == 14)) { + /* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and + * 6/14 (core1 "yonah") theoretically support sse2, but it's + * usually slower than mmx, so let's just pretend they don't. + * AV_CPU_FLAG_SSE2 is disabled and AV_CPU_FLAG_SSE2SLOW is + * enabled so that SSE2 is not used unless explicitly enabled + * by checking AV_CPU_FLAG_SSE2SLOW. The same situation + * applies for AV_CPU_FLAG_SSE3 and AV_CPU_FLAG_SSE3SLOW. */ + if (rval & AV_CPU_FLAG_SSE2) + rval ^= AV_CPU_FLAG_SSE2SLOW | AV_CPU_FLAG_SSE2; + if (rval & AV_CPU_FLAG_SSE3) + rval ^= AV_CPU_FLAG_SSE3SLOW | AV_CPU_FLAG_SSE3; + } + /* The Atom processor has SSSE3 support, which is useful in many cases, + * but sometimes the SSSE3 version is slower than the SSE2 equivalent + * on the Atom, but is generally faster on other processors supporting + * SSSE3. This flag allows for selectively disabling certain SSSE3 + * functions on the Atom. */ + if (family == 6 && model == 28) + rval |= AV_CPU_FLAG_ATOM; + + /* Conroe has a slow shuffle unit. Check the model number to ensure not + * to include crippled low-end Penryns and Nehalems that lack SSE4. */ + if ((rval & AV_CPU_FLAG_SSSE3) && !(rval & AV_CPU_FLAG_SSE4) && + family == 6 && model < 23) + rval |= AV_CPU_FLAG_SSSE3SLOW; + } + +#endif /* cpuid */ + + return rval; +} + +size_t ff_get_cpu_max_align_x86(void) +{ + int flags = av_get_cpu_flags(); + + if (flags & AV_CPU_FLAG_AVX512) + return 64; + if (flags & (AV_CPU_FLAG_AVX2 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_FMA3 | + AV_CPU_FLAG_AVXSLOW)) + return 32; + if (flags & (AV_CPU_FLAG_AESNI | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_ATOM | + AV_CPU_FLAG_SSSE3SLOW | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSE2SLOW)) + return 16; + + return 8; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpu.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpu.h new file mode 100644 index 00000000..937c697f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpu.h @@ -0,0 +1,113 @@ +/* + * 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 + */ + +#ifndef AVUTIL_X86_CPU_H +#define AVUTIL_X86_CPU_H + +#include "libavutil/cpu.h" +#include "libavutil/cpu_internal.h" + +#define AV_CPU_FLAG_AMD3DNOW AV_CPU_FLAG_3DNOW +#define AV_CPU_FLAG_AMD3DNOWEXT AV_CPU_FLAG_3DNOWEXT + +#define X86_AMD3DNOW(flags) CPUEXT(flags, AMD3DNOW) +#define X86_AMD3DNOWEXT(flags) CPUEXT(flags, AMD3DNOWEXT) +#define X86_MMX(flags) CPUEXT(flags, MMX) +#define X86_MMXEXT(flags) CPUEXT(flags, MMXEXT) +#define X86_SSE(flags) CPUEXT(flags, SSE) +#define X86_SSE2(flags) CPUEXT(flags, SSE2) +#define X86_SSE2_FAST(flags) CPUEXT_FAST(flags, SSE2) +#define X86_SSE2_SLOW(flags) CPUEXT_SLOW(flags, SSE2) +#define X86_SSE3(flags) CPUEXT(flags, SSE3) +#define X86_SSE3_FAST(flags) CPUEXT_FAST(flags, SSE3) +#define X86_SSE3_SLOW(flags) CPUEXT_SLOW(flags, SSE3) +#define X86_SSSE3(flags) CPUEXT(flags, SSSE3) +#define X86_SSSE3_FAST(flags) CPUEXT_FAST(flags, SSSE3) +#define X86_SSSE3_SLOW(flags) CPUEXT_SLOW(flags, SSSE3) +#define X86_SSE4(flags) CPUEXT(flags, SSE4) +#define X86_SSE42(flags) CPUEXT(flags, SSE42) +#define X86_AVX(flags) CPUEXT(flags, AVX) +#define X86_AVX_FAST(flags) CPUEXT_FAST(flags, AVX) +#define X86_AVX_SLOW(flags) CPUEXT_SLOW(flags, AVX) +#define X86_XOP(flags) CPUEXT(flags, XOP) +#define X86_FMA3(flags) CPUEXT(flags, FMA3) +#define X86_FMA4(flags) CPUEXT(flags, FMA4) +#define X86_AVX2(flags) CPUEXT(flags, AVX2) +#define X86_AESNI(flags) CPUEXT(flags, AESNI) +#define X86_AVX512(flags) CPUEXT(flags, AVX512) + +#define EXTERNAL_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOW) +#define EXTERNAL_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AMD3DNOWEXT) +#define EXTERNAL_MMX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, MMX) +#define EXTERNAL_MMXEXT(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, MMXEXT) +#define EXTERNAL_SSE(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE) +#define EXTERNAL_SSE2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE2_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE2_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSE2) +#define EXTERNAL_SSE3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSE3) +#define EXTERNAL_SSSE3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, SSSE3) +#define EXTERNAL_SSE4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE4) +#define EXTERNAL_SSE42(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, SSE42) +#define EXTERNAL_AVX(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX) +#define EXTERNAL_AVX_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _EXTERNAL, AVX) +#define EXTERNAL_AVX_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _EXTERNAL, AVX) +#define EXTERNAL_XOP(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, XOP) +#define EXTERNAL_FMA3(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA3) +#define EXTERNAL_FMA3_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, FMA3, AVX) +#define EXTERNAL_FMA3_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, FMA3, AVX) +#define EXTERNAL_FMA4(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, FMA4) +#define EXTERNAL_AVX2(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX2) +#define EXTERNAL_AVX2_FAST(flags) CPUEXT_SUFFIX_FAST2(flags, _EXTERNAL, AVX2, AVX) +#define EXTERNAL_AVX2_SLOW(flags) CPUEXT_SUFFIX_SLOW2(flags, _EXTERNAL, AVX2, AVX) +#define EXTERNAL_AESNI(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AESNI) +#define EXTERNAL_AVX512(flags) CPUEXT_SUFFIX(flags, _EXTERNAL, AVX512) + +#define INLINE_AMD3DNOW(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOW) +#define INLINE_AMD3DNOWEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, AMD3DNOWEXT) +#define INLINE_MMX(flags) CPUEXT_SUFFIX(flags, _INLINE, MMX) +#define INLINE_MMXEXT(flags) CPUEXT_SUFFIX(flags, _INLINE, MMXEXT) +#define INLINE_SSE(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE) +#define INLINE_SSE2(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE2) +#define INLINE_SSE2_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSE2) +#define INLINE_SSE2_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSE2) +#define INLINE_SSE3(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE3) +#define INLINE_SSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSE3) +#define INLINE_SSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSE3) +#define INLINE_SSSE3(flags) CPUEXT_SUFFIX(flags, _INLINE, SSSE3) +#define INLINE_SSSE3_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, SSSE3) +#define INLINE_SSSE3_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, SSSE3) +#define INLINE_SSE4(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE4) +#define INLINE_SSE42(flags) CPUEXT_SUFFIX(flags, _INLINE, SSE42) +#define INLINE_AVX(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX) +#define INLINE_AVX_FAST(flags) CPUEXT_SUFFIX_FAST(flags, _INLINE, AVX) +#define INLINE_AVX_SLOW(flags) CPUEXT_SUFFIX_SLOW(flags, _INLINE, AVX) +#define INLINE_XOP(flags) CPUEXT_SUFFIX(flags, _INLINE, XOP) +#define INLINE_FMA3(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA3) +#define INLINE_FMA4(flags) CPUEXT_SUFFIX(flags, _INLINE, FMA4) +#define INLINE_AVX2(flags) CPUEXT_SUFFIX(flags, _INLINE, AVX2) +#define INLINE_AESNI(flags) CPUEXT_SUFFIX(flags, _INLINE, AESNI) + +void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx); +void ff_cpu_xgetbv(int op, int *eax, int *edx); +int ff_cpu_cpuid_test(void); + +#endif /* AVUTIL_X86_CPU_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpuid.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpuid.asm new file mode 100644 index 00000000..c3f7866e --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/cpuid.asm @@ -0,0 +1,91 @@ +;***************************************************************************** +;* Copyright (C) 2005-2010 x264 project +;* +;* Authors: Loren Merritt +;* Fiona Glaser +;* +;* 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 "x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_cpu_cpuid(int index, int *eax, int *ebx, int *ecx, int *edx) +;----------------------------------------------------------------------------- +cglobal cpu_cpuid, 5,7 + push rbx + push r4 + push r3 + push r2 + push r1 + mov eax, r0d + xor ecx, ecx + cpuid + pop r4 + mov [r4], eax + pop r4 + mov [r4], ebx + pop r4 + mov [r4], ecx + pop r4 + mov [r4], edx + pop rbx + RET + +;----------------------------------------------------------------------------- +; void ff_cpu_xgetbv(int op, int *eax, int *edx) +;----------------------------------------------------------------------------- +cglobal cpu_xgetbv, 3,7 + push r2 + push r1 + mov ecx, r0d + xgetbv + pop r4 + mov [r4], eax + pop r4 + mov [r4], edx + RET + +%if ARCH_X86_64 == 0 +;----------------------------------------------------------------------------- +; int ff_cpu_cpuid_test(void) +; return 0 if unsupported +;----------------------------------------------------------------------------- +cglobal cpu_cpuid_test + pushfd + push ebx + push ebp + push esi + push edi + pushfd + pop eax + mov ebx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ebx + pop edi + pop esi + pop ebp + pop ebx + popfd + ret +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/emms.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/emms.asm new file mode 100644 index 00000000..8611762d --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/emms.asm @@ -0,0 +1,30 @@ +;***************************************************************************** +;* Copyright (C) 2013 Martin Storsjo +;* +;* 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 "x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void avpriv_emms_asm(void) +;----------------------------------------------------------------------------- +cvisible emms_asm, 0, 0 + emms + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/emms.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/emms.h new file mode 100644 index 00000000..c21e34b4 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/emms.h @@ -0,0 +1,55 @@ +/* + * 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 + */ + +#ifndef AVUTIL_X86_EMMS_H +#define AVUTIL_X86_EMMS_H + +#include "config.h" +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" + +void avpriv_emms_asm(void); + +#if HAVE_MMX_INLINE +# define emms_c emms_c +/** + * Empty mmx state. + * this must be called between any dsp function and float/double code. + * for example sin(); dsp->idct_put(); emms_c(); cos() + * Note, *alloc() and *free() also use float code in some libc implementations + * thus this also applies to them or any function using them. + */ +static av_always_inline void emms_c(void) +{ +/* Some inlined functions may also use mmx instructions regardless of + * runtime cpuflags. With that in mind, we unconditionally empty the + * mmx state if the target cpu chosen at configure time supports it. + */ +#if !defined(__MMX__) + if(av_get_cpu_flags() & AV_CPU_FLAG_MMX) +#endif + __asm__ volatile ("emms" ::: "memory"); +} +#elif HAVE_MMX && HAVE_MM_EMPTY +# include +# define emms_c _mm_empty +#elif HAVE_MMX_EXTERNAL +# define emms_c avpriv_emms_asm +#endif /* HAVE_MMX_INLINE */ + +#endif /* AVUTIL_X86_EMMS_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/fixed_dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/fixed_dsp.asm new file mode 100644 index 00000000..979dd5c3 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/fixed_dsp.asm @@ -0,0 +1,48 @@ +;***************************************************************************** +;* x86-optimized Float DSP functions +;* +;* Copyright 2016 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 "x86util.asm" + +SECTION .text + +;----------------------------------------------------------------------------- +; void ff_butterflies_fixed(float *src0, float *src1, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal butterflies_fixed, 3,3,3, src0, src1, len + shl lend, 2 + add src0q, lenq + add src1q, lenq + neg lenq + +align 16 +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + mova m2, m0 + paddd m0, m1 + psubd m2, m1 + mova [src0q + lenq], m0 + mova [src1q + lenq], m2 + add lenq, mmsize + jl .loop + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/fixed_dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/fixed_dsp_init.c new file mode 100644 index 00000000..303a2eb9 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/fixed_dsp_init.c @@ -0,0 +1,35 @@ +/* + * 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.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/fixed_dsp.h" +#include "cpu.h" + +void ff_butterflies_fixed_sse2(int *src0, int *src1, int len); + +av_cold void ff_fixed_dsp_init_x86(AVFixedDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE2(cpu_flags)) { + fdsp->butterflies_fixed = ff_butterflies_fixed_sse2; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/float_dsp.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/float_dsp.asm new file mode 100644 index 00000000..517fd636 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/float_dsp.asm @@ -0,0 +1,484 @@ +;***************************************************************************** +;* x86-optimized Float DSP functions +;* +;* Copyright 2006 Loren Merritt +;* +;* 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 "x86util.asm" + +SECTION_RODATA 32 +pd_reverse: dd 7, 6, 5, 4, 3, 2, 1, 0 + +SECTION .text + +;----------------------------------------------------------------------------- +; void vector_fmul(float *dst, const float *src0, const float *src1, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL 0 +cglobal vector_fmul, 4,4,2, dst, src0, src1, len + lea lenq, [lend*4 - 64] +ALIGN 16 +.loop: +%assign a 0 +%rep 32/mmsize + mova m0, [src0q + lenq + (a+0)*mmsize] + mova m1, [src0q + lenq + (a+1)*mmsize] + mulps m0, m0, [src1q + lenq + (a+0)*mmsize] + mulps m1, m1, [src1q + lenq + (a+1)*mmsize] + mova [dstq + lenq + (a+0)*mmsize], m0 + mova [dstq + lenq + (a+1)*mmsize], m1 +%assign a a+2 +%endrep + + sub lenq, 64 + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL +%endif + +;----------------------------------------------------------------------------- +; void vector_dmul(double *dst, const double *src0, const double *src1, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_DMUL 0 +cglobal vector_dmul, 4,4,4, dst, src0, src1, len + lea lend, [lenq*8 - mmsize*4] +ALIGN 16 +.loop: + movaps m0, [src0q + lenq + 0*mmsize] + movaps m1, [src0q + lenq + 1*mmsize] + movaps m2, [src0q + lenq + 2*mmsize] + movaps m3, [src0q + lenq + 3*mmsize] + mulpd m0, m0, [src1q + lenq + 0*mmsize] + mulpd m1, m1, [src1q + lenq + 1*mmsize] + mulpd m2, m2, [src1q + lenq + 2*mmsize] + mulpd m3, m3, [src1q + lenq + 3*mmsize] + movaps [dstq + lenq + 0*mmsize], m0 + movaps [dstq + lenq + 1*mmsize], m1 + movaps [dstq + lenq + 2*mmsize], m2 + movaps [dstq + lenq + 3*mmsize], m3 + + sub lenq, mmsize*4 + jge .loop + RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMUL +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMUL +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMAC_SCALAR 0 +%if UNIX64 +cglobal vector_fmac_scalar, 3,3,5, dst, src, len +%else +cglobal vector_fmac_scalar, 4,4,5, dst, src, mul, len +%endif +%if ARCH_X86_32 + VBROADCASTSS m0, mulm +%else +%if WIN64 + SWAP 0, 2 +%endif + shufps xm0, xm0, 0 +%if cpuflag(avx) + vinsertf128 m0, m0, xm0, 1 +%endif +%endif + lea lenq, [lend*4-64] +.loop: +%if cpuflag(fma3) + mova m1, [dstq+lenq] + mova m2, [dstq+lenq+1*mmsize] + fmaddps m1, m0, [srcq+lenq], m1 + fmaddps m2, m0, [srcq+lenq+1*mmsize], m2 +%else ; cpuflag + mulps m1, m0, [srcq+lenq] + mulps m2, m0, [srcq+lenq+1*mmsize] +%if mmsize < 32 + mulps m3, m0, [srcq+lenq+2*mmsize] + mulps m4, m0, [srcq+lenq+3*mmsize] +%endif ; mmsize + addps m1, m1, [dstq+lenq] + addps m2, m2, [dstq+lenq+1*mmsize] +%if mmsize < 32 + addps m3, m3, [dstq+lenq+2*mmsize] + addps m4, m4, [dstq+lenq+3*mmsize] +%endif ; mmsize +%endif ; cpuflag + mova [dstq+lenq], m1 + mova [dstq+lenq+1*mmsize], m2 +%if mmsize < 32 + mova [dstq+lenq+2*mmsize], m3 + mova [dstq+lenq+3*mmsize], m4 +%endif ; mmsize + sub lenq, 64 + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMAC_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMAC_SCALAR +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_FMAC_SCALAR +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmul_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMUL_SCALAR 0 +%if UNIX64 +cglobal vector_fmul_scalar, 3,3,2, dst, src, len +%else +cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len +%endif +%if ARCH_X86_32 + movss m0, mulm +%elif WIN64 + SWAP 0, 2 +%endif + shufps m0, m0, 0 + lea lenq, [lend*4-mmsize] +.loop: + mova m1, [srcq+lenq] + mulps m1, m0 + mova [dstq+lenq], m1 + sub lenq, mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_SCALAR + +;------------------------------------------------------------------------------ +; void ff_vector_dmac_scalar(double *dst, const double *src, double mul, +; int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_DMAC_SCALAR 0 +%if ARCH_X86_32 +cglobal vector_dmac_scalar, 2,4,5, dst, src, mul, len, lenaddr + mov lenq, lenaddrm + VBROADCASTSD m0, mulm +%else +%if UNIX64 +cglobal vector_dmac_scalar, 3,3,5, dst, src, len +%else +cglobal vector_dmac_scalar, 4,4,5, dst, src, mul, len + SWAP 0, 2 +%endif + movlhps xm0, xm0 +%if cpuflag(avx) + vinsertf128 m0, m0, xm0, 1 +%endif +%endif + lea lenq, [lend*8-mmsize*4] +.loop: +%if cpuflag(fma3) + movaps m1, [dstq+lenq] + movaps m2, [dstq+lenq+1*mmsize] + movaps m3, [dstq+lenq+2*mmsize] + movaps m4, [dstq+lenq+3*mmsize] + fmaddpd m1, m0, [srcq+lenq], m1 + fmaddpd m2, m0, [srcq+lenq+1*mmsize], m2 + fmaddpd m3, m0, [srcq+lenq+2*mmsize], m3 + fmaddpd m4, m0, [srcq+lenq+3*mmsize], m4 +%else ; cpuflag + mulpd m1, m0, [srcq+lenq] + mulpd m2, m0, [srcq+lenq+1*mmsize] + mulpd m3, m0, [srcq+lenq+2*mmsize] + mulpd m4, m0, [srcq+lenq+3*mmsize] + addpd m1, m1, [dstq+lenq] + addpd m2, m2, [dstq+lenq+1*mmsize] + addpd m3, m3, [dstq+lenq+2*mmsize] + addpd m4, m4, [dstq+lenq+3*mmsize] +%endif ; cpuflag + movaps [dstq+lenq], m1 + movaps [dstq+lenq+1*mmsize], m2 + movaps [dstq+lenq+2*mmsize], m3 + movaps [dstq+lenq+3*mmsize], m4 + sub lenq, mmsize*4 + jge .loop + REP_RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMAC_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMAC_SCALAR +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_DMAC_SCALAR +%endif + +;------------------------------------------------------------------------------ +; void ff_vector_dmul_scalar(double *dst, const double *src, double mul, +; int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_DMUL_SCALAR 0 +%if ARCH_X86_32 +cglobal vector_dmul_scalar, 3,4,3, dst, src, mul, len, lenaddr + mov lenq, lenaddrm +%elif UNIX64 +cglobal vector_dmul_scalar, 3,3,3, dst, src, len +%else +cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len +%endif +%if ARCH_X86_32 + VBROADCASTSD m0, mulm +%else +%if WIN64 + SWAP 0, 2 +%endif + movlhps xm0, xm0 +%if cpuflag(avx) + vinsertf128 ym0, ym0, xm0, 1 +%endif +%endif + lea lenq, [lend*8-2*mmsize] +.loop: + mulpd m1, m0, [srcq+lenq ] + mulpd m2, m0, [srcq+lenq+mmsize] + movaps [dstq+lenq ], m1 + movaps [dstq+lenq+mmsize], m2 + sub lenq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse2 +VECTOR_DMUL_SCALAR +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_DMUL_SCALAR +%endif + +;----------------------------------------------------------------------------- +; vector_fmul_window(float *dst, const float *src0, +; const float *src1, const float *win, int len); +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_WINDOW 0 +cglobal vector_fmul_window, 5, 6, 6, dst, src0, src1, win, len, len1 + shl lend, 2 + lea len1q, [lenq - mmsize] + add src0q, lenq + add dstq, lenq + add winq, lenq + neg lenq +.loop: + mova m0, [winq + lenq] + mova m4, [src0q + lenq] +%if cpuflag(sse) + mova m1, [winq + len1q] + mova m5, [src1q + len1q] + shufps m1, m1, 0x1b + shufps m5, m5, 0x1b + mova m2, m0 + mova m3, m1 + mulps m2, m4 + mulps m3, m5 + mulps m1, m4 + mulps m0, m5 + addps m2, m3 + subps m1, m0 + shufps m2, m2, 0x1b +%else + pswapd m1, [winq + len1q] + pswapd m5, [src1q + len1q] + mova m2, m0 + mova m3, m1 + pfmul m2, m4 + pfmul m3, m5 + pfmul m1, m4 + pfmul m0, m5 + pfadd m2, m3 + pfsub m1, m0 + pswapd m2, m2 +%endif + mova [dstq + lenq], m1 + mova [dstq + len1q], m2 + sub len1q, mmsize + add lenq, mmsize + jl .loop +%if mmsize == 8 + femms +%endif + REP_RET +%endmacro + +INIT_MMX 3dnowext +VECTOR_FMUL_WINDOW +INIT_XMM sse +VECTOR_FMUL_WINDOW + +;----------------------------------------------------------------------------- +; vector_fmul_add(float *dst, const float *src0, const float *src1, +; const float *src2, int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_ADD 0 +cglobal vector_fmul_add, 5,5,4, dst, src0, src1, src2, len + lea lenq, [lend*4 - 2*mmsize] +ALIGN 16 +.loop: + mova m0, [src0q + lenq] + mova m1, [src0q + lenq + mmsize] +%if cpuflag(fma3) + mova m2, [src2q + lenq] + mova m3, [src2q + lenq + mmsize] + fmaddps m0, m0, [src1q + lenq], m2 + fmaddps m1, m1, [src1q + lenq + mmsize], m3 +%else + mulps m0, m0, [src1q + lenq] + mulps m1, m1, [src1q + lenq + mmsize] + addps m0, m0, [src2q + lenq] + addps m1, m1, [src2q + lenq + mmsize] +%endif + mova [dstq + lenq], m0 + mova [dstq + lenq + mmsize], m1 + + sub lenq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_ADD +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL_ADD +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +VECTOR_FMUL_ADD +%endif + +;----------------------------------------------------------------------------- +; void vector_fmul_reverse(float *dst, const float *src0, const float *src1, +; int len) +;----------------------------------------------------------------------------- +%macro VECTOR_FMUL_REVERSE 0 +cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len +%if cpuflag(avx2) + movaps m2, [pd_reverse] +%endif + lea lenq, [lend*4 - 2*mmsize] +ALIGN 16 +.loop: +%if cpuflag(avx2) + vpermps m0, m2, [src1q] + vpermps m1, m2, [src1q+mmsize] +%elif cpuflag(avx) + vmovaps xmm0, [src1q + 16] + vinsertf128 m0, m0, [src1q], 1 + vshufps m0, m0, m0, q0123 + vmovaps xmm1, [src1q + mmsize + 16] + vinsertf128 m1, m1, [src1q + mmsize], 1 + vshufps m1, m1, m1, q0123 +%else + mova m0, [src1q] + mova m1, [src1q + mmsize] + shufps m0, m0, q0123 + shufps m1, m1, q0123 +%endif + mulps m0, m0, [src0q + lenq + mmsize] + mulps m1, m1, [src0q + lenq] + movaps [dstq + lenq + mmsize], m0 + movaps [dstq + lenq], m1 + add src1q, 2*mmsize + sub lenq, 2*mmsize + jge .loop + REP_RET +%endmacro + +INIT_XMM sse +VECTOR_FMUL_REVERSE +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +VECTOR_FMUL_REVERSE +%endif +%if HAVE_AVX2_EXTERNAL +INIT_YMM avx2 +VECTOR_FMUL_REVERSE +%endif + +; float scalarproduct_float_sse(const float *v1, const float *v2, int len) +INIT_XMM sse +cglobal scalarproduct_float, 3,3,2, v1, v2, offset + shl offsetd, 2 + add v1q, offsetq + add v2q, offsetq + neg offsetq + xorps xmm0, xmm0 +.loop: + movaps xmm1, [v1q+offsetq] + mulps xmm1, [v2q+offsetq] + addps xmm0, xmm1 + add offsetq, 16 + js .loop + movhlps xmm1, xmm0 + addps xmm0, xmm1 + movss xmm1, xmm0 + shufps xmm0, xmm0, 1 + addss xmm0, xmm1 +%if ARCH_X86_64 == 0 + movss r0m, xmm0 + fld dword r0m +%endif + RET + +;----------------------------------------------------------------------------- +; void ff_butterflies_float(float *src0, float *src1, int len); +;----------------------------------------------------------------------------- +INIT_XMM sse +cglobal butterflies_float, 3,3,3, src0, src1, len + shl lend, 2 + add src0q, lenq + add src1q, lenq + neg lenq +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + subps m2, m0, m1 + addps m0, m0, m1 + mova [src1q + lenq], m2 + mova [src0q + lenq], m0 + add lenq, mmsize + jl .loop + REP_RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/float_dsp_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/float_dsp_init.c new file mode 100644 index 00000000..8826e4e2 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/float_dsp_init.c @@ -0,0 +1,121 @@ +/* + * 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.h" + +#include "libavutil/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/float_dsp.h" +#include "cpu.h" +#include "asm.h" + +void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1, + int len); +void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1, + int len); + +void ff_vector_dmul_sse2(double *dst, const double *src0, const double *src1, + int len); +void ff_vector_dmul_avx(double *dst, const double *src0, const double *src1, + int len); + +void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul, + int len); +void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul, + int len); +void ff_vector_fmac_scalar_fma3(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul, + int len); + +void ff_vector_dmac_scalar_sse2(double *dst, const double *src, double mul, + int len); +void ff_vector_dmac_scalar_avx(double *dst, const double *src, double mul, + int len); +void ff_vector_dmac_scalar_fma3(double *dst, const double *src, double mul, + int len); + +void ff_vector_dmul_scalar_sse2(double *dst, const double *src, + double mul, int len); +void ff_vector_dmul_scalar_avx(double *dst, const double *src, + double mul, int len); + +void ff_vector_fmul_window_3dnowext(float *dst, const float *src0, + const float *src1, const float *win, int len); +void ff_vector_fmul_window_sse(float *dst, const float *src0, + const float *src1, const float *win, int len); + +void ff_vector_fmul_add_sse(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_add_avx(float *dst, const float *src0, const float *src1, + const float *src2, int len); +void ff_vector_fmul_add_fma3(float *dst, const float *src0, const float *src1, + const float *src2, int len); + +void ff_vector_fmul_reverse_sse(float *dst, const float *src0, + const float *src1, int len); +void ff_vector_fmul_reverse_avx(float *dst, const float *src0, + const float *src1, int len); +void ff_vector_fmul_reverse_avx2(float *dst, const float *src0, + const float *src1, int len); + +float ff_scalarproduct_float_sse(const float *v1, const float *v2, int order); + +void ff_butterflies_float_sse(float *av_restrict src0, float *av_restrict src1, int len); + +av_cold void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_AMD3DNOWEXT(cpu_flags)) { + fdsp->vector_fmul_window = ff_vector_fmul_window_3dnowext; + } + if (EXTERNAL_SSE(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_sse; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse; + fdsp->vector_fmul_window = ff_vector_fmul_window_sse; + fdsp->vector_fmul_add = ff_vector_fmul_add_sse; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_sse; + fdsp->scalarproduct_float = ff_scalarproduct_float_sse; + fdsp->butterflies_float = ff_butterflies_float_sse; + } + if (EXTERNAL_SSE2(cpu_flags)) { + fdsp->vector_dmul = ff_vector_dmul_sse2; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_sse2; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + fdsp->vector_fmul = ff_vector_fmul_avx; + fdsp->vector_dmul = ff_vector_dmul_avx; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; + fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_avx; + fdsp->vector_fmul_add = ff_vector_fmul_add_avx; + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx; + } + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_avx2; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_fma3; + fdsp->vector_fmul_add = ff_vector_fmul_add_fma3; + fdsp->vector_dmac_scalar = ff_vector_dmac_scalar_fma3; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/imgutils.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/imgutils.asm new file mode 100644 index 00000000..3cca56cd --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/imgutils.asm @@ -0,0 +1,53 @@ +;***************************************************************************** +;* Copyright 2016 Anton Khirnov +;* +;* 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 "libavutil/x86/x86util.asm" + +SECTION .text + +INIT_XMM sse4 +cglobal image_copy_plane_uc_from, 6, 7, 4, dst, dst_linesize, src, src_linesize, bw, height, rowpos + add dstq, bwq + add srcq, bwq + neg bwq + +.row_start: + mov rowposq, bwq + +.loop: + movntdqa m0, [srcq + rowposq + 0 * mmsize] + movntdqa m1, [srcq + rowposq + 1 * mmsize] + movntdqa m2, [srcq + rowposq + 2 * mmsize] + movntdqa m3, [srcq + rowposq + 3 * mmsize] + + mova [dstq + rowposq + 0 * mmsize], m0 + mova [dstq + rowposq + 1 * mmsize], m1 + mova [dstq + rowposq + 2 * mmsize], m2 + mova [dstq + rowposq + 3 * mmsize], m3 + + add rowposq, 4 * mmsize + jnz .loop + + add srcq, src_linesizeq + add dstq, dst_linesizeq + dec heightd + jnz .row_start + + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/imgutils_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/imgutils_init.c new file mode 100644 index 00000000..4ea39820 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/imgutils_init.c @@ -0,0 +1,49 @@ +/* + * 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 +#include + +#include "libavutil/cpu.h" +#include "libavutil/error.h" +#include "libavutil/imgutils.h" +#include "libavutil/imgutils_internal.h" +#include "libavutil/internal.h" + +#include "cpu.h" + +void ff_image_copy_plane_uc_from_sse4(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height); + +int ff_image_copy_plane_uc_from_x86(uint8_t *dst, ptrdiff_t dst_linesize, + const uint8_t *src, ptrdiff_t src_linesize, + ptrdiff_t bytewidth, int height) +{ + int cpu_flags = av_get_cpu_flags(); + ptrdiff_t bw_aligned = FFALIGN(bytewidth, 64); + + if (EXTERNAL_SSE4(cpu_flags) && + bw_aligned <= dst_linesize && bw_aligned <= src_linesize) + ff_image_copy_plane_uc_from_sse4(dst, dst_linesize, src, src_linesize, + bw_aligned, height); + else + return AVERROR(ENOSYS); + + return 0; +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/intmath.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/intmath.h new file mode 100644 index 00000000..40743fd1 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/intmath.h @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015 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 + */ + +#ifndef AVUTIL_X86_INTMATH_H +#define AVUTIL_X86_INTMATH_H + +#include +#include +#if HAVE_FAST_CLZ +#if defined(_MSC_VER) +#include +#elif defined(__INTEL_COMPILER) +#include +#endif +#endif +#include "config.h" + +#if HAVE_FAST_CLZ +#if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER>=1216)) || defined(_MSC_VER) +# if defined(__INTEL_COMPILER) +# define ff_log2(x) (_bit_scan_reverse((x)|1)) +# else +# define ff_log2 ff_log2_x86 +static av_always_inline av_const int ff_log2_x86(unsigned int v) +{ + unsigned long n; + _BitScanReverse(&n, v|1); + return n; +} +# endif +# define ff_log2_16bit av_log2 + +#if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && (_MSC_VER >= 1700) && \ + (defined(__BMI__) || !defined(__clang__))) +# define ff_ctz(v) _tzcnt_u32(v) + +# if ARCH_X86_64 +# define ff_ctzll(v) _tzcnt_u64(v) +# else +# define ff_ctzll ff_ctzll_x86 +static av_always_inline av_const int ff_ctzll_x86(long long v) +{ + return ((uint32_t)v == 0) ? _tzcnt_u32((uint32_t)(v >> 32)) + 32 : _tzcnt_u32((uint32_t)v); +} +# endif +#endif /* _MSC_VER */ + +#endif /* __INTEL_COMPILER */ + +#endif /* HAVE_FAST_CLZ */ + +#if defined(__GNUC__) + +/* Our generic version of av_popcount is faster than GCC's built-in on + * CPUs that don't support the popcnt instruction. + */ +#if defined(__POPCNT__) + #define av_popcount __builtin_popcount +#if ARCH_X86_64 + #define av_popcount64 __builtin_popcountll +#endif + +#endif /* __POPCNT__ */ + +#if defined(__BMI2__) + +#if AV_GCC_VERSION_AT_LEAST(5,1) +#define av_mod_uintp2 __builtin_ia32_bzhi_si +#elif HAVE_INLINE_ASM +/* GCC releases before 5.1.0 have a broken bzhi builtin, so for those we + * implement it using inline assembly + */ +#define av_mod_uintp2 av_mod_uintp2_bmi2 +static av_always_inline av_const unsigned av_mod_uintp2_bmi2(unsigned a, unsigned p) +{ + if (av_builtin_constant_p(p)) + return a & ((1 << p) - 1); + else { + unsigned x; + __asm__ ("bzhi %2, %1, %0 \n\t" : "=r"(x) : "rm"(a), "r"(p)); + return x; + } +} +#endif /* AV_GCC_VERSION_AT_LEAST */ + +#endif /* __BMI2__ */ + +#if defined(__SSE2__) && !defined(__INTEL_COMPILER) + +#define av_clipd av_clipd_sse2 +static av_always_inline av_const double av_clipd_sse2(double a, double amin, double amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("minsd %2, %0 \n\t" + "maxsd %1, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __SSE2__ */ + +#if defined(__SSE__) && !defined(__INTEL_COMPILER) + +#define av_clipf av_clipf_sse +static av_always_inline av_const float av_clipf_sse(float a, float amin, float amax) +{ +#if defined(ASSERT_LEVEL) && ASSERT_LEVEL >= 2 + if (amin > amax) abort(); +#endif + __asm__ ("minss %2, %0 \n\t" + "maxss %1, %0 \n\t" + : "+&x"(a) : "xm"(amin), "xm"(amax)); + return a; +} + +#endif /* __SSE__ */ + +#endif /* __GNUC__ */ + +#endif /* AVUTIL_X86_INTMATH_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/intreadwrite.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/intreadwrite.h new file mode 100644 index 00000000..4061d192 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/intreadwrite.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2010 Alexander Strange + * + * 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 + */ + +#ifndef AVUTIL_X86_INTREADWRITE_H +#define AVUTIL_X86_INTREADWRITE_H + +#include +#include "config.h" +#include "libavutil/attributes.h" + +#if HAVE_MMX + +#if !HAVE_FAST_64BIT && defined(__MMX__) + +#define AV_COPY64 AV_COPY64 +static av_always_inline void AV_COPY64(void *d, const void *s) +{ + __asm__("movq %1, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + : "=m"(*(uint64_t*)d) + : "m" (*(const uint64_t*)s) + : "mm0"); +} + +#define AV_SWAP64 AV_SWAP64 +static av_always_inline void AV_SWAP64(void *a, void *b) +{ + __asm__("movq %1, %%mm0 \n\t" + "movq %0, %%mm1 \n\t" + "movq %%mm0, %0 \n\t" + "movq %%mm1, %1 \n\t" + : "+m"(*(uint64_t*)a), "+m"(*(uint64_t*)b) + ::"mm0", "mm1"); +} + +#define AV_ZERO64 AV_ZERO64 +static av_always_inline void AV_ZERO64(void *d) +{ + __asm__("pxor %%mm0, %%mm0 \n\t" + "movq %%mm0, %0 \n\t" + : "=m"(*(uint64_t*)d) + :: "mm0"); +} + +#endif /* !HAVE_FAST_64BIT && defined(__MMX__) */ + +#ifdef __SSE__ + +#define AV_COPY128 AV_COPY128 +static av_always_inline void AV_COPY128(void *d, const void *s) +{ + struct v {uint64_t v[2];}; + + __asm__("movaps %1, %%xmm0 \n\t" + "movaps %%xmm0, %0 \n\t" + : "=m"(*(struct v*)d) + : "m" (*(const struct v*)s) + : "xmm0"); +} + +#endif /* __SSE__ */ + +#ifdef __SSE2__ + +#define AV_ZERO128 AV_ZERO128 +static av_always_inline void AV_ZERO128(void *d) +{ + struct v {uint64_t v[2];}; + + __asm__("pxor %%xmm0, %%xmm0 \n\t" + "movdqa %%xmm0, %0 \n\t" + : "=m"(*(struct v*)d) + :: "xmm0"); +} + +#endif /* __SSE2__ */ + +#endif /* HAVE_MMX */ + +#endif /* AVUTIL_X86_INTREADWRITE_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/lls.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/lls.asm new file mode 100644 index 00000000..317fba6f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/lls.asm @@ -0,0 +1,290 @@ +;****************************************************************************** +;* linear least squares model +;* +;* Copyright (c) 2013 Loren Merritt +;* +;* 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 "x86util.asm" + +SECTION .text + +%define MAX_VARS 32 +%define MAX_VARS_ALIGN (MAX_VARS+4) +%define COVAR_STRIDE MAX_VARS_ALIGN*8 +%define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE] + +struc LLSModel + .covariance: resq MAX_VARS_ALIGN*MAX_VARS_ALIGN + .coeff: resq MAX_VARS*MAX_VARS + .variance: resq MAX_VARS + .indep_count: resd 1 +endstruc + +%macro ADDPD_MEM 2 +%if cpuflag(avx) + vaddpd %2, %2, %1 +%else + addpd %2, %1 +%endif + mova %1, %2 +%endmacro + +INIT_XMM sse2 +%define movdqa movaps +cglobal update_lls, 2,5,8, ctx, var, i, j, covar2 + %define covarq ctxq + mov id, [ctxq + LLSModel.indep_count] + lea varq, [varq + iq*8] + neg iq + mov covar2q, covarq +.loopi: + ; Compute all 3 pairwise products of a 2x2 block that lies on the diagonal + mova m1, [varq + iq*8] + mova m3, [varq + iq*8 + 16] + pshufd m4, m1, q1010 + pshufd m5, m1, q3232 + pshufd m6, m3, q1010 + pshufd m7, m3, q3232 + mulpd m0, m1, m4 + mulpd m1, m1, m5 + lea covarq, [covar2q + 16] + ADDPD_MEM COVAR(-2,0), m0 + ADDPD_MEM COVAR(-2,1), m1 + lea jq, [iq + 2] + cmp jd, -2 + jg .skip4x4 +.loop4x4: + ; Compute all 16 pairwise products of a 4x4 block + mulpd m0, m4, m3 + mulpd m1, m5, m3 + mulpd m2, m6, m3 + mulpd m3, m3, m7 + ADDPD_MEM COVAR(0,0), m0 + ADDPD_MEM COVAR(0,1), m1 + ADDPD_MEM COVAR(0,2), m2 + ADDPD_MEM COVAR(0,3), m3 + mova m3, [varq + jq*8 + 16] + mulpd m0, m4, m3 + mulpd m1, m5, m3 + mulpd m2, m6, m3 + mulpd m3, m3, m7 + ADDPD_MEM COVAR(2,0), m0 + ADDPD_MEM COVAR(2,1), m1 + ADDPD_MEM COVAR(2,2), m2 + ADDPD_MEM COVAR(2,3), m3 + mova m3, [varq + jq*8 + 32] + add covarq, 32 + add jq, 4 + cmp jd, -2 + jle .loop4x4 +.skip4x4: + test jd, jd + jg .skip2x4 + mulpd m4, m3 + mulpd m5, m3 + mulpd m6, m3 + mulpd m7, m3 + ADDPD_MEM COVAR(0,0), m4 + ADDPD_MEM COVAR(0,1), m5 + ADDPD_MEM COVAR(0,2), m6 + ADDPD_MEM COVAR(0,3), m7 +.skip2x4: + add iq, 4 + add covar2q, 4*COVAR_STRIDE+32 + cmp id, -2 + jle .loopi + test id, id + jg .ret + mov jq, iq + %define covarq covar2q +.loop2x1: + movsd m0, [varq + iq*8] + movlhps m0, m0 + mulpd m0, [varq + jq*8] + ADDPD_MEM COVAR(0,0), m0 + inc iq + add covarq, COVAR_STRIDE + test id, id + jle .loop2x1 +.ret: + REP_RET + +%macro UPDATE_LLS 0 +cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2 + %define covarq ctxq + mov countd, [ctxq + LLSModel.indep_count] + lea count2d, [countq-2] + xor id, id +.loopi: + ; Compute all 10 pairwise products of a 4x4 block that lies on the diagonal + mova ymm1, [varq + iq*8] + vbroadcastsd ymm4, [varq + iq*8] + vbroadcastsd ymm5, [varq + iq*8 + 8] + vbroadcastsd ymm6, [varq + iq*8 + 16] + vbroadcastsd ymm7, [varq + iq*8 + 24] + vextractf128 xmm3, ymm1, 1 +%if cpuflag(fma3) + mova ymm0, COVAR(iq ,0) + mova xmm2, COVAR(iq+2,2) + fmaddpd ymm0, ymm1, ymm4, ymm0 + fmaddpd xmm2, xmm3, xmm6, xmm2 + fmaddpd ymm1, ymm5, ymm1, COVAR(iq ,1) + fmaddpd xmm3, xmm7, xmm3, COVAR(iq+2,3) + mova COVAR(iq ,0), ymm0 + mova COVAR(iq ,1), ymm1 + mova COVAR(iq+2,2), xmm2 + mova COVAR(iq+2,3), xmm3 +%else + vmulpd ymm0, ymm1, ymm4 + vmulpd ymm1, ymm1, ymm5 + vmulpd xmm2, xmm3, xmm6 + vmulpd xmm3, xmm3, xmm7 + ADDPD_MEM COVAR(iq ,0), ymm0 + ADDPD_MEM COVAR(iq ,1), ymm1 + ADDPD_MEM COVAR(iq+2,2), xmm2 + ADDPD_MEM COVAR(iq+2,3), xmm3 +%endif ; cpuflag(fma3) + lea jd, [iq + 4] + cmp jd, count2d + jg .skip4x4 +.loop4x4: + ; Compute all 16 pairwise products of a 4x4 block + mova ymm3, [varq + jq*8] +%if cpuflag(fma3) + mova ymm0, COVAR(jq, 0) + mova ymm1, COVAR(jq, 1) + mova ymm2, COVAR(jq, 2) + fmaddpd ymm0, ymm3, ymm4, ymm0 + fmaddpd ymm1, ymm3, ymm5, ymm1 + fmaddpd ymm2, ymm3, ymm6, ymm2 + fmaddpd ymm3, ymm7, ymm3, COVAR(jq,3) + mova COVAR(jq, 0), ymm0 + mova COVAR(jq, 1), ymm1 + mova COVAR(jq, 2), ymm2 + mova COVAR(jq, 3), ymm3 +%else + vmulpd ymm0, ymm3, ymm4 + vmulpd ymm1, ymm3, ymm5 + vmulpd ymm2, ymm3, ymm6 + vmulpd ymm3, ymm3, ymm7 + ADDPD_MEM COVAR(jq,0), ymm0 + ADDPD_MEM COVAR(jq,1), ymm1 + ADDPD_MEM COVAR(jq,2), ymm2 + ADDPD_MEM COVAR(jq,3), ymm3 +%endif ; cpuflag(fma3) + add jd, 4 + cmp jd, count2d + jle .loop4x4 +.skip4x4: + cmp jd, countd + jg .skip2x4 + mova xmm3, [varq + jq*8] +%if cpuflag(fma3) + mova xmm0, COVAR(jq, 0) + mova xmm1, COVAR(jq, 1) + mova xmm2, COVAR(jq, 2) + fmaddpd xmm0, xmm3, xmm4, xmm0 + fmaddpd xmm1, xmm3, xmm5, xmm1 + fmaddpd xmm2, xmm3, xmm6, xmm2 + fmaddpd xmm3, xmm7, xmm3, COVAR(jq,3) + mova COVAR(jq, 0), xmm0 + mova COVAR(jq, 1), xmm1 + mova COVAR(jq, 2), xmm2 + mova COVAR(jq, 3), xmm3 +%else + vmulpd xmm0, xmm3, xmm4 + vmulpd xmm1, xmm3, xmm5 + vmulpd xmm2, xmm3, xmm6 + vmulpd xmm3, xmm3, xmm7 + ADDPD_MEM COVAR(jq,0), xmm0 + ADDPD_MEM COVAR(jq,1), xmm1 + ADDPD_MEM COVAR(jq,2), xmm2 + ADDPD_MEM COVAR(jq,3), xmm3 +%endif ; cpuflag(fma3) +.skip2x4: + add id, 4 + add covarq, 4*COVAR_STRIDE + cmp id, count2d + jle .loopi + cmp id, countd + jg .ret + mov jd, id +.loop2x1: + vmovddup xmm0, [varq + iq*8] +%if cpuflag(fma3) + mova xmm1, [varq + jq*8] + fmaddpd xmm0, xmm1, xmm0, COVAR(jq,0) + mova COVAR(jq,0), xmm0 +%else + vmulpd xmm0, [varq + jq*8] + ADDPD_MEM COVAR(jq,0), xmm0 +%endif ; cpuflag(fma3) + inc id + add covarq, COVAR_STRIDE + cmp id, countd + jle .loop2x1 +.ret: + REP_RET +%endmacro ; UPDATE_LLS + +%if HAVE_AVX_EXTERNAL +INIT_YMM avx +UPDATE_LLS +%endif +%if HAVE_FMA3_EXTERNAL +INIT_YMM fma3 +UPDATE_LLS +%endif + +INIT_XMM sse2 +cglobal evaluate_lls, 3,4,2, ctx, var, order, i + ; This function is often called on the same buffer as update_lls, but with + ; an offset. They can't both be aligned. + ; Load halves rather than movu to avoid store-forwarding stalls, since the + ; input was initialized immediately prior to this function using scalar math. + %define coefsq ctxq + mov id, orderd + imul orderd, MAX_VARS + lea coefsq, [ctxq + LLSModel.coeff + orderq*8] + movsd m0, [varq] + movhpd m0, [varq + 8] + mulpd m0, [coefsq] + lea coefsq, [coefsq + iq*8] + lea varq, [varq + iq*8] + neg iq + add iq, 2 +.loop: + movsd m1, [varq + iq*8] + movhpd m1, [varq + iq*8 + 8] + mulpd m1, [coefsq + iq*8] + addpd m0, m1 + add iq, 2 + jl .loop + jg .skip1 + movsd m1, [varq + iq*8] + mulsd m1, [coefsq + iq*8] + addpd m0, m1 +.skip1: + movhlps m1, m0 + addsd m0, m1 +%if ARCH_X86_32 + movsd r0m, m0 + fld qword r0m +%endif + RET diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/lls_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/lls_init.c new file mode 100644 index 00000000..1c5dca42 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/lls_init.c @@ -0,0 +1,45 @@ +/* + * linear least squares model + * + * Copyright (c) 2013 Loren Merritt + * + * 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 "libavutil/lls.h" +#include "libavutil/x86/cpu.h" + +void ff_update_lls_sse2(LLSModel *m, const double *var); +void ff_update_lls_avx(LLSModel *m, const double *var); +void ff_update_lls_fma3(LLSModel *m, const double *var); +double ff_evaluate_lls_sse2(LLSModel *m, const double *var, int order); + +av_cold void ff_init_lls_x86(LLSModel *m) +{ + int cpu_flags = av_get_cpu_flags(); + if (EXTERNAL_SSE2(cpu_flags)) { + m->update_lls = ff_update_lls_sse2; + if (m->indep_count >= 4) + m->evaluate_lls = ff_evaluate_lls_sse2; + } + if (EXTERNAL_AVX_FAST(cpu_flags)) { + m->update_lls = ff_update_lls_avx; + } + if (EXTERNAL_FMA3_FAST(cpu_flags)) { + m->update_lls = ff_update_lls_fma3; + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils.asm new file mode 100644 index 00000000..36c57c5f --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils.asm @@ -0,0 +1,386 @@ +;****************************************************************************** +;* Pixel utilities SIMD +;* +;* Copyright (C) 2002-2004 Michael Niedermayer +;* Copyright (C) 2014 Clément Bœsch +;* +;* 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 "x86util.asm" + +SECTION .text + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_8x8_mmx(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_MMX mmx +cglobal pixelutils_sad_8x8, 4,4,0, src1, stride1, src2, stride2 + pxor m7, m7 + pxor m6, m6 +%rep 4 + mova m0, [src1q] + mova m2, [src1q + stride1q] + mova m1, [src2q] + mova m3, [src2q + stride2q] + psubusb m4, m0, m1 + psubusb m5, m2, m3 + psubusb m1, m0 + psubusb m3, m2 + por m1, m4 + por m3, m5 + punpcklbw m0, m1, m7 + punpcklbw m2, m3, m7 + punpckhbw m1, m7 + punpckhbw m3, m7 + paddw m0, m1 + paddw m2, m3 + paddw m0, m2 + paddw m6, m0 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] +%endrep + psrlq m0, m6, 32 + paddw m6, m0 + psrlq m0, m6, 16 + paddw m6, m0 + movd eax, m6 + movzx eax, ax + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_8x8_mmxext(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_MMX mmxext +cglobal pixelutils_sad_8x8, 4,4,0, src1, stride1, src2, stride2 + pxor m2, m2 +%rep 4 + mova m0, [src1q] + mova m1, [src1q + stride1q] + psadbw m0, [src2q] + psadbw m1, [src2q + stride2q] + paddw m2, m0 + paddw m2, m1 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] +%endrep + movd eax, m2 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_16x16_mmxext(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_MMX mmxext +cglobal pixelutils_sad_16x16, 4,4,0, src1, stride1, src2, stride2 + pxor m2, m2 +%rep 16 + mova m0, [src1q] + mova m1, [src1q + 8] + psadbw m0, [src2q] + psadbw m1, [src2q + 8] + paddw m2, m0 + paddw m2, m1 + add src1q, stride1q + add src2q, stride2q +%endrep + movd eax, m2 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pixelutils_sad_16x16, 4,4,5, src1, stride1, src2, stride2 + movu m4, [src1q] + movu m2, [src2q] + movu m1, [src1q + stride1q] + movu m3, [src2q + stride2q] + psadbw m4, m2 + psadbw m1, m3 + paddw m4, m1 +%rep 7 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] + movu m0, [src1q] + movu m2, [src2q] + movu m1, [src1q + stride1q] + movu m3, [src2q + stride2q] + psadbw m0, m2 + psadbw m1, m3 + paddw m4, m0 + paddw m4, m1 +%endrep + movhlps m0, m4 + paddw m4, m0 + movd eax, m4 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_[au]_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +%macro SAD_XMM_16x16 1 +INIT_XMM sse2 +cglobal pixelutils_sad_%1_16x16, 4,4,3, src1, stride1, src2, stride2 + mov%1 m2, [src2q] + psadbw m2, [src1q] + mov%1 m1, [src2q + stride2q] + psadbw m1, [src1q + stride1q] + paddw m2, m1 +%rep 7 + lea src1q, [src1q + 2*stride1q] + lea src2q, [src2q + 2*stride2q] + mov%1 m0, [src2q] + psadbw m0, [src1q] + mov%1 m1, [src2q + stride2q] + psadbw m1, [src1q + stride1q] + paddw m2, m0 + paddw m2, m1 +%endrep + movhlps m0, m2 + paddw m2, m0 + movd eax, m2 + RET +%endmacro + +SAD_XMM_16x16 a +SAD_XMM_16x16 u + + +%macro PROCESS_SAD_32x4_U 0 + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + movu m1, [r2] + movu m2, [r2 + 16] + movu m3, [r0] + movu m4, [r0 + 16] + psadbw m1, m3 + psadbw m2, m4 + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] +%endmacro + +%macro PROCESS_SAD_32x4 1 + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] + + mov%1 m1, [r2] + mov%1 m2, [r2 + 16] + psadbw m1, [r0] + psadbw m2, [r0 + 16] + paddd m1, m2 + paddd m0, m1 + lea r2, [r2 + r3] + lea r0, [r0 + r1] +%endmacro + +;----------------------------------------------------------------------------- +; int ff_pixelutils_sad_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;----------------------------------------------------------------------------- +INIT_XMM sse2 +cglobal pixelutils_sad_32x32, 4,5,5, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 4 +.loop: + PROCESS_SAD_32x4_U + PROCESS_SAD_32x4_U + dec r4d + jnz .loop + + movhlps m1, m0 + paddd m0, m1 + movd eax, m0 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_[au]_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +%macro SAD_XMM_32x32 1 +INIT_XMM sse2 +cglobal pixelutils_sad_%1_32x32, 4,5,3, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 4 +.loop: + PROCESS_SAD_32x4 %1 + PROCESS_SAD_32x4 %1 + dec r4d + jnz .loop + + movhlps m1, m0 + paddd m0, m1 + movd eax, m0 + RET +%endmacro + +SAD_XMM_32x32 a +SAD_XMM_32x32 u + +%if HAVE_AVX2_EXTERNAL +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +INIT_YMM avx2 +cglobal pixelutils_sad_32x32, 4,7,5, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 32/4 + lea r5, [stride1q * 3] + lea r6, [stride2q * 3] + +.loop: + movu m1, [src1q] ; row 0 of pix0 + movu m2, [src2q] ; row 0 of pix1 + movu m3, [src1q + stride1q] ; row 1 of pix0 + movu m4, [src2q + stride2q] ; row 1 of pix1 + + psadbw m1, m2 + psadbw m3, m4 + paddd m0, m1 + paddd m0, m3 + + movu m1, [src1q + 2 * stride1q] ; row 2 of pix0 + movu m2, [src2q + 2 * stride2q] ; row 2 of pix1 + movu m3, [src1q + r5] ; row 3 of pix0 + movu m4, [src2q + r6] ; row 3 of pix1 + + psadbw m1, m2 + psadbw m3, m4 + paddd m0, m1 + paddd m0, m3 + + lea src2q, [src2q + 4 * stride2q] + lea src1q, [src1q + 4 * stride1q] + + dec r4d + jnz .loop + + vextracti128 xm1, m0, 1 + paddd xm0, xm1 + pshufd xm1, xm0, 2 + paddd xm0, xm1 + movd eax, xm0 + RET + +;------------------------------------------------------------------------------- +; int ff_pixelutils_sad_[au]_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, +; const uint8_t *src2, ptrdiff_t stride2); +;------------------------------------------------------------------------------- +%macro SAD_AVX2_32x32 1 +INIT_YMM avx2 +cglobal pixelutils_sad_%1_32x32, 4,7,3, src1, stride1, src2, stride2 + pxor m0, m0 + mov r4d, 32/4 + lea r5, [stride1q * 3] + lea r6, [stride2q * 3] + +.loop: + mov%1 m1, [src2q] ; row 0 of pix1 + psadbw m1, [src1q] + mov%1 m2, [src2q + stride2q] ; row 1 of pix1 + psadbw m2, [src1q + stride1q] + + paddd m0, m1 + paddd m0, m2 + + mov%1 m1, [src2q + 2 * stride2q] ; row 2 of pix1 + psadbw m1, [src1q + 2 * stride1q] + mov%1 m2, [src2q + r6] ; row 3 of pix1 + psadbw m2, [src1q + r5] + + paddd m0, m1 + paddd m0, m2 + + lea src2q, [src2q + 4 * stride2q] + lea src1q, [src1q + 4 * stride1q] + + dec r4d + jnz .loop + + vextracti128 xm1, m0, 1 + paddd xm0, xm1 + pshufd xm1, xm0, 2 + paddd xm0, xm1 + movd eax, xm0 + RET +%endmacro + +SAD_AVX2_32x32 a +SAD_AVX2_32x32 u +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils.h new file mode 100644 index 00000000..876cf460 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils.h @@ -0,0 +1,26 @@ +/* + * 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 + */ + +#ifndef AVUTIL_X86_PIXELUTILS_H +#define AVUTIL_X86_PIXELUTILS_H + +#include "libavutil/pixelutils.h" + +void ff_pixelutils_sad_init_x86(av_pixelutils_sad_fn *sad, int aligned); + +#endif /* AVUTIL_X86_PIXELUTILS_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils_init.c b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils_init.c new file mode 100644 index 00000000..184a3a4a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/pixelutils_init.c @@ -0,0 +1,94 @@ +/* + * 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.h" + +#include "pixelutils.h" +#include "cpu.h" + +int ff_pixelutils_sad_8x8_mmx(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_8x8_mmxext(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_16x16_mmxext(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_16x16_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_32x32_sse2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +int ff_pixelutils_sad_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_a_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); +int ff_pixelutils_sad_u_32x32_avx2(const uint8_t *src1, ptrdiff_t stride1, + const uint8_t *src2, ptrdiff_t stride2); + +void ff_pixelutils_sad_init_x86(av_pixelutils_sad_fn *sad, int aligned) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_MMX(cpu_flags)) { + sad[2] = ff_pixelutils_sad_8x8_mmx; + } + + // The best way to use SSE2 would be to do 2 SADs in parallel, + // but we'd have to modify the pixelutils API to return SIMD functions. + + // It's probably not faster to shuffle data around + // to get two lines of 8 pixels into a single 16byte register, + // so just use the MMX 8x8 version even when SSE2 is available. + if (EXTERNAL_MMXEXT(cpu_flags)) { + sad[2] = ff_pixelutils_sad_8x8_mmxext; + sad[3] = ff_pixelutils_sad_16x16_mmxext; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + switch (aligned) { + case 0: sad[3] = ff_pixelutils_sad_16x16_sse2; break; // src1 unaligned, src2 unaligned + case 1: sad[3] = ff_pixelutils_sad_u_16x16_sse2; break; // src1 aligned, src2 unaligned + case 2: sad[3] = ff_pixelutils_sad_a_16x16_sse2; break; // src1 aligned, src2 aligned + } + } + + if (EXTERNAL_SSE2(cpu_flags)) { + switch (aligned) { + case 0: sad[4] = ff_pixelutils_sad_32x32_sse2; break; // src1 unaligned, src2 unaligned + case 1: sad[4] = ff_pixelutils_sad_u_32x32_sse2; break; // src1 aligned, src2 unaligned + case 2: sad[4] = ff_pixelutils_sad_a_32x32_sse2; break; // src1 aligned, src2 aligned + } + } + + if (EXTERNAL_AVX2_FAST(cpu_flags)) { + switch (aligned) { + case 0: sad[4] = ff_pixelutils_sad_32x32_avx2; break; // src1 unaligned, src2 unaligned + case 1: sad[4] = ff_pixelutils_sad_u_32x32_avx2; break; // src1 aligned, src2 unaligned + case 2: sad[4] = ff_pixelutils_sad_a_32x32_avx2; break; // src1 aligned, src2 aligned + } + } +} diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/timer.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/timer.h new file mode 100644 index 00000000..4d1e88de --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/timer.h @@ -0,0 +1,50 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * 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 + */ + +#ifndef AVUTIL_X86_TIMER_H +#define AVUTIL_X86_TIMER_H + +#include + +#if HAVE_INLINE_ASM + +#define FF_TIMER_UNITS "decicycles" +#define AV_READ_TIME read_time + +static inline uint64_t read_time(void) +{ + uint32_t a, d; + __asm__ volatile( +#if ARCH_X86_64 || defined(__SSE2__) + "lfence \n\t" +#endif + "rdtsc \n\t" + : "=a" (a), "=d" (d)); + return ((uint64_t)d << 32) + a; +} + +#elif HAVE_RDTSC + +#include +#define AV_READ_TIME __rdtsc + +#endif /* HAVE_INLINE_ASM */ + +#endif /* AVUTIL_X86_TIMER_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/w64xmmtest.h b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/w64xmmtest.h new file mode 100644 index 00000000..a4a05b04 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/w64xmmtest.h @@ -0,0 +1,78 @@ +/* + * check XMM registers for clobbers on Win64 + * Copyright (c) 2008 Ramiro Polla + * + * 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 + */ + +#ifndef AVUTIL_X86_W64XMMTEST_H +#define AVUTIL_X86_W64XMMTEST_H + +#include +#include +#include +#include +#include + +#include "libavutil/bswap.h" + +#define storexmmregs(mem) \ + __asm__ volatile( \ + "movups %%xmm6 , 0x00(%0)\n\t" \ + "movups %%xmm7 , 0x10(%0)\n\t" \ + "movups %%xmm8 , 0x20(%0)\n\t" \ + "movups %%xmm9 , 0x30(%0)\n\t" \ + "movups %%xmm10, 0x40(%0)\n\t" \ + "movups %%xmm11, 0x50(%0)\n\t" \ + "movups %%xmm12, 0x60(%0)\n\t" \ + "movups %%xmm13, 0x70(%0)\n\t" \ + "movups %%xmm14, 0x80(%0)\n\t" \ + "movups %%xmm15, 0x90(%0)\n\t" \ + :: "r"(mem) : "memory") + +#define testxmmclobbers(func, ctx, ...) \ + uint64_t xmm[2][10][2]; \ + int ret; \ + storexmmregs(xmm[0]); \ + ret = __real_ ## func(ctx, __VA_ARGS__); \ + storexmmregs(xmm[1]); \ + if (memcmp(xmm[0], xmm[1], sizeof(xmm[0]))) { \ + int i; \ + av_log(ctx, AV_LOG_ERROR, \ + "XMM REGS CLOBBERED IN %s!\n", #func); \ + for (i = 0; i < 10; i ++) \ + if (xmm[0][i][0] != xmm[1][i][0] || \ + xmm[0][i][1] != xmm[1][i][1]) { \ + av_log(ctx, AV_LOG_ERROR, \ + "xmm%-2d = %016"PRIx64"%016"PRIx64"\n", \ + 6 + i, av_bswap64(xmm[0][i][0]), \ + av_bswap64(xmm[0][i][1])); \ + av_log(ctx, AV_LOG_ERROR, \ + " -> %016"PRIx64"%016"PRIx64"\n", \ + av_bswap64(xmm[1][i][0]), \ + av_bswap64(xmm[1][i][1])); \ + } \ + abort(); \ + } \ + return ret + +#define wrap(func) \ +int __real_ ## func; \ +int __wrap_ ## func; \ +int __wrap_ ## func + +#endif /* AVUTIL_X86_W64XMMTEST_H */ diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/x86inc.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/x86inc.asm new file mode 100644 index 00000000..01c35e3a --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/x86inc.asm @@ -0,0 +1,1715 @@ +;***************************************************************************** +;* x86inc.asm: x264asm abstraction layer +;***************************************************************************** +;* Copyright (C) 2005-2018 x264 project +;* +;* Authors: Loren Merritt +;* Henrik Gramner +;* Anton Mitrofanov +;* Fiona Glaser +;* +;* Permission to use, copy, modify, and/or distribute this software for any +;* purpose with or without fee is hereby granted, provided that the above +;* copyright notice and this permission notice appear in all copies. +;* +;* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +;* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +;* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +;* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +;* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +;* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +;***************************************************************************** + +; This is a header file for the x264ASM assembly language, which uses +; NASM/YASM syntax combined with a large number of macros to provide easy +; abstraction between different calling conventions (x86_32, win64, linux64). +; It also has various other useful features to simplify writing the kind of +; DSP functions that are most often used in x264. + +; Unlike the rest of x264, this file is available under an ISC license, as it +; has significant usefulness outside of x264 and we want it to be available +; to the largest audience possible. Of course, if you modify it for your own +; purposes to add a new feature, we strongly encourage contributing a patch +; as this feature might be useful for others as well. Send patches or ideas +; to x264-devel@videolan.org . + +%ifndef private_prefix + %define private_prefix x264 +%endif + +%ifndef public_prefix + %define public_prefix private_prefix +%endif + +%if HAVE_ALIGNED_STACK + %define STACK_ALIGNMENT 16 +%endif +%ifndef STACK_ALIGNMENT + %if ARCH_X86_64 + %define STACK_ALIGNMENT 16 + %else + %define STACK_ALIGNMENT 4 + %endif +%endif + +%define WIN64 0 +%define UNIX64 0 +%if ARCH_X86_64 + %ifidn __OUTPUT_FORMAT__,win32 + %define WIN64 1 + %elifidn __OUTPUT_FORMAT__,win64 + %define WIN64 1 + %elifidn __OUTPUT_FORMAT__,x64 + %define WIN64 1 + %else + %define UNIX64 1 + %endif +%endif + +%define FORMAT_ELF 0 +%ifidn __OUTPUT_FORMAT__,elf + %define FORMAT_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf32 + %define FORMAT_ELF 1 +%elifidn __OUTPUT_FORMAT__,elf64 + %define FORMAT_ELF 1 +%endif + +%ifdef PREFIX + %define mangle(x) _ %+ x +%else + %define mangle(x) x +%endif + +; aout does not support align= +; NOTE: This section is out of sync with x264, in order to +; keep supporting OS/2. +%macro SECTION_RODATA 0-1 16 + %ifidn __OUTPUT_FORMAT__,aout + SECTION .text + %elifidn __OUTPUT_FORMAT__,coff + SECTION .text + %elifidn __OUTPUT_FORMAT__,win32 + SECTION .rdata align=%1 + %elif WIN64 + SECTION .rdata align=%1 + %else + SECTION .rodata align=%1 + %endif +%endmacro + +%if WIN64 + %define PIC +%elif ARCH_X86_64 == 0 +; x86_32 doesn't require PIC. +; Some distros prefer shared objects to be PIC, but nothing breaks if +; the code contains a few textrels, so we'll skip that complexity. + %undef PIC +%endif +%ifdef PIC + default rel +%endif + +%macro CPUNOP 1 + %if HAVE_CPUNOP + CPU %1 + %endif +%endmacro + +; Macros to eliminate most code duplication between x86_32 and x86_64: +; Currently this works only for leaf functions which load all their arguments +; into registers at the start, and make no other use of the stack. Luckily that +; covers most of x264's asm. + +; PROLOGUE: +; %1 = number of arguments. loads them from stack if needed. +; %2 = number of registers used. pushes callee-saved regs if needed. +; %3 = number of xmm registers used. pushes callee-saved xmm regs if needed. +; %4 = (optional) stack size to be allocated. The stack will be aligned before +; allocating the specified stack size. If the required stack alignment is +; larger than the known stack alignment the stack will be manually aligned +; and an extra register will be allocated to hold the original stack +; pointer (to not invalidate r0m etc.). To prevent the use of an extra +; register as stack pointer, request a negative stack size. +; %4+/%5+ = list of names to define to registers +; PROLOGUE can also be invoked by adding the same options to cglobal + +; e.g. +; cglobal foo, 2,3,7,0x40, dst, src, tmp +; declares a function (foo) that automatically loads two arguments (dst and +; src) into registers, uses one additional register (tmp) plus 7 vector +; registers (m0-m6) and allocates 0x40 bytes of stack space. + +; TODO Some functions can use some args directly from the stack. If they're the +; last args then you can just not declare them, but if they're in the middle +; we need more flexible macro. + +; RET: +; Pops anything that was pushed by PROLOGUE, and returns. + +; REP_RET: +; Use this instead of RET if it's a branch target. + +; registers: +; rN and rNq are the native-size register holding function argument N +; rNd, rNw, rNb are dword, word, and byte size +; rNh is the high 8 bits of the word size +; rNm is the original location of arg N (a register or on the stack), dword +; rNmp is native size + +%macro DECLARE_REG 2-3 + %define r%1q %2 + %define r%1d %2d + %define r%1w %2w + %define r%1b %2b + %define r%1h %2h + %define %2q %2 + %if %0 == 2 + %define r%1m %2d + %define r%1mp %2 + %elif ARCH_X86_64 ; memory + %define r%1m [rstk + stack_offset + %3] + %define r%1mp qword r %+ %1 %+ m + %else + %define r%1m [rstk + stack_offset + %3] + %define r%1mp dword r %+ %1 %+ m + %endif + %define r%1 %2 +%endmacro + +%macro DECLARE_REG_SIZE 3 + %define r%1q r%1 + %define e%1q r%1 + %define r%1d e%1 + %define e%1d e%1 + %define r%1w %1 + %define e%1w %1 + %define r%1h %3 + %define e%1h %3 + %define r%1b %2 + %define e%1b %2 + %if ARCH_X86_64 == 0 + %define r%1 e%1 + %endif +%endmacro + +DECLARE_REG_SIZE ax, al, ah +DECLARE_REG_SIZE bx, bl, bh +DECLARE_REG_SIZE cx, cl, ch +DECLARE_REG_SIZE dx, dl, dh +DECLARE_REG_SIZE si, sil, null +DECLARE_REG_SIZE di, dil, null +DECLARE_REG_SIZE bp, bpl, null + +; t# defines for when per-arch register allocation is more complex than just function arguments + +%macro DECLARE_REG_TMP 1-* + %assign %%i 0 + %rep %0 + CAT_XDEFINE t, %%i, r%1 + %assign %%i %%i+1 + %rotate 1 + %endrep +%endmacro + +%macro DECLARE_REG_TMP_SIZE 0-* + %rep %0 + %define t%1q t%1 %+ q + %define t%1d t%1 %+ d + %define t%1w t%1 %+ w + %define t%1h t%1 %+ h + %define t%1b t%1 %+ b + %rotate 1 + %endrep +%endmacro + +DECLARE_REG_TMP_SIZE 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 + +%if ARCH_X86_64 + %define gprsize 8 +%else + %define gprsize 4 +%endif + +%macro PUSH 1 + push %1 + %ifidn rstk, rsp + %assign stack_offset stack_offset+gprsize + %endif +%endmacro + +%macro POP 1 + pop %1 + %ifidn rstk, rsp + %assign stack_offset stack_offset-gprsize + %endif +%endmacro + +%macro PUSH_IF_USED 1-* + %rep %0 + %if %1 < regs_used + PUSH r%1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro POP_IF_USED 1-* + %rep %0 + %if %1 < regs_used + pop r%1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro LOAD_IF_USED 1-* + %rep %0 + %if %1 < num_args + mov r%1, r %+ %1 %+ mp + %endif + %rotate 1 + %endrep +%endmacro + +%macro SUB 2 + sub %1, %2 + %ifidn %1, rstk + %assign stack_offset stack_offset+(%2) + %endif +%endmacro + +%macro ADD 2 + add %1, %2 + %ifidn %1, rstk + %assign stack_offset stack_offset-(%2) + %endif +%endmacro + +%macro movifnidn 2 + %ifnidn %1, %2 + mov %1, %2 + %endif +%endmacro + +%macro movsxdifnidn 2 + %ifnidn %1, %2 + movsxd %1, %2 + %endif +%endmacro + +%macro ASSERT 1 + %if (%1) == 0 + %error assertion ``%1'' failed + %endif +%endmacro + +%macro DEFINE_ARGS 0-* + %ifdef n_arg_names + %assign %%i 0 + %rep n_arg_names + CAT_UNDEF arg_name %+ %%i, q + CAT_UNDEF arg_name %+ %%i, d + CAT_UNDEF arg_name %+ %%i, w + CAT_UNDEF arg_name %+ %%i, h + CAT_UNDEF arg_name %+ %%i, b + CAT_UNDEF arg_name %+ %%i, m + CAT_UNDEF arg_name %+ %%i, mp + CAT_UNDEF arg_name, %%i + %assign %%i %%i+1 + %endrep + %endif + + %xdefine %%stack_offset stack_offset + %undef stack_offset ; so that the current value of stack_offset doesn't get baked in by xdefine + %assign %%i 0 + %rep %0 + %xdefine %1q r %+ %%i %+ q + %xdefine %1d r %+ %%i %+ d + %xdefine %1w r %+ %%i %+ w + %xdefine %1h r %+ %%i %+ h + %xdefine %1b r %+ %%i %+ b + %xdefine %1m r %+ %%i %+ m + %xdefine %1mp r %+ %%i %+ mp + CAT_XDEFINE arg_name, %%i, %1 + %assign %%i %%i+1 + %rotate 1 + %endrep + %xdefine stack_offset %%stack_offset + %assign n_arg_names %0 +%endmacro + +%define required_stack_alignment ((mmsize + 15) & ~15) +%define vzeroupper_required (mmsize > 16 && (ARCH_X86_64 == 0 || xmm_regs_used > 16 || notcpuflag(avx512))) +%define high_mm_regs (16*cpuflag(avx512)) + +%macro ALLOC_STACK 1-2 0 ; stack_size, n_xmm_regs (for win64 only) + %ifnum %1 + %if %1 != 0 + %assign %%pad 0 + %assign stack_size %1 + %if stack_size < 0 + %assign stack_size -stack_size + %endif + %if WIN64 + %assign %%pad %%pad + 32 ; shadow space + %if mmsize != 8 + %assign xmm_regs_used %2 + %if xmm_regs_used > 8 + %assign %%pad %%pad + (xmm_regs_used-8)*16 ; callee-saved xmm registers + %endif + %endif + %endif + %if required_stack_alignment <= STACK_ALIGNMENT + ; maintain the current stack alignment + %assign stack_size_padded stack_size + %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) + SUB rsp, stack_size_padded + %else + %assign %%reg_num (regs_used - 1) + %xdefine rstk r %+ %%reg_num + ; align stack, and save original stack location directly above + ; it, i.e. in [rsp+stack_size_padded], so we can restore the + ; stack in a single instruction (i.e. mov rsp, rstk or mov + ; rsp, [rsp+stack_size_padded]) + %if %1 < 0 ; need to store rsp on stack + %xdefine rstkm [rsp + stack_size + %%pad] + %assign %%pad %%pad + gprsize + %else ; can keep rsp in rstk during whole function + %xdefine rstkm rstk + %endif + %assign stack_size_padded stack_size + ((%%pad + required_stack_alignment-1) & ~(required_stack_alignment-1)) + mov rstk, rsp + and rsp, ~(required_stack_alignment-1) + sub rsp, stack_size_padded + movifnidn rstkm, rstk + %endif + WIN64_PUSH_XMM + %endif + %endif +%endmacro + +%macro SETUP_STACK_POINTER 1 + %ifnum %1 + %if %1 != 0 && required_stack_alignment > STACK_ALIGNMENT + %if %1 > 0 + ; Reserve an additional register for storing the original stack pointer, but avoid using + ; eax/rax for this purpose since it can potentially get overwritten as a return value. + %assign regs_used (regs_used + 1) + %if ARCH_X86_64 && regs_used == 7 + %assign regs_used 8 + %elif ARCH_X86_64 == 0 && regs_used == 1 + %assign regs_used 2 + %endif + %endif + %if ARCH_X86_64 && regs_used < 5 + UNIX64 * 3 + ; Ensure that we don't clobber any registers containing arguments. For UNIX64 we also preserve r6 (rax) + ; since it's used as a hidden argument in vararg functions to specify the number of vector registers used. + %assign regs_used 5 + UNIX64 * 3 + %endif + %endif + %endif +%endmacro + +%if WIN64 ; Windows x64 ;================================================= + +DECLARE_REG 0, rcx +DECLARE_REG 1, rdx +DECLARE_REG 2, R8 +DECLARE_REG 3, R9 +DECLARE_REG 4, R10, 40 +DECLARE_REG 5, R11, 48 +DECLARE_REG 6, rax, 56 +DECLARE_REG 7, rdi, 64 +DECLARE_REG 8, rsi, 72 +DECLARE_REG 9, rbx, 80 +DECLARE_REG 10, rbp, 88 +DECLARE_REG 11, R14, 96 +DECLARE_REG 12, R15, 104 +DECLARE_REG 13, R12, 112 +DECLARE_REG 14, R13, 120 + +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + ASSERT regs_used >= num_args + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 15 + PUSH_IF_USED 7, 8, 9, 10, 11, 12, 13, 14 + ALLOC_STACK %4, %3 + %if mmsize != 8 && stack_size == 0 + WIN64_SPILL_XMM %3 + %endif + LOAD_IF_USED 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif +%endmacro + +%macro WIN64_PUSH_XMM 0 + ; Use the shadow space to store XMM6 and XMM7, the rest needs stack space allocated. + %if xmm_regs_used > 6 + high_mm_regs + movaps [rstk + stack_offset + 8], xmm6 + %endif + %if xmm_regs_used > 7 + high_mm_regs + movaps [rstk + stack_offset + 24], xmm7 + %endif + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i 8 + %rep %%xmm_regs_on_stack + movaps [rsp + (%%i-8)*16 + stack_size + 32], xmm %+ %%i + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +%macro WIN64_SPILL_XMM 1 + %assign xmm_regs_used %1 + ASSERT xmm_regs_used <= 16 + high_mm_regs + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + ; Allocate stack space for callee-saved xmm registers plus shadow space and align the stack. + %assign %%pad %%xmm_regs_on_stack*16 + 32 + %assign stack_size_padded %%pad + ((-%%pad-stack_offset-gprsize) & (STACK_ALIGNMENT-1)) + SUB rsp, stack_size_padded + %endif + WIN64_PUSH_XMM +%endmacro + +%macro WIN64_RESTORE_XMM_INTERNAL 0 + %assign %%pad_size 0 + %assign %%xmm_regs_on_stack xmm_regs_used - high_mm_regs - 8 + %if %%xmm_regs_on_stack > 0 + %assign %%i xmm_regs_used - high_mm_regs + %rep %%xmm_regs_on_stack + %assign %%i %%i-1 + movaps xmm %+ %%i, [rsp + (%%i-8)*16 + stack_size + 32] + %endrep + %endif + %if stack_size_padded > 0 + %if stack_size > 0 && required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %assign %%pad_size stack_size_padded + %endif + %endif + %if xmm_regs_used > 7 + high_mm_regs + movaps xmm7, [rsp + stack_offset - %%pad_size + 24] + %endif + %if xmm_regs_used > 6 + high_mm_regs + movaps xmm6, [rsp + stack_offset - %%pad_size + 8] + %endif +%endmacro + +%macro WIN64_RESTORE_XMM 0 + WIN64_RESTORE_XMM_INTERNAL + %assign stack_offset (stack_offset-stack_size_padded) + %assign stack_size_padded 0 + %assign xmm_regs_used 0 +%endmacro + +%define has_epilogue regs_used > 7 || stack_size > 0 || vzeroupper_required || xmm_regs_used > 6+high_mm_regs + +%macro RET 0 + WIN64_RESTORE_XMM_INTERNAL + POP_IF_USED 14, 13, 12, 11, 10, 9, 8, 7 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%elif ARCH_X86_64 ; *nix x64 ;============================================= + +DECLARE_REG 0, rdi +DECLARE_REG 1, rsi +DECLARE_REG 2, rdx +DECLARE_REG 3, rcx +DECLARE_REG 4, R8 +DECLARE_REG 5, R9 +DECLARE_REG 6, rax, 8 +DECLARE_REG 7, R10, 16 +DECLARE_REG 8, R11, 24 +DECLARE_REG 9, rbx, 32 +DECLARE_REG 10, rbp, 40 +DECLARE_REG 11, R14, 48 +DECLARE_REG 12, R15, 56 +DECLARE_REG 13, R12, 64 +DECLARE_REG 14, R13, 72 + +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + %assign xmm_regs_used %3 + ASSERT regs_used >= num_args + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 15 + PUSH_IF_USED 9, 10, 11, 12, 13, 14 + ALLOC_STACK %4 + LOAD_IF_USED 6, 7, 8, 9, 10, 11, 12, 13, 14 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif +%endmacro + +%define has_epilogue regs_used > 9 || stack_size > 0 || vzeroupper_required + +%macro RET 0 + %if stack_size_padded > 0 + %if required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %endif + %endif + POP_IF_USED 14, 13, 12, 11, 10, 9 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%else ; X86_32 ;============================================================== + +DECLARE_REG 0, eax, 4 +DECLARE_REG 1, ecx, 8 +DECLARE_REG 2, edx, 12 +DECLARE_REG 3, ebx, 16 +DECLARE_REG 4, esi, 20 +DECLARE_REG 5, edi, 24 +DECLARE_REG 6, ebp, 28 +%define rsp esp + +%macro DECLARE_ARG 1-* + %rep %0 + %define r%1m [rstk + stack_offset + 4*%1 + 4] + %define r%1mp dword r%1m + %rotate 1 + %endrep +%endmacro + +DECLARE_ARG 7, 8, 9, 10, 11, 12, 13, 14 + +%macro PROLOGUE 2-5+ 0, 0 ; #args, #regs, #xmm_regs, [stack_size,] arg_names... + %assign num_args %1 + %assign regs_used %2 + ASSERT regs_used >= num_args + %if num_args > 7 + %assign num_args 7 + %endif + %if regs_used > 7 + %assign regs_used 7 + %endif + SETUP_STACK_POINTER %4 + ASSERT regs_used <= 7 + PUSH_IF_USED 3, 4, 5, 6 + ALLOC_STACK %4 + LOAD_IF_USED 0, 1, 2, 3, 4, 5, 6 + %if %0 > 4 + %ifnum %4 + DEFINE_ARGS %5 + %else + DEFINE_ARGS %4, %5 + %endif + %elifnnum %4 + DEFINE_ARGS %4 + %endif +%endmacro + +%define has_epilogue regs_used > 3 || stack_size > 0 || vzeroupper_required + +%macro RET 0 + %if stack_size_padded > 0 + %if required_stack_alignment > STACK_ALIGNMENT + mov rsp, rstkm + %else + add rsp, stack_size_padded + %endif + %endif + POP_IF_USED 6, 5, 4, 3 + %if vzeroupper_required + vzeroupper + %endif + AUTO_REP_RET +%endmacro + +%endif ;====================================================================== + +%if WIN64 == 0 + %macro WIN64_SPILL_XMM 1 + %endmacro + %macro WIN64_RESTORE_XMM 0 + %endmacro + %macro WIN64_PUSH_XMM 0 + %endmacro +%endif + +; On AMD cpus <=K10, an ordinary ret is slow if it immediately follows either +; a branch or a branch target. So switch to a 2-byte form of ret in that case. +; We can automatically detect "follows a branch", but not a branch target. +; (SSSE3 is a sufficient condition to know that your cpu doesn't have this problem.) +%macro REP_RET 0 + %if has_epilogue || cpuflag(ssse3) + RET + %else + rep ret + %endif + annotate_function_size +%endmacro + +%define last_branch_adr $$ +%macro AUTO_REP_RET 0 + %if notcpuflag(ssse3) + times ((last_branch_adr-$)>>31)+1 rep ; times 1 iff $ == last_branch_adr. + %endif + ret + annotate_function_size +%endmacro + +%macro BRANCH_INSTR 0-* + %rep %0 + %macro %1 1-2 %1 + %2 %1 + %if notcpuflag(ssse3) + %%branch_instr equ $ + %xdefine last_branch_adr %%branch_instr + %endif + %endmacro + %rotate 1 + %endrep +%endmacro + +BRANCH_INSTR jz, je, jnz, jne, jl, jle, jnl, jnle, jg, jge, jng, jnge, ja, jae, jna, jnae, jb, jbe, jnb, jnbe, jc, jnc, js, jns, jo, jno, jp, jnp + +%macro TAIL_CALL 2 ; callee, is_nonadjacent + %if has_epilogue + call %1 + RET + %elif %2 + jmp %1 + %endif + annotate_function_size +%endmacro + +;============================================================================= +; arch-independent part +;============================================================================= + +%assign function_align 16 + +; Begin a function. +; Applies any symbol mangling needed for C linkage, and sets up a define such that +; subsequent uses of the function name automatically refer to the mangled version. +; Appends cpuflags to the function name if cpuflags has been specified. +; The "" empty default parameter is a workaround for nasm, which fails if SUFFIX +; is empty and we call cglobal_internal with just %1 %+ SUFFIX (without %2). +%macro cglobal 1-2+ "" ; name, [PROLOGUE args] + cglobal_internal 1, %1 %+ SUFFIX, %2 +%endmacro +%macro cvisible 1-2+ "" ; name, [PROLOGUE args] + cglobal_internal 0, %1 %+ SUFFIX, %2 +%endmacro +%macro cglobal_internal 2-3+ + annotate_function_size + %if %1 + %xdefine %%FUNCTION_PREFIX private_prefix + %xdefine %%VISIBILITY hidden + %else + %xdefine %%FUNCTION_PREFIX public_prefix + %xdefine %%VISIBILITY + %endif + %ifndef cglobaled_%2 + %xdefine %2 mangle(%%FUNCTION_PREFIX %+ _ %+ %2) + %xdefine %2.skip_prologue %2 %+ .skip_prologue + CAT_XDEFINE cglobaled_, %2, 1 + %endif + %xdefine current_function %2 + %xdefine current_function_section __SECT__ + %if FORMAT_ELF + global %2:function %%VISIBILITY + %else + global %2 + %endif + align function_align + %2: + RESET_MM_PERMUTATION ; needed for x86-64, also makes disassembly somewhat nicer + %xdefine rstk rsp ; copy of the original stack pointer, used when greater alignment than the known stack alignment is required + %assign stack_offset 0 ; stack pointer offset relative to the return address + %assign stack_size 0 ; amount of stack space that can be freely used inside a function + %assign stack_size_padded 0 ; total amount of allocated stack space, including space for callee-saved xmm registers on WIN64 and alignment padding + %assign xmm_regs_used 0 ; number of XMM registers requested, used for dealing with callee-saved registers on WIN64 and vzeroupper + %ifnidn %3, "" + PROLOGUE %3 + %endif +%endmacro + +; Create a global symbol from a local label with the correct name mangling and type +%macro cglobal_label 1 + %if FORMAT_ELF + global current_function %+ %1:function hidden + %else + global current_function %+ %1 + %endif + %1: +%endmacro + +%macro cextern 1 + %xdefine %1 mangle(private_prefix %+ _ %+ %1) + CAT_XDEFINE cglobaled_, %1, 1 + extern %1 +%endmacro + +; like cextern, but without the prefix +%macro cextern_naked 1 + %ifdef PREFIX + %xdefine %1 mangle(%1) + %endif + CAT_XDEFINE cglobaled_, %1, 1 + extern %1 +%endmacro + +%macro const 1-2+ + %xdefine %1 mangle(private_prefix %+ _ %+ %1) + %if FORMAT_ELF + global %1:data hidden + %else + global %1 + %endif + %1: %2 +%endmacro + +; This is needed for ELF, otherwise the GNU linker assumes the stack is executable by default. +%if FORMAT_ELF + [SECTION .note.GNU-stack noalloc noexec nowrite progbits] +%endif + +; Tell debuggers how large the function was. +; This may be invoked multiple times per function; we rely on later instances overriding earlier ones. +; This is invoked by RET and similar macros, and also cglobal does it for the previous function, +; but if the last function in a source file doesn't use any of the standard macros for its epilogue, +; then its size might be unspecified. +%macro annotate_function_size 0 + %ifdef __YASM_VER__ + %ifdef current_function + %if FORMAT_ELF + current_function_section + %%ecf equ $ + size current_function %%ecf - current_function + __SECT__ + %endif + %endif + %endif +%endmacro + +; cpuflags + +%assign cpuflags_mmx (1<<0) +%assign cpuflags_mmx2 (1<<1) | cpuflags_mmx +%assign cpuflags_3dnow (1<<2) | cpuflags_mmx +%assign cpuflags_3dnowext (1<<3) | cpuflags_3dnow +%assign cpuflags_sse (1<<4) | cpuflags_mmx2 +%assign cpuflags_sse2 (1<<5) | cpuflags_sse +%assign cpuflags_sse2slow (1<<6) | cpuflags_sse2 +%assign cpuflags_lzcnt (1<<7) | cpuflags_sse2 +%assign cpuflags_sse3 (1<<8) | cpuflags_sse2 +%assign cpuflags_ssse3 (1<<9) | cpuflags_sse3 +%assign cpuflags_sse4 (1<<10)| cpuflags_ssse3 +%assign cpuflags_sse42 (1<<11)| cpuflags_sse4 +%assign cpuflags_aesni (1<<12)| cpuflags_sse42 +%assign cpuflags_avx (1<<13)| cpuflags_sse42 +%assign cpuflags_xop (1<<14)| cpuflags_avx +%assign cpuflags_fma4 (1<<15)| cpuflags_avx +%assign cpuflags_fma3 (1<<16)| cpuflags_avx +%assign cpuflags_bmi1 (1<<17)| cpuflags_avx|cpuflags_lzcnt +%assign cpuflags_bmi2 (1<<18)| cpuflags_bmi1 +%assign cpuflags_avx2 (1<<19)| cpuflags_fma3|cpuflags_bmi2 +%assign cpuflags_avx512 (1<<20)| cpuflags_avx2 ; F, CD, BW, DQ, VL + +%assign cpuflags_cache32 (1<<21) +%assign cpuflags_cache64 (1<<22) +%assign cpuflags_aligned (1<<23) ; not a cpu feature, but a function variant +%assign cpuflags_atom (1<<24) + +; Returns a boolean value expressing whether or not the specified cpuflag is enabled. +%define cpuflag(x) (((((cpuflags & (cpuflags_ %+ x)) ^ (cpuflags_ %+ x)) - 1) >> 31) & 1) +%define notcpuflag(x) (cpuflag(x) ^ 1) + +; Takes an arbitrary number of cpuflags from the above list. +; All subsequent functions (up to the next INIT_CPUFLAGS) is built for the specified cpu. +; You shouldn't need to invoke this macro directly, it's a subroutine for INIT_MMX &co. +%macro INIT_CPUFLAGS 0-* + %xdefine SUFFIX + %undef cpuname + %assign cpuflags 0 + + %if %0 >= 1 + %rep %0 + %ifdef cpuname + %xdefine cpuname cpuname %+ _%1 + %else + %xdefine cpuname %1 + %endif + %assign cpuflags cpuflags | cpuflags_%1 + %rotate 1 + %endrep + %xdefine SUFFIX _ %+ cpuname + + %if cpuflag(avx) + %assign avx_enabled 1 + %endif + %if (mmsize == 16 && notcpuflag(sse2)) || (mmsize == 32 && notcpuflag(avx2)) + %define mova movaps + %define movu movups + %define movnta movntps + %endif + %if cpuflag(aligned) + %define movu mova + %elif cpuflag(sse3) && notcpuflag(ssse3) + %define movu lddqu + %endif + %endif + + %if ARCH_X86_64 || cpuflag(sse2) + CPUNOP amdnop + %else + CPUNOP basicnop + %endif +%endmacro + +; Merge mmx, sse*, and avx* +; m# is a simd register of the currently selected size +; xm# is the corresponding xmm register if mmsize >= 16, otherwise the same as m# +; ym# is the corresponding ymm register if mmsize >= 32, otherwise the same as m# +; zm# is the corresponding zmm register if mmsize >= 64, otherwise the same as m# +; (All 4 remain in sync through SWAP.) + +%macro CAT_XDEFINE 3 + %xdefine %1%2 %3 +%endmacro + +%macro CAT_UNDEF 2 + %undef %1%2 +%endmacro + +%macro DEFINE_MMREGS 1 ; mmtype + %assign %%prev_mmregs 0 + %ifdef num_mmregs + %assign %%prev_mmregs num_mmregs + %endif + + %assign num_mmregs 8 + %if ARCH_X86_64 && mmsize >= 16 + %assign num_mmregs 16 + %if cpuflag(avx512) || mmsize == 64 + %assign num_mmregs 32 + %endif + %endif + + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1 %+ %%i + CAT_XDEFINE nn%1, %%i, %%i + %assign %%i %%i+1 + %endrep + %if %%prev_mmregs > num_mmregs + %rep %%prev_mmregs - num_mmregs + CAT_UNDEF m, %%i + CAT_UNDEF nn %+ mmtype, %%i + %assign %%i %%i+1 + %endrep + %endif + %xdefine mmtype %1 +%endmacro + +; Prefer registers 16-31 over 0-15 to avoid having to use vzeroupper +%macro AVX512_MM_PERMUTATION 0-1 0 ; start_reg + %if ARCH_X86_64 && cpuflag(avx512) + %assign %%i %1 + %rep 16-%1 + %assign %%i_high %%i+16 + SWAP %%i, %%i_high + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +%macro INIT_MMX 0-1+ + %assign avx_enabled 0 + %define RESET_MM_PERMUTATION INIT_MMX %1 + %define mmsize 8 + %define mova movq + %define movu movq + %define movh movd + %define movnta movntq + INIT_CPUFLAGS %1 + DEFINE_MMREGS mm +%endmacro + +%macro INIT_XMM 0-1+ + %assign avx_enabled 0 + %define RESET_MM_PERMUTATION INIT_XMM %1 + %define mmsize 16 + %define mova movdqa + %define movu movdqu + %define movh movq + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS xmm + %if WIN64 + AVX512_MM_PERMUTATION 6 ; Swap callee-saved registers with volatile registers + %endif +%endmacro + +%macro INIT_YMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_YMM %1 + %define mmsize 32 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS ymm + AVX512_MM_PERMUTATION +%endmacro + +%macro INIT_ZMM 0-1+ + %assign avx_enabled 1 + %define RESET_MM_PERMUTATION INIT_ZMM %1 + %define mmsize 64 + %define mova movdqa + %define movu movdqu + %undef movh + %define movnta movntdq + INIT_CPUFLAGS %1 + DEFINE_MMREGS zmm + AVX512_MM_PERMUTATION +%endmacro + +INIT_XMM + +%macro DECLARE_MMCAST 1 + %define mmmm%1 mm%1 + %define mmxmm%1 mm%1 + %define mmymm%1 mm%1 + %define mmzmm%1 mm%1 + %define xmmmm%1 mm%1 + %define xmmxmm%1 xmm%1 + %define xmmymm%1 xmm%1 + %define xmmzmm%1 xmm%1 + %define ymmmm%1 mm%1 + %define ymmxmm%1 xmm%1 + %define ymmymm%1 ymm%1 + %define ymmzmm%1 ymm%1 + %define zmmmm%1 mm%1 + %define zmmxmm%1 xmm%1 + %define zmmymm%1 ymm%1 + %define zmmzmm%1 zmm%1 + %define xm%1 xmm %+ m%1 + %define ym%1 ymm %+ m%1 + %define zm%1 zmm %+ m%1 +%endmacro + +%assign i 0 +%rep 32 + DECLARE_MMCAST i + %assign i i+1 +%endrep + +; I often want to use macros that permute their arguments. e.g. there's no +; efficient way to implement butterfly or transpose or dct without swapping some +; arguments. +; +; I would like to not have to manually keep track of the permutations: +; If I insert a permutation in the middle of a function, it should automatically +; change everything that follows. For more complex macros I may also have multiple +; implementations, e.g. the SSE2 and SSSE3 versions may have different permutations. +; +; Hence these macros. Insert a PERMUTE or some SWAPs at the end of a macro that +; permutes its arguments. It's equivalent to exchanging the contents of the +; registers, except that this way you exchange the register names instead, so it +; doesn't cost any cycles. + +%macro PERMUTE 2-* ; takes a list of pairs to swap + %rep %0/2 + %xdefine %%tmp%2 m%2 + %rotate 2 + %endrep + %rep %0/2 + %xdefine m%1 %%tmp%2 + CAT_XDEFINE nn, m%1, %1 + %rotate 2 + %endrep +%endmacro + +%macro SWAP 2+ ; swaps a single chain (sometimes more concise than pairs) + %ifnum %1 ; SWAP 0, 1, ... + SWAP_INTERNAL_NUM %1, %2 + %else ; SWAP m0, m1, ... + SWAP_INTERNAL_NAME %1, %2 + %endif +%endmacro + +%macro SWAP_INTERNAL_NUM 2-* + %rep %0-1 + %xdefine %%tmp m%1 + %xdefine m%1 m%2 + %xdefine m%2 %%tmp + CAT_XDEFINE nn, m%1, %1 + CAT_XDEFINE nn, m%2, %2 + %rotate 1 + %endrep +%endmacro + +%macro SWAP_INTERNAL_NAME 2-* + %xdefine %%args nn %+ %1 + %rep %0-1 + %xdefine %%args %%args, nn %+ %2 + %rotate 1 + %endrep + SWAP_INTERNAL_NUM %%args +%endmacro + +; If SAVE_MM_PERMUTATION is placed at the end of a function, then any later +; calls to that function will automatically load the permutation, so values can +; be returned in mmregs. +%macro SAVE_MM_PERMUTATION 0-1 + %if %0 + %xdefine %%f %1_m + %else + %xdefine %%f current_function %+ _m + %endif + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE %%f, %%i, m %+ %%i + %assign %%i %%i+1 + %endrep +%endmacro + +%macro LOAD_MM_PERMUTATION 1 ; name to load from + %ifdef %1_m0 + %assign %%i 0 + %rep num_mmregs + CAT_XDEFINE m, %%i, %1_m %+ %%i + CAT_XDEFINE nn, m %+ %%i, %%i + %assign %%i %%i+1 + %endrep + %endif +%endmacro + +; Append cpuflags to the callee's name iff the appended name is known and the plain name isn't +%macro call 1 + %ifid %1 + call_internal %1 %+ SUFFIX, %1 + %else + call %1 + %endif +%endmacro +%macro call_internal 2 + %xdefine %%i %2 + %ifndef cglobaled_%2 + %ifdef cglobaled_%1 + %xdefine %%i %1 + %endif + %endif + call %%i + LOAD_MM_PERMUTATION %%i +%endmacro + +; Substitutions that reduce instruction size but are functionally equivalent +%macro add 2 + %ifnum %2 + %if %2==128 + sub %1, -128 + %else + add %1, %2 + %endif + %else + add %1, %2 + %endif +%endmacro + +%macro sub 2 + %ifnum %2 + %if %2==128 + add %1, -128 + %else + sub %1, %2 + %endif + %else + sub %1, %2 + %endif +%endmacro + +;============================================================================= +; AVX abstraction layer +;============================================================================= + +%assign i 0 +%rep 32 + %if i < 8 + CAT_XDEFINE sizeofmm, i, 8 + CAT_XDEFINE regnumofmm, i, i + %endif + CAT_XDEFINE sizeofxmm, i, 16 + CAT_XDEFINE sizeofymm, i, 32 + CAT_XDEFINE sizeofzmm, i, 64 + CAT_XDEFINE regnumofxmm, i, i + CAT_XDEFINE regnumofymm, i, i + CAT_XDEFINE regnumofzmm, i, i + %assign i i+1 +%endrep +%undef i + +%macro CHECK_AVX_INSTR_EMU 3-* + %xdefine %%opcode %1 + %xdefine %%dst %2 + %rep %0-2 + %ifidn %%dst, %3 + %error non-avx emulation of ``%%opcode'' is not supported + %endif + %rotate 1 + %endrep +%endmacro + +;%1 == instruction +;%2 == minimal instruction set +;%3 == 1 if float, 0 if int +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) +;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not +;%6+: operands +%macro RUN_AVX_INSTR 6-9+ + %ifnum sizeof%7 + %assign __sizeofreg sizeof%7 + %elifnum sizeof%6 + %assign __sizeofreg sizeof%6 + %else + %assign __sizeofreg mmsize + %endif + %assign __emulate_avx 0 + %if avx_enabled && __sizeofreg >= 16 + %xdefine __instr v%1 + %else + %xdefine __instr %1 + %if %0 >= 8+%4 + %assign __emulate_avx 1 + %endif + %endif + %ifnidn %2, fnord + %ifdef cpuname + %if notcpuflag(%2) + %error use of ``%1'' %2 instruction in cpuname function: current_function + %elif cpuflags_%2 < cpuflags_sse && notcpuflag(sse2) && __sizeofreg > 8 + %error use of ``%1'' sse2 instruction in cpuname function: current_function + %endif + %endif + %endif + + %if __emulate_avx + %xdefine __src1 %7 + %xdefine __src2 %8 + %if %5 && %4 == 0 + %ifnidn %6, %7 + %ifidn %6, %8 + %xdefine __src1 %8 + %xdefine __src2 %7 + %elifnnum sizeof%8 + ; 3-operand AVX instructions with a memory arg can only have it in src2, + ; whereas SSE emulation prefers to have it in src1 (i.e. the mov). + ; So, if the instruction is commutative with a memory arg, swap them. + %xdefine __src1 %8 + %xdefine __src2 %7 + %endif + %endif + %endif + %ifnidn %6, __src1 + %if %0 >= 9 + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8, %9}, %6, __src2, %9 + %else + CHECK_AVX_INSTR_EMU {%1 %6, %7, %8}, %6, __src2 + %endif + %if __sizeofreg == 8 + MOVQ %6, __src1 + %elif %3 + MOVAPS %6, __src1 + %else + MOVDQA %6, __src1 + %endif + %endif + %if %0 >= 9 + %1 %6, __src2, %9 + %else + %1 %6, __src2 + %endif + %elif %0 >= 9 + __instr %6, %7, %8, %9 + %elif %0 == 8 + __instr %6, %7, %8 + %elif %0 == 7 + __instr %6, %7 + %else + __instr %6 + %endif +%endmacro + +;%1 == instruction +;%2 == minimal instruction set +;%3 == 1 if float, 0 if int +;%4 == 1 if 4-operand emulation, 0 if 3-operand emulation, 255 otherwise (no emulation) +;%5 == 1 if commutative (i.e. doesn't matter which src arg is which), 0 if not +%macro AVX_INSTR 1-5 fnord, 0, 255, 0 + %macro %1 1-10 fnord, fnord, fnord, fnord, %1, %2, %3, %4, %5 + %ifidn %2, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1 + %elifidn %3, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2 + %elifidn %4, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3 + %elifidn %5, fnord + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4 + %else + RUN_AVX_INSTR %6, %7, %8, %9, %10, %1, %2, %3, %4, %5 + %endif + %endmacro +%endmacro + +; Instructions with both VEX/EVEX and legacy encodings +; Non-destructive instructions are written without parameters +AVX_INSTR addpd, sse2, 1, 0, 1 +AVX_INSTR addps, sse, 1, 0, 1 +AVX_INSTR addsd, sse2, 1, 0, 0 +AVX_INSTR addss, sse, 1, 0, 0 +AVX_INSTR addsubpd, sse3, 1, 0, 0 +AVX_INSTR addsubps, sse3, 1, 0, 0 +AVX_INSTR aesdec, aesni, 0, 0, 0 +AVX_INSTR aesdeclast, aesni, 0, 0, 0 +AVX_INSTR aesenc, aesni, 0, 0, 0 +AVX_INSTR aesenclast, aesni, 0, 0, 0 +AVX_INSTR aesimc, aesni +AVX_INSTR aeskeygenassist, aesni +AVX_INSTR andnpd, sse2, 1, 0, 0 +AVX_INSTR andnps, sse, 1, 0, 0 +AVX_INSTR andpd, sse2, 1, 0, 1 +AVX_INSTR andps, sse, 1, 0, 1 +AVX_INSTR blendpd, sse4, 1, 1, 0 +AVX_INSTR blendps, sse4, 1, 1, 0 +AVX_INSTR blendvpd, sse4 ; can't be emulated +AVX_INSTR blendvps, sse4 ; can't be emulated +AVX_INSTR cmpeqpd, sse2, 1, 0, 1 +AVX_INSTR cmpeqps, sse, 1, 0, 1 +AVX_INSTR cmpeqsd, sse2, 1, 0, 0 +AVX_INSTR cmpeqss, sse, 1, 0, 0 +AVX_INSTR cmplepd, sse2, 1, 0, 0 +AVX_INSTR cmpleps, sse, 1, 0, 0 +AVX_INSTR cmplesd, sse2, 1, 0, 0 +AVX_INSTR cmpless, sse, 1, 0, 0 +AVX_INSTR cmpltpd, sse2, 1, 0, 0 +AVX_INSTR cmpltps, sse, 1, 0, 0 +AVX_INSTR cmpltsd, sse2, 1, 0, 0 +AVX_INSTR cmpltss, sse, 1, 0, 0 +AVX_INSTR cmpneqpd, sse2, 1, 0, 1 +AVX_INSTR cmpneqps, sse, 1, 0, 1 +AVX_INSTR cmpneqsd, sse2, 1, 0, 0 +AVX_INSTR cmpneqss, sse, 1, 0, 0 +AVX_INSTR cmpnlepd, sse2, 1, 0, 0 +AVX_INSTR cmpnleps, sse, 1, 0, 0 +AVX_INSTR cmpnlesd, sse2, 1, 0, 0 +AVX_INSTR cmpnless, sse, 1, 0, 0 +AVX_INSTR cmpnltpd, sse2, 1, 0, 0 +AVX_INSTR cmpnltps, sse, 1, 0, 0 +AVX_INSTR cmpnltsd, sse2, 1, 0, 0 +AVX_INSTR cmpnltss, sse, 1, 0, 0 +AVX_INSTR cmpordpd, sse2 1, 0, 1 +AVX_INSTR cmpordps, sse 1, 0, 1 +AVX_INSTR cmpordsd, sse2 1, 0, 0 +AVX_INSTR cmpordss, sse 1, 0, 0 +AVX_INSTR cmppd, sse2, 1, 1, 0 +AVX_INSTR cmpps, sse, 1, 1, 0 +AVX_INSTR cmpsd, sse2, 1, 1, 0 +AVX_INSTR cmpss, sse, 1, 1, 0 +AVX_INSTR cmpunordpd, sse2, 1, 0, 1 +AVX_INSTR cmpunordps, sse, 1, 0, 1 +AVX_INSTR cmpunordsd, sse2, 1, 0, 0 +AVX_INSTR cmpunordss, sse, 1, 0, 0 +AVX_INSTR comisd, sse2 +AVX_INSTR comiss, sse +AVX_INSTR cvtdq2pd, sse2 +AVX_INSTR cvtdq2ps, sse2 +AVX_INSTR cvtpd2dq, sse2 +AVX_INSTR cvtpd2ps, sse2 +AVX_INSTR cvtps2dq, sse2 +AVX_INSTR cvtps2pd, sse2 +AVX_INSTR cvtsd2si, sse2 +AVX_INSTR cvtsd2ss, sse2, 1, 0, 0 +AVX_INSTR cvtsi2sd, sse2, 1, 0, 0 +AVX_INSTR cvtsi2ss, sse, 1, 0, 0 +AVX_INSTR cvtss2sd, sse2, 1, 0, 0 +AVX_INSTR cvtss2si, sse +AVX_INSTR cvttpd2dq, sse2 +AVX_INSTR cvttps2dq, sse2 +AVX_INSTR cvttsd2si, sse2 +AVX_INSTR cvttss2si, sse +AVX_INSTR divpd, sse2, 1, 0, 0 +AVX_INSTR divps, sse, 1, 0, 0 +AVX_INSTR divsd, sse2, 1, 0, 0 +AVX_INSTR divss, sse, 1, 0, 0 +AVX_INSTR dppd, sse4, 1, 1, 0 +AVX_INSTR dpps, sse4, 1, 1, 0 +AVX_INSTR extractps, sse4 +AVX_INSTR haddpd, sse3, 1, 0, 0 +AVX_INSTR haddps, sse3, 1, 0, 0 +AVX_INSTR hsubpd, sse3, 1, 0, 0 +AVX_INSTR hsubps, sse3, 1, 0, 0 +AVX_INSTR insertps, sse4, 1, 1, 0 +AVX_INSTR lddqu, sse3 +AVX_INSTR ldmxcsr, sse +AVX_INSTR maskmovdqu, sse2 +AVX_INSTR maxpd, sse2, 1, 0, 1 +AVX_INSTR maxps, sse, 1, 0, 1 +AVX_INSTR maxsd, sse2, 1, 0, 0 +AVX_INSTR maxss, sse, 1, 0, 0 +AVX_INSTR minpd, sse2, 1, 0, 1 +AVX_INSTR minps, sse, 1, 0, 1 +AVX_INSTR minsd, sse2, 1, 0, 0 +AVX_INSTR minss, sse, 1, 0, 0 +AVX_INSTR movapd, sse2 +AVX_INSTR movaps, sse +AVX_INSTR movd, mmx +AVX_INSTR movddup, sse3 +AVX_INSTR movdqa, sse2 +AVX_INSTR movdqu, sse2 +AVX_INSTR movhlps, sse, 1, 0, 0 +AVX_INSTR movhpd, sse2, 1, 0, 0 +AVX_INSTR movhps, sse, 1, 0, 0 +AVX_INSTR movlhps, sse, 1, 0, 0 +AVX_INSTR movlpd, sse2, 1, 0, 0 +AVX_INSTR movlps, sse, 1, 0, 0 +AVX_INSTR movmskpd, sse2 +AVX_INSTR movmskps, sse +AVX_INSTR movntdq, sse2 +AVX_INSTR movntdqa, sse4 +AVX_INSTR movntpd, sse2 +AVX_INSTR movntps, sse +AVX_INSTR movq, mmx +AVX_INSTR movsd, sse2, 1, 0, 0 +AVX_INSTR movshdup, sse3 +AVX_INSTR movsldup, sse3 +AVX_INSTR movss, sse, 1, 0, 0 +AVX_INSTR movupd, sse2 +AVX_INSTR movups, sse +AVX_INSTR mpsadbw, sse4, 0, 1, 0 +AVX_INSTR mulpd, sse2, 1, 0, 1 +AVX_INSTR mulps, sse, 1, 0, 1 +AVX_INSTR mulsd, sse2, 1, 0, 0 +AVX_INSTR mulss, sse, 1, 0, 0 +AVX_INSTR orpd, sse2, 1, 0, 1 +AVX_INSTR orps, sse, 1, 0, 1 +AVX_INSTR pabsb, ssse3 +AVX_INSTR pabsd, ssse3 +AVX_INSTR pabsw, ssse3 +AVX_INSTR packsswb, mmx, 0, 0, 0 +AVX_INSTR packssdw, mmx, 0, 0, 0 +AVX_INSTR packuswb, mmx, 0, 0, 0 +AVX_INSTR packusdw, sse4, 0, 0, 0 +AVX_INSTR paddb, mmx, 0, 0, 1 +AVX_INSTR paddw, mmx, 0, 0, 1 +AVX_INSTR paddd, mmx, 0, 0, 1 +AVX_INSTR paddq, sse2, 0, 0, 1 +AVX_INSTR paddsb, mmx, 0, 0, 1 +AVX_INSTR paddsw, mmx, 0, 0, 1 +AVX_INSTR paddusb, mmx, 0, 0, 1 +AVX_INSTR paddusw, mmx, 0, 0, 1 +AVX_INSTR palignr, ssse3, 0, 1, 0 +AVX_INSTR pand, mmx, 0, 0, 1 +AVX_INSTR pandn, mmx, 0, 0, 0 +AVX_INSTR pavgb, mmx2, 0, 0, 1 +AVX_INSTR pavgw, mmx2, 0, 0, 1 +AVX_INSTR pblendvb, sse4 ; can't be emulated +AVX_INSTR pblendw, sse4, 0, 1, 0 +AVX_INSTR pclmulqdq, fnord, 0, 1, 0 +AVX_INSTR pclmulhqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmulhqlqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqhqdq, fnord, 0, 0, 0 +AVX_INSTR pclmullqlqdq, fnord, 0, 0, 0 +AVX_INSTR pcmpestri, sse42 +AVX_INSTR pcmpestrm, sse42 +AVX_INSTR pcmpistri, sse42 +AVX_INSTR pcmpistrm, sse42 +AVX_INSTR pcmpeqb, mmx, 0, 0, 1 +AVX_INSTR pcmpeqw, mmx, 0, 0, 1 +AVX_INSTR pcmpeqd, mmx, 0, 0, 1 +AVX_INSTR pcmpeqq, sse4, 0, 0, 1 +AVX_INSTR pcmpgtb, mmx, 0, 0, 0 +AVX_INSTR pcmpgtw, mmx, 0, 0, 0 +AVX_INSTR pcmpgtd, mmx, 0, 0, 0 +AVX_INSTR pcmpgtq, sse42, 0, 0, 0 +AVX_INSTR pextrb, sse4 +AVX_INSTR pextrd, sse4 +AVX_INSTR pextrq, sse4 +AVX_INSTR pextrw, mmx2 +AVX_INSTR phaddw, ssse3, 0, 0, 0 +AVX_INSTR phaddd, ssse3, 0, 0, 0 +AVX_INSTR phaddsw, ssse3, 0, 0, 0 +AVX_INSTR phminposuw, sse4 +AVX_INSTR phsubw, ssse3, 0, 0, 0 +AVX_INSTR phsubd, ssse3, 0, 0, 0 +AVX_INSTR phsubsw, ssse3, 0, 0, 0 +AVX_INSTR pinsrb, sse4, 0, 1, 0 +AVX_INSTR pinsrd, sse4, 0, 1, 0 +AVX_INSTR pinsrq, sse4, 0, 1, 0 +AVX_INSTR pinsrw, mmx2, 0, 1, 0 +AVX_INSTR pmaddwd, mmx, 0, 0, 1 +AVX_INSTR pmaddubsw, ssse3, 0, 0, 0 +AVX_INSTR pmaxsb, sse4, 0, 0, 1 +AVX_INSTR pmaxsw, mmx2, 0, 0, 1 +AVX_INSTR pmaxsd, sse4, 0, 0, 1 +AVX_INSTR pmaxub, mmx2, 0, 0, 1 +AVX_INSTR pmaxuw, sse4, 0, 0, 1 +AVX_INSTR pmaxud, sse4, 0, 0, 1 +AVX_INSTR pminsb, sse4, 0, 0, 1 +AVX_INSTR pminsw, mmx2, 0, 0, 1 +AVX_INSTR pminsd, sse4, 0, 0, 1 +AVX_INSTR pminub, mmx2, 0, 0, 1 +AVX_INSTR pminuw, sse4, 0, 0, 1 +AVX_INSTR pminud, sse4, 0, 0, 1 +AVX_INSTR pmovmskb, mmx2 +AVX_INSTR pmovsxbw, sse4 +AVX_INSTR pmovsxbd, sse4 +AVX_INSTR pmovsxbq, sse4 +AVX_INSTR pmovsxwd, sse4 +AVX_INSTR pmovsxwq, sse4 +AVX_INSTR pmovsxdq, sse4 +AVX_INSTR pmovzxbw, sse4 +AVX_INSTR pmovzxbd, sse4 +AVX_INSTR pmovzxbq, sse4 +AVX_INSTR pmovzxwd, sse4 +AVX_INSTR pmovzxwq, sse4 +AVX_INSTR pmovzxdq, sse4 +AVX_INSTR pmuldq, sse4, 0, 0, 1 +AVX_INSTR pmulhrsw, ssse3, 0, 0, 1 +AVX_INSTR pmulhuw, mmx2, 0, 0, 1 +AVX_INSTR pmulhw, mmx, 0, 0, 1 +AVX_INSTR pmullw, mmx, 0, 0, 1 +AVX_INSTR pmulld, sse4, 0, 0, 1 +AVX_INSTR pmuludq, sse2, 0, 0, 1 +AVX_INSTR por, mmx, 0, 0, 1 +AVX_INSTR psadbw, mmx2, 0, 0, 1 +AVX_INSTR pshufb, ssse3, 0, 0, 0 +AVX_INSTR pshufd, sse2 +AVX_INSTR pshufhw, sse2 +AVX_INSTR pshuflw, sse2 +AVX_INSTR psignb, ssse3, 0, 0, 0 +AVX_INSTR psignw, ssse3, 0, 0, 0 +AVX_INSTR psignd, ssse3, 0, 0, 0 +AVX_INSTR psllw, mmx, 0, 0, 0 +AVX_INSTR pslld, mmx, 0, 0, 0 +AVX_INSTR psllq, mmx, 0, 0, 0 +AVX_INSTR pslldq, sse2, 0, 0, 0 +AVX_INSTR psraw, mmx, 0, 0, 0 +AVX_INSTR psrad, mmx, 0, 0, 0 +AVX_INSTR psrlw, mmx, 0, 0, 0 +AVX_INSTR psrld, mmx, 0, 0, 0 +AVX_INSTR psrlq, mmx, 0, 0, 0 +AVX_INSTR psrldq, sse2, 0, 0, 0 +AVX_INSTR psubb, mmx, 0, 0, 0 +AVX_INSTR psubw, mmx, 0, 0, 0 +AVX_INSTR psubd, mmx, 0, 0, 0 +AVX_INSTR psubq, sse2, 0, 0, 0 +AVX_INSTR psubsb, mmx, 0, 0, 0 +AVX_INSTR psubsw, mmx, 0, 0, 0 +AVX_INSTR psubusb, mmx, 0, 0, 0 +AVX_INSTR psubusw, mmx, 0, 0, 0 +AVX_INSTR ptest, sse4 +AVX_INSTR punpckhbw, mmx, 0, 0, 0 +AVX_INSTR punpckhwd, mmx, 0, 0, 0 +AVX_INSTR punpckhdq, mmx, 0, 0, 0 +AVX_INSTR punpckhqdq, sse2, 0, 0, 0 +AVX_INSTR punpcklbw, mmx, 0, 0, 0 +AVX_INSTR punpcklwd, mmx, 0, 0, 0 +AVX_INSTR punpckldq, mmx, 0, 0, 0 +AVX_INSTR punpcklqdq, sse2, 0, 0, 0 +AVX_INSTR pxor, mmx, 0, 0, 1 +AVX_INSTR rcpps, sse +AVX_INSTR rcpss, sse, 1, 0, 0 +AVX_INSTR roundpd, sse4 +AVX_INSTR roundps, sse4 +AVX_INSTR roundsd, sse4, 1, 1, 0 +AVX_INSTR roundss, sse4, 1, 1, 0 +AVX_INSTR rsqrtps, sse +AVX_INSTR rsqrtss, sse, 1, 0, 0 +AVX_INSTR shufpd, sse2, 1, 1, 0 +AVX_INSTR shufps, sse, 1, 1, 0 +AVX_INSTR sqrtpd, sse2 +AVX_INSTR sqrtps, sse +AVX_INSTR sqrtsd, sse2, 1, 0, 0 +AVX_INSTR sqrtss, sse, 1, 0, 0 +AVX_INSTR stmxcsr, sse +AVX_INSTR subpd, sse2, 1, 0, 0 +AVX_INSTR subps, sse, 1, 0, 0 +AVX_INSTR subsd, sse2, 1, 0, 0 +AVX_INSTR subss, sse, 1, 0, 0 +AVX_INSTR ucomisd, sse2 +AVX_INSTR ucomiss, sse +AVX_INSTR unpckhpd, sse2, 1, 0, 0 +AVX_INSTR unpckhps, sse, 1, 0, 0 +AVX_INSTR unpcklpd, sse2, 1, 0, 0 +AVX_INSTR unpcklps, sse, 1, 0, 0 +AVX_INSTR xorpd, sse2, 1, 0, 1 +AVX_INSTR xorps, sse, 1, 0, 1 + +; 3DNow instructions, for sharing code between AVX, SSE and 3DN +AVX_INSTR pfadd, 3dnow, 1, 0, 1 +AVX_INSTR pfsub, 3dnow, 1, 0, 0 +AVX_INSTR pfmul, 3dnow, 1, 0, 1 + +; base-4 constants for shuffles +%assign i 0 +%rep 256 + %assign j ((i>>6)&3)*1000 + ((i>>4)&3)*100 + ((i>>2)&3)*10 + (i&3) + %if j < 10 + CAT_XDEFINE q000, j, i + %elif j < 100 + CAT_XDEFINE q00, j, i + %elif j < 1000 + CAT_XDEFINE q0, j, i + %else + CAT_XDEFINE q, j, i + %endif + %assign i i+1 +%endrep +%undef i +%undef j + +%macro FMA_INSTR 3 + %macro %1 4-7 %1, %2, %3 + %if cpuflag(xop) + v%5 %1, %2, %3, %4 + %elifnidn %1, %4 + %6 %1, %2, %3 + %7 %1, %4 + %else + %error non-xop emulation of ``%5 %1, %2, %3, %4'' is not supported + %endif + %endmacro +%endmacro + +FMA_INSTR pmacsww, pmullw, paddw +FMA_INSTR pmacsdd, pmulld, paddd ; sse4 emulation +FMA_INSTR pmacsdql, pmuldq, paddq ; sse4 emulation +FMA_INSTR pmadcswd, pmaddwd, paddd + +; tzcnt is equivalent to "rep bsf" and is backwards-compatible with bsf. +; This lets us use tzcnt without bumping the yasm version requirement yet. +%define tzcnt rep bsf + +; Macros for consolidating FMA3 and FMA4 using 4-operand (dst, src1, src2, src3) syntax. +; FMA3 is only possible if dst is the same as one of the src registers. +; Either src2 or src3 can be a memory operand. +%macro FMA4_INSTR 2-* + %push fma4_instr + %xdefine %$prefix %1 + %rep %0 - 1 + %macro %$prefix%2 4-6 %$prefix, %2 + %if notcpuflag(fma3) && notcpuflag(fma4) + %error use of ``%5%6'' fma instruction in cpuname function: current_function + %elif cpuflag(fma4) + v%5%6 %1, %2, %3, %4 + %elifidn %1, %2 + ; If %3 or %4 is a memory operand it needs to be encoded as the last operand. + %ifnum sizeof%3 + v%{5}213%6 %2, %3, %4 + %else + v%{5}132%6 %2, %4, %3 + %endif + %elifidn %1, %3 + v%{5}213%6 %3, %2, %4 + %elifidn %1, %4 + v%{5}231%6 %4, %2, %3 + %else + %error fma3 emulation of ``%5%6 %1, %2, %3, %4'' is not supported + %endif + %endmacro + %rotate 1 + %endrep + %pop +%endmacro + +FMA4_INSTR fmadd, pd, ps, sd, ss +FMA4_INSTR fmaddsub, pd, ps +FMA4_INSTR fmsub, pd, ps, sd, ss +FMA4_INSTR fmsubadd, pd, ps +FMA4_INSTR fnmadd, pd, ps, sd, ss +FMA4_INSTR fnmsub, pd, ps, sd, ss + +; Macros for converting VEX instructions to equivalent EVEX ones. +%macro EVEX_INSTR 2-3 0 ; vex, evex, prefer_evex + %macro %1 2-7 fnord, fnord, %1, %2, %3 + %ifidn %3, fnord + %define %%args %1, %2 + %elifidn %4, fnord + %define %%args %1, %2, %3 + %else + %define %%args %1, %2, %3, %4 + %endif + %assign %%evex_required cpuflag(avx512) & %7 + %ifnum regnumof%1 + %if regnumof%1 >= 16 || sizeof%1 > 32 + %assign %%evex_required 1 + %endif + %endif + %ifnum regnumof%2 + %if regnumof%2 >= 16 || sizeof%2 > 32 + %assign %%evex_required 1 + %endif + %endif + %if %%evex_required + %6 %%args + %else + %5 %%args ; Prefer VEX over EVEX due to shorter instruction length + %endif + %endmacro +%endmacro + +EVEX_INSTR vbroadcastf128, vbroadcastf32x4 +EVEX_INSTR vbroadcasti128, vbroadcasti32x4 +EVEX_INSTR vextractf128, vextractf32x4 +EVEX_INSTR vextracti128, vextracti32x4 +EVEX_INSTR vinsertf128, vinsertf32x4 +EVEX_INSTR vinserti128, vinserti32x4 +EVEX_INSTR vmovdqa, vmovdqa32 +EVEX_INSTR vmovdqu, vmovdqu32 +EVEX_INSTR vpand, vpandd +EVEX_INSTR vpandn, vpandnd +EVEX_INSTR vpor, vpord +EVEX_INSTR vpxor, vpxord +EVEX_INSTR vrcpps, vrcp14ps, 1 ; EVEX versions have higher precision +EVEX_INSTR vrcpss, vrcp14ss, 1 +EVEX_INSTR vrsqrtps, vrsqrt14ps, 1 +EVEX_INSTR vrsqrtss, vrsqrt14ss, 1 + +; workaround: vpbroadcastq is broken in x86_32 due to a yasm bug (fixed in 1.3.0) +%ifdef __YASM_VER__ + %if __YASM_VERSION_ID__ < 0x01030000 && ARCH_X86_64 == 0 + %macro vpbroadcastq 2 + %if sizeof%1 == 16 + movddup %1, %2 + %else + vbroadcastsd %1, %2 + %endif + %endmacro + %endif +%endif diff --git a/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/x86util.asm b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/x86util.asm new file mode 100644 index 00000000..d7cd9968 --- /dev/null +++ b/thirdparty/rexglue-sdk/thirdparty/FFmpeg/libavutil/x86/x86util.asm @@ -0,0 +1,1028 @@ +;***************************************************************************** +;* x86util.asm +;***************************************************************************** +;* Copyright (C) 2008-2010 x264 project +;* +;* Authors: Loren Merritt +;* Holger Lubitz +;* +;* 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 +;****************************************************************************** + +%define private_prefix ff +%define public_prefix avpriv +%define cpuflags_mmxext cpuflags_mmx2 + +%include "libavutil/x86/x86inc.asm" + +; expands to [base],...,[base+7*stride] +%define PASS8ROWS(base, base3, stride, stride3) \ + [base], [base + stride], [base + 2*stride], [base3], \ + [base3 + stride], [base3 + 2*stride], [base3 + stride3], [base3 + stride*4] + +; Interleave low src0 with low src1 and store in src0, +; interleave high src0 with high src1 and store in src1. +; %1 - types +; %2 - index of the register with src0 +; %3 - index of the register with src1 +; %4 - index of the register for intermediate results +; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3 +; src1: y0 y1 y2 y3 q0 q1 q2 q3 +; output: src0: x0 y0 x1 y1 x2 y2 x3 y3 +; src1: z0 q0 z1 q1 z2 q2 z3 q3 +%macro SBUTTERFLY 4 +%ifidn %1, dqqq + vperm2i128 m%4, m%2, m%3, q0301 + vinserti128 m%2, m%2, xm%3, 1 +%elif avx_enabled == 0 + mova m%4, m%2 + punpckl%1 m%2, m%3 + punpckh%1 m%4, m%3 +%else + punpckh%1 m%4, m%2, m%3 + punpckl%1 m%2, m%3 +%endif + SWAP %3, %4 +%endmacro + +%macro SBUTTERFLY2 4 + punpckl%1 m%4, m%2, m%3 + punpckh%1 m%2, m%2, m%3 + SWAP %2, %4, %3 +%endmacro + +%macro SBUTTERFLYPS 3 + unpcklps m%3, m%1, m%2 + unpckhps m%1, m%1, m%2 + SWAP %1, %3, %2 +%endmacro + +%macro SBUTTERFLYPD 3 + movlhps m%3, m%1, m%2 + movhlps m%2, m%2, m%1 + SWAP %1, %3 +%endmacro + +%macro TRANSPOSE4x4B 5 + SBUTTERFLY bw, %1, %2, %5 + SBUTTERFLY bw, %3, %4, %5 + SBUTTERFLY wd, %1, %3, %5 + SBUTTERFLY wd, %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE4x4W 5 + SBUTTERFLY wd, %1, %2, %5 + SBUTTERFLY wd, %3, %4, %5 + SBUTTERFLY dq, %1, %3, %5 + SBUTTERFLY dq, %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE2x4x4B 5 + SBUTTERFLY bw, %1, %2, %5 + SBUTTERFLY bw, %3, %4, %5 + SBUTTERFLY wd, %1, %3, %5 + SBUTTERFLY wd, %2, %4, %5 + SBUTTERFLY dq, %1, %2, %5 + SBUTTERFLY dq, %3, %4, %5 +%endmacro + +%macro TRANSPOSE2x4x4W 5 + SBUTTERFLY wd, %1, %2, %5 + SBUTTERFLY wd, %3, %4, %5 + SBUTTERFLY dq, %1, %3, %5 + SBUTTERFLY dq, %2, %4, %5 + SBUTTERFLY qdq, %1, %2, %5 + SBUTTERFLY qdq, %3, %4, %5 +%endmacro + +%macro TRANSPOSE4x4D 5 + SBUTTERFLY dq, %1, %2, %5 + SBUTTERFLY dq, %3, %4, %5 + SBUTTERFLY qdq, %1, %3, %5 + SBUTTERFLY qdq, %2, %4, %5 + SWAP %2, %3 +%endmacro + +; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops +%macro TRANSPOSE4x4PS 5 + SBUTTERFLYPS %1, %2, %5 + SBUTTERFLYPS %3, %4, %5 + SBUTTERFLYPD %1, %3, %5 + SBUTTERFLYPD %2, %4, %5 + SWAP %2, %3 +%endmacro + +%macro TRANSPOSE8x4D 9-11 +%if ARCH_X86_64 + SBUTTERFLY dq, %1, %2, %9 + SBUTTERFLY dq, %3, %4, %9 + SBUTTERFLY dq, %5, %6, %9 + SBUTTERFLY dq, %7, %8, %9 + SBUTTERFLY qdq, %1, %3, %9 + SBUTTERFLY qdq, %2, %4, %9 + SBUTTERFLY qdq, %5, %7, %9 + SBUTTERFLY qdq, %6, %8, %9 + SWAP %2, %5 + SWAP %4, %7 +%else +; in: m0..m7 +; out: m0..m7, unless %11 in which case m2 is in %9 +; spills into %9 and %10 + movdqa %9, m%7 + SBUTTERFLY dq, %1, %2, %7 + movdqa %10, m%2 + movdqa m%7, %9 + SBUTTERFLY dq, %3, %4, %2 + SBUTTERFLY dq, %5, %6, %2 + SBUTTERFLY dq, %7, %8, %2 + SBUTTERFLY qdq, %1, %3, %2 + movdqa %9, m%3 + movdqa m%2, %10 + SBUTTERFLY qdq, %2, %4, %3 + SBUTTERFLY qdq, %5, %7, %3 + SBUTTERFLY qdq, %6, %8, %3 + SWAP %2, %5 + SWAP %4, %7 +%if %0<11 + movdqa m%3, %9 +%endif +%endif +%endmacro + +%macro TRANSPOSE8x8W 9-11 +%if ARCH_X86_64 + SBUTTERFLY wd, %1, %2, %9 + SBUTTERFLY wd, %3, %4, %9 + SBUTTERFLY wd, %5, %6, %9 + SBUTTERFLY wd, %7, %8, %9 + SBUTTERFLY dq, %1, %3, %9 + SBUTTERFLY dq, %2, %4, %9 + SBUTTERFLY dq, %5, %7, %9 + SBUTTERFLY dq, %6, %8, %9 + SBUTTERFLY qdq, %1, %5, %9 + SBUTTERFLY qdq, %2, %6, %9 + SBUTTERFLY qdq, %3, %7, %9 + SBUTTERFLY qdq, %4, %8, %9 + SWAP %2, %5 + SWAP %4, %7 +%else +; in: m0..m7, unless %11 in which case m6 is in %9 +; out: m0..m7, unless %11 in which case m4 is in %10 +; spills into %9 and %10 +%if %0<11 + movdqa %9, m%7 +%endif + SBUTTERFLY wd, %1, %2, %7 + movdqa %10, m%2 + movdqa m%7, %9 + SBUTTERFLY wd, %3, %4, %2 + SBUTTERFLY wd, %5, %6, %2 + SBUTTERFLY wd, %7, %8, %2 + SBUTTERFLY dq, %1, %3, %2 + movdqa %9, m%3 + movdqa m%2, %10 + SBUTTERFLY dq, %2, %4, %3 + SBUTTERFLY dq, %5, %7, %3 + SBUTTERFLY dq, %6, %8, %3 + SBUTTERFLY qdq, %1, %5, %3 + SBUTTERFLY qdq, %2, %6, %3 + movdqa %10, m%2 + movdqa m%3, %9 + SBUTTERFLY qdq, %3, %7, %2 + SBUTTERFLY qdq, %4, %8, %2 + SWAP %2, %5 + SWAP %4, %7 +%if %0<11 + movdqa m%5, %10 +%endif +%endif +%endmacro + +%macro TRANSPOSE16x16W 18-19 +; in: m0..m15, unless %19 in which case m6 is in %17 +; out: m0..m15, unless %19 in which case m4 is in %18 +; spills into %17 and %18 +%if %0 < 19 + mova %17, m%7 +%endif + + SBUTTERFLY dqqq, %1, %9, %7 + SBUTTERFLY dqqq, %2, %10, %7 + SBUTTERFLY dqqq, %3, %11, %7 + SBUTTERFLY dqqq, %4, %12, %7 + SBUTTERFLY dqqq, %5, %13, %7 + SBUTTERFLY dqqq, %6, %14, %7 + mova %18, m%14 + mova m%7, %17 + SBUTTERFLY dqqq, %7, %15, %14 + SBUTTERFLY dqqq, %8, %16, %14 + + SBUTTERFLY wd, %1, %2, %14 + SBUTTERFLY wd, %3, %4, %14 + SBUTTERFLY wd, %5, %6, %14 + SBUTTERFLY wd, %7, %8, %14 + SBUTTERFLY wd, %9, %10, %14 + SBUTTERFLY wd, %11, %12, %14 + mova %17, m%12 + mova m%14, %18 + SBUTTERFLY wd, %13, %14, %12 + SBUTTERFLY wd, %15, %16, %12 + + SBUTTERFLY dq, %1, %3, %12 + SBUTTERFLY dq, %2, %4, %12 + SBUTTERFLY dq, %5, %7, %12 + SBUTTERFLY dq, %6, %8, %12 + SBUTTERFLY dq, %9, %11, %12 + mova %18, m%11 + mova m%12, %17 + SBUTTERFLY dq, %10, %12, %11 + SBUTTERFLY dq, %13, %15, %11 + SBUTTERFLY dq, %14, %16, %11 + + SBUTTERFLY qdq, %1, %5, %11 + SBUTTERFLY qdq, %2, %6, %11 + SBUTTERFLY qdq, %3, %7, %11 + SBUTTERFLY qdq, %4, %8, %11 + + SWAP %2, %5 + SWAP %4, %7 + + SBUTTERFLY qdq, %9, %13, %11 + SBUTTERFLY qdq, %10, %14, %11 + mova m%11, %18 + mova %18, m%5 + SBUTTERFLY qdq, %11, %15, %5 + SBUTTERFLY qdq, %12, %16, %5 + +%if %0 < 19 + mova m%5, %18 +%endif + + SWAP %10, %13 + SWAP %12, %15 +%endmacro + +%macro TRANSPOSE_8X8B 8 + %if mmsize == 8 + %error "This macro does not support mmsize == 8" + %endif + punpcklbw m%1, m%2 + punpcklbw m%3, m%4 + punpcklbw m%5, m%6 + punpcklbw m%7, m%8 + TRANSPOSE4x4W %1, %3, %5, %7, %2 + MOVHL m%2, m%1 + MOVHL m%4, m%3 + MOVHL m%6, m%5 + MOVHL m%8, m%7 +%endmacro + +; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place +%macro PABSW 2 +%if cpuflag(ssse3) + pabsw %1, %2 +%elif cpuflag(mmxext) + pxor %1, %1 + psubw %1, %2 + pmaxsw %1, %2 +%else + pxor %1, %1 + pcmpgtw %1, %2 + pxor %2, %1 + psubw %2, %1 + SWAP %1, %2 +%endif +%endmacro + +%macro PSIGNW 2 +%if cpuflag(ssse3) + psignw %1, %2 +%else + pxor %1, %2 + psubw %1, %2 +%endif +%endmacro + +%macro ABS1 2 +%if cpuflag(ssse3) + pabsw %1, %1 +%elif cpuflag(mmxext) ; a, tmp + pxor %2, %2 + psubw %2, %1 + pmaxsw %1, %2 +%else ; a, tmp + pxor %2, %2 + pcmpgtw %2, %1 + pxor %1, %2 + psubw %1, %2 +%endif +%endmacro + +%macro ABS2 4 +%if cpuflag(ssse3) + pabsw %1, %1 + pabsw %2, %2 +%elif cpuflag(mmxext) ; a, b, tmp0, tmp1 + pxor %3, %3 + pxor %4, %4 + psubw %3, %1 + psubw %4, %2 + pmaxsw %1, %3 + pmaxsw %2, %4 +%else ; a, b, tmp0, tmp1 + pxor %3, %3 + pxor %4, %4 + pcmpgtw %3, %1 + pcmpgtw %4, %2 + pxor %1, %3 + pxor %2, %4 + psubw %1, %3 + psubw %2, %4 +%endif +%endmacro + +%macro ABSB 2 ; source mmreg, temp mmreg (unused for SSSE3) +%if cpuflag(ssse3) + pabsb %1, %1 +%else + pxor %2, %2 + psubb %2, %1 + pminub %1, %2 +%endif +%endmacro + +%macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3) +%if cpuflag(ssse3) + pabsb %1, %1 + pabsb %2, %2 +%else + pxor %3, %3 + pxor %4, %4 + psubb %3, %1 + psubb %4, %2 + pminub %1, %3 + pminub %2, %4 +%endif +%endmacro + +%macro ABSD2 4 + pxor %3, %3 + pxor %4, %4 + pcmpgtd %3, %1 + pcmpgtd %4, %2 + pxor %1, %3 + pxor %2, %4 + psubd %1, %3 + psubd %2, %4 +%endmacro + +%macro ABS4 6 + ABS2 %1, %2, %5, %6 + ABS2 %3, %4, %5, %6 +%endmacro + +%macro SPLATB_LOAD 3 +%if cpuflag(ssse3) + movd %1, [%2-3] + pshufb %1, %3 +%else + movd %1, [%2-3] ;to avoid crossing a cacheline + punpcklbw %1, %1 + SPLATW %1, %1, 3 +%endif +%endmacro + +%macro SPLATB_REG 3 +%if cpuflag(ssse3) + movd %1, %2d + pshufb %1, %3 +%else + movd %1, %2d + punpcklbw %1, %1 + SPLATW %1, %1, 0 +%endif +%endmacro + +%macro HADDD 2 ; sum junk +%if sizeof%1 == 32 +%define %2 xmm%2 + vextracti128 %2, %1, 1 +%define %1 xmm%1 + paddd %1, %2 +%endif +%if mmsize >= 16 +%if cpuflag(xop) && sizeof%1 == 16 + vphadddq %1, %1 +%endif + movhlps %2, %1 + paddd %1, %2 +%endif +%if notcpuflag(xop) || sizeof%1 != 16 +%if cpuflag(mmxext) + PSHUFLW %2, %1, q0032 +%else ; mmx + mova %2, %1 + psrlq %2, 32 +%endif + paddd %1, %2 +%endif +%undef %1 +%undef %2 +%endmacro + +%macro HADDW 2 ; reg, tmp +%if cpuflag(xop) && sizeof%1 == 16 + vphaddwq %1, %1 + movhlps %2, %1 + paddd %1, %2 +%else + pmaddwd %1, [pw_1] + HADDD %1, %2 +%endif +%endmacro + +%macro HADDPS 3 ; dst, src, tmp +%if cpuflag(sse3) + haddps %1, %1, %2 +%else + movaps %3, %1 + shufps %1, %2, q2020 + shufps %3, %2, q3131 + addps %1, %3 +%endif +%endmacro + +%macro PALIGNR 4-5 +%if cpuflag(ssse3) +%if %0==5 + palignr %1, %2, %3, %4 +%else + palignr %1, %2, %3 +%endif +%else ; [dst,] src1, src2, imm, tmp + %define %%dst %1 +%if %0==5 +%ifnidn %1, %2 + mova %%dst, %2 +%endif + %rotate 1 +%endif +%ifnidn %4, %2 + mova %4, %2 +%endif +%if mmsize==8 + psllq %%dst, (8-%3)*8 + psrlq %4, %3*8 +%else + pslldq %%dst, 16-%3 + psrldq %4, %3 +%endif + por %%dst, %4 +%endif +%endmacro + +%macro PAVGB 2-4 +%if cpuflag(mmxext) + pavgb %1, %2 +%elif cpuflag(3dnow) + pavgusb %1, %2 +%elif cpuflag(mmx) + movu %3, %2 + por %3, %1 + pxor %1, %2 + pand %1, %4 + psrlq %1, 1 + psubb %3, %1 + SWAP %1, %3 +%endif +%endmacro + +%macro PSHUFLW 1+ + %if mmsize == 8 + pshufw %1 + %else + pshuflw %1 + %endif +%endmacro + +%macro PSWAPD 2 +%if cpuflag(mmxext) + pshufw %1, %2, q1032 +%elif cpuflag(3dnowext) + pswapd %1, %2 +%elif cpuflag(3dnow) + movq %1, %2 + psrlq %1, 32 + punpckldq %1, %2 +%endif +%endmacro + +%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from +%ifnum %5 + pand m%3, m%5, m%4 ; src .. y6 .. y4 + pand m%1, m%5, m%2 ; dst .. y6 .. y4 +%else + mova m%1, %5 + pand m%3, m%1, m%4 ; src .. y6 .. y4 + pand m%1, m%1, m%2 ; dst .. y6 .. y4 +%endif + psrlw m%2, 8 ; dst .. y7 .. y5 + psrlw m%4, 8 ; src .. y7 .. y5 +%endmacro + +%macro SUMSUB_BA 3-4 +%if %0==3 + padd%1 m%2, m%3 + padd%1 m%3, m%3 + psub%1 m%3, m%2 +%else +%if avx_enabled == 0 + mova m%4, m%2 + padd%1 m%2, m%3 + psub%1 m%3, m%4 +%else + padd%1 m%4, m%2, m%3 + psub%1 m%3, m%2 + SWAP %2, %4 +%endif +%endif +%endmacro + +%macro SUMSUB_BADC 5-6 +%if %0==6 + SUMSUB_BA %1, %2, %3, %6 + SUMSUB_BA %1, %4, %5, %6 +%else + padd%1 m%2, m%3 + padd%1 m%4, m%5 + padd%1 m%3, m%3 + padd%1 m%5, m%5 + psub%1 m%3, m%2 + psub%1 m%5, m%4 +%endif +%endmacro + +%macro SUMSUB2_AB 4 +%ifnum %3 + psub%1 m%4, m%2, m%3 + psub%1 m%4, m%3 + padd%1 m%2, m%2 + padd%1 m%2, m%3 +%else + mova m%4, m%2 + padd%1 m%2, m%2 + padd%1 m%2, %3 + psub%1 m%4, %3 + psub%1 m%4, %3 +%endif +%endmacro + +%macro SUMSUB2_BA 4 +%if avx_enabled == 0 + mova m%4, m%2 + padd%1 m%2, m%3 + padd%1 m%2, m%3 + psub%1 m%3, m%4 + psub%1 m%3, m%4 +%else + padd%1 m%4, m%2, m%3 + padd%1 m%4, m%3 + psub%1 m%3, m%2 + psub%1 m%3, m%2 + SWAP %2, %4 +%endif +%endmacro + +%macro SUMSUBD2_AB 5 +%ifnum %4 + psra%1 m%5, m%2, 1 ; %3: %3>>1 + psra%1 m%4, m%3, 1 ; %2: %2>>1 + padd%1 m%4, m%2 ; %3: %3>>1+%2 + psub%1 m%5, m%3 ; %2: %2>>1-%3 + SWAP %2, %5 + SWAP %3, %4 +%else + mova %5, m%2 + mova %4, m%3 + psra%1 m%3, 1 ; %3: %3>>1 + psra%1 m%2, 1 ; %2: %2>>1 + padd%1 m%3, %5 ; %3: %3>>1+%2 + psub%1 m%2, %4 ; %2: %2>>1-%3 +%endif +%endmacro + +%macro DCT4_1D 5 +%ifnum %5 + SUMSUB_BADC w, %4, %1, %3, %2, %5 + SUMSUB_BA w, %3, %4, %5 + SUMSUB2_AB w, %1, %2, %5 + SWAP %1, %3, %4, %5, %2 +%else + SUMSUB_BADC w, %4, %1, %3, %2 + SUMSUB_BA w, %3, %4 + mova [%5], m%2 + SUMSUB2_AB w, %1, [%5], %2 + SWAP %1, %3, %4, %2 +%endif +%endmacro + +%macro IDCT4_1D 6-7 +%ifnum %6 + SUMSUBD2_AB %1, %3, %5, %7, %6 + ; %3: %3>>1-%5 %5: %3+%5>>1 + SUMSUB_BA %1, %4, %2, %7 + ; %4: %2+%4 %2: %2-%4 + SUMSUB_BADC %1, %5, %4, %3, %2, %7 + ; %5: %2+%4 + (%3+%5>>1) + ; %4: %2+%4 - (%3+%5>>1) + ; %3: %2-%4 + (%3>>1-%5) + ; %2: %2-%4 - (%3>>1-%5) +%else +%ifidn %1, w + SUMSUBD2_AB %1, %3, %5, [%6], [%6+16] +%else + SUMSUBD2_AB %1, %3, %5, [%6], [%6+32] +%endif + SUMSUB_BA %1, %4, %2 + SUMSUB_BADC %1, %5, %4, %3, %2 +%endif + SWAP %2, %5, %4 + ; %2: %2+%4 + (%3+%5>>1) row0 + ; %3: %2-%4 + (%3>>1-%5) row1 + ; %4: %2-%4 - (%3>>1-%5) row2 + ; %5: %2+%4 - (%3+%5>>1) row3 +%endmacro + + +%macro LOAD_DIFF 5 +%ifidn %3, none + movh %1, %4 + movh %2, %5 + punpcklbw %1, %2 + punpcklbw %2, %2 + psubw %1, %2 +%else + movh %1, %4 + punpcklbw %1, %3 + movh %2, %5 + punpcklbw %2, %3 + psubw %1, %2 +%endif +%endmacro + +%macro STORE_DCT 6 + movq [%5+%6+ 0], m%1 + movq [%5+%6+ 8], m%2 + movq [%5+%6+16], m%3 + movq [%5+%6+24], m%4 + movhps [%5+%6+32], m%1 + movhps [%5+%6+40], m%2 + movhps [%5+%6+48], m%3 + movhps [%5+%6+56], m%4 +%endmacro + +%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment? + LOAD_DIFF m%1, m%5, m%7, [%8], [%9] + LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3] + LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3] + LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5] +%if %10 + lea %8, [%8+4*r1] + lea %9, [%9+4*r3] +%endif +%endmacro + +%macro DIFFx2 6-7 + movh %3, %5 + punpcklbw %3, %4 + psraw %1, 6 + paddsw %1, %3 + movh %3, %6 + punpcklbw %3, %4 + psraw %2, 6 + paddsw %2, %3 + packuswb %2, %1 +%endmacro + +%macro STORE_DIFF 4 + movh %2, %4 + punpcklbw %2, %3 + psraw %1, 6 + paddsw %1, %2 + packuswb %1, %1 + movh %4, %1 +%endmacro + +%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride + movh %3, [%7] + movh %4, [%7+%8] + psraw %1, %6 + psraw %2, %6 + punpcklbw %3, %5 + punpcklbw %4, %5 + paddw %3, %1 + paddw %4, %2 + packuswb %3, %5 + packuswb %4, %5 + movh [%7], %3 + movh [%7+%8], %4 +%endmacro + +%macro PMINUB 3 ; dst, src, ignored +%if cpuflag(mmxext) + pminub %1, %2 +%else ; dst, src, tmp + mova %3, %1 + psubusb %3, %2 + psubb %1, %3 +%endif +%endmacro + +%macro SPLATW 2-3 0 +%if cpuflag(avx2) && %3 == 0 + vpbroadcastw %1, %2 +%elif mmsize == 16 + pshuflw %1, %2, (%3)*0x55 + punpcklqdq %1, %1 +%elif cpuflag(mmxext) + pshufw %1, %2, (%3)*0x55 +%else + %ifnidn %1, %2 + mova %1, %2 + %endif + %if %3 & 2 + punpckhwd %1, %1 + %else + punpcklwd %1, %1 + %endif + %if %3 & 1 + punpckhwd %1, %1 + %else + punpcklwd %1, %1 + %endif +%endif +%endmacro + +%macro SPLATD 1 +%if mmsize == 8 + punpckldq %1, %1 +%elif cpuflag(sse2) + pshufd %1, %1, 0 +%elif cpuflag(sse) + shufps %1, %1, 0 +%endif +%endmacro + +%macro CLIPUB 3 ;(dst, min, max) + pmaxub %1, %2 + pminub %1, %3 +%endmacro + +%macro CLIPW 3 ;(dst, min, max) + pmaxsw %1, %2 + pminsw %1, %3 +%endmacro + +%macro PMINSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pminsd %1, %2 +%elif cpuflag(sse2) + cvtdq2ps %1, %1 + minps %1, %2 + cvtps2dq %1, %1 +%else + mova %3, %2 + pcmpgtd %3, %1 + pxor %1, %2 + pand %1, %3 + pxor %1, %2 +%endif +%endmacro + +%macro PMAXSD 3 ; dst, src, tmp/unused +%if cpuflag(sse4) + pmaxsd %1, %2 +%else + mova %3, %1 + pcmpgtd %3, %2 + pand %1, %3 + pandn %3, %2 + por %1, %3 +%endif +%endmacro + +%macro CLIPD 3-4 +%if cpuflag(sse4); src/dst, min, max, unused + pminsd %1, %3 + pmaxsd %1, %2 +%elif cpuflag(sse2) ; src/dst, min (float), max (float), unused + cvtdq2ps %1, %1 + minps %1, %3 + maxps %1, %2 + cvtps2dq %1, %1 +%else ; src/dst, min, max, tmp + PMINSD %1, %3, %4 + PMAXSD %1, %2, %4 +%endif +%endmacro + +%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vbroadcastss %1, %2 +%elif cpuflag(avx) + %ifnum sizeof%2 ; avx1 register + shufps xmm%1, xmm%2, xmm%2, q0000 + %if sizeof%1 >= 32 ; mmsize>=32 + vinsertf128 %1, %1, xmm%1, 1 + %endif + %else ; avx1 memory + vbroadcastss %1, %2 + %endif +%else + %ifnum sizeof%2 ; sse register + shufps %1, %2, %2, q0000 + %else ; sse memory + movss %1, %2 + shufps %1, %1, 0 + %endif +%endif +%endmacro + +%macro VBROADCASTSD 2 ; dst xmm/ymm, src m64 +%if cpuflag(avx) && mmsize == 32 + vbroadcastsd %1, %2 +%elif cpuflag(sse3) + movddup %1, %2 +%else ; sse2 + movsd %1, %2 + movlhps %1, %1 +%endif +%endmacro + +%macro VPBROADCASTD 2 ; dst xmm/ymm, src m32/xmm +%if cpuflag(avx2) + vpbroadcastd %1, %2 +%elif cpuflag(avx) && sizeof%1 >= 32 + %error vpbroadcastd not possible with ymm on avx1. try vbroadcastss +%else + %ifnum sizeof%2 ; sse2 register + pshufd %1, %2, q0000 + %else ; sse memory + movd %1, %2 + pshufd %1, %1, 0 + %endif +%endif +%endmacro + +%macro VBROADCASTI128 2 ; dst xmm/ymm, src : 128bits val +%if mmsize > 16 + vbroadcasti128 %1, %2 +%else + mova %1, %2 +%endif +%endmacro + +%macro SHUFFLE_MASK_W 8 + %rep 8 + %if %1>=0x80 + db %1, %1 + %else + db %1*2 + db %1*2+1 + %endif + %rotate 1 + %endrep +%endmacro + +%macro PMOVSXWD 2; dst, src +%if cpuflag(sse4) + pmovsxwd %1, %2 +%else + %ifnidn %1, %2 + mova %1, %2 + %endif + punpcklwd %1, %1 + psrad %1, 16 +%endif +%endmacro + +; Wrapper for non-FMA version of fmaddps +%macro FMULADD_PS 5 + %if cpuflag(fma3) || cpuflag(fma4) + fmaddps %1, %2, %3, %4 + %elifidn %1, %4 + mulps %5, %2, %3 + addps %1, %4, %5 + %else + mulps %1, %2, %3 + addps %1, %4 + %endif +%endmacro + +%macro LSHIFT 2 +%if mmsize > 8 + pslldq %1, %2 +%else + psllq %1, 8*(%2) +%endif +%endmacro + +%macro RSHIFT 2 +%if mmsize > 8 + psrldq %1, %2 +%else + psrlq %1, 8*(%2) +%endif +%endmacro + +%macro MOVHL 2 ; dst, src +%ifidn %1, %2 + punpckhqdq %1, %2 +%elif cpuflag(avx) + punpckhqdq %1, %2, %2 +%elif cpuflag(sse4) + pshufd %1, %2, q3232 ; pshufd is slow on some older CPUs, so only use it on more modern ones +%else + movhlps %1, %2 ; may cause an int/float domain transition and has a dependency on dst +%endif +%endmacro + +; Horizontal Sum of Packed Single precision floats +; The resulting sum is in all elements. +%macro HSUMPS 2 ; dst/src, tmp +%if cpuflag(avx) + %if sizeof%1>=32 ; avx + vperm2f128 %2, %1, %1, (0)*16+(1) + addps %1, %2 + %endif + shufps %2, %1, %1, q1032 + addps %1, %2 + shufps %2, %1, %1, q0321 + addps %1, %2 +%else ; this form is a bit faster than the short avx-like emulation. + movaps %2, %1 + shufps %1, %1, q1032 + addps %1, %2 + movaps %2, %1 + shufps %1, %1, q0321 + addps %1, %2 + ; all %1 members should be equal for as long as float a+b==b+a +%endif +%endmacro + +; Emulate blendvps if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro BLENDVPS 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + blendvps %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 blendvps uses xmm0 as default 3d operand, you used %3 + %endif + blendvps %1, %2, %3 +%else + xorps %2, %1 + andps %2, %3 + xorps %1, %2 +%endif +%endmacro + +; Emulate pblendvb if not available +; +; src_b is destroyed when using emulation with logical operands +; SSE41 blendv instruction is hard coded to use xmm0 as mask +%macro PBLENDVB 3 ; dst/src_a, src_b, mask +%if cpuflag(avx) + %if cpuflag(avx) && notcpuflag(avx2) && sizeof%1 >= 32 + %error pblendb not possible with ymm on avx1, try blendvps. + %endif + pblendvb %1, %1, %2, %3 +%elif cpuflag(sse4) + %ifnidn %3,xmm0 + %error sse41 pblendvd uses xmm0 as default 3d operand, you used %3 + %endif + pblendvb %1, %2, %3 +%else + pxor %2, %1 + pand %2, %3 + pxor %1, %2 +%endif +%endmacro