From 8b29d2e74e358db5d0fd3bcf0e1242dde225fb8c Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Oct 2025 08:32:36 +1100 Subject: [PATCH 1/8] implement SVE/SVE2 and list out the missing feature flags --- src/arm/windows/init.c | 39 ++++++++++++++++++------------ src/arm/windows/windows-arm-init.h | 8 ++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c index 79e947a6..6a4bc622 100644 --- a/src/arm/windows/init.c +++ b/src/arm/windows/init.c @@ -195,21 +195,30 @@ static void set_cpuinfo_isa_fields(void) { const bool dotprod = IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.dot = dotprod; - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - switch (system_info.wProcessorLevel) { - case 0x803: // Kryo 385 Silver (Snapdragon 850) - cpuinfo_isa.fp16arith = dotprod; - cpuinfo_isa.rdm = dotprod; - break; - default: - // Assume that Dot Product support implies FP16 - // arithmetics and RDM support. ARM manuals don't - // guarantee that, but it holds in practice. - cpuinfo_isa.fp16arith = dotprod; - cpuinfo_isa.rdm = dotprod; - break; - } + cpuinfo_isa.sve = IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sve2 = IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) != 0; + + // TODO: + // - i8mm + // - jscvt + // - fcma + // - sme + // - sme2 + // - sme2p1 + // - sme_i16i32 + // - sme_bi32i32 + // - sme_b16b16 + // - sme_f16f16 + // - bf16 + // - fhm + // - svelen + // - smelen + + // Assume that Dot Product support implies FP16 + // arithmetics and RDM support. ARM manuals don't + // guarantee that, but it holds in practice. + cpuinfo_isa.fp16arith = dotprod; + cpuinfo_isa.rdm = dotprod; /* Windows API reports all or nothing for cryptographic instructions. */ const bool crypto = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0; diff --git a/src/arm/windows/windows-arm-init.h b/src/arm/windows/windows-arm-init.h index 52dd1807..93db0da9 100644 --- a/src/arm/windows/windows-arm-init.h +++ b/src/arm/windows/windows-arm-init.h @@ -19,3 +19,11 @@ struct woa_chip_info { }; bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor); + +#ifndef PF_ARM_SVE_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SVE_INSTRUCTIONS_AVAILABLE (46) +#endif + +#ifndef PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE (47) +#endif \ No newline at end of file From 1bd00f0fed464fa57eda7270d66b805481c11a4d Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Oct 2025 10:15:42 +1100 Subject: [PATCH 2/8] Implement most of the ISA feature flags --- src/arm/windows/init.c | 23 +++++++------ src/arm/windows/windows-arm-init.h | 54 +++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c index 6a4bc622..c30812ee 100644 --- a/src/arm/windows/init.c +++ b/src/arm/windows/init.c @@ -197,20 +197,21 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.sve = IsProcessorFeaturePresent(PF_ARM_SVE_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sve2 = IsProcessorFeaturePresent(PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE) != 0; - - // TODO: - // - i8mm - // - jscvt - // - fcma - // - sme - // - sme2 - // - sme2p1 + cpuinfo_isa.i8mm = IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.jscvt = IsProcessorFeaturePresent(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.fcma = IsProcessorFeaturePresent(PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme = IsProcessorFeaturePresent(PF_ARM_SME_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme2 = IsProcessorFeaturePresent(PF_ARM_SME2_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme2p1 = IsProcessorFeaturePresent(PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE) != 0; + // I don't see // - sme_i16i32 // - sme_bi32i32 - // - sme_b16b16 - // - sme_f16f16 - // - bf16 + // cpuinfo_isa.sme_bi32i32 = IsProcessorFeaturePresent(PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0; // - fhm + // Not available in Windows API: // - svelen // - smelen diff --git a/src/arm/windows/windows-arm-init.h b/src/arm/windows/windows-arm-init.h index 93db0da9..8fe0afd7 100644 --- a/src/arm/windows/windows-arm-init.h +++ b/src/arm/windows/windows-arm-init.h @@ -20,10 +20,62 @@ struct woa_chip_info { bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor); + + +#ifndef PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE +#define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE (27) +#endif + +#ifndef PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE +#define PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE (34) +#endif + +#ifndef PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE +#define PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE (44) +#endif + #ifndef PF_ARM_SVE_INSTRUCTIONS_AVAILABLE #define PF_ARM_SVE_INSTRUCTIONS_AVAILABLE (46) #endif #ifndef PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE #define PF_ARM_SVE2_INSTRUCTIONS_AVAILABLE (47) -#endif \ No newline at end of file +#endif + +#ifndef PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE (55) +#endif + +#ifndef PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE +#define PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE (66) +#endif + +#ifndef PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE +#define PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE (68) +#endif + +#ifndef PF_ARM_SME_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME_INSTRUCTIONS_AVAILABLE (70) +#endif + +#ifndef PF_ARM_SME2_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME2_INSTRUCTIONS_AVAILABLE (71) +#endif + +#ifndef PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE (72) +#endif + +#ifndef PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME2_2_INSTRUCTIONS_AVAILABLE (73) +#endif + +#ifndef PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE (83) +#endif + +#ifndef PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE +#define PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE (84) +#endif + + From 56e3fb971f41ab5e9ab3b3363e603aeb2ac77969 Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Oct 2025 10:23:01 +1100 Subject: [PATCH 3/8] Update notes --- src/arm/windows/init.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c index c30812ee..012010e8 100644 --- a/src/arm/windows/init.c +++ b/src/arm/windows/init.c @@ -203,14 +203,15 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.sme = IsProcessorFeaturePresent(PF_ARM_SME_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme2 = IsProcessorFeaturePresent(PF_ARM_SME2_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme2p1 = IsProcessorFeaturePresent(PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE) != 0; - // I don't see + + // TODO: // - sme_i16i32 // - sme_bi32i32 - // cpuinfo_isa.sme_bi32i32 = IsProcessorFeaturePresent(PF_ARM_SME_BI32I32_INSTRUCTIONS_AVAILABLE) != 0; + // - fhm + cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0; - // - fhm // Not available in Windows API: // - svelen // - smelen From cadb6c0fd35427278a0cce13e81db9c3b938e9e1 Mon Sep 17 00:00:00 2001 From: Anthony Date: Tue, 21 Oct 2025 10:44:08 +1100 Subject: [PATCH 4/8] Add more flags to isa info --- tools/isa-info.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/isa-info.c b/tools/isa-info.c index 740be648..a7e387a1 100644 --- a/tools/isa-info.c +++ b/tools/isa-info.c @@ -175,6 +175,11 @@ int main(int argc, char** argv) { printf("\tARM SVE 2: %s\n", cpuinfo_has_arm_sve2() ? "yes" : "no"); printf("\tARM SME: %s\n", cpuinfo_has_arm_sme() ? "yes" : "no"); printf("\tARM SME 2: %s\n", cpuinfo_has_arm_sme2() ? "yes" : "no"); + printf("\tARM SME 2P1: %s\n", cpuinfo_has_arm_sme2p1() ? "yes" : "no"); + printf("\tARM SME I16I32: %s\n", cpuinfo_has_arm_sme_i16i32() ? "yes" : "no"); + printf("\tARM SME BI32I32: %s\n", cpuinfo_has_arm_sme_bi32i32() ? "yes" : "no"); + printf("\tARM SME B16B16: %s\n", cpuinfo_has_arm_sme_b16b16() ? "yes" : "no"); + printf("\tARM SME F16F16: %s\n", cpuinfo_has_arm_sme_f16f16() ? "yes" : "no"); printf("ARM SVE Capabilities:\n"); printf("\tSVE max length: %d\n", cpuinfo_get_max_arm_sve_length()); From 4d44950c3afd1df5418936a52498c9ca106aaedb Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 23 Oct 2025 13:40:38 +1100 Subject: [PATCH 5/8] Additional flags --- src/arm/windows/init.c | 33 +++++++++++++++++++++++++----- src/arm/windows/windows-arm-init.h | 4 +++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c index 012010e8..679b0d88 100644 --- a/src/arm/windows/init.c +++ b/src/arm/windows/init.c @@ -134,6 +134,26 @@ static struct core_info_by_chip_name get_core_info_from_midr(uint32_t midr, uint return info; } +/* https://developer.arm.com/documentation/ddi0601/2024-06/AArch64-Registers + CP 4000: MIDR_EL1 + CP 4020: ID_AA64PFR0_EL1 + CP 4021: ID_AA64PFR1_EL1 + CP 4028: ID_AA64DFR0_EL1 + CP 4029: ID_AA64DFR1_EL1 + CP 402C: ID_AA64AFR0_EL1 + CP 402D: ID_AA64AFR1_EL1 + CP 4030: ID_AA64ISAR0_EL1 + CP 4031: ID_AA64ISAR1_EL1 + CP 4038: ID_AA64MMFR0_EL1 + CP 4039: ID_AA64MMFR1_EL1 + CP 403A: ID_AA64MMFR2_EL1 + CP 4080: ? + CP 4081: ? + CP 4100: ? + CP 4510: ? + CP 5801: ? + */ + static struct woa_chip_info* get_system_info_from_registry(void) { wchar_t* text_buffer = NULL; LPCWSTR cpu0_subkey = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; @@ -200,26 +220,29 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.i8mm = IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.jscvt = IsProcessorFeaturePresent(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.fcma = IsProcessorFeaturePresent(PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) != 0; + // FEAT_FP16 Implies FEAT_FHM in 8.4 https://developer.arm.com/documentation/109697/2025_09/Feature-descriptions/The-Armv8-4-architecture-extension?lang=en + cpuinfo_isa.fhm = IsProcessorFeaturePresent(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.fp16arith = cpuinfo_isa.fhm; + cpuinfo_isa.sme = IsProcessorFeaturePresent(PF_ARM_SME_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme2 = IsProcessorFeaturePresent(PF_ARM_SME2_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme2p1 = IsProcessorFeaturePresent(PF_ARM_SME2_1_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0; + cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0; // TODO: // - sme_i16i32 // - sme_bi32i32 - // - fhm - cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0; - cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0; - // Not available in Windows API: + + // TODO: // - svelen // - smelen // Assume that Dot Product support implies FP16 // arithmetics and RDM support. ARM manuals don't // guarantee that, but it holds in practice. - cpuinfo_isa.fp16arith = dotprod; cpuinfo_isa.rdm = dotprod; /* Windows API reports all or nothing for cryptographic instructions. */ diff --git a/src/arm/windows/windows-arm-init.h b/src/arm/windows/windows-arm-init.h index 8fe0afd7..aa11b893 100644 --- a/src/arm/windows/windows-arm-init.h +++ b/src/arm/windows/windows-arm-init.h @@ -78,4 +78,6 @@ bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, en #define PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE (84) #endif - +#ifndef PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE +#define PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE (67) +#endif From 9bf288ca46e486952ca84ab3d350288c414cb64c Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 23 Oct 2025 14:16:39 +1100 Subject: [PATCH 6/8] Add conservative values for SVE --- src/arm/windows/init.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c index 679b0d88..99f3a832 100644 --- a/src/arm/windows/init.c +++ b/src/arm/windows/init.c @@ -230,15 +230,18 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0; - // TODO: + // TODO: There are no PF flags for these yet. // - sme_i16i32 // - sme_bi32i32 cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0; - // TODO: - // - svelen - // - smelen + // TODO: This is not available in the Windows SDK yet , so conservatively go with the lowest value (128 bits) + // https://developer.arm.com/documentation/101427/0102/Register-descriptions/Scalable-vector-extensions--SVE--registers/ZCR-EL1--SVE-Control-Register--EL1 + cpuinfo_isa.svelen = cpuinfo_isa.sve ? 128 / 8 : 0; // This value is in bytes, see cpuinfo_get_max_arm_sve_length + + // TODO : Fetch from feature registers when available + // cpuinfo_isa.smelen = 0; // Assume that Dot Product support implies FP16 // arithmetics and RDM support. ARM manuals don't From cc0cab3b591d99ef703eb02df8eb5f4e70f657b8 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sun, 9 Nov 2025 13:28:09 +1100 Subject: [PATCH 7/8] clang formatting --- src/arm/windows/init.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c index 99f3a832..596c6b28 100644 --- a/src/arm/windows/init.c +++ b/src/arm/windows/init.c @@ -146,7 +146,7 @@ static struct core_info_by_chip_name get_core_info_from_midr(uint32_t midr, uint CP 4031: ID_AA64ISAR1_EL1 CP 4038: ID_AA64MMFR0_EL1 CP 4039: ID_AA64MMFR1_EL1 - CP 403A: ID_AA64MMFR2_EL1 + CP 403A: ID_AA64MMFR2_EL1 CP 4080: ? CP 4081: ? CP 4100: ? @@ -220,7 +220,8 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.i8mm = IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.jscvt = IsProcessorFeaturePresent(PF_ARM_V83_JSCVT_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.fcma = IsProcessorFeaturePresent(PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE) != 0; - // FEAT_FP16 Implies FEAT_FHM in 8.4 https://developer.arm.com/documentation/109697/2025_09/Feature-descriptions/The-Armv8-4-architecture-extension?lang=en + // FEAT_FP16 Implies FEAT_FHM in 8.4 + // https://developer.arm.com/documentation/109697/2025_09/Feature-descriptions/The-Armv8-4-architecture-extension?lang=en cpuinfo_isa.fhm = IsProcessorFeaturePresent(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.fp16arith = cpuinfo_isa.fhm; @@ -230,7 +231,7 @@ static void set_cpuinfo_isa_fields(void) { cpuinfo_isa.sme_b16b16 = IsProcessorFeaturePresent(PF_ARM_SME_B16B16_INSTRUCTIONS_AVAILABLE) != 0; cpuinfo_isa.sme_f16f16 = IsProcessorFeaturePresent(PF_ARM_SME_F16F16_INSTRUCTIONS_AVAILABLE) != 0; - // TODO: There are no PF flags for these yet. + // TODO: Add when available in Windows SDK // - sme_i16i32 // - sme_bi32i32 @@ -238,8 +239,9 @@ static void set_cpuinfo_isa_fields(void) { // TODO: This is not available in the Windows SDK yet , so conservatively go with the lowest value (128 bits) // https://developer.arm.com/documentation/101427/0102/Register-descriptions/Scalable-vector-extensions--SVE--registers/ZCR-EL1--SVE-Control-Register--EL1 - cpuinfo_isa.svelen = cpuinfo_isa.sve ? 128 / 8 : 0; // This value is in bytes, see cpuinfo_get_max_arm_sve_length - + cpuinfo_isa.svelen = + cpuinfo_isa.sve ? 128 / 8 : 0; // This value is in bytes, see cpuinfo_get_max_arm_sve_length + // TODO : Fetch from feature registers when available // cpuinfo_isa.smelen = 0; From 6029b6b70ba2311b7df6b5f2b7affcca84fef594 Mon Sep 17 00:00:00 2001 From: Anthony Date: Mon, 10 Nov 2025 09:14:16 -0800 Subject: [PATCH 8/8] format headers --- src/arm/windows/windows-arm-init.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/arm/windows/windows-arm-init.h b/src/arm/windows/windows-arm-init.h index aa11b893..3c492849 100644 --- a/src/arm/windows/windows-arm-init.h +++ b/src/arm/windows/windows-arm-init.h @@ -20,8 +20,6 @@ struct woa_chip_info { bool cpu_info_init_by_logical_sys_info(const struct woa_chip_info* chip_info, enum cpuinfo_vendor vendor); - - #ifndef PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE #define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE (27) #endif