float_dsp: add vector_dmul_scalar() to multiply a vector of doubles
authorJustin Ruggles <justin.ruggles@gmail.com>
Mon, 24 Sep 2012 19:00:53 +0000 (15:00 -0400)
committerJustin Ruggles <justin.ruggles@gmail.com>
Wed, 5 Dec 2012 16:23:36 +0000 (11:23 -0500)
Include x86-optimized versions for SSE2 and AVX.

libavutil/float_dsp.c
libavutil/float_dsp.h
libavutil/x86/float_dsp.asm
libavutil/x86/float_dsp_init.c
libavutil/x86/x86util.asm

index b6b11818b5dd10c1f65362906f1c6e9a5f8c3098..22139defe4035b73ade7454b24c6832b46f3be9a 100644 (file)
@@ -44,11 +44,20 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul,
         dst[i] = src[i] * mul;
 }
 
+static void vector_dmul_scalar_c(double *dst, const double *src, double mul,
+                                 int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        dst[i] = src[i] * mul;
+}
+
 void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact)
 {
     fdsp->vector_fmul = vector_fmul_c;
     fdsp->vector_fmac_scalar = vector_fmac_scalar_c;
     fdsp->vector_fmul_scalar = vector_fmul_scalar_c;
+    fdsp->vector_dmul_scalar = vector_dmul_scalar_c;
 
 #if ARCH_ARM
     ff_float_dsp_init_arm(fdsp);
index cb4b28f0e2bd55c08c4c1976a7a00b7f2991f003..41b73c5b265634b3ece78cb24b0e04d8ac1d3361 100644 (file)
@@ -66,6 +66,21 @@ typedef struct AVFloatDSPContext {
      */
     void (*vector_fmul_scalar)(float *dst, const float *src, float mul,
                                int len);
+
+    /**
+     * Multiply a vector of double by a scalar double.  Source and
+     * destination vectors must overlap exactly or not at all.
+     *
+     * @param dst result vector
+     *            constraints: 32-byte aligned
+     * @param src input vector
+     *            constraints: 32-byte aligned
+     * @param mul scalar value
+     * @param len length of vector
+     *            constraints: multiple of 8
+     */
+    void (*vector_dmul_scalar)(double *dst, const double *src, double mul,
+                               int len);
 } AVFloatDSPContext;
 
 /**
index 317df9c3c145fd11c8a52efdeaf84d3469f0a8a7..d8fd93a6258a5535254bc2f112b1680a1f28d0e7 100644 (file)
@@ -114,3 +114,48 @@ cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len
 
 INIT_XMM sse
 VECTOR_FMUL_SCALAR
+
+;------------------------------------------------------------------------------
+; void ff_vector_dmul_scalar(double *dst, const double *src, double mul,
+;                            int len)
+;------------------------------------------------------------------------------
+
+%macro VECTOR_DMUL_SCALAR 0
+%if 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 xmm0, mulm
+%else
+%if WIN64
+    movlhps      xmm2, xmm2
+%if cpuflag(avx)
+    vinsertf128  ymm2, ymm2, xmm2, 1
+%endif
+    SWAP 0, 2
+%else
+    movlhps      xmm0, xmm0
+%if cpuflag(avx)
+    vinsertf128  ymm0, ymm0, xmm0, 1
+%endif
+%endif
+%endif
+    lea          lenq, [lend*8-2*mmsize]
+.loop:
+    mulpd          m1, m0, [srcq+lenq       ]
+    mulpd          m2, m0, [srcq+lenq+mmsize]
+    mova   [dstq+lenq       ], m1
+    mova   [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
index d14ec6a377097cfaa2d9a8d6c71ee49ad4ac71a5..b3b7ff4c3a29698ac2a1e5c6380bc045ff55511a 100644 (file)
@@ -35,6 +35,11 @@ extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
 extern void ff_vector_fmul_scalar_sse(float *dst, const float *src, float mul,
                                       int len);
 
+extern void ff_vector_dmul_scalar_sse2(double *dst, const double *src,
+                                       double mul, int len);
+extern void ff_vector_dmul_scalar_avx(double *dst, const double *src,
+                                      double mul, int len);
+
 void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
 {
     int mm_flags = av_get_cpu_flags();
@@ -44,8 +49,12 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp)
         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse;
         fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_sse;
     }
+    if (EXTERNAL_SSE2(mm_flags)) {
+        fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_sse2;
+    }
     if (EXTERNAL_AVX(mm_flags)) {
         fdsp->vector_fmul = ff_vector_fmul_avx;
         fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx;
+        fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_avx;
     }
 }
index d3c0d86056777e29c9c9f100aed63c97d45ce4c5..16ee6cfe94d1f55127f9d017b1fbaa57916c64af 100644 (file)
 %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 SHUFFLE_MASK_W 8
     %rep 8
         %if %1>=0x80