Commit 85ab1b01e7

Andrew Kelley <andrew@ziglang.org>
2021-02-28 01:26:06
tools/update_cpu_features: add a "flatten" feature
and use it to clean up aarch64 target CPU features
1 parent e02acc0
Changed files (2)
lib/std/target/aarch64.zig
@@ -1,14 +1,10 @@
-// SPDX-License-Identifier: MIT
-// Copyright (c) 2015-2021 Zig Contributors
-// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
-// The MIT license requires this copyright notice to be included in all copies
-// and substantial portions of the software.
+//! This file is auto-generated by tools/update_cpu_features.zig.
+
 const std = @import("../std.zig");
 const CpuFeature = std.Target.Cpu.Feature;
 const CpuModel = std.Target.Cpu.Model;
 
 pub const Feature = enum {
-    a34,
     a65,
     a76,
     aes,
@@ -17,8 +13,6 @@ pub const Feature = enum {
     altnzcv,
     am,
     amvs,
-    apple_a10,
-    apple_a11,
     apple_a12,
     apple_a13,
     apple_a7,
@@ -26,6 +20,7 @@ pub const Feature = enum {
     arith_cbz_fusion,
     balance_fp_ops,
     bf16,
+    brbe,
     bti,
     call_saved_x10,
     call_saved_x11,
@@ -39,8 +34,11 @@ pub const Feature = enum {
     ccdp,
     ccidx,
     ccpp,
+    cmp_bcc_fusion,
     complxnum,
-    context_id_rel2,
+    contextidr_el2,
+    cortex_a78c,
+    cortex_r82,
     crc,
     crypto,
     custom_cheap_as_move,
@@ -50,14 +48,14 @@ pub const Feature = enum {
     ecv,
     ete,
     exynos_cheap_as_move,
-    exynosm4,
+    exynos_m4,
     f32mm,
     f64mm,
     fgt,
-    fmi,
+    flagm,
     force_32bit_jump_tables,
-    fp_armv8,
     fp16fml,
+    fp_armv8,
     fptoint,
     fullfp16,
     fuse_address,
@@ -68,9 +66,11 @@ pub const Feature = enum {
     fuse_literals,
     harden_sls_blr,
     harden_sls_retbr,
+    hcx,
     i8mm,
     jsconv,
     lor,
+    ls64,
     lse,
     lsl_fast,
     mpam,
@@ -83,9 +83,9 @@ pub const Feature = enum {
     no_neg_immediates,
     nv,
     outline_atomics,
-    pa,
     pan,
     pan_rwv,
+    pauth,
     perfmon,
     pmu,
     predictable_select_expensive,
@@ -129,6 +129,7 @@ pub const Feature = enum {
     slow_strqro_store,
     sm4,
     spe,
+    spe_eef,
     specrestrict,
     ssbs,
     strict_align,
@@ -151,15 +152,18 @@ pub const Feature = enum {
     use_experimental_zeroing_pseudos,
     use_postra_scheduler,
     use_reciprocal_square_root,
-    v8a,
     v8_1a,
     v8_2a,
     v8_3a,
     v8_4a,
     v8_5a,
     v8_6a,
+    v8_7a,
+    v8a,
     v8r,
     vh,
+    wfxt,
+    xs,
     zcm,
     zcz,
     zcz_fp,
@@ -174,26 +178,16 @@ pub const all_features = blk: {
     const len = @typeInfo(Feature).Enum.fields.len;
     std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
     var result: [len]CpuFeature = undefined;
-    result[@enumToInt(Feature.a34)] = .{
-        .llvm_name = "a35",
-        .description = "Cortex-A34 ARM processors",
-        .dependencies = featureSet(&[_]Feature{
-            .crc,
-            .crypto,
-            .perfmon,
-            .v8a,
-        }),
-    };
     result[@enumToInt(Feature.a65)] = .{
         .llvm_name = "a65",
         .description = "Cortex-A65 ARM processors",
         .dependencies = featureSet(&[_]Feature{
             .crypto,
             .dotprod,
-            .fp_armv8,
             .fullfp16,
-            .neon,
-            .ras,
+            .fuse_address,
+            .fuse_aes,
+            .fuse_literals,
             .rcpc,
             .ssbs,
             .v8_2a,
@@ -206,6 +200,7 @@ pub const all_features = blk: {
             .crypto,
             .dotprod,
             .fullfp16,
+            .fuse_aes,
             .rcpc,
             .ssbs,
             .v8_2a,
@@ -245,49 +240,6 @@ pub const all_features = blk: {
             .am,
         }),
     };
-    result[@enumToInt(Feature.apple_a10)] = .{
-        .llvm_name = "apple-a10",
-        .description = "Apple A10",
-        .dependencies = featureSet(&[_]Feature{
-            .alternate_sextload_cvt_f32_pattern,
-            .arith_bcc_fusion,
-            .arith_cbz_fusion,
-            .crc,
-            .crypto,
-            .disable_latency_sched_heuristic,
-            .fp_armv8,
-            .fuse_aes,
-            .fuse_crypto_eor,
-            .lor,
-            .neon,
-            .pan,
-            .perfmon,
-            .rdm,
-            .vh,
-            .zcm,
-            .zcz,
-        }),
-    };
-    result[@enumToInt(Feature.apple_a11)] = .{
-        .llvm_name = "apple-a11",
-        .description = "Apple A11",
-        .dependencies = featureSet(&[_]Feature{
-            .alternate_sextload_cvt_f32_pattern,
-            .arith_bcc_fusion,
-            .arith_cbz_fusion,
-            .crypto,
-            .disable_latency_sched_heuristic,
-            .fp_armv8,
-            .fullfp16,
-            .fuse_aes,
-            .fuse_crypto_eor,
-            .neon,
-            .perfmon,
-            .v8_2a,
-            .zcm,
-            .zcz,
-        }),
-    };
     result[@enumToInt(Feature.apple_a12)] = .{
         .llvm_name = "apple-a12",
         .description = "Apple A12",
@@ -297,11 +249,9 @@ pub const all_features = blk: {
             .arith_cbz_fusion,
             .crypto,
             .disable_latency_sched_heuristic,
-            .fp_armv8,
             .fullfp16,
             .fuse_aes,
             .fuse_crypto_eor,
-            .neon,
             .perfmon,
             .v8_3a,
             .zcm,
@@ -317,12 +267,9 @@ pub const all_features = blk: {
             .arith_cbz_fusion,
             .crypto,
             .disable_latency_sched_heuristic,
-            .fp_armv8,
             .fp16fml,
-            .fullfp16,
             .fuse_aes,
             .fuse_crypto_eor,
-            .neon,
             .perfmon,
             .sha3,
             .v8_4a,
@@ -339,10 +286,8 @@ pub const all_features = blk: {
             .arith_cbz_fusion,
             .crypto,
             .disable_latency_sched_heuristic,
-            .fp_armv8,
             .fuse_aes,
             .fuse_crypto_eor,
-            .neon,
             .perfmon,
             .zcm,
             .zcz,
@@ -369,6 +314,11 @@ pub const all_features = blk: {
         .description = "Enable BFloat16 Extension",
         .dependencies = featureSet(&[_]Feature{}),
     };
+    result[@enumToInt(Feature.brbe)] = .{
+        .llvm_name = "brbe",
+        .description = "Enable Branch Record Buffer Extension",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.bti)] = .{
         .llvm_name = "bti",
         .description = "Enable Branch Target Identification",
@@ -434,6 +384,11 @@ pub const all_features = blk: {
         .description = "Enable v8.2 data Cache Clean to Point of Persistence",
         .dependencies = featureSet(&[_]Feature{}),
     };
+    result[@enumToInt(Feature.cmp_bcc_fusion)] = .{
+        .llvm_name = "cmp-bcc-fusion",
+        .description = "CPU fuses cmp+bcc operations",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.complxnum)] = .{
         .llvm_name = "complxnum",
         .description = "Enable v8.3-A Floating-point complex number support",
@@ -441,11 +396,38 @@ pub const all_features = blk: {
             .neon,
         }),
     };
-    result[@enumToInt(Feature.context_id_rel2)] = .{
+    result[@enumToInt(Feature.contextidr_el2)] = .{
         .llvm_name = "CONTEXTIDREL2",
-        .description = "Enable RW operand CONTEXTIDR_EL2",
+        .description = "Enable RW operand Context ID Register (EL2)",
         .dependencies = featureSet(&[_]Feature{}),
     };
+    result[@enumToInt(Feature.cortex_a78c)] = .{
+        .llvm_name = "cortex-a78c",
+        .description = "Cortex-A78C ARM processors",
+        .dependencies = featureSet(&[_]Feature{
+            .cmp_bcc_fusion,
+            .crypto,
+            .dotprod,
+            .flagm,
+            .fp16fml,
+            .fuse_aes,
+            .pauth,
+            .perfmon,
+            .rcpc,
+            .spe,
+            .ssbs,
+            .use_postra_scheduler,
+            .v8_2a,
+        }),
+    };
+    result[@enumToInt(Feature.cortex_r82)] = .{
+        .llvm_name = "cortex-r82",
+        .description = "Cortex-R82 ARM Processors",
+        .dependencies = featureSet(&[_]Feature{
+            .use_postra_scheduler,
+            .v8r,
+        }),
+    };
     result[@enumToInt(Feature.crc)] = .{
         .llvm_name = "crc",
         .description = "Enable ARMv8 CRC-32 checksum instructions",
@@ -456,7 +438,6 @@ pub const all_features = blk: {
         .description = "Enable cryptographic instructions",
         .dependencies = featureSet(&[_]Feature{
             .aes,
-            .neon,
             .sha2,
         }),
     };
@@ -499,7 +480,7 @@ pub const all_features = blk: {
             .custom_cheap_as_move,
         }),
     };
-    result[@enumToInt(Feature.exynosm4)] = .{
+    result[@enumToInt(Feature.exynos_m4)] = .{
         .llvm_name = "exynosm4",
         .description = "Samsung Exynos-M4 processors",
         .dependencies = featureSet(&[_]Feature{
@@ -541,8 +522,8 @@ pub const all_features = blk: {
         .description = "Enable fine grained virtualization traps extension",
         .dependencies = featureSet(&[_]Feature{}),
     };
-    result[@enumToInt(Feature.fmi)] = .{
-        .llvm_name = "fmi",
+    result[@enumToInt(Feature.flagm)] = .{
+        .llvm_name = "flagm",
         .description = "Enable v8.4-A Flag Manipulation Instructions",
         .dependencies = featureSet(&[_]Feature{}),
     };
@@ -551,11 +532,6 @@ pub const all_features = blk: {
         .description = "Force jump table entries to be 32-bits wide except at MinSize",
         .dependencies = featureSet(&[_]Feature{}),
     };
-    result[@enumToInt(Feature.fp_armv8)] = .{
-        .llvm_name = "fp-armv8",
-        .description = "Enable ARMv8 FP",
-        .dependencies = featureSet(&[_]Feature{}),
-    };
     result[@enumToInt(Feature.fp16fml)] = .{
         .llvm_name = "fp16fml",
         .description = "Enable FP16 FML instructions",
@@ -563,6 +539,11 @@ pub const all_features = blk: {
             .fullfp16,
         }),
     };
+    result[@enumToInt(Feature.fp_armv8)] = .{
+        .llvm_name = "fp-armv8",
+        .description = "Enable ARMv8 FP",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.fptoint)] = .{
         .llvm_name = "fptoint",
         .description = "Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int",
@@ -615,6 +596,11 @@ pub const all_features = blk: {
         .description = "Harden against straight line speculation across RET and BR instructions",
         .dependencies = featureSet(&[_]Feature{}),
     };
+    result[@enumToInt(Feature.hcx)] = .{
+        .llvm_name = "hcx",
+        .description = "Enable Armv8.7-A HCRX_EL2 system register",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.i8mm)] = .{
         .llvm_name = "i8mm",
         .description = "Enable Matrix Multiply Int8 Extension",
@@ -632,6 +618,11 @@ pub const all_features = blk: {
         .description = "Enables ARM v8.1 Limited Ordering Regions extension",
         .dependencies = featureSet(&[_]Feature{}),
     };
+    result[@enumToInt(Feature.ls64)] = .{
+        .llvm_name = "ls64",
+        .description = "Enable Armv8.7-A LD64B/ST64B Accelerator Extension",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.lse)] = .{
         .llvm_name = "lse",
         .description = "Enable ARMv8.1 Large System Extension (LSE) atomic instructions",
@@ -665,9 +656,7 @@ pub const all_features = blk: {
         .dependencies = featureSet(&[_]Feature{
             .crypto,
             .dotprod,
-            .fp_armv8,
             .fullfp16,
-            .neon,
             .rcpc,
             .ssbs,
             .v8_2a,
@@ -679,9 +668,7 @@ pub const all_features = blk: {
         .dependencies = featureSet(&[_]Feature{
             .crypto,
             .dotprod,
-            .fp_armv8,
             .fullfp16,
-            .neon,
             .rcpc,
             .spe,
             .ssbs,
@@ -696,9 +683,7 @@ pub const all_features = blk: {
             .ete,
             .i8mm,
             .mte,
-            .sve2,
             .sve2_bitperm,
-            .trbe,
             .v8_5a,
         }),
     };
@@ -709,12 +694,9 @@ pub const all_features = blk: {
             .bf16,
             .ccdp,
             .crypto,
-            .fp_armv8,
             .fp16fml,
-            .fullfp16,
             .fuse_aes,
             .i8mm,
-            .neon,
             .perfmon,
             .rand,
             .spe,
@@ -731,7 +713,7 @@ pub const all_features = blk: {
     };
     result[@enumToInt(Feature.nv)] = .{
         .llvm_name = "nv",
-        .description = "Enable v8.4-A Nested Virtualization extension",
+        .description = "Enable v8.4-A Nested Virtualization Enchancement",
         .dependencies = featureSet(&[_]Feature{}),
     };
     result[@enumToInt(Feature.outline_atomics)] = .{
@@ -739,11 +721,6 @@ pub const all_features = blk: {
         .description = "Enable out of line atomics to support LSE instructions",
         .dependencies = featureSet(&[_]Feature{}),
     };
-    result[@enumToInt(Feature.pa)] = .{
-        .llvm_name = "pa",
-        .description = "Enable v8.3-A Pointer Authentication extension",
-        .dependencies = featureSet(&[_]Feature{}),
-    };
     result[@enumToInt(Feature.pan)] = .{
         .llvm_name = "pan",
         .description = "Enables ARM v8.1 Privileged Access-Never extension",
@@ -756,6 +733,11 @@ pub const all_features = blk: {
             .pan,
         }),
     };
+    result[@enumToInt(Feature.pauth)] = .{
+        .llvm_name = "pauth",
+        .description = "Enable v8.3-A Pointer Authentication extension",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.perfmon)] = .{
         .llvm_name = "perfmon",
         .description = "Enable ARMv8 PMUv3 Performance Monitors extension",
@@ -949,7 +931,6 @@ pub const all_features = blk: {
         .llvm_name = "sha3",
         .description = "Enable SHA512 and SHA3 support",
         .dependencies = featureSet(&[_]Feature{
-            .neon,
             .sha2,
         }),
     };
@@ -980,6 +961,11 @@ pub const all_features = blk: {
         .description = "Enable Statistical Profiling extension",
         .dependencies = featureSet(&[_]Feature{}),
     };
+    result[@enumToInt(Feature.spe_eef)] = .{
+        .llvm_name = "spe-eef",
+        .description = "Enable extra register in the Statistical Profiling Extension",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.specrestrict)] = .{
         .llvm_name = "specrestrict",
         .description = "Enable architectural speculation restriction",
@@ -998,7 +984,9 @@ pub const all_features = blk: {
     result[@enumToInt(Feature.sve)] = .{
         .llvm_name = "sve",
         .description = "Enable Scalable Vector Extension (SVE) instructions",
-        .dependencies = featureSet(&[_]Feature{}),
+        .dependencies = featureSet(&[_]Feature{
+            .fullfp16,
+        }),
     };
     result[@enumToInt(Feature.sve2)] = .{
         .llvm_name = "sve2",
@@ -1103,14 +1091,6 @@ pub const all_features = blk: {
         .description = "Use the reciprocal square root approximation",
         .dependencies = featureSet(&[_]Feature{}),
     };
-    result[@enumToInt(Feature.v8a)] = .{
-        .llvm_name = null,
-        .description = "Support ARM v8a instructions",
-        .dependencies = featureSet(&[_]Feature{
-            .fp_armv8,
-            .neon,
-        }),
-    };
     result[@enumToInt(Feature.v8_1a)] = .{
         .llvm_name = "v8.1a",
         .description = "Support ARM v8.1a instructions",
@@ -1120,8 +1100,8 @@ pub const all_features = blk: {
             .lse,
             .pan,
             .rdm,
-            .vh,
             .v8a,
+            .vh,
         }),
     };
     result[@enumToInt(Feature.v8_2a)] = .{
@@ -1142,7 +1122,7 @@ pub const all_features = blk: {
             .ccidx,
             .complxnum,
             .jsconv,
-            .pa,
+            .pauth,
             .rcpc,
             .v8_2a,
         }),
@@ -1154,7 +1134,7 @@ pub const all_features = blk: {
             .am,
             .dit,
             .dotprod,
-            .fmi,
+            .flagm,
             .mpam,
             .nv,
             .pmu,
@@ -1192,13 +1172,73 @@ pub const all_features = blk: {
             .v8_5a,
         }),
     };
+    result[@enumToInt(Feature.v8_7a)] = .{
+        .llvm_name = "v8.7a",
+        .description = "Support ARM v8.7a instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .hcx,
+            .v8_6a,
+            .wfxt,
+            .xs,
+        }),
+    };
+    result[@enumToInt(Feature.v8a)] = .{
+        .llvm_name = null,
+        .description = "Support ARM v8a instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .neon,
+        }),
+    };
+    result[@enumToInt(Feature.v8r)] = .{
+        .llvm_name = "v8r",
+        .description = "Support ARM v8r instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .ccidx,
+            .ccpp,
+            .complxnum,
+            .contextidr_el2,
+            .crc,
+            .dit,
+            .dotprod,
+            .flagm,
+            .fp16fml,
+            .jsconv,
+            .lse,
+            .pan_rwv,
+            .pauth,
+            .perfmon,
+            .predres,
+            .ras,
+            .rcpc_immo,
+            .rdm,
+            .sb,
+            .sel2,
+            .sha3,
+            .sm4,
+            .specrestrict,
+            .ssbs,
+            .tlb_rmi,
+            .tracev8_4,
+            .uaops,
+        }),
+    };
     result[@enumToInt(Feature.vh)] = .{
         .llvm_name = "vh",
         .description = "Enables ARM v8.1 Virtual Host extension",
         .dependencies = featureSet(&[_]Feature{
-            .context_id_rel2,
+            .contextidr_el2,
         }),
     };
+    result[@enumToInt(Feature.wfxt)] = .{
+        .llvm_name = "wfxt",
+        .description = "Enable Armv8.7-A WFET and WFIT instruction",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
+    result[@enumToInt(Feature.xs)] = .{
+        .llvm_name = "xs",
+        .description = "Enable Armv8.7-A limited-TLB-maintenance instruction",
+        .dependencies = featureSet(&[_]Feature{}),
+    };
     result[@enumToInt(Feature.zcm)] = .{
         .llvm_name = "zcm",
         .description = "Has zero-cycle register moves",
@@ -1240,11 +1280,11 @@ pub const cpu = struct {
         .name = "a64fx",
         .llvm_name = "a64fx",
         .features = featureSet(&[_]Feature{
+            .aggressive_fma,
+            .arith_bcc_fusion,
             .complxnum,
-            .fp_armv8,
-            .fullfp16,
-            .neon,
             .perfmon,
+            .predictable_select_expensive,
             .sha2,
             .sve,
             .use_postra_scheduler,
@@ -1255,14 +1295,39 @@ pub const cpu = struct {
         .name = "apple_a10",
         .llvm_name = "apple-a10",
         .features = featureSet(&[_]Feature{
-            .apple_a10,
+            .alternate_sextload_cvt_f32_pattern,
+            .arith_bcc_fusion,
+            .arith_cbz_fusion,
+            .crc,
+            .crypto,
+            .disable_latency_sched_heuristic,
+            .fuse_aes,
+            .fuse_crypto_eor,
+            .lor,
+            .pan,
+            .perfmon,
+            .rdm,
+            .vh,
+            .zcm,
+            .zcz,
         }),
     };
     pub const apple_a11 = CpuModel{
         .name = "apple_a11",
         .llvm_name = "apple-a11",
         .features = featureSet(&[_]Feature{
-            .apple_a11,
+            .alternate_sextload_cvt_f32_pattern,
+            .arith_bcc_fusion,
+            .arith_cbz_fusion,
+            .crypto,
+            .disable_latency_sched_heuristic,
+            .fullfp16,
+            .fuse_aes,
+            .fuse_crypto_eor,
+            .perfmon,
+            .v8_2a,
+            .zcm,
+            .zcz,
         }),
     };
     pub const apple_a12 = CpuModel{
@@ -1279,6 +1344,37 @@ pub const cpu = struct {
             .apple_a13,
         }),
     };
+    pub const apple_a14 = CpuModel{
+        .name = "apple_a14",
+        .llvm_name = "apple-a14",
+        .features = featureSet(&[_]Feature{
+            .aggressive_fma,
+            .alternate_sextload_cvt_f32_pattern,
+            .altnzcv,
+            .arith_bcc_fusion,
+            .arith_cbz_fusion,
+            .ccdp,
+            .crypto,
+            .disable_latency_sched_heuristic,
+            .fp16fml,
+            .fptoint,
+            .fuse_address,
+            .fuse_aes,
+            .fuse_arith_logic,
+            .fuse_crypto_eor,
+            .fuse_csel,
+            .fuse_literals,
+            .perfmon,
+            .predres,
+            .sb,
+            .sha3,
+            .specrestrict,
+            .ssbs,
+            .v8_4a,
+            .zcm,
+            .zcz,
+        }),
+    };
     pub const apple_a7 = CpuModel{
         .name = "apple_a7",
         .llvm_name = "apple-a7",
@@ -1327,7 +1423,6 @@ pub const cpu = struct {
         .features = featureSet(&[_]Feature{
             .crypto,
             .fullfp16,
-            .neon,
             .v8_2a,
         }),
     };
@@ -1335,14 +1430,20 @@ pub const cpu = struct {
         .name = "cortex_a34",
         .llvm_name = "cortex-a34",
         .features = featureSet(&[_]Feature{
-            .a34,
+            .crc,
+            .crypto,
+            .perfmon,
+            .v8a,
         }),
     };
     pub const cortex_a35 = CpuModel{
         .name = "cortex_a35",
         .llvm_name = "cortex-a35",
         .features = featureSet(&[_]Feature{
-            .a34,
+            .crc,
+            .crypto,
+            .perfmon,
+            .v8a,
         }),
     };
     pub const cortex_a53 = CpuModel{
@@ -1410,6 +1511,7 @@ pub const cpu = struct {
             .crc,
             .crypto,
             .fuse_aes,
+            .fuse_literals,
             .perfmon,
             .v8a,
         }),
@@ -1456,11 +1558,11 @@ pub const cpu = struct {
         .name = "cortex_a77",
         .llvm_name = "cortex-a77",
         .features = featureSet(&[_]Feature{
+            .cmp_bcc_fusion,
             .crypto,
             .dotprod,
-            .fp_armv8,
             .fullfp16,
-            .neon,
+            .fuse_aes,
             .rcpc,
             .v8_2a,
         }),
@@ -1469,12 +1571,11 @@ pub const cpu = struct {
         .name = "cortex_a78",
         .llvm_name = "cortex-a78",
         .features = featureSet(&[_]Feature{
+            .cmp_bcc_fusion,
             .crypto,
             .dotprod,
-            .fp_armv8,
             .fullfp16,
             .fuse_aes,
-            .neon,
             .perfmon,
             .rcpc,
             .spe,
@@ -1483,24 +1584,29 @@ pub const cpu = struct {
             .v8_2a,
         }),
     };
+    pub const cortex_a78c = CpuModel{
+        .name = "cortex_a78c",
+        .llvm_name = "cortex-a78c",
+        .features = featureSet(&[_]Feature{
+            .cortex_a78c,
+        }),
+    };
     pub const cortex_r82 = CpuModel{
         .name = "cortex_r82",
         .llvm_name = "cortex-r82",
         .features = featureSet(&[_]Feature{
-            .use_postra_scheduler,
-            .v8r,
+            .cortex_r82,
         }),
     };
     pub const cortex_x1 = CpuModel{
         .name = "cortex_x1",
         .llvm_name = "cortex-x1",
         .features = featureSet(&[_]Feature{
+            .cmp_bcc_fusion,
             .crypto,
             .dotprod,
-            .fp_armv8,
             .fullfp16,
             .fuse_aes,
-            .neon,
             .perfmon,
             .rcpc,
             .spe,
@@ -1574,14 +1680,14 @@ pub const cpu = struct {
         .name = "exynos_m4",
         .llvm_name = "exynos-m4",
         .features = featureSet(&[_]Feature{
-            .exynosm4,
+            .exynos_m4,
         }),
     };
     pub const exynos_m5 = CpuModel{
         .name = "exynos_m5",
         .llvm_name = "exynos-m5",
         .features = featureSet(&[_]Feature{
-            .exynosm4,
+            .exynos_m4,
         }),
     };
     pub const falkor = CpuModel{
@@ -1607,9 +1713,9 @@ pub const cpu = struct {
         .features = featureSet(&[_]Feature{
             .ete,
             .fuse_aes,
+            .neon,
             .perfmon,
             .use_postra_scheduler,
-            .v8a,
         }),
     };
     pub const kryo = CpuModel{
@@ -1623,8 +1729,8 @@ pub const cpu = struct {
             .perfmon,
             .predictable_select_expensive,
             .use_postra_scheduler,
-            .zcz,
             .v8a,
+            .zcz,
         }),
     };
     pub const neoverse_e1 = CpuModel{
@@ -1688,9 +1794,7 @@ pub const cpu = struct {
         .features = featureSet(&[_]Feature{
             .aggressive_fma,
             .arith_bcc_fusion,
-            .crc,
             .crypto,
-            .lse,
             .predictable_select_expensive,
             .use_postra_scheduler,
             .v8_1a,
@@ -1703,12 +1807,7 @@ pub const cpu = struct {
             .aggressive_fma,
             .arith_bcc_fusion,
             .balance_fp_ops,
-            .crc,
             .crypto,
-            .fp_armv8,
-            .lse,
-            .neon,
-            .pa,
             .perfmon,
             .predictable_select_expensive,
             .strict_align,
@@ -1761,7 +1860,6 @@ pub const cpu = struct {
             .custom_cheap_as_move,
             .dotprod,
             .fp16fml,
-            .fullfp16,
             .fuse_aes,
             .perfmon,
             .spe,
tools/update_cpu_features.zig
@@ -8,7 +8,11 @@ const assert = std.debug.assert;
 
 const FeatureOverride = struct {
     llvm_name: []const u8,
+    /// If true, completely omit the feature; as if it does not exist.
     omit: bool = false,
+    /// If true, omit the feature, but all the dependencies of the feature
+    /// are added in its place.
+    flatten: bool = false,
     zig_name: ?[]const u8 = null,
     desc: ?[]const u8 = null,
     extra_deps: []const []const u8 = &.{},
@@ -25,6 +29,7 @@ const Feature = struct {
     zig_name: []const u8,
     desc: []const u8,
     deps: []const []const u8,
+    flatten: bool = false,
 };
 
 const LlvmTarget = struct {
@@ -68,6 +73,8 @@ const llvm_targets = [_]LlvmTarget{
             .{
                 .llvm_name = "exynosm3",
                 .zig_name = "exynos_m3",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
             },
             .{
                 .llvm_name = "exynosm4",
@@ -77,6 +84,117 @@ const llvm_targets = [_]LlvmTarget{
                 .llvm_name = "v8.1a",
                 .extra_deps = &.{"v8a"},
             },
+            .{
+                .llvm_name = "a35",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "a53",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "a55",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "a57",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "a64fx",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "a72",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "a73",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "a75",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "a77",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "apple-a10",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "apple-a11",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "apple-a14",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "carmel",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "cortex-a78",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "cortex-x1",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "falkor",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "kryo",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "saphira",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "thunderx",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "thunderx2t99",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "thunderx3t110",
+                .flatten = true,
+            },
+            .{
+                .llvm_name = "thunderxt81",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "thunderxt83",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "thunderxt88",
+                .flatten = true,
+                .extra_deps = &.{"v8a"},
+            },
+            .{
+                .llvm_name = "tsv110",
+                .flatten = true,
+            },
         },
         .extra_features = &.{
             .{
@@ -85,6 +203,43 @@ const llvm_targets = [_]LlvmTarget{
                 .deps = &.{ "fp_armv8", "neon" },
             },
         },
+        .extra_cpus = &.{
+            .{
+                .llvm_name = null,
+                .zig_name = "exynos_m1",
+                .features = &.{
+                    "crc",
+                    "crypto",
+                    "exynos_cheap_as_move",
+                    "force_32bit_jump_tables",
+                    "fuse_aes",
+                    "perfmon",
+                    "slow_misaligned_128store",
+                    "slow_paired_128",
+                    "use_postra_scheduler",
+                    "use_reciprocal_square_root",
+                    "v8a",
+                    "zcz_fp",
+                },
+            },
+            .{
+                .llvm_name = null,
+                .zig_name = "exynos_m2",
+                .features = &.{
+                    "crc",
+                    "crypto",
+                    "exynos_cheap_as_move",
+                    "force_32bit_jump_tables",
+                    "fuse_aes",
+                    "perfmon",
+                    "slow_misaligned_128store",
+                    "slow_paired_128",
+                    "use_postra_scheduler",
+                    "v8a",
+                    "zcz_fp",
+                },
+            },
+        },
     },
     .{
         .zig_name = "amdgpu",
@@ -374,22 +529,32 @@ fn processOneTarget(job: Job) anyerror!void {
                 const llvm_name = kv.value.Object.get("Name").?.String;
                 if (llvm_name.len == 0) continue;
 
-                var zig_name = (try llvmNameToZigName(arena, llvm_target, llvm_name)) orelse
-                    continue :root_it;
+                var zig_name = try llvmNameToZigName(arena, llvm_name);
                 var desc = kv.value.Object.get("Desc").?.String;
                 var deps = std.ArrayList([]const u8).init(arena);
+                var omit = false;
+                var flatten = false;
                 const implies = kv.value.Object.get("Implies").?.Array;
                 for (implies.items) |imply| {
                     const other_key = imply.Object.get("def").?.String;
                     const other_obj = &root_map.getEntry(other_key).?.value.Object;
                     const other_llvm_name = other_obj.get("Name").?.String;
-                    const other_zig_name = (try llvmNameToZigName(arena, llvm_target, other_llvm_name)) orelse continue;
+                    const other_zig_name = (try llvmNameToZigNameOmit(
+                        arena,
+                        llvm_target,
+                        other_llvm_name,
+                    )) orelse continue;
                     try deps.append(other_zig_name);
                 }
                 for (llvm_target.feature_overrides) |feature_override| {
                     if (mem.eql(u8, llvm_name, feature_override.llvm_name)) {
                         if (feature_override.omit) {
-                            continue :root_it;
+                            // Still put the feature into the table so that we can
+                            // expand dependencies for the feature overrides marked `flatten`.
+                            omit = true;
+                        }
+                        if (feature_override.flatten) {
+                            flatten = true;
                         }
                         if (feature_override.zig_name) |override_name| {
                             zig_name = override_name;
@@ -408,16 +573,18 @@ fn processOneTarget(job: Job) anyerror!void {
                     .zig_name = zig_name,
                     .desc = desc,
                     .deps = deps.items,
+                    .flatten = flatten,
                 };
                 try features_table.put(zig_name, feature);
-                try all_features.append(feature);
+                if (!omit and !flatten) {
+                    try all_features.append(feature);
+                }
             }
             if (hasSuperclass(&kv.value.Object, "Processor")) {
                 const llvm_name = kv.value.Object.get("Name").?.String;
                 if (llvm_name.len == 0) continue;
 
-                var zig_name = (try llvmNameToZigName(arena, llvm_target, llvm_name)) orelse
-                    continue :root_it;
+                var zig_name = try llvmNameToZigName(arena, llvm_name);
                 var deps = std.ArrayList([]const u8).init(arena);
                 const features = kv.value.Object.get("Features").?.Array;
                 for (features.items) |feature| {
@@ -425,7 +592,11 @@ fn processOneTarget(job: Job) anyerror!void {
                     const feature_obj = &root_map.getEntry(feature_key).?.value.Object;
                     const feature_llvm_name = feature_obj.get("Name").?.String;
                     if (feature_llvm_name.len == 0) continue;
-                    const feature_zig_name = (try llvmNameToZigName(arena, llvm_target, feature_llvm_name)) orelse continue;
+                    const feature_zig_name = (try llvmNameToZigNameOmit(
+                        arena,
+                        llvm_target,
+                        feature_llvm_name,
+                    )) orelse continue;
                     try deps.append(feature_zig_name);
                 }
                 const tune_features = kv.value.Object.get("TuneFeatures").?.Array;
@@ -434,7 +605,11 @@ fn processOneTarget(job: Job) anyerror!void {
                     const feature_obj = &root_map.getEntry(feature_key).?.value.Object;
                     const feature_llvm_name = feature_obj.get("Name").?.String;
                     if (feature_llvm_name.len == 0) continue;
-                    const feature_zig_name = (try llvmNameToZigName(arena, llvm_target, feature_llvm_name)) orelse continue;
+                    const feature_zig_name = (try llvmNameToZigNameOmit(
+                        arena,
+                        llvm_target,
+                        feature_llvm_name,
+                    )) orelse continue;
                     try deps.append(feature_zig_name);
                 }
                 for (llvm_target.feature_overrides) |feature_override| {
@@ -549,7 +724,7 @@ fn processOneTarget(job: Job) anyerror!void {
         }
         var deps_set = std.StringHashMap(void).init(arena);
         for (feature.deps) |dep| {
-            try deps_set.put(dep, {});
+            try putDep(&deps_set, features_table, dep);
         }
         try pruneFeatures(arena, features_table, &deps_set);
         var dependencies = std.ArrayList([]const u8).init(arena);
@@ -594,7 +769,7 @@ fn processOneTarget(job: Job) anyerror!void {
     for (all_cpus.items) |cpu| {
         var deps_set = std.StringHashMap(void).init(arena);
         for (cpu.features) |feature_zig_name| {
-            try deps_set.put(feature_zig_name, {});
+            try putDep(&deps_set, features_table, feature_zig_name);
         }
         try pruneFeatures(arena, features_table, &deps_set);
         var cpu_features = std.ArrayList([]const u8).init(arena);
@@ -679,7 +854,16 @@ fn asciiLessThan(context: void, a: []const u8, b: []const u8) bool {
     return std.ascii.lessThanIgnoreCase(a, b);
 }
 
-fn llvmNameToZigName(
+fn llvmNameToZigName(arena: *mem.Allocator, llvm_name: []const u8) ![]const u8 {
+    const duped = try arena.dupe(u8, llvm_name);
+    for (duped) |*byte| switch (byte.*) {
+        '-', '.' => byte.* = '_',
+        else => continue,
+    };
+    return duped;
+}
+
+fn llvmNameToZigNameOmit(
     arena: *mem.Allocator,
     llvm_target: LlvmTarget,
     llvm_name: []const u8,
@@ -690,12 +874,7 @@ fn llvmNameToZigName(
             return feature_override.zig_name orelse break;
         }
     }
-    const duped = try arena.dupe(u8, llvm_name);
-    for (duped) |*byte| switch (byte.*) {
-        '-', '.' => byte.* = '_',
-        else => continue,
-    };
-    return duped;
+    return try llvmNameToZigName(arena, llvm_name);
 }
 
 fn hasSuperclass(obj: *json.ObjectMap, class_name: []const u8) bool {
@@ -744,3 +923,18 @@ fn walkFeatures(
         try walkFeatures(features_table, deletion_set, other_feature);
     }
 }
+
+fn putDep(
+    deps_set: *std.StringHashMap(void),
+    features_table: std.StringHashMap(Feature),
+    zig_feature_name: []const u8,
+) error{OutOfMemory}!void {
+    const feature = features_table.get(zig_feature_name).?;
+    if (feature.flatten) {
+        for (feature.deps) |dep| {
+            try putDep(deps_set, features_table, dep);
+        }
+    } else {
+        try deps_set.put(zig_feature_name, {});
+    }
+}