Implement missing ISA feature flags for ARM64/Windows (#333)

* implement SVE/SVE2 and list out the missing feature flags

* Implement most of the ISA feature flags

* Update notes

* Add more flags to isa info

* Additional flags

* Add conservative values for SVE

* clang formatting

* format headers
diff --git a/src/arm/windows/init.c b/src/arm/windows/init.c
index b5559ad..5c0a5f3 100644
--- a/src/arm/windows/init.c
+++ b/src/arm/windows/init.c
@@ -133,6 +133,26 @@
 	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";

@@ -194,21 +214,40 @@
 	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;

+	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: Add when available in Windows SDK

+	// - sme_i16i32

+	// - sme_bi32i32

+

+	cpuinfo_isa.bf16 = IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != 0;

+

+	// 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

+	// guarantee that, but it holds in practice.

+	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 52dd180..3c49284 100644
--- a/src/arm/windows/windows-arm-init.h
+++ b/src/arm/windows/windows-arm-init.h
@@ -19,3 +19,63 @@
 };

 

 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

+

+#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

+

+#ifndef PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE

+#define PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE (67)

+#endif

diff --git a/tools/isa-info.c b/tools/isa-info.c
index 740be64..a7e387a 100644
--- a/tools/isa-info.c
+++ b/tools/isa-info.c
@@ -175,6 +175,11 @@
 	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());