/*
 * 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/float_dsp.h"
#include "cpu.h"

extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1,
                               int len);
extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1,
                               int len);

extern void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul,
                                      int len);
extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul,
                                      int len);

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();

    if (EXTERNAL_SSE(mm_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;
    }
    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;
    }
}
