Unified · Split
| @@ -62,6 +62,7 @@ YASM-OBJS-$(CONFIG_RV40_DECODER) += x86/rv34dsp.o \ · 61 unmodified lines | |||
| 62 | x86/rv40dsp.o | 62 | x86/rv40dsp.o |
| 63 | YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp.o | 63 | YASM-OBJS-$(CONFIG_VC1_DECODER) += x86/vc1dsp.o |
| 64 | YASM-OBJS-$(CONFIG_VIDEODSP) += x86/videodsp.o | 64 | YASM-OBJS-$(CONFIG_VIDEODSP) += x86/videodsp.o |
| 65 | YASM-OBJS-$(CONFIG_VORBIS_DECODER) += x86/vorbisdsp.o | ||
| 65 | YASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o | 66 | YASM-OBJS-$(CONFIG_VP3DSP) += x86/vp3dsp.o |
| 66 | YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp56dsp.o | 67 | YASM-OBJS-$(CONFIG_VP6_DECODER) += x86/vp56dsp.o |
| 67 | YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o | 68 | YASM-OBJS-$(CONFIG_VP8_DECODER) += x86/vp8dsp.o |
| @@ -38,9 +38,6 @@ · 37 unmodified lines | |||
| 38 | DECLARE_ALIGNED(8, const uint64_t, ff_bone) = 0x0101010101010101ULL; | 38 | DECLARE_ALIGNED(8, const uint64_t, ff_bone) = 0x0101010101010101ULL; |
| 39 | DECLARE_ALIGNED(8, const uint64_t, ff_wtwo) = 0x0002000200020002ULL; | 39 | DECLARE_ALIGNED(8, const uint64_t, ff_wtwo) = 0x0002000200020002ULL; |
| 40 | 40 | ||
| 41 | DECLARE_ALIGNED(16, const uint64_t, ff_pdw_80000000)[2] = | ||
| 42 | { 0x8000000080000000ULL, 0x8000000080000000ULL }; | ||
| 43 | |||
| 44 | DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1) = { 0x0001000100010001ULL, 0x0001000100010001ULL }; | 41 | DECLARE_ALIGNED(16, const xmm_reg, ff_pw_1) = { 0x0001000100010001ULL, 0x0001000100010001ULL }; |
| 45 | DECLARE_ALIGNED(16, const xmm_reg, ff_pw_2) = { 0x0002000200020002ULL, 0x0002000200020002ULL }; | 42 | DECLARE_ALIGNED(16, const xmm_reg, ff_pw_2) = { 0x0002000200020002ULL, 0x0002000200020002ULL }; |
| 46 | DECLARE_ALIGNED(16, const xmm_reg, ff_pw_3) = { 0x0003000300030003ULL, 0x0003000300030003ULL }; | 43 | DECLARE_ALIGNED(16, const xmm_reg, ff_pw_3) = { 0x0003000300030003ULL, 0x0003000300030003ULL }; |
| @@ -31,8 +31,6 @@ typedef struct xmm_reg { uint64_t a, b; } xmm_reg; · 30 unmodified lines | |||
| 31 | extern const uint64_t ff_bone; | 31 | extern const uint64_t ff_bone; |
| 32 | extern const uint64_t ff_wtwo; | 32 | extern const uint64_t ff_wtwo; |
| 33 | 33 | ||
| 34 | extern const uint64_t ff_pdw_80000000[2]; | ||
| 35 | |||
| 36 | extern const xmm_reg ff_pw_3; | 34 | extern const xmm_reg ff_pw_3; |
| 37 | extern const xmm_reg ff_pw_4; | 35 | extern const xmm_reg ff_pw_4; |
| 38 | extern const xmm_reg ff_pw_5; | 36 | extern const xmm_reg ff_pw_5; |
| @@ -0,0 +1,83 @@ | |||
| 1 | ;****************************************************************************** | ||
| 2 | ;* Vorbis x86 optimizations | ||
| 3 | ;* Copyright (C) 2006 Loren Merritt <lorenm@u.washington.edu> | ||
| 4 | ;* | ||
| 5 | ;* This file is part of Libav. | ||
| 6 | ;* | ||
| 7 | ;* Libav is free software; you can redistribute it and/or | ||
| 8 | ;* modify it under the terms of the GNU Lesser General Public | ||
| 9 | ;* License as published by the Free Software Foundation; either | ||
| 10 | ;* version 2.1 of the License, or (at your option) any later version. | ||
| 11 | ;* | ||
| 12 | ;* Libav is distributed in the hope that it will be useful, | ||
| 13 | ;* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 15 | ;* Lesser General Public License for more details. | ||
| 16 | ;* | ||
| 17 | ;* You should have received a copy of the GNU Lesser General Public | ||
| 18 | ;* License along with Libav; if not, write to the Free Software | ||
| 19 | ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | ;****************************************************************************** | ||
| 21 | |||
| 22 | %include "libavutil/x86/x86util.asm" | ||
| 23 | |||
| 24 | SECTION_RODATA | ||
| 25 | |||
| 26 | pdw_80000000: times 4 dd 0x80000000 | ||
| 27 | |||
| 28 | SECTION .text | ||
| 29 | |||
| 30 | %if ARCH_X86_32 | ||
| 31 | INIT_MMX 3dnow | ||
| 32 | cglobal vorbis_inverse_coupling, 3, 3, 6, mag, ang, block_size | ||
| 33 | pxor m7, m7 | ||
| 34 | lea magq, [magq+block_sizeq*4] | ||
| 35 | lea angq, [angq+block_sizeq*4] | ||
| 36 | neg block_sizeq | ||
| 37 | .loop: | ||
| 38 | mova m0, [magq+block_sizeq*4] | ||
| 39 | mova m1, [angq+block_sizeq*4] | ||
| 40 | mova m2, m0 | ||
| 41 | mova m3, m1 | ||
| 42 | pfcmpge m2, m7 ; m <= 0.0 | ||
| 43 | pfcmpge m3, m7 ; a <= 0.0 | ||
| 44 | pslld m2, 31 ; keep only the sign bit | ||
| 45 | pxor m1, m2 | ||
| 46 | mova m4, m3 | ||
| 47 | pand m3, m1 | ||
| 48 | pandn m4, m1 | ||
| 49 | pfadd m3, m0 ; a = m + ((a < 0) & (a ^ sign(m))) | ||
| 50 | pfsub m0, m4 ; m = m + ((a > 0) & (a ^ sign(m))) | ||
| 51 | mova [angq+block_sizeq*4], m3 | ||
| 52 | mova [magq+block_sizeq*4], m0 | ||
| 53 | add block_sizeq, 2 | ||
| 54 | jl .loop | ||
| 55 | femms | ||
| 56 | RET | ||
| 57 | %endif | ||
| 58 | |||
| 59 | INIT_XMM sse | ||
| 60 | cglobal vorbis_inverse_coupling, 3, 4, 6, mag, ang, block_size, cntr | ||
| 61 | mova m5, [pdw_80000000] | ||
| 62 | xor cntrq, cntrq | ||
| 63 | align 16 | ||
| 64 | .loop: | ||
| 65 | mova m0, [magq+cntrq*4] | ||
| 66 | mova m1, [angq+cntrq*4] | ||
| 67 | xorps m2, m2 | ||
| 68 | xorps m3, m3 | ||
| 69 | cmpleps m2, m0 ; m <= 0.0 | ||
| 70 | cmpleps m3, m1 ; a <= 0.0 | ||
| 71 | andps m2, m5 ; keep only the sign bit | ||
| 72 | xorps m1, m2 | ||
| 73 | mova m4, m3 | ||
| 74 | andps m3, m1 | ||
| 75 | andnps m4, m1 | ||
| 76 | addps m3, m0 ; a = m + ((a < 0) & (a ^ sign(m))) | ||
| 77 | subps m0, m4 ; m = m + ((a > 0) & (a ^ sign(m))) | ||
| 78 | mova [angq+cntrq*4], m3 | ||
| 79 | mova [magq+cntrq*4], m0 | ||
| 80 | add cntrq, 4 | ||
| 81 | cmp cntrq, block_sizeq | ||
| 82 | jl .loop | ||
| 83 | RET | ||
| @@ -21,83 +21,22 @@ · 20 unmodified lines | |||
| 21 | #include "config.h" | 21 | #include "config.h" |
| 22 | #include "libavutil/cpu.h" | 22 | #include "libavutil/cpu.h" |
| 23 | #include "libavcodec/vorbisdsp.h" | 23 | #include "libavcodec/vorbisdsp.h" |
| 24 | #include "dsputil_mmx.h" // for ff_pdw_80000000 | ||
| 25 | 24 | ||
| 26 | #if HAVE_INLINE_ASM | 25 | void ff_vorbis_inverse_coupling_3dnow(float *mag, float *ang, |
| 27 | #if ARCH_X86_32 | 26 | intptr_t blocksize); |
| 28 | static void vorbis_inverse_coupling_3dnow(float *mag, float *ang, | 27 | void ff_vorbis_inverse_coupling_sse(float *mag, float *ang, |
| 29 | intptr_t blocksize) | 28 | intptr_t blocksize); |
| 30 | { | ||
| 31 | int i; | ||
| 32 | __asm__ volatile ("pxor %%mm7, %%mm7":); | ||
| 33 | for (i = 0; i < blocksize; i += 2) { | ||
| 34 | __asm__ volatile ( | ||
| 35 | "movq %0, %%mm0 \n\t" | ||
| 36 | "movq %1, %%mm1 \n\t" | ||
| 37 | "movq %%mm0, %%mm2 \n\t" | ||
| 38 | "movq %%mm1, %%mm3 \n\t" | ||
| 39 | "pfcmpge %%mm7, %%mm2 \n\t" // m <= 0.0 | ||
| 40 | "pfcmpge %%mm7, %%mm3 \n\t" // a <= 0.0 | ||
| 41 | "pslld $31, %%mm2 \n\t" // keep only the sign bit | ||
| 42 | "pxor %%mm2, %%mm1 \n\t" | ||
| 43 | "movq %%mm3, %%mm4 \n\t" | ||
| 44 | "pand %%mm1, %%mm3 \n\t" | ||
| 45 | "pandn %%mm1, %%mm4 \n\t" | ||
| 46 | "pfadd %%mm0, %%mm3 \n\t" // a = m + ((a < 0) & (a ^ sign(m))) | ||
| 47 | "pfsub %%mm4, %%mm0 \n\t" // m = m + ((a > 0) & (a ^ sign(m))) | ||
| 48 | "movq %%mm3, %1 \n\t" | ||
| 49 | "movq %%mm0, %0 \n\t" | ||
| 50 | : "+m"(mag[i]), "+m"(ang[i]) | ||
| 51 | :: "memory" | ||
| 52 | ); | ||
| 53 | } | ||
| 54 | __asm__ volatile ("femms"); | ||
| 55 | } | ||
| 56 | #endif | ||
| 57 | |||
| 58 | static void vorbis_inverse_coupling_sse(float *mag, float *ang, | ||
| 59 | intptr_t blocksize) | ||
| 60 | { | ||
| 61 | int i; | ||
| 62 | |||
| 63 | __asm__ volatile ( | ||
| 64 | "movaps %0, %%xmm5 \n\t" | ||
| 65 | :: "m"(ff_pdw_80000000[0]) | ||
| 66 | ); | ||
| 67 | for (i = 0; i < blocksize; i += 4) { | ||
| 68 | __asm__ volatile ( | ||
| 69 | "movaps %0, %%xmm0 \n\t" | ||
| 70 | "movaps %1, %%xmm1 \n\t" | ||
| 71 | "xorps %%xmm2, %%xmm2 \n\t" | ||
| 72 | "xorps %%xmm3, %%xmm3 \n\t" | ||
| 73 | "cmpleps %%xmm0, %%xmm2 \n\t" // m <= 0.0 | ||
| 74 | "cmpleps %%xmm1, %%xmm3 \n\t" // a <= 0.0 | ||
| 75 | "andps %%xmm5, %%xmm2 \n\t" // keep only the sign bit | ||
| 76 | "xorps %%xmm2, %%xmm1 \n\t" | ||
| 77 | "movaps %%xmm3, %%xmm4 \n\t" | ||
| 78 | "andps %%xmm1, %%xmm3 \n\t" | ||
| 79 | "andnps %%xmm1, %%xmm4 \n\t" | ||
| 80 | "addps %%xmm0, %%xmm3 \n\t" // a = m + ((a < 0) & (a ^ sign(m))) | ||
| 81 | "subps %%xmm4, %%xmm0 \n\t" // m = m + ((a > 0) & (a ^ sign(m))) | ||
| 82 | "movaps %%xmm3, %1 \n\t" | ||
| 83 | "movaps %%xmm0, %0 \n\t" | ||
| 84 | : "+m"(mag[i]), "+m"(ang[i]) | ||
| 85 | :: "memory" | ||
| 86 | ); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | #endif | ||
| 90 | 29 | ||
| 91 | void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp) | 30 | void ff_vorbisdsp_init_x86(VorbisDSPContext *dsp) |
| 92 | { | 31 | { |
| 93 | #if HAVE_INLINE_ASM | 32 | #if HAVE_YASM |
| 94 | int mm_flags = av_get_cpu_flags(); | 33 | int mm_flags = av_get_cpu_flags(); |
| 95 | 34 | ||
| 96 | #if ARCH_X86_32 | 35 | #if ARCH_X86_32 |
| 97 | if (mm_flags & AV_CPU_FLAG_3DNOW) | 36 | if (mm_flags & AV_CPU_FLAG_3DNOW) |
| 98 | dsp->vorbis_inverse_coupling = vorbis_inverse_coupling_3dnow; | 37 | dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_3dnow; |
| 99 | #endif /* ARCH_X86_32 */ | 38 | #endif /* ARCH_X86_32 */ |
| 100 | if (mm_flags & AV_CPU_FLAG_SSE) | 39 | if (mm_flags & AV_CPU_FLAG_SSE) |
| 101 | dsp->vorbis_inverse_coupling = vorbis_inverse_coupling_sse; | 40 | dsp->vorbis_inverse_coupling = ff_vorbis_inverse_coupling_sse; |
| 102 | #endif /* HAVE_INLINE_ASM */ | 41 | #endif /* HAVE_YASM */ |
| 103 | } | 42 | } |