#include "libyuv/cpu_id.h"
#if defined(_MSC_VER)
#include <intrin.h>
#endif
#if !defined(__pnacl__) && !defined(__CLR_VER) && \
!defined(__native_client__) && (defined(_M_IX86) || defined(_M_X64)) && \
defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219)
#include <immintrin.h>
#endif
#include <stdio.h>
#include <string.h>
#if defined(__linux__) && defined(__aarch64__)
#include <sys/auxv.h>
#endif
#if defined(_WIN32) && defined(__aarch64__)
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#undef WIN32_EXTRA_LEAN
#define WIN32_EXTRA_LEAN
#include <windows.h>
#endif
#if defined(__APPLE__) && defined(__aarch64__)
#include <sys/sysctl.h>
#endif
#ifdef __cplusplus
namespace libyuv {
extern "C" {
#endif
#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 160040219) && \
!defined(__clang__)
#define SAFEBUFFERS …
#else
#define SAFEBUFFERS
#endif
LIBYUV_API int cpu_info_ = …;
#if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
defined(__x86_64__)) && \
!defined(__pnacl__) && !defined(__CLR_VER)
LIBYUV_API
void CpuId(int info_eax, int info_ecx, int* cpu_info) { … }
#else
LIBYUV_API
void CpuId(int eax, int ecx, int* cpu_info) {
(void)eax;
(void)ecx;
cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0;
}
#endif
#if defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER < 1900)
#pragma optimize("g", off)
#endif
#if (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
defined(__x86_64__)) && \
!defined(__pnacl__) && !defined(__CLR_VER) && !defined(__native_client__)
static int GetXCR0() { … }
#else
#define GetXCR0 …
#endif
#if defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER < 1900)
#pragma optimize("g", on)
#endif
static int cpuinfo_search(const char* cpuinfo_line,
const char* needle,
int needle_len) { … }
LIBYUV_API SAFEBUFFERS int ArmCpuCaps(const char* cpuinfo_name) { … }
#ifdef __aarch64__
#ifdef __linux__
#define YUV_AARCH64_HWCAP_ASIMDDP …
#define YUV_AARCH64_HWCAP_SVE …
#define YUV_AARCH64_HWCAP2_SVE2 …
#define YUV_AARCH64_HWCAP2_I8MM …
#define YUV_AARCH64_HWCAP2_SME …
LIBYUV_API SAFEBUFFERS int AArch64CpuCaps(unsigned long hwcap,
unsigned long hwcap2) {
int features = kCpuHasNEON;
if (hwcap & YUV_AARCH64_HWCAP_ASIMDDP) {
features |= kCpuHasNeonDotProd;
if (hwcap2 & YUV_AARCH64_HWCAP2_I8MM) {
features |= kCpuHasNeonI8MM;
if (hwcap & YUV_AARCH64_HWCAP_SVE) {
features |= kCpuHasSVE;
if (hwcap2 & YUV_AARCH64_HWCAP2_SVE2) {
features |= kCpuHasSVE2;
if (hwcap2 & YUV_AARCH64_HWCAP2_SME) {
features |= kCpuHasSME;
}
}
}
}
}
return features;
}
#elif defined(_WIN32)
LIBYUV_API SAFEBUFFERS int AArch64CpuCaps() {
int features = kCpuHasNEON;
#ifdef PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE
if (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE)) {
features |= kCpuHasNeonDotProd;
}
#endif
return features;
}
#elif defined(__APPLE__)
static bool have_feature(const char* feature) {
int64_t feature_present = 0;
size_t size = sizeof(feature_present);
if (sysctlbyname(feature, &feature_present, &size, NULL, 0) != 0) {
return false;
}
return feature_present;
}
LIBYUV_API SAFEBUFFERS int AArch64CpuCaps() {
int features = kCpuHasNEON;
if (have_feature("hw.optional.arm.FEAT_DotProd")) {
features |= kCpuHasNeonDotProd;
if (have_feature("hw.optional.arm.FEAT_I8MM")) {
features |= kCpuHasNeonI8MM;
if (have_feature("hw.optional.arm.FEAT_SME2")) {
features |= kCpuHasSME;
}
}
}
return features;
}
#else
LIBYUV_API SAFEBUFFERS int AArch64CpuCaps() {
int features = kCpuHasNEON;
return features;
}
#endif
#endif
LIBYUV_API SAFEBUFFERS int RiscvCpuCaps(const char* cpuinfo_name) { … }
LIBYUV_API SAFEBUFFERS int MipsCpuCaps(const char* cpuinfo_name) { … }
#define LOONGARCH_CFG2 …
#define LOONGARCH_CFG2_LSX …
#define LOONGARCH_CFG2_LASX …
#if defined(__loongarch__)
LIBYUV_API SAFEBUFFERS int LoongarchCpuCaps(void) {
int flag = 0;
uint32_t cfg2 = 0;
__asm__ volatile("cpucfg %0, %1 \n\t" : "+&r"(cfg2) : "r"(LOONGARCH_CFG2));
if (cfg2 & LOONGARCH_CFG2_LSX)
flag |= kCpuHasLSX;
if (cfg2 & LOONGARCH_CFG2_LASX)
flag |= kCpuHasLASX;
return flag;
}
#endif
static SAFEBUFFERS int GetCpuFlags(void) { … }
LIBYUV_API
int MaskCpuFlags(int enable_flags) { … }
LIBYUV_API
int InitCpuFlags(void) { … }
#ifdef __cplusplus
}
}
#endif