Refactor uarch and ISA detection on iOS (#110)

- Nuke support for 32-bit iOS (was already broken anyway)
- Detect Avalanche & Blizzard cores
- Add more fallbacks for detection based on CPU Family for older iOS /
  macOS versions and core types

GitOrigin-RevId: 49610f89b8b1eb52d75d1eda7a2c40c1e86a78e7
Change-Id: I20abf522300177eb851baf7c14b35f7a9f5a983b
diff --git a/include/cpuinfo.h b/include/cpuinfo.h
index 12e17e4..bcbb3ec 100644
--- a/include/cpuinfo.h
+++ b/include/cpuinfo.h
@@ -500,10 +500,14 @@
 	cpuinfo_uarch_lightning = 0x00700109,
 	/** Apple A13 processor (little cores). */
 	cpuinfo_uarch_thunder   = 0x0070010A,
-	/** Apple M1 processor (big cores). */
+	/** Apple A14 / M1 processor (big cores). */
 	cpuinfo_uarch_firestorm = 0x0070010B,
-	/** Apple M1 processor (little cores). */
+	/** Apple A14 / M1 processor (little cores). */
 	cpuinfo_uarch_icestorm  = 0x0070010C,
+	/** Apple A15 / M2 processor (big cores). */
+	cpuinfo_uarch_avalanche = 0x0070010D,
+	/** Apple A15 / M2 processor (little cores). */
+	cpuinfo_uarch_blizzard  = 0x0070010E,
 
 	/** Cavium ThunderX. */
 	cpuinfo_uarch_thunderx = 0x00800100,
diff --git a/src/arm/mach/init.c b/src/arm/mach/init.c
index b52dd4c..6a28b2d 100644
--- a/src/arm/mach/init.c
+++ b/src/arm/mach/init.c
@@ -15,43 +15,25 @@
 #include <cpuinfo/log.h>
 
 /* Polyfill recent CPUFAMILY_ARM_* values for older SDKs */
-#ifndef CPUFAMILY_ARM_MONSOON_MISTRAL
-	#define CPUFAMILY_ARM_MONSOON_MISTRAL   0xE81E7EF6
-#endif
 #ifndef CPUFAMILY_ARM_VORTEX_TEMPEST
-	#define CPUFAMILY_ARM_VORTEX_TEMPEST    0x07D34B9F
+	#define CPUFAMILY_ARM_VORTEX_TEMPEST     0x07D34B9F
 #endif
 #ifndef CPUFAMILY_ARM_LIGHTNING_THUNDER
-	#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504D2
+	#define CPUFAMILY_ARM_LIGHTNING_THUNDER  0x462504D2
 #endif
 #ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
 	#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
 #endif
+#ifndef CPUFAMILY_ARM_AVALANCHE_BLIZZARD
+	#define CPUFAMILY_ARM_AVALANCHE_BLIZZARD 0xDA33D83D
+#endif
 
 struct cpuinfo_arm_isa cpuinfo_isa = {
-#if CPUINFO_ARCH_ARM
-	.thumb = true,
-	.thumb2 = true,
-	.thumbee = false,
-	.jazelle = false,
-	.armv5e = true,
-	.armv6 = true,
-	.armv6k = true,
-	.armv7 = true,
-	.vfpv2 = false,
-	.vfpv3 = true,
-	.d32 = true,
-	.wmmx = false,
-	.wmmx2 = false,
-	.neon = true,
-#endif
-#if CPUINFO_ARCH_ARM64
 	.aes = true,
 	.sha1 = true,
 	.sha2 = true,
 	.pmull = true,
 	.crc32 = true,
-#endif
 };
 
 static uint32_t get_sys_info(int type_specifier, const char* name) {
@@ -83,10 +65,8 @@
 	return result;
 }
 
-static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t cpu_subtype, uint32_t core_index, uint32_t core_count) {
+static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index, uint32_t core_count) {
 	switch (cpu_family) {
-		case CPUFAMILY_ARM_SWIFT:
-			return cpuinfo_uarch_swift;
 		case CPUFAMILY_ARM_CYCLONE:
 			return cpuinfo_uarch_cyclone;
 		case CPUFAMILY_ARM_TYPHOON:
@@ -107,25 +87,15 @@
 		case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
 			/* Hexa-core: 2x Firestorm + 4x Icestorm; Octa-core: 4x Firestorm + 4x Icestorm */
 			return core_index + 4 < core_count ? cpuinfo_uarch_firestorm : cpuinfo_uarch_icestorm;
+		case CPUFAMILY_ARM_AVALANCHE_BLIZZARD:
+			/* Hexa-core: 2x Avalanche + 4x Blizzard */
+			return core_index + 4 < core_count ? cpuinfo_uarch_avalanche : cpuinfo_uarch_blizzard;
 		default:
 			/* Use hw.cpusubtype for detection */
 			break;
 	}
 
-	#if CPUINFO_ARCH_ARM
-		switch (cpu_subtype) {
-			case CPU_SUBTYPE_ARM_V7:
-				return cpuinfo_uarch_cortex_a8;
-			case CPU_SUBTYPE_ARM_V7F:
-				return cpuinfo_uarch_cortex_a9;
-			case CPU_SUBTYPE_ARM_V7K:
-				return cpuinfo_uarch_cortex_a7;
-			default:
-				return cpuinfo_uarch_unknown;
-		}
-	#else
-		return cpuinfo_uarch_unknown;
-	#endif
+	return cpuinfo_uarch_unknown;
 }
 
 static void decode_package_name(char* package_name) {
@@ -299,75 +269,46 @@
 
 
 	const uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
-	const uint32_t cpu_type = get_sys_info_by_name("hw.cputype");
-	const uint32_t cpu_subtype = get_sys_info_by_name("hw.cpusubtype");
-	switch (cpu_type) {
-		case CPU_TYPE_ARM64:
-			cpuinfo_isa.aes = true;
-			cpuinfo_isa.sha1 = true;
-			cpuinfo_isa.sha2 = true;
-			cpuinfo_isa.pmull = true;
-			cpuinfo_isa.crc32 = true;
-			break;
-#if CPUINFO_ARCH_ARM
-		case CPU_TYPE_ARM:
-			switch (cpu_subtype) {
-				case CPU_SUBTYPE_ARM_V8:
-					cpuinfo_isa.armv8 = true;
-					cpuinfo_isa.aes = true;
-					cpuinfo_isa.sha1 = true;
-					cpuinfo_isa.sha2 = true;
-					cpuinfo_isa.pmull = true;
-					cpuinfo_isa.crc32 = true;
-					/* Fall-through to add ARMv7S features */
-				case CPU_SUBTYPE_ARM_V7S:
-				case CPU_SUBTYPE_ARM_V7K:
-					cpuinfo_isa.fma = true;
-					/* Fall-through to add ARMv7F features */
-				case CPU_SUBTYPE_ARM_V7F:
-					cpuinfo_isa.armv7mp = true;
-					cpuinfo_isa.fp16 = true;
-					/* Fall-through to add ARMv7 features */
-				case CPU_SUBTYPE_ARM_V7:
-					break;
-				default:
-					break;
-			}
-			break;
-#endif
-	}
 
 	/*
-	 * iOS 15 and macOS 12 added sysctls for ARM features.  Use them where
-	 * possible.  Otherwise, fallback to hardcoded set of CPUs with known
-	 * support.
+	 * iOS 15 and macOS 12 added sysctls for ARM features, use them where possible.
+	 * Otherwise, fallback to hardcoded set of CPUs with known support.
 	 */
-
 	const uint32_t has_feat_lse = get_sys_info_by_name("hw.optional.arm.FEAT_LSE");
 	if (has_feat_lse != 0) {
 		cpuinfo_isa.atomics = true;
-	}
-	#if CPUINFO_ARCH_ARM64
-		else {
-			switch (cpu_family) {
-				case CPUFAMILY_ARM_MONSOON_MISTRAL:
-				case CPUFAMILY_ARM_VORTEX_TEMPEST:
-				case CPUFAMILY_ARM_LIGHTNING_THUNDER:
-				case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
-					cpuinfo_isa.atomics = true;
-			}
+	} else {
+		// Mandatory in ARMv8.1-A, list only cores released before iOS 15 / macOS 12
+		switch (cpu_family) {
+			case CPUFAMILY_ARM_MONSOON_MISTRAL:
+			case CPUFAMILY_ARM_VORTEX_TEMPEST:
+			case CPUFAMILY_ARM_LIGHTNING_THUNDER:
+			case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
+				cpuinfo_isa.atomics = true;
 		}
-	#endif
+	}
 
 	const uint32_t has_feat_rdm = get_sys_info_by_name("hw.optional.arm.FEAT_RDM");
 	if (has_feat_rdm != 0) {
 		cpuinfo_isa.rdm = true;
+	} else {
+		// Optional in ARMv8.2-A (implemented in Apple cores),
+		// list only cores released before iOS 15 / macOS 12
+		switch (cpu_family) {
+			case CPUFAMILY_ARM_MONSOON_MISTRAL:
+			case CPUFAMILY_ARM_VORTEX_TEMPEST:
+			case CPUFAMILY_ARM_LIGHTNING_THUNDER:
+			case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
+				cpuinfo_isa.rdm = true;
+		}
 	}
 
 	const uint32_t has_feat_fp16 = get_sys_info_by_name("hw.optional.arm.FEAT_FP16");
 	if (has_feat_fp16 != 0) {
 		cpuinfo_isa.fp16arith = true;
 	} else {
+		// Optional in ARMv8.2-A (implemented in Apple cores),
+		// list only cores released before iOS 15 / macOS 12
 		switch (cpu_family) {
 			case CPUFAMILY_ARM_MONSOON_MISTRAL:
 			case CPUFAMILY_ARM_VORTEX_TEMPEST:
@@ -377,37 +318,6 @@
 		}
 	}
 
-	const uint32_t has_feat_dotprod = get_sys_info_by_name("hw.optional.arm.FEAT_DotProd");
-	if (has_feat_dotprod != 0) {
-		cpuinfo_isa.dot = true;
-	} else {
-		switch (cpu_family) {
-			case CPUFAMILY_ARM_LIGHTNING_THUNDER:
-			case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
-				cpuinfo_isa.dot = true;
-		}
-	}
-
-	const uint32_t has_feat_jscvt = get_sys_info_by_name("hw.optional.arm.FEAT_JSCVT");
-	if (has_feat_jscvt != 0) {
-		cpuinfo_isa.jscvt = true;
-	}
-
-	const uint32_t has_feat_fcma = get_sys_info_by_name("hw.optional.arm.FEAT_FCMA");
-	if (has_feat_fcma != 0) {
-		cpuinfo_isa.fcma = true;
-	}
-
-	const uint32_t has_feat_bf16 = get_sys_info_by_name("hw.optional.arm.FEAT_BF16");
-	if (has_feat_bf16 != 0) {
-		cpuinfo_isa.bf16 = true;
-	}
-
-	const uint32_t has_feat_i8mm = get_sys_info_by_name("hw.optional.arm.FEAT_I8MM");
-	if (has_feat_i8mm != 0) {
-		cpuinfo_isa.i8mm = true;
-	}
-
 	const uint32_t has_feat_fhm = get_sys_info_by_name("hw.optional.arm.FEAT_FHM");
 	if (has_feat_fhm != 0) {
 		cpuinfo_isa.fhm = true;
@@ -416,9 +326,63 @@
 		const uint32_t has_feat_fhm_legacy = get_sys_info_by_name("hw.optional.armv8_2_fhm");
 		if (has_feat_fhm_legacy != 0) {
 			cpuinfo_isa.fhm = true;
+		} else {
+			// Mandatory in ARMv8.4-A when FP16 arithmetics is implemented,
+			// list only cores released before iOS 15 / macOS 12
+			switch (cpu_family) {
+				case CPUFAMILY_ARM_LIGHTNING_THUNDER:
+				case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
+					cpuinfo_isa.fhm = true;
+			}
 		}
 	}
 
+	const uint32_t has_feat_bf16 = get_sys_info_by_name("hw.optional.arm.FEAT_BF16");
+	if (has_feat_bf16 != 0) {
+		cpuinfo_isa.bf16 = true;
+	}
+
+	const uint32_t has_feat_fcma = get_sys_info_by_name("hw.optional.arm.FEAT_FCMA");
+	if (has_feat_fcma != 0) {
+		cpuinfo_isa.fcma = true;
+	} else {
+		// Mandatory in ARMv8.3-A, list only cores released before iOS 15 / macOS 12
+		switch (cpu_family) {
+			case CPUFAMILY_ARM_LIGHTNING_THUNDER:
+			case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
+				cpuinfo_isa.fcma = true;
+		}
+	}
+
+	const uint32_t has_feat_jscvt = get_sys_info_by_name("hw.optional.arm.FEAT_JSCVT");
+	if (has_feat_jscvt != 0) {
+		cpuinfo_isa.jscvt = true;
+	} else {
+		// Mandatory in ARMv8.3-A, list only cores released before iOS 15 / macOS 12
+		switch (cpu_family) {
+			case CPUFAMILY_ARM_LIGHTNING_THUNDER:
+			case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
+				cpuinfo_isa.jscvt = true;
+		}
+	}
+
+	const uint32_t has_feat_dotprod = get_sys_info_by_name("hw.optional.arm.FEAT_DotProd");
+	if (has_feat_dotprod != 0) {
+		cpuinfo_isa.dot = true;
+	} else {
+		// Mandatory in ARMv8.4-A, list only cores released before iOS 15 / macOS 12
+		switch (cpu_family) {
+			case CPUFAMILY_ARM_LIGHTNING_THUNDER:
+			case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
+				cpuinfo_isa.dot = true;
+		}
+	}
+
+	const uint32_t has_feat_i8mm = get_sys_info_by_name("hw.optional.arm.FEAT_I8MM");
+	if (has_feat_i8mm != 0) {
+		cpuinfo_isa.i8mm = true;
+	}
+
 	uint32_t num_clusters = 1;
 	for (uint32_t i = 0; i < mach_topology.cores; i++) {
 		cores[i] = (struct cpuinfo_core) {
@@ -427,7 +391,7 @@
 			.core_id = i % cores_per_package,
 			.package = packages + i / cores_per_package,
 			.vendor = cpuinfo_vendor_apple,
-			.uarch = decode_uarch(cpu_family, cpu_subtype, i, mach_topology.cores),
+			.uarch = decode_uarch(cpu_family, i, mach_topology.cores),
 		};
 		if (i != 0 && cores[i].uarch != cores[i - 1].uarch) {
 			num_clusters++;
diff --git a/tools/cpu-info.c b/tools/cpu-info.c
index 2cd9598..8602fc0 100644
--- a/tools/cpu-info.c
+++ b/tools/cpu-info.c
@@ -253,6 +253,10 @@
 			return "Firestorm";
 		case cpuinfo_uarch_icestorm:
 			return "Icestorm";
+		case cpuinfo_uarch_avalanche:
+			return "Avalanche";
+		case cpuinfo_uarch_blizzard:
+			return "Blizzard";
 		case cpuinfo_uarch_thunderx:
 			return "ThunderX";
 		case cpuinfo_uarch_thunderx2: