use crate::cache::Features;
use crate::features::Feature;
use super::sys::IsProcessorFeaturePresent;
const PF_ARM_VFP_32_REGISTERS_AVAILABLE: u32 = 18;
const PF_ARM_NEON_INSTRUCTIONS_AVAILABLE: u32 = 19;
const PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE: u32 = 30;
const PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE: u32 = 31;
const PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE: u32 = 34;
const PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE: u32 = 43;
const PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE: u32 = 44;
const PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE: u32 = 45;
const PF_ARM_SVE_INSTRUCTIONS_AVAILABLE: u32 = 46;
const PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE: u32 = 47;
const PF_ARM_SVE2_1_INSTRUCTIONS_AVAILABLE: u32 = 48;
const PF_ARM_SVE_AES_INSTRUCTIONS_AVAILABLE: u32 = 49;
const PF_ARM_SVE_PMULL128_INSTRUCTIONS_AVAILABLE: u32 = 50;
const PF_ARM_SVE_BITPERM_INSTRUCTIONS_AVAILABLE: u32 = 51;
const PF_ARM_SVE_B16B16_INSTRUCTIONS_AVAILABLE: u32 = 54;
const PF_ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE: u32 = 55;
const PF_ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE: u32 = 56;
const PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE: u32 = 58;
const PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE: u32 = 59;
const PF_ARM_LSE2_AVAILABLE: u32 = 62;
const PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE: u32 = 64;
const PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE: u32 = 65;
const PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE: u32 = 66;
const PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE: u32 = 67;
const PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE: u32 = 68;
const PF_ARM_SME_INSTRUCTIONS_AVAILABLE: u32 = 70;
const PF_ARM_SME2_INSTRUCTIONS_AVAILABLE: u32 = 71;
const PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE: u32 = 72;
const PF_ARM_SME_SF8DP2_INSTRUCTIONS_AVAILABLE: u32 = 78;
const PF_ARM_SME_SF8DP4_INSTRUCTIONS_AVAILABLE: u32 = 79;
const PF_ARM_SME_SF8FMA_INSTRUCTIONS_AVAILABLE: u32 = 80;
const PF_ARM_SME_F8F32_INSTRUCTIONS_AVAILABLE: u32 = 81;
const PF_ARM_SME_F8F16_INSTRUCTIONS_AVAILABLE: u32 = 82;
const PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE: u32 = 83;
const PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE: u32 = 84;
const PF_ARM_SME_F64F64_INSTRUCTIONS_AVAILABLE: u32 = 85;
const PF_ARM_SME_I16I64_INSTRUCTIONS_AVAILABLE: u32 = 86;
#[allow(non_upper_case_globals)] const PF_ARM_SME_LUTv2_INSTRUCTIONS_AVAILABLE: u32 = 87;
const PF_ARM_SME_FA64_INSTRUCTIONS_AVAILABLE: u32 = 88;
#[inline]
fn present(feature: u32) -> bool {
IsProcessorFeaturePresent(feature) != 0
}
pub(crate) fn fill(f: &mut Features) {
if present(PF_ARM_VFP_32_REGISTERS_AVAILABLE) {
*f = f.with(Feature::Fp);
}
if present(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Asimd);
}
if present(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Crc);
}
if present(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) {
*f = f
.with(Feature::Aes)
.with(Feature::Pmull)
.with(Feature::Sha2);
}
let lse = present(PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE);
if lse {
*f = f.with(Feature::Lse);
}
if present(PF_ARM_LSE2_AVAILABLE) {
*f = f.with(Feature::Lse2);
}
if present(PF_ARM_V83_LRCPC_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Rcpc);
}
let dotprod = present(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE);
if dotprod {
*f = f.with(Feature::Dotprod);
}
if present(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::JsConv);
}
if present(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Fp16);
}
if present(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::I8mm);
}
if present(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Bf16);
}
if present(PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE) && present(PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE)
{
*f = f.with(Feature::Sha3);
}
if present(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sve);
}
if present(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sve2);
}
if present(PF_ARM_SVE2_1_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sve2p1);
}
if present(PF_ARM_SVE_AES_INSTRUCTIONS_AVAILABLE)
&& present(PF_ARM_SVE_PMULL128_INSTRUCTIONS_AVAILABLE)
{
*f = f.with(Feature::Sve2Aes);
}
if present(PF_ARM_SVE_BITPERM_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sve2Bitperm);
}
if present(PF_ARM_SVE_B16B16_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SveB16b16);
}
if present(PF_ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sve2Sha3);
}
if present(PF_ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sve2Sm4);
}
if present(PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::F32mm);
}
if present(PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::F64mm);
}
if present(PF_ARM_SME_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sme);
}
if present(PF_ARM_SME2_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sme2);
}
if present(PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::Sme2p1);
}
if present(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeB16b16);
}
if present(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeF16f16);
}
if present(PF_ARM_SME_F64F64_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeF64f64);
}
if present(PF_ARM_SME_F8F16_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeF8f16);
}
if present(PF_ARM_SME_F8F32_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeF8f32);
}
if present(PF_ARM_SME_FA64_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeFa64);
}
if present(PF_ARM_SME_I16I64_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeI16i64);
}
if present(PF_ARM_SME_LUTv2_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SmeLutv2);
}
if present(PF_ARM_SME_SF8DP2_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SsveFp8Dot2);
}
if present(PF_ARM_SME_SF8DP4_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SsveFp8Dot4);
}
if present(PF_ARM_SME_SF8FMA_INSTRUCTIONS_AVAILABLE) {
*f = f.with(Feature::SsveFp8Fma);
}
if dotprod || lse {
*f = f.with(Feature::Rdm);
}
}