libswresample: Implement MMX, SSE4 and AVX 6ch float and int32 packing function.
authorJustin Ruggles <justin.ruggles@gmail.com>
Sun, 13 May 2012 17:09:01 +0000 (19:09 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Sun, 13 May 2012 17:31:59 +0000 (19:31 +0200)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libswresample/x86/audio_convert.asm
libswresample/x86/swresample_x86.c

index 5768405..1fa519a 100644 (file)
@@ -199,6 +199,84 @@ cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len
     REP_RET
 %endmacro
 
+%macro CONV_FLTP_TO_FLT_6CH 3
+cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
+%if ARCH_X86_64
+    mov     lend, r2d
+%else
+    %define lend dword r2m
+%endif
+    mov    src1q, [srcq+1*gprsize]
+    mov    src2q, [srcq+2*gprsize]
+    mov    src3q, [srcq+3*gprsize]
+    mov    src4q, [srcq+4*gprsize]
+    mov    src5q, [srcq+5*gprsize]
+    mov     srcq, [srcq]
+    mov     dstq, [dstq]
+    sub    src1q, srcq
+    sub    src2q, srcq
+    sub    src3q, srcq
+    sub    src4q, srcq
+    sub    src5q, srcq
+.loop:
+    mova      m0, [srcq      ]
+    mova      m1, [srcq+src1q]
+    mova      m2, [srcq+src2q]
+    mova      m3, [srcq+src3q]
+    mova      m4, [srcq+src4q]
+    mova      m5, [srcq+src5q]
+%if cpuflag(sse4)
+    SBUTTERFLYPS 0, 1, 6
+    SBUTTERFLYPS 2, 3, 6
+    SBUTTERFLYPS 4, 5, 6
+
+    blendps   m6, m4, m0, 1100b
+    movlhps   m0, m2
+    movhlps   m4, m2
+    blendps   m2, m5, m1, 1100b
+    movlhps   m1, m3
+    movhlps   m5, m3
+
+    movaps [dstq   ], m0
+    movaps [dstq+16], m6
+    movaps [dstq+32], m4
+    movaps [dstq+48], m1
+    movaps [dstq+64], m2
+    movaps [dstq+80], m5
+%else ; mmx
+    SBUTTERFLY dq, 0, 1, 6
+    SBUTTERFLY dq, 2, 3, 6
+    SBUTTERFLY dq, 4, 5, 6
+
+    movq   [dstq   ], m0
+    movq   [dstq+ 8], m2
+    movq   [dstq+16], m4
+    movq   [dstq+24], m1
+    movq   [dstq+32], m3
+    movq   [dstq+40], m5
+%endif
+    add      srcq, mmsize
+    add      dstq, mmsize*6
+    sub      lend, mmsize/4
+    jg .loop
+%if mmsize == 8
+    emms
+    RET
+%else
+    REP_RET
+%endif
+%endmacro
+
+INIT_MMX mmx
+CONV_FLTP_TO_FLT_6CH float,float,a
+INIT_XMM sse4
+CONV_FLTP_TO_FLT_6CH float,float,a
+%if HAVE_AVX
+INIT_XMM avx
+CONV_FLTP_TO_FLT_6CH float,float,a
+%endif
+
+
 %macro INT16_TO_INT32_N 0
     pxor      m2, m2
     pxor      m3, m3
index e600100..f2349b5 100644 (file)
 #define PROTO(pre, in, out, cap) void ff ## pre ## _ ##in## _to_ ##out## _a_ ##cap(uint8_t **dst, const uint8_t **src, int len);
 #define PROTO2(pre, out, cap) PROTO(pre, int16, out, cap) PROTO(pre, int32, out, cap) PROTO(pre, float, out, cap)
 #define PROTO3(pre, cap) PROTO2(pre, int16, cap) PROTO2(pre, int32, cap) PROTO2(pre, float, cap)
-#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, avx)
+#define PROTO4(pre) PROTO3(pre, mmx) PROTO3(pre, sse) PROTO3(pre, sse2) PROTO3(pre, ssse3) PROTO3(pre, sse4) PROTO3(pre, avx)
 PROTO4()
 PROTO4(_pack_2ch)
+PROTO4(_pack_6ch)
 PROTO4(_unpack_2ch)
 
 void swri_audio_convert_init_x86(struct AudioConvert *ac,
@@ -50,6 +51,13 @@ void swri_audio_convert_init_x86(struct AudioConvert *ac,
 MULTI_CAPS_FUNC(AV_CPU_FLAG_MMX, mmx)
 MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse)
 
+    if(mm_flags & AV_CPU_FLAG_MMX) {
+        if(channels == 6) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_float_to_float_a_mmx;
+        }
+    }
+
     if(mm_flags & AV_CPU_FLAG_SSE) {
         if(channels == 2) {
             if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
@@ -111,8 +119,18 @@ MULTI_CAPS_FUNC(AV_CPU_FLAG_SSE, sse)
                 ac->simd_f =  ff_unpack_2ch_int16_to_float_a_ssse3;
         }
     }
+    if(mm_flags & AV_CPU_FLAG_SSE4) {
+        if(channels == 6) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_float_to_float_a_sse4;
+        }
+    }
     if(HAVE_AVX && mm_flags & AV_CPU_FLAG_AVX) {
         if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_S32 || out_fmt == AV_SAMPLE_FMT_FLTP && in_fmt == AV_SAMPLE_FMT_S32P)
             ac->simd_f =  ff_int32_to_float_a_avx;
+        if(channels == 6) {
+            if(   out_fmt == AV_SAMPLE_FMT_FLT  && in_fmt == AV_SAMPLE_FMT_FLTP || out_fmt == AV_SAMPLE_FMT_S32 && in_fmt == AV_SAMPLE_FMT_S32P)
+                ac->simd_f =  ff_pack_6ch_float_to_float_a_avx;
+        }
     }
 }