

/* this file was generated by volk template utils, do not edit! */

/* -*- c++ -*- */
/*
 * Copyright 2011-2012 Free Software Foundation, Inc.
 *
 * This file is part of VOLK
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#include <volk/volk_cpu.h>
#include <volk/volk_config_fixed.h>
#include <stdlib.h>
#include <string.h>


#if defined(VOLK_CPU_FEATURES)
#include "cpu_features_macros.h"
#if defined(CPU_FEATURES_ARCH_X86)
#include "cpuinfo_x86.h"
#elif defined(CPU_FEATURES_ARCH_ARM)
#include "cpuinfo_arm.h"
#elif defined(CPU_FEATURES_ARCH_AARCH64)
#include "cpuinfo_aarch64.h"
#elif defined(CPU_FEATURES_ARCH_MIPS)
#include "cpuinfo_mips.h"
#elif defined(CPU_FEATURES_ARCH_PPC)
#include "cpuinfo_ppc.h"
#elif defined(CPU_FEATURES_ARCH_RISCV)
#include "cpuinfo_riscv.h"
#endif

// This is required for MSVC
#if defined(__cplusplus)
using namespace cpu_features;
#endif
#endif


struct VOLK_CPU volk_cpu;

static int i_can_has_generic (void) {
    return 1;
}

static int i_can_has_softfp (void) {
    return 1;
}

static int i_can_has_hardfp (void) {
    return 1;
}

static int i_can_has_32 (void) {
    return 1;
}

static int i_can_has_64 (void) {
    return 1;
}

static int i_can_has_popcount (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.popcnt == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_mmx (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.mmx == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_fma (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.fma3 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_sse (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.sse == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_sse2 (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.sse2 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_orc (void) {
    return 1;
}

static int i_can_has_norc (void) {
    return 1;
}

static int i_can_has_neon (void) {
#if defined(CPU_FEATURES_ARCH_ARM)
    if (GetArmInfo().features.neon == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_neonv7 (void) {
#if defined(CPU_FEATURES_ARCH_ARM)
    if (GetArmInfo().features.neon == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_neonv8 (void) {
#if defined(CPU_FEATURES_ARCH_ARM)
    if (GetArmInfo().features.neon == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_sse3 (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.sse3 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_ssse3 (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.ssse3 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_sse4_a (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.sse4a == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_sse4_1 (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.sse4_1 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_sse4_2 (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.sse4_2 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_avx (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.avx == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_avx2 (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.avx2 == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_avx512f (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.avx512f == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_avx512cd (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.avx512cd == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_avx512dq (void) {
#if defined(CPU_FEATURES_ARCH_X86)
    if (GetX86Info().features.avx512dq == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_riscv64 (void) {
    return 1;
}

static int i_can_has_rvv (void) {
#if defined(CPU_FEATURES_ARCH_RISCV)
    if (GetRiscvInfo().features.V == 0){ return 0; }
#endif
    return 1;
}

static int i_can_has_rvvseg (void) {
#if defined(CPU_FEATURES_ARCH_RISCV)
    if (GetRiscvInfo().features.V == 0){ return 0; }
#endif
    return 1;
}


#if defined(HAVE_FENV_H)
    #if defined(FE_TONEAREST)
        #include <fenv.h>
        static inline void set_float_rounding(void){
            fesetround(FE_TONEAREST);
        }
    #else
        static inline void set_float_rounding(void){
            //do nothing
        }
    #endif
#elif defined(_MSC_VER)
    #include <float.h>
    static inline void set_float_rounding(void){
        unsigned int cwrd;
        _controlfp_s(&cwrd, 0, 0);
        _controlfp_s(&cwrd, _RC_NEAR, _MCW_RC);
    }
#else
    static inline void set_float_rounding(void){
        //do nothing
    }
#endif


void volk_cpu_init() {
    volk_cpu.has_generic = &i_can_has_generic;
    volk_cpu.has_softfp = &i_can_has_softfp;
    volk_cpu.has_hardfp = &i_can_has_hardfp;
    volk_cpu.has_32 = &i_can_has_32;
    volk_cpu.has_64 = &i_can_has_64;
    volk_cpu.has_popcount = &i_can_has_popcount;
    volk_cpu.has_mmx = &i_can_has_mmx;
    volk_cpu.has_fma = &i_can_has_fma;
    volk_cpu.has_sse = &i_can_has_sse;
    volk_cpu.has_sse2 = &i_can_has_sse2;
    volk_cpu.has_orc = &i_can_has_orc;
    volk_cpu.has_norc = &i_can_has_norc;
    volk_cpu.has_neon = &i_can_has_neon;
    volk_cpu.has_neonv7 = &i_can_has_neonv7;
    volk_cpu.has_neonv8 = &i_can_has_neonv8;
    volk_cpu.has_sse3 = &i_can_has_sse3;
    volk_cpu.has_ssse3 = &i_can_has_ssse3;
    volk_cpu.has_sse4_a = &i_can_has_sse4_a;
    volk_cpu.has_sse4_1 = &i_can_has_sse4_1;
    volk_cpu.has_sse4_2 = &i_can_has_sse4_2;
    volk_cpu.has_avx = &i_can_has_avx;
    volk_cpu.has_avx2 = &i_can_has_avx2;
    volk_cpu.has_avx512f = &i_can_has_avx512f;
    volk_cpu.has_avx512cd = &i_can_has_avx512cd;
    volk_cpu.has_avx512dq = &i_can_has_avx512dq;
    volk_cpu.has_riscv64 = &i_can_has_riscv64;
    volk_cpu.has_rvv = &i_can_has_rvv;
    volk_cpu.has_rvvseg = &i_can_has_rvvseg;
    set_float_rounding();
}

unsigned int volk_get_lvarch() {
    unsigned int retval = 0;
    volk_cpu_init();
    retval += volk_cpu.has_generic() << LV_GENERIC;
    retval += volk_cpu.has_softfp() << LV_SOFTFP;
    retval += volk_cpu.has_hardfp() << LV_HARDFP;
    retval += volk_cpu.has_32() << LV_32;
    retval += volk_cpu.has_64() << LV_64;
    retval += volk_cpu.has_popcount() << LV_POPCOUNT;
    retval += volk_cpu.has_mmx() << LV_MMX;
    retval += volk_cpu.has_fma() << LV_FMA;
    retval += volk_cpu.has_sse() << LV_SSE;
    retval += volk_cpu.has_sse2() << LV_SSE2;
    retval += volk_cpu.has_orc() << LV_ORC;
    retval += volk_cpu.has_norc() << LV_NORC;
    retval += volk_cpu.has_neon() << LV_NEON;
    retval += volk_cpu.has_neonv7() << LV_NEONV7;
    retval += volk_cpu.has_neonv8() << LV_NEONV8;
    retval += volk_cpu.has_sse3() << LV_SSE3;
    retval += volk_cpu.has_ssse3() << LV_SSSE3;
    retval += volk_cpu.has_sse4_a() << LV_SSE4_A;
    retval += volk_cpu.has_sse4_1() << LV_SSE4_1;
    retval += volk_cpu.has_sse4_2() << LV_SSE4_2;
    retval += volk_cpu.has_avx() << LV_AVX;
    retval += volk_cpu.has_avx2() << LV_AVX2;
    retval += volk_cpu.has_avx512f() << LV_AVX512F;
    retval += volk_cpu.has_avx512cd() << LV_AVX512CD;
    retval += volk_cpu.has_avx512dq() << LV_AVX512DQ;
    retval += volk_cpu.has_riscv64() << LV_RISCV64;
    retval += volk_cpu.has_rvv() << LV_RVV;
    retval += volk_cpu.has_rvvseg() << LV_RVVSEG;
    return retval;
}
