#include <cstdio>
int astcenc_main_veneer(
int argc,
char **argv);
#if (ASTCENC_SSE > 20) || (ASTCENC_AVX > 0) || \
(ASTCENC_POPCNT > 0) || (ASTCENC_F16C > 0)
static bool g_init { false };
static bool g_cpu_has_sse41 { false };
static bool g_cpu_has_avx2 { false };
static bool g_cpu_has_popcnt { false };
static bool g_cpu_has_f16c { false };
#if !defined(__clang__) && defined(_MSC_VER)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <intrin.h>
static void detect_cpu_isa()
{
int data[4];
__cpuid(data, 0);
int num_id = data[0];
if (num_id >= 1)
{
__cpuidex(data, 1, 0);
g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false;
g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false;
g_cpu_has_f16c = data[2] & (1 << 29) ? true : false;
}
if (num_id >= 7)
{
__cpuidex(data, 7, 0);
g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false;
}
MemoryBarrier();
g_init = true;
}
#else
#include <cpuid.h>
static void detect_cpu_isa()
{
unsigned int data[4];
if (__get_cpuid_count(1, 0, &data[0], &data[1], &data[2], &data[3]))
{
g_cpu_has_sse41 = data[2] & (1 << 19) ? true : false;
g_cpu_has_popcnt = data[2] & (1 << 23) ? true : false;
g_cpu_has_f16c = data[2] & (1 << 29) ? true : false;
}
g_cpu_has_avx2 = 0;
if (__get_cpuid_count(7, 0, &data[0], &data[1], &data[2], &data[3]))
{
g_cpu_has_avx2 = data[1] & (1 << 5) ? true : false;
}
__sync_synchronize();
g_init = true;
}
#endif
#if ASTCENC_POPCNT > 0
static bool cpu_supports_popcnt()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_popcnt;
}
#endif
#if ASTCENC_F16C > 0
static bool cpu_supports_f16c()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_f16c;
}
#endif
#if ASTCENC_SSE >= 41
static bool cpu_supports_sse41()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_sse41;
}
#endif
#if ASTCENC_AVX >= 2
static bool cpu_supports_avx2()
{
if (!g_init)
{
detect_cpu_isa();
}
return g_cpu_has_avx2;
}
#endif
static inline void print_error(
const char* format
) {
fprintf(stderr, "%s", format);
}
static bool validate_cpu_isa()
{
#if ASTCENC_AVX >= 2
if (!cpu_supports_avx2())
{
print_error("ERROR: Host does not support AVX2 ISA extension\n");
return false;
}
#endif
#if ASTCENC_F16C >= 1
if (!cpu_supports_f16c())
{
print_error("ERROR: Host does not support F16C ISA extension\n");
return false;
}
#endif
#if ASTCENC_SSE >= 41
if (!cpu_supports_sse41())
{
print_error("ERROR: Host does not support SSE4.1 ISA extension\n");
return false;
}
#endif
#if ASTCENC_POPCNT >= 1
if (!cpu_supports_popcnt())
{
print_error("ERROR: Host does not support POPCNT ISA extension\n");
return false;
}
#endif
return true;
}
#elif ASTCENC_SVE != 0
#include <sys/auxv.h>
static bool cpu_supports_sve()
{
long hwcaps = getauxval(AT_HWCAP);
return (hwcaps & HWCAP_SVE) != 0;
}
static inline void print_error(
const char* format
) {
fprintf(stderr, "%s", format);
}
static bool validate_cpu_isa()
{
if (!cpu_supports_sve())
{
print_error("ERROR: Host does not support SVE ISA extension\n");
return false;
}
return true;
}
#else
static bool validate_cpu_isa()
{
return true;
}
#endif
int main(
int argc,
char **argv
) {
if (!validate_cpu_isa())
{
return 1;
}
return astcenc_main_veneer(argc, argv);
}