aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/x86/ac3dsp.asm
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2011-02-13 14:49:50 -0500
committerRonald S. Bultje <rsbultje@gmail.com>2011-02-13 16:49:39 -0500
commitfbb6b49dabc3398440c6dfa838aa090a7a6ebc0d (patch)
tree050f0baf5915823f816682340bde83417541854c /libavcodec/x86/ac3dsp.asm
parent1a973feb45826a1998b4286ecfe1fa7a602b8780 (diff)
downloadffmpeg-fbb6b49dabc3398440c6dfa838aa090a7a6ebc0d.tar.gz
ac3enc: Add x86-optimized function to speed up log2_tab().
AC3DSPContext.ac3_max_msb_abs_int16() finds the maximum MSB of the absolute value of each element in an array of int16_t. Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libavcodec/x86/ac3dsp.asm')
-rw-r--r--libavcodec/x86/ac3dsp.asm69
1 files changed, 69 insertions, 0 deletions
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm
index e71c51cf33..dc71ccf91c 100644
--- a/libavcodec/x86/ac3dsp.asm
+++ b/libavcodec/x86/ac3dsp.asm
@@ -65,3 +65,72 @@ AC3_EXPONENT_MIN sse2
%endif
%undef PMINUB
%undef LOOP_ALIGN
+
+;-----------------------------------------------------------------------------
+; int ff_ac3_max_msb_abs_int16(const int16_t *src, int len)
+;
+; This function uses 2 different methods to calculate a valid result.
+; 1) logical 'or' of abs of each element
+; This is used for ssse3 because of the pabsw instruction.
+; It is also used for mmx because of the lack of min/max instructions.
+; 2) calculate min/max for the array, then or(abs(min),abs(max))
+; This is used for mmxext and sse2 because they have pminsw/pmaxsw.
+;-----------------------------------------------------------------------------
+
+%macro AC3_MAX_MSB_ABS_INT16 2
+cglobal ac3_max_msb_abs_int16_%1, 2,2,5, src, len
+ pxor m2, m2
+ pxor m3, m3
+.loop:
+%ifidn %2, min_max
+ mova m0, [srcq]
+ mova m1, [srcq+mmsize]
+ pminsw m2, m0
+ pminsw m2, m1
+ pmaxsw m3, m0
+ pmaxsw m3, m1
+%else ; or_abs
+%ifidn %1, mmx
+ mova m0, [srcq]
+ mova m1, [srcq+mmsize]
+ ABS2 m0, m1, m3, m4
+%else ; ssse3
+ ; using memory args is faster for ssse3
+ pabsw m0, [srcq]
+ pabsw m1, [srcq+mmsize]
+%endif
+ por m2, m0
+ por m2, m1
+%endif
+ add srcq, mmsize*2
+ sub lend, mmsize
+ ja .loop
+%ifidn %2, min_max
+ ABS2 m2, m3, m0, m1
+ por m2, m3
+%endif
+%ifidn mmsize, 16
+ mova m0, m2
+ punpckhqdq m0, m0
+ por m2, m0
+%endif
+ PSHUFLW m0, m2, 0xe
+ por m2, m0
+ PSHUFLW m0, m2, 0x1
+ por m2, m0
+ movd eax, m2
+ and eax, 0xFFFF
+ RET
+%endmacro
+
+INIT_MMX
+%define ABS2 ABS2_MMX
+%define PSHUFLW pshufw
+AC3_MAX_MSB_ABS_INT16 mmx, or_abs
+%define ABS2 ABS2_MMX2
+AC3_MAX_MSB_ABS_INT16 mmxext, min_max
+INIT_XMM
+%define PSHUFLW pshuflw
+AC3_MAX_MSB_ABS_INT16 sse2, min_max
+%define ABS2 ABS2_SSSE3
+AC3_MAX_MSB_ABS_INT16 ssse3, or_abs