Commit a867b43366

Andrew Kelley <andrew@ziglang.org>
2020-01-19 08:40:35
progress towards merging
see BRANCH_TODO file
1 parent c156234
lib/std/os/linux/tls.zig
@@ -211,7 +211,7 @@ pub fn initTLS() ?*elf.Phdr {
 
     if (tls_phdr) |phdr| {
         // If the cpu is arm-based, check if it supports the TLS register
-        if (builtin.arch == builtin.Arch.arm and at_hwcap & std.os.linux.HWCAP_TLS == 0) {
+        if (builtin.arch == .arm and at_hwcap & std.os.linux.HWCAP_TLS == 0) {
             // If the CPU does not support TLS via a coprocessor register,
             // a kernel helper function can be used instead on certain linux kernels.
             // See linux/arch/arm/include/asm/tls.h and musl/src/thread/arm/__set_thread_area.c.
lib/std/target/aarch64.zig
@@ -1,1603 +1,1528 @@
-const Feature = @import("std").target.Feature;
-const Cpu = @import("std").target.Cpu;
-
-pub const feature_aes = Feature{
-    .name = "aes",
-    .llvm_name = "aes",
-    .description = "Enable AES support",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_am = Feature{
-    .name = "am",
-    .llvm_name = "am",
-    .description = "Enable v8.4-A Activity Monitors extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_aggressiveFma = Feature{
-    .name = "aggressiveFma",
-    .llvm_name = "aggressive-fma",
-    .description = "Enable Aggressive FMA for floating-point.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_altnzcv = Feature{
-    .name = "altnzcv",
-    .llvm_name = "altnzcv",
-    .description = "Enable alternative NZCV format for floating point comparisons",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_alternateSextloadCvtF32Pattern = Feature{
-    .name = "alternateSextloadCvtF32Pattern",
-    .llvm_name = "alternate-sextload-cvt-f32-pattern",
-    .description = "Use alternative pattern for sextload convert to f32",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_arithBccFusion = Feature{
-    .name = "arithBccFusion",
-    .llvm_name = "arith-bcc-fusion",
-    .description = "CPU fuses arithmetic+bcc operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_arithCbzFusion = Feature{
-    .name = "arithCbzFusion",
-    .llvm_name = "arith-cbz-fusion",
-    .description = "CPU fuses arithmetic + cbz/cbnz operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_balanceFpOps = Feature{
-    .name = "balanceFpOps",
-    .llvm_name = "balance-fp-ops",
-    .description = "balance mix of odd and even D-registers for fp multiply(-accumulate) ops",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_bti = Feature{
-    .name = "bti",
-    .llvm_name = "bti",
-    .description = "Enable Branch Target Identification",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_ccidx = Feature{
-    .name = "ccidx",
-    .llvm_name = "ccidx",
-    .description = "Enable v8.3-A Extend of the CCSIDR number of sets",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_ccpp = Feature{
-    .name = "ccpp",
-    .llvm_name = "ccpp",
-    .description = "Enable v8.2 data Cache Clean to Point of Persistence",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_crc = Feature{
-    .name = "crc",
-    .llvm_name = "crc",
-    .description = "Enable ARMv8 CRC-32 checksum instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_ccdp = Feature{
-    .name = "ccdp",
-    .llvm_name = "ccdp",
-    .description = "Enable v8.5 Cache Clean to Point of Deep Persistence",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX8 = Feature{
-    .name = "callSavedX8",
-    .llvm_name = "call-saved-x8",
-    .description = "Make X8 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX9 = Feature{
-    .name = "callSavedX9",
-    .llvm_name = "call-saved-x9",
-    .description = "Make X9 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX10 = Feature{
-    .name = "callSavedX10",
-    .llvm_name = "call-saved-x10",
-    .description = "Make X10 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX11 = Feature{
-    .name = "callSavedX11",
-    .llvm_name = "call-saved-x11",
-    .description = "Make X11 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX12 = Feature{
-    .name = "callSavedX12",
-    .llvm_name = "call-saved-x12",
-    .description = "Make X12 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX13 = Feature{
-    .name = "callSavedX13",
-    .llvm_name = "call-saved-x13",
-    .description = "Make X13 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX14 = Feature{
-    .name = "callSavedX14",
-    .llvm_name = "call-saved-x14",
-    .description = "Make X14 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX15 = Feature{
-    .name = "callSavedX15",
-    .llvm_name = "call-saved-x15",
-    .description = "Make X15 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_callSavedX18 = Feature{
-    .name = "callSavedX18",
-    .llvm_name = "call-saved-x18",
-    .description = "Make X18 callee saved.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_complxnum = Feature{
-    .name = "complxnum",
-    .llvm_name = "complxnum",
-    .description = "Enable v8.3-A Floating-point complex number support",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_crypto = Feature{
-    .name = "crypto",
-    .llvm_name = "crypto",
-    .description = "Enable cryptographic instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_customCheapAsMove = Feature{
-    .name = "customCheapAsMove",
-    .llvm_name = "custom-cheap-as-move",
-    .description = "Use custom handling of cheap instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_dit = Feature{
-    .name = "dit",
-    .llvm_name = "dit",
-    .description = "Enable v8.4-A Data Independent Timing instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_disableLatencySchedHeuristic = Feature{
-    .name = "disableLatencySchedHeuristic",
-    .llvm_name = "disable-latency-sched-heuristic",
-    .description = "Disable latency scheduling heuristic",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_dotprod = Feature{
-    .name = "dotprod",
-    .llvm_name = "dotprod",
-    .description = "Enable dot product support",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_exynosCheapAsMove = Feature{
-    .name = "exynosCheapAsMove",
-    .llvm_name = "exynos-cheap-as-move",
-    .description = "Use Exynos specific handling of cheap instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_customCheapAsMove,
-    },
-};
-
-pub const feature_fmi = Feature{
-    .name = "fmi",
-    .llvm_name = "fmi",
-    .description = "Enable v8.4-A Flag Manipulation Instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fp16fml = Feature{
-    .name = "fp16fml",
-    .llvm_name = "fp16fml",
-    .description = "Enable FP16 FML instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_fpArmv8 = Feature{
-    .name = "fpArmv8",
-    .llvm_name = "fp-armv8",
-    .description = "Enable ARMv8 FP",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fptoint = Feature{
-    .name = "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",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_force32bitJumpTables = Feature{
-    .name = "force32bitJumpTables",
-    .llvm_name = "force-32bit-jump-tables",
-    .description = "Force jump table entries to be 32-bits wide except at MinSize",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fullfp16 = Feature{
-    .name = "fullfp16",
-    .llvm_name = "fullfp16",
-    .description = "Full FP16",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_fuseAes = Feature{
-    .name = "fuseAes",
-    .llvm_name = "fuse-aes",
-    .description = "CPU fuses AES crypto operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fuseAddress = Feature{
-    .name = "fuseAddress",
-    .llvm_name = "fuse-address",
-    .description = "CPU fuses address generation and memory operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fuseArithLogic = Feature{
-    .name = "fuseArithLogic",
-    .llvm_name = "fuse-arith-logic",
-    .description = "CPU fuses arithmetic and logic operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fuseCsel = Feature{
-    .name = "fuseCsel",
-    .llvm_name = "fuse-csel",
-    .description = "CPU fuses conditional select operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fuseCryptoEor = Feature{
-    .name = "fuseCryptoEor",
-    .llvm_name = "fuse-crypto-eor",
-    .description = "CPU fuses AES/PMULL and EOR operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_fuseLiterals = Feature{
-    .name = "fuseLiterals",
-    .llvm_name = "fuse-literals",
-    .description = "CPU fuses literal generation operations",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_jsconv = Feature{
-    .name = "jsconv",
-    .llvm_name = "jsconv",
-    .description = "Enable v8.3-A JavaScript FP conversion enchancement",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_lor = Feature{
-    .name = "lor",
-    .llvm_name = "lor",
-    .description = "Enables ARM v8.1 Limited Ordering Regions extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_lse = Feature{
-    .name = "lse",
-    .llvm_name = "lse",
-    .description = "Enable ARMv8.1 Large System Extension (LSE) atomic instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_lslFast = Feature{
-    .name = "lslFast",
-    .llvm_name = "lsl-fast",
-    .description = "CPU has a fastpath logical shift of up to 3 places",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_mpam = Feature{
-    .name = "mpam",
-    .llvm_name = "mpam",
-    .description = "Enable v8.4-A Memory system Partitioning and Monitoring extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_mte = Feature{
-    .name = "mte",
-    .llvm_name = "mte",
-    .description = "Enable Memory Tagging Extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_neon = Feature{
-    .name = "neon",
-    .llvm_name = "neon",
-    .description = "Enable Advanced SIMD instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_nv = Feature{
-    .name = "nv",
-    .llvm_name = "nv",
-    .description = "Enable v8.4-A Nested Virtualization Enchancement",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_noNegImmediates = Feature{
-    .name = "noNegImmediates",
-    .llvm_name = "no-neg-immediates",
-    .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_pa = Feature{
-    .name = "pa",
-    .llvm_name = "pa",
-    .description = "Enable v8.3-A Pointer Authentication enchancement",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_pan = Feature{
-    .name = "pan",
-    .llvm_name = "pan",
-    .description = "Enables ARM v8.1 Privileged Access-Never extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_panRwv = Feature{
-    .name = "panRwv",
-    .llvm_name = "pan-rwv",
-    .description = "Enable v8.2 PAN s1e1R and s1e1W Variants",
-    .dependencies = &[_]*const Feature {
-        &feature_pan,
-    },
-};
-
-pub const feature_perfmon = Feature{
-    .name = "perfmon",
-    .llvm_name = "perfmon",
-    .description = "Enable ARMv8 PMUv3 Performance Monitors extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_usePostraScheduler = Feature{
-    .name = "usePostraScheduler",
-    .llvm_name = "use-postra-scheduler",
-    .description = "Schedule again after register allocation",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_predres = Feature{
-    .name = "predres",
-    .llvm_name = "predres",
-    .description = "Enable v8.5a execution and data prediction invalidation instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_predictableSelectExpensive = Feature{
-    .name = "predictableSelectExpensive",
-    .llvm_name = "predictable-select-expensive",
-    .description = "Prefer likely predicted branches over selects",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_uaops = Feature{
-    .name = "uaops",
-    .llvm_name = "uaops",
-    .description = "Enable v8.2 UAO PState",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_ras = Feature{
-    .name = "ras",
-    .llvm_name = "ras",
-    .description = "Enable ARMv8 Reliability, Availability and Serviceability Extensions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_rasv8_4 = Feature{
-    .name = "rasv8_4",
-    .llvm_name = "rasv8_4",
-    .description = "Enable v8.4-A Reliability, Availability and Serviceability extension",
-    .dependencies = &[_]*const Feature {
-        &feature_ras,
-    },
-};
-
-pub const feature_rcpc = Feature{
-    .name = "rcpc",
-    .llvm_name = "rcpc",
-    .description = "Enable support for RCPC extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_rcpcImmo = Feature{
-    .name = "rcpcImmo",
-    .llvm_name = "rcpc-immo",
-    .description = "Enable v8.4-A RCPC instructions with Immediate Offsets",
-    .dependencies = &[_]*const Feature {
-        &feature_rcpc,
-    },
-};
-
-pub const feature_rdm = Feature{
-    .name = "rdm",
-    .llvm_name = "rdm",
-    .description = "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_rand = Feature{
-    .name = "rand",
-    .llvm_name = "rand",
-    .description = "Enable Random Number generation instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX1 = Feature{
-    .name = "reserveX1",
-    .llvm_name = "reserve-x1",
-    .description = "Reserve X1, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX2 = Feature{
-    .name = "reserveX2",
-    .llvm_name = "reserve-x2",
-    .description = "Reserve X2, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX3 = Feature{
-    .name = "reserveX3",
-    .llvm_name = "reserve-x3",
-    .description = "Reserve X3, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX4 = Feature{
-    .name = "reserveX4",
-    .llvm_name = "reserve-x4",
-    .description = "Reserve X4, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX5 = Feature{
-    .name = "reserveX5",
-    .llvm_name = "reserve-x5",
-    .description = "Reserve X5, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX6 = Feature{
-    .name = "reserveX6",
-    .llvm_name = "reserve-x6",
-    .description = "Reserve X6, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX7 = Feature{
-    .name = "reserveX7",
-    .llvm_name = "reserve-x7",
-    .description = "Reserve X7, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX9 = Feature{
-    .name = "reserveX9",
-    .llvm_name = "reserve-x9",
-    .description = "Reserve X9, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX10 = Feature{
-    .name = "reserveX10",
-    .llvm_name = "reserve-x10",
-    .description = "Reserve X10, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX11 = Feature{
-    .name = "reserveX11",
-    .llvm_name = "reserve-x11",
-    .description = "Reserve X11, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX12 = Feature{
-    .name = "reserveX12",
-    .llvm_name = "reserve-x12",
-    .description = "Reserve X12, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX13 = Feature{
-    .name = "reserveX13",
-    .llvm_name = "reserve-x13",
-    .description = "Reserve X13, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX14 = Feature{
-    .name = "reserveX14",
-    .llvm_name = "reserve-x14",
-    .description = "Reserve X14, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX15 = Feature{
-    .name = "reserveX15",
-    .llvm_name = "reserve-x15",
-    .description = "Reserve X15, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX18 = Feature{
-    .name = "reserveX18",
-    .llvm_name = "reserve-x18",
-    .description = "Reserve X18, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX20 = Feature{
-    .name = "reserveX20",
-    .llvm_name = "reserve-x20",
-    .description = "Reserve X20, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX21 = Feature{
-    .name = "reserveX21",
-    .llvm_name = "reserve-x21",
-    .description = "Reserve X21, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX22 = Feature{
-    .name = "reserveX22",
-    .llvm_name = "reserve-x22",
-    .description = "Reserve X22, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX23 = Feature{
-    .name = "reserveX23",
-    .llvm_name = "reserve-x23",
-    .description = "Reserve X23, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX24 = Feature{
-    .name = "reserveX24",
-    .llvm_name = "reserve-x24",
-    .description = "Reserve X24, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX25 = Feature{
-    .name = "reserveX25",
-    .llvm_name = "reserve-x25",
-    .description = "Reserve X25, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX26 = Feature{
-    .name = "reserveX26",
-    .llvm_name = "reserve-x26",
-    .description = "Reserve X26, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX27 = Feature{
-    .name = "reserveX27",
-    .llvm_name = "reserve-x27",
-    .description = "Reserve X27, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_reserveX28 = Feature{
-    .name = "reserveX28",
-    .llvm_name = "reserve-x28",
-    .description = "Reserve X28, making it unavailable as a GPR",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_sb = Feature{
-    .name = "sb",
-    .llvm_name = "sb",
-    .description = "Enable v8.5 Speculation Barrier",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_sel2 = Feature{
-    .name = "sel2",
-    .llvm_name = "sel2",
-    .description = "Enable v8.4-A Secure Exception Level 2 extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_sha2 = Feature{
-    .name = "sha2",
-    .llvm_name = "sha2",
-    .description = "Enable SHA1 and SHA256 support",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_sha3 = Feature{
-    .name = "sha3",
-    .llvm_name = "sha3",
-    .description = "Enable SHA512 and SHA3 support",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_sm4 = Feature{
-    .name = "sm4",
-    .llvm_name = "sm4",
-    .description = "Enable SM3 and SM4 support",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_spe = Feature{
-    .name = "spe",
-    .llvm_name = "spe",
-    .description = "Enable Statistical Profiling extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_ssbs = Feature{
-    .name = "ssbs",
-    .llvm_name = "ssbs",
-    .description = "Enable Speculative Store Bypass Safe bit",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_sve = Feature{
-    .name = "sve",
-    .llvm_name = "sve",
-    .description = "Enable Scalable Vector Extension (SVE) instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_sve2 = Feature{
-    .name = "sve2",
-    .llvm_name = "sve2",
-    .description = "Enable Scalable Vector Extension 2 (SVE2) instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_sve,
-    },
-};
-
-pub const feature_sve2Aes = Feature{
-    .name = "sve2Aes",
-    .llvm_name = "sve2-aes",
-    .description = "Enable AES SVE2 instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_sve,
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_sve2Bitperm = Feature{
-    .name = "sve2Bitperm",
-    .llvm_name = "sve2-bitperm",
-    .description = "Enable bit permutation SVE2 instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_sve,
-    },
-};
-
-pub const feature_sve2Sha3 = Feature{
-    .name = "sve2Sha3",
-    .llvm_name = "sve2-sha3",
-    .description = "Enable SHA3 SVE2 instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_sve,
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_sve2Sm4 = Feature{
-    .name = "sve2Sm4",
-    .llvm_name = "sve2-sm4",
-    .description = "Enable SM4 SVE2 instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_sve,
-        &feature_fpArmv8,
-    },
-};
-
-pub const feature_slowMisaligned128store = Feature{
-    .name = "slowMisaligned128store",
-    .llvm_name = "slow-misaligned-128store",
-    .description = "Misaligned 128 bit stores are slow",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_slowPaired128 = Feature{
-    .name = "slowPaired128",
-    .llvm_name = "slow-paired-128",
-    .description = "Paired 128 bit loads and stores are slow",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_slowStrqroStore = Feature{
-    .name = "slowStrqroStore",
-    .llvm_name = "slow-strqro-store",
-    .description = "STR of Q register with register offset is slow",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_specrestrict = Feature{
-    .name = "specrestrict",
-    .llvm_name = "specrestrict",
-    .description = "Enable architectural speculation restriction",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_strictAlign = Feature{
-    .name = "strictAlign",
-    .llvm_name = "strict-align",
-    .description = "Disallow all unaligned memory access",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_tlbRmi = Feature{
-    .name = "tlbRmi",
-    .llvm_name = "tlb-rmi",
-    .description = "Enable v8.4-A TLB Range and Maintenance Instructions",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_tracev84 = Feature{
-    .name = "tracev84",
-    .llvm_name = "tracev8.4",
-    .description = "Enable v8.4-A Trace extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_useAa = Feature{
-    .name = "useAa",
-    .llvm_name = "use-aa",
-    .description = "Use alias analysis during codegen",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_tpidrEl1 = Feature{
-    .name = "tpidrEl1",
-    .llvm_name = "tpidr-el1",
-    .description = "Permit use of TPIDR_EL1 for the TLS base",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_tpidrEl2 = Feature{
-    .name = "tpidrEl2",
-    .llvm_name = "tpidr-el2",
-    .description = "Permit use of TPIDR_EL2 for the TLS base",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_tpidrEl3 = Feature{
-    .name = "tpidrEl3",
-    .llvm_name = "tpidr-el3",
-    .description = "Permit use of TPIDR_EL3 for the TLS base",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_useReciprocalSquareRoot = Feature{
-    .name = "useReciprocalSquareRoot",
-    .llvm_name = "use-reciprocal-square-root",
-    .description = "Use the reciprocal square root approximation",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_vh = Feature{
-    .name = "vh",
-    .llvm_name = "vh",
-    .description = "Enables ARM v8.1 Virtual Host extension",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_zcm = Feature{
-    .name = "zcm",
-    .llvm_name = "zcm",
-    .description = "Has zero-cycle register moves",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_zcz = Feature{
-    .name = "zcz",
-    .llvm_name = "zcz",
-    .description = "Has zero-cycle zeroing instructions",
-    .dependencies = &[_]*const Feature {
-        &feature_zczFp,
-        &feature_zczGp,
-    },
-};
-
-pub const feature_zczFp = Feature{
-    .name = "zczFp",
-    .llvm_name = "zcz-fp",
-    .description = "Has zero-cycle zeroing instructions for FP registers",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_zczFpWorkaround = Feature{
-    .name = "zczFpWorkaround",
-    .llvm_name = "zcz-fp-workaround",
-    .description = "The zero-cycle floating-point zeroing instruction has a bug",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const feature_zczGp = Feature{
-    .name = "zczGp",
-    .llvm_name = "zcz-gp",
-    .description = "Has zero-cycle zeroing instructions for generic registers",
-    .dependencies = &[_]*const Feature {
-    },
-};
-
-pub const features = &[_]*const Feature {
-    &feature_aes,
-    &feature_am,
-    &feature_aggressiveFma,
-    &feature_altnzcv,
-    &feature_alternateSextloadCvtF32Pattern,
-    &feature_arithBccFusion,
-    &feature_arithCbzFusion,
-    &feature_balanceFpOps,
-    &feature_bti,
-    &feature_ccidx,
-    &feature_ccpp,
-    &feature_crc,
-    &feature_ccdp,
-    &feature_callSavedX8,
-    &feature_callSavedX9,
-    &feature_callSavedX10,
-    &feature_callSavedX11,
-    &feature_callSavedX12,
-    &feature_callSavedX13,
-    &feature_callSavedX14,
-    &feature_callSavedX15,
-    &feature_callSavedX18,
-    &feature_complxnum,
-    &feature_crypto,
-    &feature_customCheapAsMove,
-    &feature_dit,
-    &feature_disableLatencySchedHeuristic,
-    &feature_dotprod,
-    &feature_exynosCheapAsMove,
-    &feature_fmi,
-    &feature_fp16fml,
-    &feature_fpArmv8,
-    &feature_fptoint,
-    &feature_force32bitJumpTables,
-    &feature_fullfp16,
-    &feature_fuseAes,
-    &feature_fuseAddress,
-    &feature_fuseArithLogic,
-    &feature_fuseCsel,
-    &feature_fuseCryptoEor,
-    &feature_fuseLiterals,
-    &feature_jsconv,
-    &feature_lor,
-    &feature_lse,
-    &feature_lslFast,
-    &feature_mpam,
-    &feature_mte,
-    &feature_neon,
-    &feature_nv,
-    &feature_noNegImmediates,
-    &feature_pa,
-    &feature_pan,
-    &feature_panRwv,
-    &feature_perfmon,
-    &feature_usePostraScheduler,
-    &feature_predres,
-    &feature_predictableSelectExpensive,
-    &feature_uaops,
-    &feature_ras,
-    &feature_rasv8_4,
-    &feature_rcpc,
-    &feature_rcpcImmo,
-    &feature_rdm,
-    &feature_rand,
-    &feature_reserveX1,
-    &feature_reserveX2,
-    &feature_reserveX3,
-    &feature_reserveX4,
-    &feature_reserveX5,
-    &feature_reserveX6,
-    &feature_reserveX7,
-    &feature_reserveX9,
-    &feature_reserveX10,
-    &feature_reserveX11,
-    &feature_reserveX12,
-    &feature_reserveX13,
-    &feature_reserveX14,
-    &feature_reserveX15,
-    &feature_reserveX18,
-    &feature_reserveX20,
-    &feature_reserveX21,
-    &feature_reserveX22,
-    &feature_reserveX23,
-    &feature_reserveX24,
-    &feature_reserveX25,
-    &feature_reserveX26,
-    &feature_reserveX27,
-    &feature_reserveX28,
-    &feature_sb,
-    &feature_sel2,
-    &feature_sha2,
-    &feature_sha3,
-    &feature_sm4,
-    &feature_spe,
-    &feature_ssbs,
-    &feature_sve,
-    &feature_sve2,
-    &feature_sve2Aes,
-    &feature_sve2Bitperm,
-    &feature_sve2Sha3,
-    &feature_sve2Sm4,
-    &feature_slowMisaligned128store,
-    &feature_slowPaired128,
-    &feature_slowStrqroStore,
-    &feature_specrestrict,
-    &feature_strictAlign,
-    &feature_tlbRmi,
-    &feature_tracev84,
-    &feature_useAa,
-    &feature_tpidrEl1,
-    &feature_tpidrEl2,
-    &feature_tpidrEl3,
-    &feature_useReciprocalSquareRoot,
-    &feature_vh,
-    &feature_zcm,
-    &feature_zcz,
-    &feature_zczFp,
-    &feature_zczFpWorkaround,
-    &feature_zczGp,
-};
-
-pub const cpu_appleLatest = Cpu{
-    .name = "appleLatest",
-    .llvm_name = "apple-latest",
-    .dependencies = &[_]*const Feature {
-        &feature_arithCbzFusion,
-        &feature_zczFpWorkaround,
-        &feature_alternateSextloadCvtF32Pattern,
-        &feature_fuseCryptoEor,
-        &feature_zcm,
-        &feature_zczGp,
-        &feature_perfmon,
-        &feature_disableLatencySchedHeuristic,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_arithBccFusion,
-        &feature_fuseAes,
-    },
-};
-
-pub const cpu_cortexA35 = Cpu{
-    .name = "cortexA35",
-    .llvm_name = "cortex-a35",
-    .dependencies = &[_]*const Feature {
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_crc,
-    },
-};
-
-pub const cpu_cortexA53 = Cpu{
-    .name = "cortexA53",
-    .llvm_name = "cortex-a53",
-    .dependencies = &[_]*const Feature {
-        &feature_customCheapAsMove,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_useAa,
-        &feature_fpArmv8,
-        &feature_fuseAes,
-        &feature_balanceFpOps,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_cortexA55 = Cpu{
-    .name = "cortexA55",
-    .llvm_name = "cortex-a55",
-    .dependencies = &[_]*const Feature {
-        &feature_ccpp,
-        &feature_rcpc,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_ras,
-        &feature_lse,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_vh,
-        &feature_fuseAes,
-        &feature_lor,
-        &feature_dotprod,
-        &feature_pan,
-    },
-};
-
-pub const cpu_cortexA57 = Cpu{
-    .name = "cortexA57",
-    .llvm_name = "cortex-a57",
-    .dependencies = &[_]*const Feature {
-        &feature_fuseLiterals,
-        &feature_predictableSelectExpensive,
-        &feature_customCheapAsMove,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_fuseAes,
-        &feature_balanceFpOps,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_cortexA72 = Cpu{
-    .name = "cortexA72",
-    .llvm_name = "cortex-a72",
-    .dependencies = &[_]*const Feature {
-        &feature_fuseAes,
-        &feature_fpArmv8,
-        &feature_perfmon,
-        &feature_crc,
-    },
-};
-
-pub const cpu_cortexA73 = Cpu{
-    .name = "cortexA73",
-    .llvm_name = "cortex-a73",
-    .dependencies = &[_]*const Feature {
-        &feature_fuseAes,
-        &feature_fpArmv8,
-        &feature_perfmon,
-        &feature_crc,
-    },
-};
-
-pub const cpu_cortexA75 = Cpu{
-    .name = "cortexA75",
-    .llvm_name = "cortex-a75",
-    .dependencies = &[_]*const Feature {
-        &feature_ccpp,
-        &feature_rcpc,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_ras,
-        &feature_lse,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_vh,
-        &feature_fuseAes,
-        &feature_lor,
-        &feature_dotprod,
-        &feature_pan,
-    },
-};
-
-pub const cpu_cortexA76 = Cpu{
-    .name = "cortexA76",
-    .llvm_name = "cortex-a76",
-    .dependencies = &[_]*const Feature {
-        &feature_ccpp,
-        &feature_rcpc,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_ras,
-        &feature_lse,
-        &feature_crc,
-        &feature_fpArmv8,
-        &feature_vh,
-        &feature_lor,
-        &feature_ssbs,
-        &feature_dotprod,
-        &feature_pan,
-    },
-};
-
-pub const cpu_cortexA76ae = Cpu{
-    .name = "cortexA76ae",
-    .llvm_name = "cortex-a76ae",
-    .dependencies = &[_]*const Feature {
-        &feature_ccpp,
-        &feature_rcpc,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_ras,
-        &feature_lse,
-        &feature_crc,
-        &feature_fpArmv8,
-        &feature_vh,
-        &feature_lor,
-        &feature_ssbs,
-        &feature_dotprod,
-        &feature_pan,
-    },
-};
-
-pub const cpu_cyclone = Cpu{
-    .name = "cyclone",
-    .llvm_name = "cyclone",
-    .dependencies = &[_]*const Feature {
-        &feature_arithCbzFusion,
-        &feature_zczFpWorkaround,
-        &feature_alternateSextloadCvtF32Pattern,
-        &feature_fuseCryptoEor,
-        &feature_zcm,
-        &feature_zczGp,
-        &feature_perfmon,
-        &feature_disableLatencySchedHeuristic,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_arithBccFusion,
-        &feature_fuseAes,
-    },
-};
-
-pub const cpu_exynosM1 = Cpu{
-    .name = "exynosM1",
-    .llvm_name = "exynos-m1",
-    .dependencies = &[_]*const Feature {
-        &feature_customCheapAsMove,
-        &feature_crc,
-        &feature_force32bitJumpTables,
-        &feature_perfmon,
-        &feature_slowMisaligned128store,
-        &feature_useReciprocalSquareRoot,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_fuseAes,
-        &feature_slowPaired128,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_exynosM2 = Cpu{
-    .name = "exynosM2",
-    .llvm_name = "exynos-m2",
-    .dependencies = &[_]*const Feature {
-        &feature_customCheapAsMove,
-        &feature_crc,
-        &feature_force32bitJumpTables,
-        &feature_perfmon,
-        &feature_slowMisaligned128store,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_fuseAes,
-        &feature_slowPaired128,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_exynosM3 = Cpu{
-    .name = "exynosM3",
-    .llvm_name = "exynos-m3",
-    .dependencies = &[_]*const Feature {
-        &feature_fuseLiterals,
-        &feature_predictableSelectExpensive,
-        &feature_customCheapAsMove,
-        &feature_crc,
-        &feature_force32bitJumpTables,
-        &feature_fuseAddress,
-        &feature_fuseCsel,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_fuseAes,
-        &feature_lslFast,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_exynosM4 = Cpu{
-    .name = "exynosM4",
-    .llvm_name = "exynos-m4",
-    .dependencies = &[_]*const Feature {
-        &feature_arithCbzFusion,
-        &feature_customCheapAsMove,
-        &feature_lse,
-        &feature_zczFp,
-        &feature_lslFast,
-        &feature_lor,
-        &feature_fuseLiterals,
-        &feature_ccpp,
-        &feature_ras,
-        &feature_fpArmv8,
-        &feature_fuseAes,
-        &feature_pan,
-        &feature_fuseArithLogic,
-        &feature_crc,
-        &feature_force32bitJumpTables,
-        &feature_fuseAddress,
-        &feature_fuseCsel,
-        &feature_arithBccFusion,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_zczGp,
-        &feature_perfmon,
-        &feature_vh,
-        &feature_usePostraScheduler,
-        &feature_dotprod,
-    },
-};
-
-pub const cpu_exynosM5 = Cpu{
-    .name = "exynosM5",
-    .llvm_name = "exynos-m5",
-    .dependencies = &[_]*const Feature {
-        &feature_arithCbzFusion,
-        &feature_customCheapAsMove,
-        &feature_lse,
-        &feature_zczFp,
-        &feature_lslFast,
-        &feature_lor,
-        &feature_fuseLiterals,
-        &feature_ccpp,
-        &feature_ras,
-        &feature_fpArmv8,
-        &feature_fuseAes,
-        &feature_pan,
-        &feature_fuseArithLogic,
-        &feature_crc,
-        &feature_force32bitJumpTables,
-        &feature_fuseAddress,
-        &feature_fuseCsel,
-        &feature_arithBccFusion,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_zczGp,
-        &feature_perfmon,
-        &feature_vh,
-        &feature_usePostraScheduler,
-        &feature_dotprod,
-    },
-};
-
-pub const cpu_falkor = Cpu{
-    .name = "falkor",
-    .llvm_name = "falkor",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_customCheapAsMove,
-        &feature_rdm,
-        &feature_slowStrqroStore,
-        &feature_zczGp,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_lslFast,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_generic = Cpu{
-    .name = "generic",
-    .llvm_name = "generic",
-    .dependencies = &[_]*const Feature {
-        &feature_fpArmv8,
-        &feature_fuseAes,
-        &feature_neon,
-        &feature_perfmon,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_kryo = Cpu{
-    .name = "kryo",
-    .llvm_name = "kryo",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_customCheapAsMove,
-        &feature_zczGp,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_zczFp,
-        &feature_lslFast,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_saphira = Cpu{
-    .name = "saphira",
-    .llvm_name = "saphira",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_customCheapAsMove,
-        &feature_fmi,
-        &feature_lse,
-        &feature_zczFp,
-        &feature_lslFast,
-        &feature_lor,
-        &feature_dit,
-        &feature_pa,
-        &feature_ccpp,
-        &feature_sel2,
-        &feature_ras,
-        &feature_fpArmv8,
-        &feature_ccidx,
-        &feature_pan,
-        &feature_rcpc,
-        &feature_crc,
-        &feature_tracev84,
-        &feature_mpam,
-        &feature_am,
-        &feature_nv,
-        &feature_tlbRmi,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_zczGp,
-        &feature_perfmon,
-        &feature_vh,
-        &feature_usePostraScheduler,
-        &feature_dotprod,
-        &feature_spe,
-    },
-};
-
-pub const cpu_thunderx = Cpu{
-    .name = "thunderx",
-    .llvm_name = "thunderx",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_thunderx2t99 = Cpu{
-    .name = "thunderx2t99",
-    .llvm_name = "thunderx2t99",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_aggressiveFma,
-        &feature_rdm,
-        &feature_lse,
-        &feature_crc,
-        &feature_fpArmv8,
-        &feature_vh,
-        &feature_arithBccFusion,
-        &feature_lor,
-        &feature_usePostraScheduler,
-        &feature_pan,
-    },
-};
-
-pub const cpu_thunderxt81 = Cpu{
-    .name = "thunderxt81",
-    .llvm_name = "thunderxt81",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_thunderxt83 = Cpu{
-    .name = "thunderxt83",
-    .llvm_name = "thunderxt83",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_thunderxt88 = Cpu{
-    .name = "thunderxt88",
-    .llvm_name = "thunderxt88",
-    .dependencies = &[_]*const Feature {
-        &feature_predictableSelectExpensive,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_usePostraScheduler,
-    },
-};
-
-pub const cpu_tsv110 = Cpu{
-    .name = "tsv110",
-    .llvm_name = "tsv110",
-    .dependencies = &[_]*const Feature {
-        &feature_ccpp,
-        &feature_customCheapAsMove,
-        &feature_uaops,
-        &feature_rdm,
-        &feature_ras,
-        &feature_lse,
-        &feature_crc,
-        &feature_perfmon,
-        &feature_fpArmv8,
-        &feature_vh,
-        &feature_fuseAes,
-        &feature_lor,
-        &feature_usePostraScheduler,
-        &feature_dotprod,
-        &feature_pan,
-        &feature_spe,
-    },
-};
-
-pub const cpus = &[_]*const Cpu {
-    &cpu_appleLatest,
-    &cpu_cortexA35,
-    &cpu_cortexA53,
-    &cpu_cortexA55,
-    &cpu_cortexA57,
-    &cpu_cortexA72,
-    &cpu_cortexA73,
-    &cpu_cortexA75,
-    &cpu_cortexA76,
-    &cpu_cortexA76ae,
-    &cpu_cyclone,
-    &cpu_exynosM1,
-    &cpu_exynosM2,
-    &cpu_exynosM3,
-    &cpu_exynosM4,
-    &cpu_exynosM5,
-    &cpu_falkor,
-    &cpu_generic,
-    &cpu_kryo,
-    &cpu_saphira,
-    &cpu_thunderx,
-    &cpu_thunderx2t99,
-    &cpu_thunderxt81,
-    &cpu_thunderxt83,
-    &cpu_thunderxt88,
-    &cpu_tsv110,
+const std = @import("../std.zig");
+const Cpu = std.Target.Cpu;
+
+pub const Feature = enum {
+    aes,
+    am,
+    aggressive_fma,
+    altnzcv,
+    alternate_sextload_cvt_f32_pattern,
+    arith_bcc_fusion,
+    arith_cbz_fusion,
+    balance_fp_ops,
+    bti,
+    ccidx,
+    ccpp,
+    crc,
+    ccdp,
+    call_saved_x8,
+    call_saved_x9,
+    call_saved_x10,
+    call_saved_x11,
+    call_saved_x12,
+    call_saved_x13,
+    call_saved_x14,
+    call_saved_x15,
+    call_saved_x18,
+    complxnum,
+    crypto,
+    custom_cheap_as_move,
+    dit,
+    disable_latency_sched_heuristic,
+    dotprod,
+    exynos_cheap_as_move,
+    fmi,
+    fp16fml,
+    fp_armv8,
+    fptoint,
+    force_32bit_jump_tables,
+    fullfp16,
+    fuse_aes,
+    fuse_address,
+    fuse_arith_logic,
+    fuse_csel,
+    fuse_crypto_eor,
+    fuse_literals,
+    jsconv,
+    lor,
+    lse,
+    lsl_fast,
+    mpam,
+    mte,
+    neon,
+    nv,
+    no_neg_immediates,
+    pa,
+    pan,
+    pan_rwv,
+    perfmon,
+    use_postra_scheduler,
+    predres,
+    predictable_select_expensive,
+    uaops,
+    ras,
+    rasv8_4,
+    rcpc,
+    rcpc_immo,
+    rdm,
+    rand,
+    reserve_x1,
+    reserve_x2,
+    reserve_x3,
+    reserve_x4,
+    reserve_x5,
+    reserve_x6,
+    reserve_x7,
+    reserve_x9,
+    reserve_x10,
+    reserve_x11,
+    reserve_x12,
+    reserve_x13,
+    reserve_x14,
+    reserve_x15,
+    reserve_x18,
+    reserve_x20,
+    reserve_x21,
+    reserve_x22,
+    reserve_x23,
+    reserve_x24,
+    reserve_x25,
+    reserve_x26,
+    reserve_x27,
+    reserve_x28,
+    sb,
+    sel2,
+    sha2,
+    sha3,
+    sm4,
+    spe,
+    ssbs,
+    sve,
+    sve2,
+    sve2_aes,
+    sve2_bitperm,
+    sve2_sha3,
+    sve2_sm4,
+    slow_misaligned_128store,
+    slow_paired_128,
+    slow_strqro_store,
+    specrestrict,
+    strict_align,
+    tlb_rmi,
+    tracev84,
+    use_aa,
+    tpidr_el1,
+    tpidr_el2,
+    tpidr_el3,
+    use_reciprocal_square_root,
+    vh,
+    zcm,
+    zcz,
+    zcz_fp,
+    zcz_fp_workaround,
+    zcz_gp,
+};
+
+pub fn featureSet(features: []const Feature) Cpu.Feature.Set {
+    var x: Cpu.Feature.Set = 0;
+    for (features) |feature| {
+        x |= 1 << @enumToInt(feature);
+    }
+    return x;
+}
+
+pub fn featureSetHas(set: Feature.Set, feature: Feature) bool {
+    return (set & (1 << @enumToInt(feature))) != 0;
+}
+
+pub const all_features = blk: {
+    const len = @typeInfo(Feature).Enum.fields.len;
+    std.debug.assert(len <= @typeInfo(Feature.Set).Int.bits);
+    var result: [len]Cpu.Feature = undefined;
+    result[@enumToInt(Feature.aes)] = .{
+        .index = @enumToInt(Feature.aes),
+        .name = @tagName(Feature.aes),
+        .llvm_name = "aes",
+        .description = "Enable AES support",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.am)] = .{
+        .index = @enumToInt(Feature.am),
+        .name = @tagName(Feature.am),
+        .llvm_name = "am",
+        .description = "Enable v8.4-A Activity Monitors extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.aggressive_fma)] = .{
+        .index = @enumToInt(Feature.aggressive_fma),
+        .name = @tagName(Feature.aggressive_fma),
+        .llvm_name = "aggressive-fma",
+        .description = "Enable Aggressive FMA for floating-point.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.altnzcv)] = .{
+        .index = @enumToInt(Feature.altnzcv),
+        .name = @tagName(Feature.altnzcv),
+        .llvm_name = "altnzcv",
+        .description = "Enable alternative NZCV format for floating point comparisons",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.alternate_sextload_cvt_f32_pattern)] = .{
+        .index = @enumToInt(Feature.alternate_sextload_cvt_f32_pattern),
+        .name = @tagName(Feature.alternate_sextload_cvt_f32_pattern),
+        .llvm_name = "alternate-sextload-cvt-f32-pattern",
+        .description = "Use alternative pattern for sextload convert to f32",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.arith_bcc_fusion)] = .{
+        .index = @enumToInt(Feature.arith_bcc_fusion),
+        .name = @tagName(Feature.arith_bcc_fusion),
+        .llvm_name = "arith-bcc-fusion",
+        .description = "CPU fuses arithmetic+bcc operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.arith_cbz_fusion)] = .{
+        .index = @enumToInt(Feature.arith_cbz_fusion),
+        .name = @tagName(Feature.arith_cbz_fusion),
+        .llvm_name = "arith-cbz-fusion",
+        .description = "CPU fuses arithmetic + cbz/cbnz operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.balance_fp_ops)] = .{
+        .index = @enumToInt(Feature.balance_fp_ops),
+        .name = @tagName(Feature.balance_fp_ops),
+        .llvm_name = "balance-fp-ops",
+        .description = "balance mix of odd and even D-registers for fp multiply(-accumulate) ops",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.bti)] = .{
+        .index = @enumToInt(Feature.bti),
+        .name = @tagName(Feature.bti),
+        .llvm_name = "bti",
+        .description = "Enable Branch Target Identification",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.ccidx)] = .{
+        .index = @enumToInt(Feature.ccidx),
+        .name = @tagName(Feature.ccidx),
+        .llvm_name = "ccidx",
+        .description = "Enable v8.3-A Extend of the CCSIDR number of sets",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.ccpp)] = .{
+        .index = @enumToInt(Feature.ccpp),
+        .name = @tagName(Feature.ccpp),
+        .llvm_name = "ccpp",
+        .description = "Enable v8.2 data Cache Clean to Point of Persistence",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.crc)] = .{
+        .index = @enumToInt(Feature.crc),
+        .name = @tagName(Feature.crc),
+        .llvm_name = "crc",
+        .description = "Enable ARMv8 CRC-32 checksum instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.ccdp)] = .{
+        .index = @enumToInt(Feature.ccdp),
+        .name = @tagName(Feature.ccdp),
+        .llvm_name = "ccdp",
+        .description = "Enable v8.5 Cache Clean to Point of Deep Persistence",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x8)] = .{
+        .index = @enumToInt(Feature.call_saved_x8),
+        .name = @tagName(Feature.call_saved_x8),
+        .llvm_name = "call-saved-x8",
+        .description = "Make X8 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x9)] = .{
+        .index = @enumToInt(Feature.call_saved_x9),
+        .name = @tagName(Feature.call_saved_x9),
+        .llvm_name = "call-saved-x9",
+        .description = "Make X9 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x10)] = .{
+        .index = @enumToInt(Feature.call_saved_x10),
+        .name = @tagName(Feature.call_saved_x10),
+        .llvm_name = "call-saved-x10",
+        .description = "Make X10 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x11)] = .{
+        .index = @enumToInt(Feature.call_saved_x11),
+        .name = @tagName(Feature.call_saved_x11),
+        .llvm_name = "call-saved-x11",
+        .description = "Make X11 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x12)] = .{
+        .index = @enumToInt(Feature.call_saved_x12),
+        .name = @tagName(Feature.call_saved_x12),
+        .llvm_name = "call-saved-x12",
+        .description = "Make X12 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x13)] = .{
+        .index = @enumToInt(Feature.call_saved_x13),
+        .name = @tagName(Feature.call_saved_x13),
+        .llvm_name = "call-saved-x13",
+        .description = "Make X13 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x14)] = .{
+        .index = @enumToInt(Feature.call_saved_x14),
+        .name = @tagName(Feature.call_saved_x14),
+        .llvm_name = "call-saved-x14",
+        .description = "Make X14 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x15)] = .{
+        .index = @enumToInt(Feature.call_saved_x15),
+        .name = @tagName(Feature.call_saved_x15),
+        .llvm_name = "call-saved-x15",
+        .description = "Make X15 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.call_saved_x18)] = .{
+        .index = @enumToInt(Feature.call_saved_x18),
+        .name = @tagName(Feature.call_saved_x18),
+        .llvm_name = "call-saved-x18",
+        .description = "Make X18 callee saved.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.complxnum)] = .{
+        .index = @enumToInt(Feature.complxnum),
+        .name = @tagName(Feature.complxnum),
+        .llvm_name = "complxnum",
+        .description = "Enable v8.3-A Floating-point complex number support",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.crypto)] = .{
+        .index = @enumToInt(Feature.crypto),
+        .name = @tagName(Feature.crypto),
+        .llvm_name = "crypto",
+        .description = "Enable cryptographic instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.custom_cheap_as_move)] = .{
+        .index = @enumToInt(Feature.custom_cheap_as_move),
+        .name = @tagName(Feature.custom_cheap_as_move),
+        .llvm_name = "custom-cheap-as-move",
+        .description = "Use custom handling of cheap instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.dit)] = .{
+        .index = @enumToInt(Feature.dit),
+        .name = @tagName(Feature.dit),
+        .llvm_name = "dit",
+        .description = "Enable v8.4-A Data Independent Timing instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.disable_latency_sched_heuristic)] = .{
+        .index = @enumToInt(Feature.disable_latency_sched_heuristic),
+        .name = @tagName(Feature.disable_latency_sched_heuristic),
+        .llvm_name = "disable-latency-sched-heuristic",
+        .description = "Disable latency scheduling heuristic",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.dotprod)] = .{
+        .index = @enumToInt(Feature.dotprod),
+        .name = @tagName(Feature.dotprod),
+        .llvm_name = "dotprod",
+        .description = "Enable dot product support",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.exynos_cheap_as_move)] = .{
+        .index = @enumToInt(Feature.exynos_cheap_as_move),
+        .name = @tagName(Feature.exynos_cheap_as_move),
+        .llvm_name = "exynos-cheap-as-move",
+        .description = "Use Exynos specific handling of cheap instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .custom_cheap_as_move,
+        }),
+    };
+    result[@enumToInt(Feature.fmi)] = .{
+        .index = @enumToInt(Feature.fmi),
+        .name = @tagName(Feature.fmi),
+        .llvm_name = "fmi",
+        .description = "Enable v8.4-A Flag Manipulation Instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fp16fml)] = .{
+        .index = @enumToInt(Feature.fp16fml),
+        .name = @tagName(Feature.fp16fml),
+        .llvm_name = "fp16fml",
+        .description = "Enable FP16 FML instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.fp_armv8)] = .{
+        .index = @enumToInt(Feature.fp_armv8),
+        .name = @tagName(Feature.fp_armv8),
+        .llvm_name = "fp-armv8",
+        .description = "Enable ARMv8 FP",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fptoint)] = .{
+        .index = @enumToInt(Feature.fptoint),
+        .name = @tagName(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",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.force_32bit_jump_tables)] = .{
+        .index = @enumToInt(Feature.force_32bit_jump_tables),
+        .name = @tagName(Feature.force_32bit_jump_tables),
+        .llvm_name = "force-32bit-jump-tables",
+        .description = "Force jump table entries to be 32-bits wide except at MinSize",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fullfp16)] = .{
+        .index = @enumToInt(Feature.fullfp16),
+        .name = @tagName(Feature.fullfp16),
+        .llvm_name = "fullfp16",
+        .description = "Full FP16",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.fuse_aes)] = .{
+        .index = @enumToInt(Feature.fuse_aes),
+        .name = @tagName(Feature.fuse_aes),
+        .llvm_name = "fuse-aes",
+        .description = "CPU fuses AES crypto operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fuse_address)] = .{
+        .index = @enumToInt(Feature.fuse_address),
+        .name = @tagName(Feature.fuse_address),
+        .llvm_name = "fuse-address",
+        .description = "CPU fuses address generation and memory operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fuse_arith_logic)] = .{
+        .index = @enumToInt(Feature.fuse_arith_logic),
+        .name = @tagName(Feature.fuse_arith_logic),
+        .llvm_name = "fuse-arith-logic",
+        .description = "CPU fuses arithmetic and logic operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fuse_csel)] = .{
+        .index = @enumToInt(Feature.fuse_csel),
+        .name = @tagName(Feature.fuse_csel),
+        .llvm_name = "fuse-csel",
+        .description = "CPU fuses conditional select operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fuse_crypto_eor)] = .{
+        .index = @enumToInt(Feature.fuse_crypto_eor),
+        .name = @tagName(Feature.fuse_crypto_eor),
+        .llvm_name = "fuse-crypto-eor",
+        .description = "CPU fuses AES/PMULL and EOR operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.fuse_literals)] = .{
+        .index = @enumToInt(Feature.fuse_literals),
+        .name = @tagName(Feature.fuse_literals),
+        .llvm_name = "fuse-literals",
+        .description = "CPU fuses literal generation operations",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.jsconv)] = .{
+        .index = @enumToInt(Feature.jsconv),
+        .name = @tagName(Feature.jsconv),
+        .llvm_name = "jsconv",
+        .description = "Enable v8.3-A JavaScript FP conversion enchancement",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.lor)] = .{
+        .index = @enumToInt(Feature.lor),
+        .name = @tagName(Feature.lor),
+        .llvm_name = "lor",
+        .description = "Enables ARM v8.1 Limited Ordering Regions extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.lse)] = .{
+        .index = @enumToInt(Feature.lse),
+        .name = @tagName(Feature.lse),
+        .llvm_name = "lse",
+        .description = "Enable ARMv8.1 Large System Extension (LSE) atomic instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.lsl_fast)] = .{
+        .index = @enumToInt(Feature.lsl_fast),
+        .name = @tagName(Feature.lsl_fast),
+        .llvm_name = "lsl-fast",
+        .description = "CPU has a fastpath logical shift of up to 3 places",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.mpam)] = .{
+        .index = @enumToInt(Feature.mpam),
+        .name = @tagName(Feature.mpam),
+        .llvm_name = "mpam",
+        .description = "Enable v8.4-A Memory system Partitioning and Monitoring extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.mte)] = .{
+        .index = @enumToInt(Feature.mte),
+        .name = @tagName(Feature.mte),
+        .llvm_name = "mte",
+        .description = "Enable Memory Tagging Extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.neon)] = .{
+        .index = @enumToInt(Feature.neon),
+        .name = @tagName(Feature.neon),
+        .llvm_name = "neon",
+        .description = "Enable Advanced SIMD instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.nv)] = .{
+        .index = @enumToInt(Feature.nv),
+        .name = @tagName(Feature.nv),
+        .llvm_name = "nv",
+        .description = "Enable v8.4-A Nested Virtualization Enchancement",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.no_neg_immediates)] = .{
+        .index = @enumToInt(Feature.no_neg_immediates),
+        .name = @tagName(Feature.no_neg_immediates),
+        .llvm_name = "no-neg-immediates",
+        .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.pa)] = .{
+        .index = @enumToInt(Feature.pa),
+        .name = @tagName(Feature.pa),
+        .llvm_name = "pa",
+        .description = "Enable v8.3-A Pointer Authentication enchancement",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.pan)] = .{
+        .index = @enumToInt(Feature.pan),
+        .name = @tagName(Feature.pan),
+        .llvm_name = "pan",
+        .description = "Enables ARM v8.1 Privileged Access-Never extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.pan_rwv)] = .{
+        .index = @enumToInt(Feature.pan_rwv),
+        .name = @tagName(Feature.pan_rwv),
+        .llvm_name = "pan-rwv",
+        .description = "Enable v8.2 PAN s1e1R and s1e1W Variants",
+        .dependencies = featureSet(&[_]Feature{
+            .pan,
+        }),
+    };
+    result[@enumToInt(Feature.perfmon)] = .{
+        .index = @enumToInt(Feature.perfmon),
+        .name = @tagName(Feature.perfmon),
+        .llvm_name = "perfmon",
+        .description = "Enable ARMv8 PMUv3 Performance Monitors extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.use_postra_scheduler)] = .{
+        .index = @enumToInt(Feature.use_postra_scheduler),
+        .name = @tagName(Feature.use_postra_scheduler),
+        .llvm_name = "use-postra-scheduler",
+        .description = "Schedule again after register allocation",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.predres)] = .{
+        .index = @enumToInt(Feature.predres),
+        .name = @tagName(Feature.predres),
+        .llvm_name = "predres",
+        .description = "Enable v8.5a execution and data prediction invalidation instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.predictable_select_expensive)] = .{
+        .index = @enumToInt(Feature.predictable_select_expensive),
+        .name = @tagName(Feature.predictable_select_expensive),
+        .llvm_name = "predictable-select-expensive",
+        .description = "Prefer likely predicted branches over selects",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.uaops)] = .{
+        .index = @enumToInt(Feature.uaops),
+        .name = @tagName(Feature.uaops),
+        .llvm_name = "uaops",
+        .description = "Enable v8.2 UAO PState",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.ras)] = .{
+        .index = @enumToInt(Feature.ras),
+        .name = @tagName(Feature.ras),
+        .llvm_name = "ras",
+        .description = "Enable ARMv8 Reliability, Availability and Serviceability Extensions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.rasv8_4)] = .{
+        .index = @enumToInt(Feature.rasv8_4),
+        .name = @tagName(Feature.rasv8_4),
+        .llvm_name = "rasv8_4",
+        .description = "Enable v8.4-A Reliability, Availability and Serviceability extension",
+        .dependencies = featureSet(&[_]Feature{
+            .ras,
+        }),
+    };
+    result[@enumToInt(Feature.rcpc)] = .{
+        .index = @enumToInt(Feature.rcpc),
+        .name = @tagName(Feature.rcpc),
+        .llvm_name = "rcpc",
+        .description = "Enable support for RCPC extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.rcpc_immo)] = .{
+        .index = @enumToInt(Feature.rcpc_immo),
+        .name = @tagName(Feature.rcpc_immo),
+        .llvm_name = "rcpc-immo",
+        .description = "Enable v8.4-A RCPC instructions with Immediate Offsets",
+        .dependencies = featureSet(&[_]Feature{
+            .rcpc,
+        }),
+    };
+    result[@enumToInt(Feature.rdm)] = .{
+        .index = @enumToInt(Feature.rdm),
+        .name = @tagName(Feature.rdm),
+        .llvm_name = "rdm",
+        .description = "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.rand)] = .{
+        .index = @enumToInt(Feature.rand),
+        .name = @tagName(Feature.rand),
+        .llvm_name = "rand",
+        .description = "Enable Random Number generation instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x1)] = .{
+        .index = @enumToInt(Feature.reserve_x1),
+        .name = @tagName(Feature.reserve_x1),
+        .llvm_name = "reserve-x1",
+        .description = "Reserve X1, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x2)] = .{
+        .index = @enumToInt(Feature.reserve_x2),
+        .name = @tagName(Feature.reserve_x2),
+        .llvm_name = "reserve-x2",
+        .description = "Reserve X2, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x3)] = .{
+        .index = @enumToInt(Feature.reserve_x3),
+        .name = @tagName(Feature.reserve_x3),
+        .llvm_name = "reserve-x3",
+        .description = "Reserve X3, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x4)] = .{
+        .index = @enumToInt(Feature.reserve_x4),
+        .name = @tagName(Feature.reserve_x4),
+        .llvm_name = "reserve-x4",
+        .description = "Reserve X4, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x5)] = .{
+        .index = @enumToInt(Feature.reserve_x5),
+        .name = @tagName(Feature.reserve_x5),
+        .llvm_name = "reserve-x5",
+        .description = "Reserve X5, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x6)] = .{
+        .index = @enumToInt(Feature.reserve_x6),
+        .name = @tagName(Feature.reserve_x6),
+        .llvm_name = "reserve-x6",
+        .description = "Reserve X6, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x7)] = .{
+        .index = @enumToInt(Feature.reserve_x7),
+        .name = @tagName(Feature.reserve_x7),
+        .llvm_name = "reserve-x7",
+        .description = "Reserve X7, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x9)] = .{
+        .index = @enumToInt(Feature.reserve_x9),
+        .name = @tagName(Feature.reserve_x9),
+        .llvm_name = "reserve-x9",
+        .description = "Reserve X9, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x10)] = .{
+        .index = @enumToInt(Feature.reserve_x10),
+        .name = @tagName(Feature.reserve_x10),
+        .llvm_name = "reserve-x10",
+        .description = "Reserve X10, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x11)] = .{
+        .index = @enumToInt(Feature.reserve_x11),
+        .name = @tagName(Feature.reserve_x11),
+        .llvm_name = "reserve-x11",
+        .description = "Reserve X11, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x12)] = .{
+        .index = @enumToInt(Feature.reserve_x12),
+        .name = @tagName(Feature.reserve_x12),
+        .llvm_name = "reserve-x12",
+        .description = "Reserve X12, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x13)] = .{
+        .index = @enumToInt(Feature.reserve_x13),
+        .name = @tagName(Feature.reserve_x13),
+        .llvm_name = "reserve-x13",
+        .description = "Reserve X13, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x14)] = .{
+        .index = @enumToInt(Feature.reserve_x14),
+        .name = @tagName(Feature.reserve_x14),
+        .llvm_name = "reserve-x14",
+        .description = "Reserve X14, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x15)] = .{
+        .index = @enumToInt(Feature.reserve_x15),
+        .name = @tagName(Feature.reserve_x15),
+        .llvm_name = "reserve-x15",
+        .description = "Reserve X15, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x18)] = .{
+        .index = @enumToInt(Feature.reserve_x18),
+        .name = @tagName(Feature.reserve_x18),
+        .llvm_name = "reserve-x18",
+        .description = "Reserve X18, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x20)] = .{
+        .index = @enumToInt(Feature.reserve_x20),
+        .name = @tagName(Feature.reserve_x20),
+        .llvm_name = "reserve-x20",
+        .description = "Reserve X20, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x21)] = .{
+        .index = @enumToInt(Feature.reserve_x21),
+        .name = @tagName(Feature.reserve_x21),
+        .llvm_name = "reserve-x21",
+        .description = "Reserve X21, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x22)] = .{
+        .index = @enumToInt(Feature.reserve_x22),
+        .name = @tagName(Feature.reserve_x22),
+        .llvm_name = "reserve-x22",
+        .description = "Reserve X22, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x23)] = .{
+        .index = @enumToInt(Feature.reserve_x23),
+        .name = @tagName(Feature.reserve_x23),
+        .llvm_name = "reserve-x23",
+        .description = "Reserve X23, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x24)] = .{
+        .index = @enumToInt(Feature.reserve_x24),
+        .name = @tagName(Feature.reserve_x24),
+        .llvm_name = "reserve-x24",
+        .description = "Reserve X24, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x25)] = .{
+        .index = @enumToInt(Feature.reserve_x25),
+        .name = @tagName(Feature.reserve_x25),
+        .llvm_name = "reserve-x25",
+        .description = "Reserve X25, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x26)] = .{
+        .index = @enumToInt(Feature.reserve_x26),
+        .name = @tagName(Feature.reserve_x26),
+        .llvm_name = "reserve-x26",
+        .description = "Reserve X26, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x27)] = .{
+        .index = @enumToInt(Feature.reserve_x27),
+        .name = @tagName(Feature.reserve_x27),
+        .llvm_name = "reserve-x27",
+        .description = "Reserve X27, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.reserve_x28)] = .{
+        .index = @enumToInt(Feature.reserve_x28),
+        .name = @tagName(Feature.reserve_x28),
+        .llvm_name = "reserve-x28",
+        .description = "Reserve X28, making it unavailable as a GPR",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.sb)] = .{
+        .index = @enumToInt(Feature.sb),
+        .name = @tagName(Feature.sb),
+        .llvm_name = "sb",
+        .description = "Enable v8.5 Speculation Barrier",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.sel2)] = .{
+        .index = @enumToInt(Feature.sel2),
+        .name = @tagName(Feature.sel2),
+        .llvm_name = "sel2",
+        .description = "Enable v8.4-A Secure Exception Level 2 extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.sha2)] = .{
+        .index = @enumToInt(Feature.sha2),
+        .name = @tagName(Feature.sha2),
+        .llvm_name = "sha2",
+        .description = "Enable SHA1 and SHA256 support",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.sha3)] = .{
+        .index = @enumToInt(Feature.sha3),
+        .name = @tagName(Feature.sha3),
+        .llvm_name = "sha3",
+        .description = "Enable SHA512 and SHA3 support",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.sm4)] = .{
+        .index = @enumToInt(Feature.sm4),
+        .name = @tagName(Feature.sm4),
+        .llvm_name = "sm4",
+        .description = "Enable SM3 and SM4 support",
+        .dependencies = featureSet(&[_]Feature{
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.spe)] = .{
+        .index = @enumToInt(Feature.spe),
+        .name = @tagName(Feature.spe),
+        .llvm_name = "spe",
+        .description = "Enable Statistical Profiling extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.ssbs)] = .{
+        .index = @enumToInt(Feature.ssbs),
+        .name = @tagName(Feature.ssbs),
+        .llvm_name = "ssbs",
+        .description = "Enable Speculative Store Bypass Safe bit",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.sve)] = .{
+        .index = @enumToInt(Feature.sve),
+        .name = @tagName(Feature.sve),
+        .llvm_name = "sve",
+        .description = "Enable Scalable Vector Extension (SVE) instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.sve2)] = .{
+        .index = @enumToInt(Feature.sve2),
+        .name = @tagName(Feature.sve2),
+        .llvm_name = "sve2",
+        .description = "Enable Scalable Vector Extension 2 (SVE2) instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .sve,
+        }),
+    };
+    result[@enumToInt(Feature.sve2_aes)] = .{
+        .index = @enumToInt(Feature.sve2_aes),
+        .name = @tagName(Feature.sve2_aes),
+        .llvm_name = "sve2-aes",
+        .description = "Enable AES SVE2 instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .sve,
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.sve2_bitperm)] = .{
+        .index = @enumToInt(Feature.sve2_bitperm),
+        .name = @tagName(Feature.sve2_bitperm),
+        .llvm_name = "sve2-bitperm",
+        .description = "Enable bit permutation SVE2 instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .sve,
+        }),
+    };
+    result[@enumToInt(Feature.sve2_sha3)] = .{
+        .index = @enumToInt(Feature.sve2_sha3),
+        .name = @tagName(Feature.sve2_sha3),
+        .llvm_name = "sve2-sha3",
+        .description = "Enable SHA3 SVE2 instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .sve,
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.sve2_sm4)] = .{
+        .index = @enumToInt(Feature.sve2_sm4),
+        .name = @tagName(Feature.sve2_sm4),
+        .llvm_name = "sve2-sm4",
+        .description = "Enable SM4 SVE2 instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .sve,
+            .fp_armv8,
+        }),
+    };
+    result[@enumToInt(Feature.slow_misaligned_128store)] = .{
+        .index = @enumToInt(Feature.slow_misaligned_128store),
+        .name = @tagName(Feature.slow_misaligned_128store),
+        .llvm_name = "slow-misaligned-128store",
+        .description = "Misaligned 128 bit stores are slow",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.slow_paired_128)] = .{
+        .index = @enumToInt(Feature.slow_paired_128),
+        .name = @tagName(Feature.slow_paired_128),
+        .llvm_name = "slow-paired-128",
+        .description = "Paired 128 bit loads and stores are slow",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.slow_strqro_store)] = .{
+        .index = @enumToInt(Feature.slow_strqro_store),
+        .name = @tagName(Feature.slow_strqro_store),
+        .llvm_name = "slow-strqro-store",
+        .description = "STR of Q register with register offset is slow",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.specrestrict)] = .{
+        .index = @enumToInt(Feature.specrestrict),
+        .name = @tagName(Feature.specrestrict),
+        .llvm_name = "specrestrict",
+        .description = "Enable architectural speculation restriction",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.strict_align)] = .{
+        .index = @enumToInt(Feature.strict_align),
+        .name = @tagName(Feature.strict_align),
+        .llvm_name = "strict-align",
+        .description = "Disallow all unaligned memory access",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.tlb_rmi)] = .{
+        .index = @enumToInt(Feature.tlb_rmi),
+        .name = @tagName(Feature.tlb_rmi),
+        .llvm_name = "tlb-rmi",
+        .description = "Enable v8.4-A TLB Range and Maintenance Instructions",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.tracev84)] = .{
+        .index = @enumToInt(Feature.tracev84),
+        .name = @tagName(Feature.tracev84),
+        .llvm_name = "tracev8.4",
+        .description = "Enable v8.4-A Trace extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.use_aa)] = .{
+        .index = @enumToInt(Feature.use_aa),
+        .name = @tagName(Feature.use_aa),
+        .llvm_name = "use-aa",
+        .description = "Use alias analysis during codegen",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.tpidr_el1)] = .{
+        .index = @enumToInt(Feature.tpidr_el1),
+        .name = @tagName(Feature.tpidr_el1),
+        .llvm_name = "tpidr-el1",
+        .description = "Permit use of TPIDR_EL1 for the TLS base",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.tpidr_el2)] = .{
+        .index = @enumToInt(Feature.tpidr_el2),
+        .name = @tagName(Feature.tpidr_el2),
+        .llvm_name = "tpidr-el2",
+        .description = "Permit use of TPIDR_EL2 for the TLS base",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.tpidr_el3)] = .{
+        .index = @enumToInt(Feature.tpidr_el3),
+        .name = @tagName(Feature.tpidr_el3),
+        .llvm_name = "tpidr-el3",
+        .description = "Permit use of TPIDR_EL3 for the TLS base",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.use_reciprocal_square_root)] = .{
+        .index = @enumToInt(Feature.use_reciprocal_square_root),
+        .name = @tagName(Feature.use_reciprocal_square_root),
+        .llvm_name = "use-reciprocal-square-root",
+        .description = "Use the reciprocal square root approximation",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.vh)] = .{
+        .index = @enumToInt(Feature.vh),
+        .name = @tagName(Feature.vh),
+        .llvm_name = "vh",
+        .description = "Enables ARM v8.1 Virtual Host extension",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.zcm)] = .{
+        .index = @enumToInt(Feature.zcm),
+        .name = @tagName(Feature.zcm),
+        .llvm_name = "zcm",
+        .description = "Has zero-cycle register moves",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.zcz)] = .{
+        .index = @enumToInt(Feature.zcz),
+        .name = @tagName(Feature.zcz),
+        .llvm_name = "zcz",
+        .description = "Has zero-cycle zeroing instructions",
+        .dependencies = featureSet(&[_]Feature{
+            .zcz_fp,
+            .zcz_gp,
+        }),
+    };
+    result[@enumToInt(Feature.zcz_fp)] = .{
+        .index = @enumToInt(Feature.zcz_fp),
+        .name = @tagName(Feature.zcz_fp),
+        .llvm_name = "zcz-fp",
+        .description = "Has zero-cycle zeroing instructions for FP registers",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.zcz_fp_workaround)] = .{
+        .index = @enumToInt(Feature.zcz_fp_workaround),
+        .name = @tagName(Feature.zcz_fp_workaround),
+        .llvm_name = "zcz-fp-workaround",
+        .description = "The zero-cycle floating-point zeroing instruction has a bug",
+        .dependencies = 0,
+    };
+    result[@enumToInt(Feature.zcz_gp)] = .{
+        .index = @enumToInt(Feature.zcz_gp),
+        .name = @tagName(Feature.zcz_gp),
+        .llvm_name = "zcz-gp",
+        .description = "Has zero-cycle zeroing instructions for generic registers",
+        .dependencies = 0,
+    };
+    break :blk result;
+};
+
+pub const cpu = struct {
+    pub const apple_latest = Cpu{
+        .name = "apple_latest",
+        .llvm_name = "apple-latest",
+        .features = featureSet(&[_]Feature{
+            .arith_cbz_fusion,
+            .zcz_fp_workaround,
+            .alternate_sextload_cvt_f32_pattern,
+            .fuse_crypto_eor,
+            .zcm,
+            .zcz_gp,
+            .perfmon,
+            .disable_latency_sched_heuristic,
+            .fp_armv8,
+            .zcz_fp,
+            .arith_bcc_fusion,
+            .fuse_aes,
+        }),
+    };
+
+    pub const cortex_a35 = Cpu{
+        .name = "cortex_a35",
+        .llvm_name = "cortex-a35",
+        .features = featureSet(&[_]Feature{
+            .perfmon,
+            .fp_armv8,
+            .crc,
+        }),
+    };
+
+    pub const cortex_a53 = Cpu{
+        .name = "cortex_a53",
+        .llvm_name = "cortex-a53",
+        .features = featureSet(&[_]Feature{
+            .custom_cheap_as_move,
+            .crc,
+            .perfmon,
+            .use_aa,
+            .fp_armv8,
+            .fuse_aes,
+            .balance_fp_ops,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const cortex_a55 = Cpu{
+        .name = "cortex_a55",
+        .llvm_name = "cortex-a55",
+        .features = featureSet(&[_]Feature{
+            .ccpp,
+            .rcpc,
+            .uaops,
+            .rdm,
+            .ras,
+            .lse,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .vh,
+            .fuse_aes,
+            .lor,
+            .dotprod,
+            .pan,
+        }),
+    };
+
+    pub const cortex_a57 = Cpu{
+        .name = "cortex_a57",
+        .llvm_name = "cortex-a57",
+        .features = featureSet(&[_]Feature{
+            .fuse_literals,
+            .predictable_select_expensive,
+            .custom_cheap_as_move,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .fuse_aes,
+            .balance_fp_ops,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const cortex_a72 = Cpu{
+        .name = "cortex_a72",
+        .llvm_name = "cortex-a72",
+        .features = featureSet(&[_]Feature{
+            .fuse_aes,
+            .fp_armv8,
+            .perfmon,
+            .crc,
+        }),
+    };
+
+    pub const cortex_a73 = Cpu{
+        .name = "cortex_a73",
+        .llvm_name = "cortex-a73",
+        .features = featureSet(&[_]Feature{
+            .fuse_aes,
+            .fp_armv8,
+            .perfmon,
+            .crc,
+        }),
+    };
+
+    pub const cortex_a75 = Cpu{
+        .name = "cortex_a75",
+        .llvm_name = "cortex-a75",
+        .features = featureSet(&[_]Feature{
+            .ccpp,
+            .rcpc,
+            .uaops,
+            .rdm,
+            .ras,
+            .lse,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .vh,
+            .fuse_aes,
+            .lor,
+            .dotprod,
+            .pan,
+        }),
+    };
+
+    pub const cortex_a76 = Cpu{
+        .name = "cortex_a76",
+        .llvm_name = "cortex-a76",
+        .features = featureSet(&[_]Feature{
+            .ccpp,
+            .rcpc,
+            .uaops,
+            .rdm,
+            .ras,
+            .lse,
+            .crc,
+            .fp_armv8,
+            .vh,
+            .lor,
+            .ssbs,
+            .dotprod,
+            .pan,
+        }),
+    };
+
+    pub const cortex_a76ae = Cpu{
+        .name = "cortex_a76ae",
+        .llvm_name = "cortex-a76ae",
+        .features = featureSet(&[_]Feature{
+            .ccpp,
+            .rcpc,
+            .uaops,
+            .rdm,
+            .ras,
+            .lse,
+            .crc,
+            .fp_armv8,
+            .vh,
+            .lor,
+            .ssbs,
+            .dotprod,
+            .pan,
+        }),
+    };
+
+    pub const cyclone = Cpu{
+        .name = "cyclone",
+        .llvm_name = "cyclone",
+        .features = featureSet(&[_]Feature{
+            .arith_cbz_fusion,
+            .zcz_fp_workaround,
+            .alternate_sextload_cvt_f32_pattern,
+            .fuse_crypto_eor,
+            .zcm,
+            .zcz_gp,
+            .perfmon,
+            .disable_latency_sched_heuristic,
+            .fp_armv8,
+            .zcz_fp,
+            .arith_bcc_fusion,
+            .fuse_aes,
+        }),
+    };
+
+    pub const exynos_m1 = Cpu{
+        .name = "exynos_m1",
+        .llvm_name = "exynos-m1",
+        .features = featureSet(&[_]Feature{
+            .custom_cheap_as_move,
+            .crc,
+            .force_32bit_jump_tables,
+            .perfmon,
+            .slow_misaligned_128store,
+            .use_reciprocal_square_root,
+            .fp_armv8,
+            .zcz_fp,
+            .fuse_aes,
+            .slow_paired_128,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const exynos_m2 = Cpu{
+        .name = "exynos_m2",
+        .llvm_name = "exynos-m2",
+        .features = featureSet(&[_]Feature{
+            .custom_cheap_as_move,
+            .crc,
+            .force_32bit_jump_tables,
+            .perfmon,
+            .slow_misaligned_128store,
+            .fp_armv8,
+            .zcz_fp,
+            .fuse_aes,
+            .slow_paired_128,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const exynos_m3 = Cpu{
+        .name = "exynos_m3",
+        .llvm_name = "exynos-m3",
+        .features = featureSet(&[_]Feature{
+            .fuse_literals,
+            .predictable_select_expensive,
+            .custom_cheap_as_move,
+            .crc,
+            .force_32bit_jump_tables,
+            .fuse_address,
+            .fuse_csel,
+            .perfmon,
+            .fp_armv8,
+            .zcz_fp,
+            .fuse_aes,
+            .lsl_fast,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const exynos_m4 = Cpu{
+        .name = "exynos_m4",
+        .llvm_name = "exynos-m4",
+        .features = featureSet(&[_]Feature{
+            .arith_cbz_fusion,
+            .custom_cheap_as_move,
+            .lse,
+            .zcz_fp,
+            .lsl_fast,
+            .lor,
+            .fuse_literals,
+            .ccpp,
+            .ras,
+            .fp_armv8,
+            .fuse_aes,
+            .pan,
+            .fuse_arith_logic,
+            .crc,
+            .force_32bit_jump_tables,
+            .fuse_address,
+            .fuse_csel,
+            .arith_bcc_fusion,
+            .uaops,
+            .rdm,
+            .zcz_gp,
+            .perfmon,
+            .vh,
+            .use_postra_scheduler,
+            .dotprod,
+        }),
+    };
+
+    pub const exynos_m5 = Cpu{
+        .name = "exynos_m5",
+        .llvm_name = "exynos-m5",
+        .features = featureSet(&[_]Feature{
+            .arith_cbz_fusion,
+            .custom_cheap_as_move,
+            .lse,
+            .zcz_fp,
+            .lsl_fast,
+            .lor,
+            .fuse_literals,
+            .ccpp,
+            .ras,
+            .fp_armv8,
+            .fuse_aes,
+            .pan,
+            .fuse_arith_logic,
+            .crc,
+            .force_32bit_jump_tables,
+            .fuse_address,
+            .fuse_csel,
+            .arith_bcc_fusion,
+            .uaops,
+            .rdm,
+            .zcz_gp,
+            .perfmon,
+            .vh,
+            .use_postra_scheduler,
+            .dotprod,
+        }),
+    };
+
+    pub const falkor = Cpu{
+        .name = "falkor",
+        .llvm_name = "falkor",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .custom_cheap_as_move,
+            .rdm,
+            .slow_strqro_store,
+            .zcz_gp,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .zcz_fp,
+            .lsl_fast,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const generic = Cpu{
+        .name = "generic",
+        .llvm_name = "generic",
+        .features = featureSet(&[_]Feature{
+            .fp_armv8,
+            .fuse_aes,
+            .neon,
+            .perfmon,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const kryo = Cpu{
+        .name = "kryo",
+        .llvm_name = "kryo",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .custom_cheap_as_move,
+            .zcz_gp,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .zcz_fp,
+            .lsl_fast,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const saphira = Cpu{
+        .name = "saphira",
+        .llvm_name = "saphira",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .custom_cheap_as_move,
+            .fmi,
+            .lse,
+            .zcz_fp,
+            .lsl_fast,
+            .lor,
+            .dit,
+            .pa,
+            .ccpp,
+            .sel2,
+            .ras,
+            .fp_armv8,
+            .ccidx,
+            .pan,
+            .rcpc,
+            .crc,
+            .tracev84,
+            .mpam,
+            .am,
+            .nv,
+            .tlb_rmi,
+            .uaops,
+            .rdm,
+            .zcz_gp,
+            .perfmon,
+            .vh,
+            .use_postra_scheduler,
+            .dotprod,
+            .spe,
+        }),
+    };
+
+    pub const thunderx = Cpu{
+        .name = "thunderx",
+        .llvm_name = "thunderx",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const thunderx2t99 = Cpu{
+        .name = "thunderx2t99",
+        .llvm_name = "thunderx2t99",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .aggressive_fma,
+            .rdm,
+            .lse,
+            .crc,
+            .fp_armv8,
+            .vh,
+            .arith_bcc_fusion,
+            .lor,
+            .use_postra_scheduler,
+            .pan,
+        }),
+    };
+
+    pub const thunderxt81 = Cpu{
+        .name = "thunderxt81",
+        .llvm_name = "thunderxt81",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const thunderxt83 = Cpu{
+        .name = "thunderxt83",
+        .llvm_name = "thunderxt83",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const thunderxt88 = Cpu{
+        .name = "thunderxt88",
+        .llvm_name = "thunderxt88",
+        .features = featureSet(&[_]Feature{
+            .predictable_select_expensive,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .use_postra_scheduler,
+        }),
+    };
+
+    pub const tsv110 = Cpu{
+        .name = "tsv110",
+        .llvm_name = "tsv110",
+        .features = featureSet(&[_]Feature{
+            .ccpp,
+            .custom_cheap_as_move,
+            .uaops,
+            .rdm,
+            .ras,
+            .lse,
+            .crc,
+            .perfmon,
+            .fp_armv8,
+            .vh,
+            .fuse_aes,
+            .lor,
+            .use_postra_scheduler,
+            .dotprod,
+            .pan,
+            .spe,
+        }),
+    };
+};
+
+/// All aarch64 CPUs, sorted alphabetically by name.
+/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
+/// compiler has inefficient memory and CPU usage, affecting build times.
+pub const all_cpus = &[_]*const Cpu{
+    &cpu.apple_latest,
+    &cpu.cortex_a35,
+    &cpu.cortex_a53,
+    &cpu.cortex_a55,
+    &cpu.cortex_a57,
+    &cpu.cortex_a72,
+    &cpu.cortex_a73,
+    &cpu.cortex_a75,
+    &cpu.cortex_a76,
+    &cpu.cortex_a76ae,
+    &cpu.cyclone,
+    &cpu.exynos_m1,
+    &cpu.exynos_m2,
+    &cpu.exynos_m3,
+    &cpu.exynos_m4,
+    &cpu.exynos_m5,
+    &cpu.falkor,
+    &cpu.generic,
+    &cpu.kryo,
+    &cpu.saphira,
+    &cpu.thunderx,
+    &cpu.thunderx2t99,
+    &cpu.thunderxt81,
+    &cpu.thunderxt83,
+    &cpu.thunderxt88,
+    &cpu.tsv110,
 };
lib/std/buffer.zig
@@ -57,11 +57,11 @@ pub const Buffer = struct {
 
     /// The caller owns the returned memory. The Buffer becomes null and
     /// is safe to `deinit`.
-    pub fn toOwnedSlice(self: *Buffer) []u8 {
+    pub fn toOwnedSlice(self: *Buffer) [:0]u8 {
         const allocator = self.list.allocator;
         const result = allocator.shrink(self.list.items, self.len());
         self.* = initNull(allocator);
-        return result;
+        return result[0 .. result.len - 1 :0];
     }
 
     pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: var) !Buffer {
lib/std/build.zig
@@ -1199,8 +1199,6 @@ pub const LibExeObjStep = struct {
 
     subsystem: ?builtin.SubSystem = null,
 
-    target_details: ?std.target.TargetDetails = null,
-
     const LinkObject = union(enum) {
         StaticPath: []const u8,
         OtherStep: *LibExeObjStep,
@@ -1386,10 +1384,6 @@ pub const LibExeObjStep = struct {
         self.computeOutFileNames();
     }
 
-    pub fn setTargetDetails(self: *LibExeObjStep, target_details: std.target.TargetDetails) void {
-        self.target_details = target_details;
-    }
-
     pub fn setTargetGLibC(self: *LibExeObjStep, major: u32, minor: u32, patch: u32) void {
         self.target_glibc = Version{
             .major = major,
@@ -1974,32 +1968,31 @@ pub const LibExeObjStep = struct {
 
         switch (self.target) {
             .Native => {},
-            .Cross => {
+            .Cross => |cross| {
                 try zig_args.append("-target");
                 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
-            },
-        }
 
-        if (self.target_details) |td| {
-            switch (td) {
-                .cpu => |cpu| {
-                    try zig_args.append("--cpu");
-                    try zig_args.append(cpu.name);
-                },
-                .features => |features| {
-                    try zig_args.append("--features");
-                    
-                    var feature_str_buffer = try std.Buffer.initSize(builder.allocator, 0);
-                    defer feature_str_buffer.deinit();
-
-                    for (features) |feature| {
-                        try feature_str_buffer.append(feature.name);
-                        try feature_str_buffer.append(",");
-                    }
+                switch (cross.cpu_features) {
+                    .baseline => {},
+                    .cpu => |cpu| {
+                        try zig_args.append("-target-cpu");
+                        try zig_args.append(cpu.name);
+                    },
+                    .features => |features| {
+                        try zig_args.append("-target-cpu-features");
+
+                        var feature_str_buffer = try std.Buffer.initSize(builder.allocator, 0);
+                        for (self.target.getArch().allFeaturesList()) |feature, i| {
+                            if (Target.Cpu.Feature.isEnabled(features, @intCast(u7, i))) {
+                                try feature_str_buffer.append(feature.name);
+                                try feature_str_buffer.append(",");
+                            }
+                        }
 
-                    try zig_args.append(feature_str_buffer.toOwnedSlice());
-                },
-            }
+                        try zig_args.append(feature_str_buffer.toSlice());
+                    },
+                }
+            },
         }
 
         if (self.target_glibc) |ver| {
lib/std/builtin.zig
@@ -15,6 +15,12 @@ pub const ObjectFormat = std.Target.ObjectFormat;
 /// Deprecated: use `std.Target.SubSystem`.
 pub const SubSystem = std.Target.SubSystem;
 
+/// Deprecated: use `std.Target.Cross.CpuFeatures`.
+pub const CpuFeatures = std.Target.Cross.CpuFeatures;
+
+/// Deprecated: use `std.Target.Cpu`.
+pub const Cpu = std.Target.Cpu;
+
 /// `explicit_subsystem` is missing when the subsystem is automatically detected,
 /// so Zig standard library has the subsystem detection logic here. This should generally be
 /// used rather than `explicit_subsystem`.
lib/std/fmt.zig
@@ -1138,6 +1138,11 @@ fn countSize(size: *usize, bytes: []const u8) (error{}!void) {
     size.* += bytes.len;
 }
 
+pub fn allocPrint0(allocator: *mem.Allocator, comptime fmt: []const u8, args: var) AllocPrintError![:0]u8 {
+    const result = try allocPrint(allocator, fmt ++ "\x00", args);
+    return result[0 .. result.len - 1 :0];
+}
+
 test "bufPrintInt" {
     var buffer: [100]u8 = undefined;
     const buf = buffer[0..];
lib/std/meta.zig
@@ -556,3 +556,21 @@ pub fn refAllDecls(comptime T: type) void {
     if (!builtin.is_test) return;
     _ = declarations(T);
 }
+
+/// Returns a slice of pointers to public declarations of a namespace.
+pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const Decl {
+    const S = struct {
+        fn declNameLessThan(lhs: *const Decl, rhs: *const Decl) bool {
+            return mem.lessThan(u8, lhs.name, rhs.name);
+        }
+    };
+    comptime {
+        const decls = declarations(Namespace);
+        var array: [decls.len]*const Decl = undefined;
+        for (decls) |decl, i| {
+            array[i] = &@field(Namespace, decl.name);
+        }
+        std.sort.sort(*const Decl, &array, S.declNameLessThan);
+        return &array;
+    }
+}
lib/std/std.zig
@@ -60,7 +60,6 @@ pub const rand = @import("rand.zig");
 pub const rb = @import("rb.zig");
 pub const sort = @import("sort.zig");
 pub const ascii = @import("ascii.zig");
-pub const target = @import("target.zig");
 pub const testing = @import("testing.zig");
 pub const time = @import("time.zig");
 pub const unicode = @import("unicode.zig");
lib/std/target.zig
@@ -101,6 +101,22 @@ pub const Target = union(enum) {
         renderscript32,
         renderscript64,
 
+        pub const aarch64 = @import("target/aarch64.zig");
+        pub const amdgpu = @import("target/amdgpu.zig");
+        pub const arm = @import("target/arm.zig");
+        pub const avr = @import("target/avr.zig");
+        pub const bpf = @import("target/bpf.zig");
+        pub const hexagon = @import("target/hexagon.zig");
+        pub const mips = @import("target/mips.zig");
+        pub const msp430 = @import("target/msp430.zig");
+        pub const nvptx = @import("target/nvptx.zig");
+        pub const powerpc = @import("target/powerpc.zig");
+        pub const riscv = @import("target/riscv.zig");
+        pub const sparc = @import("target/sparc.zig");
+        pub const systemz = @import("target/systemz.zig");
+        pub const wasm = @import("target/wasm.zig");
+        pub const x86 = @import("target/x86.zig");
+
         pub const Arm32 = enum {
             v8_5a,
             v8_4a,
@@ -184,6 +200,71 @@ pub const Target = union(enum) {
             };
         }
 
+        pub fn parseCpu(arch: Arch, cpu_name: []const u8) !*const Cpu {
+            for (arch.allCpus()) |cpu| {
+                if (mem.eql(u8, cpu_name, cpu.name)) {
+                    return cpu;
+                }
+            }
+            return error.UnknownCpu;
+        }
+
+        /// This parsing function supports 2 syntaxes.
+        /// * Comma-separated list of features, with + or - in front of each feature. This
+        ///   form represents a deviation from baseline.
+        /// * Comma-separated list of features, with no + or - in front of each feature. This
+        ///   form represents an exclusive list of enabled features; no other features besides
+        ///   the ones listed, and their dependencies, will be enabled.
+        /// Extra commas are ignored.
+        pub fn parseCpuFeatureSet(arch: Arch, features_text: []const u8) !Cpu.Feature.Set {
+            // Here we compute both and choose the correct result at the end, based
+            // on whether or not we saw + and - signs.
+            var set: @Vector(2, Cpu.Feature.Set) = [2]Cpu.Feature.Set{ 0, arch.baselineFeatures() };
+            var mode: enum {
+                unknown,
+                baseline,
+                whitelist,
+            } = .unknown;
+
+            var it = mem.tokenize(features_text, ",");
+            while (it.next()) |item_text| {
+                const feature_name = blk: {
+                    if (mem.startsWith(u8, item_text, "+")) {
+                        switch (mode) {
+                            .unknown, .baseline => mode = .baseline,
+                            .whitelist => return error.InvalidCpuFeatures,
+                        }
+                        break :blk item_text[1..];
+                    } else if (mem.startsWith(u8, item_text, "-")) {
+                        switch (mode) {
+                            .unknown, .baseline => mode = .baseline,
+                            .whitelist => return error.InvalidCpuFeatures,
+                        }
+                        break :blk item_text[1..];
+                    } else {
+                        switch (mode) {
+                            .unknown, .whitelist => mode = .whitelist,
+                            .baseline => return error.InvalidCpuFeatures,
+                        }
+                        break :blk item_text;
+                    }
+                };
+                for (arch.allFeaturesList()) |feature, index| {
+                    if (mem.eql(u8, feature_name, feature.name)) {
+                        set |= @splat(2, 1 << index);
+                        break;
+                    }
+                } else {
+                    return error.UnknownCpuFeature;
+                }
+            }
+
+            return switch (mode) {
+                .unknown, .whitelist => set[0],
+                .baseline => set[1],
+            };
+        }
+
         pub fn toElfMachine(arch: Arch) std.elf.EM {
             return switch (arch) {
                 .avr => ._AVR,
@@ -296,6 +377,98 @@ pub const Target = union(enum) {
                 => .Big,
             };
         }
+
+        /// Returns a name that matches the lib/std/target/* directory name.
+        pub fn genericName(arch: Arch) []const u8 {
+            return switch (arch) {
+                .arm, .armeb, .thumb, .thumbeb => "arm",
+                .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
+                .avr => "avr",
+                .bpfel, .bpfeb => "bpf",
+                .hexagon => "hexagon",
+                .mips, .mipsel, .mips64, .mips64el => "mips",
+                .msp430 => "msp430",
+                .powerpc, .powerpc64, .powerpc64le => "powerpc",
+                .amdgcn => "amdgpu",
+                .riscv32, .riscv64 => "riscv",
+                .sparc, .sparcv9, .sparcel => "sparc",
+                .s390x => "systemz",
+                .i386, .x86_64 => "x86",
+                .nvptx, .nvptx64 => "nvptx",
+                .wasm32, .wasm64 => "wasm",
+                else => @tagName(arch),
+            };
+        }
+
+        /// All CPU features Zig is aware of, sorted lexicographically by name.
+        pub fn allFeaturesList(arch: Arch) []const *const Cpu.Feature {
+            return switch (arch) {
+                .arm, .armeb, .thumb, .thumbeb => arm.all_features,
+                .aarch64, .aarch64_be, .aarch64_32 => aarch64.all_features,
+                .avr => avr.all_features,
+                .bpfel, .bpfeb => bpf.all_features,
+                .hexagon => hexagon.all_features,
+                .mips, .mipsel, .mips64, .mips64el => mips.all_features,
+                .msp430 => msp430.all_features,
+                .powerpc, .powerpc64, .powerpc64le => powerpc.all_features,
+                .amdgcn => amdgpu.all_features,
+                .riscv32, .riscv64 => riscv.all_features,
+                .sparc, .sparcv9, .sparcel => sparc.all_features,
+                .s390x => systemz.all_features,
+                .i386, .x86_64 => x86.all_features,
+                .nvptx, .nvptx64 => nvptx.all_features,
+                .wasm32, .wasm64 => wasm.all_features,
+
+                else => &[0]*const Cpu.Feature{},
+            };
+        }
+
+        /// The "default" set of CPU features for cross-compiling. A conservative set
+        /// of features that is expected to be supported on most available hardware.
+        pub fn baselineFeatures(arch: Arch) Cpu.Feature.Set {
+            return switch (arch) {
+                .arm, .armeb, .thumb, .thumbeb => arm.baseline_features,
+                .aarch64, .aarch64_be, .aarch64_32 => aarch64.cpu.generic.features,
+                .avr => avr.baseline_features,
+                .bpfel, .bpfeb => bpf.baseline_features,
+                .hexagon => hexagon.baseline_features,
+                .mips, .mipsel, .mips64, .mips64el => mips.baseline_features,
+                .msp430 => msp430.baseline_features,
+                .powerpc, .powerpc64, .powerpc64le => powerpc.baseline_features,
+                .amdgcn => amdgpu.baseline_features,
+                .riscv32, .riscv64 => riscv.baseline_features,
+                .sparc, .sparcv9, .sparcel => sparc.baseline_features,
+                .s390x => systemz.baseline_features,
+                .i386, .x86_64 => x86.baseline_features,
+                .nvptx, .nvptx64 => nvptx.baseline_features,
+                .wasm32, .wasm64 => wasm.baseline_features,
+
+                else => &[0]*const Cpu.Feature{},
+            };
+        }
+
+        /// All CPUs Zig is aware of, sorted lexicographically by name.
+        pub fn allCpus(arch: Arch) []const *const Cpu {
+            return switch (arch) {
+                .arm, .armeb, .thumb, .thumbeb => arm.all_cpus,
+                .aarch64, .aarch64_be, .aarch64_32 => aarch64.all_cpus,
+                .avr => avr.all_cpus,
+                .bpfel, .bpfeb => bpf.all_cpus,
+                .hexagon => hexagon.all_cpus,
+                .mips, .mipsel, .mips64, .mips64el => mips.all_cpus,
+                .msp430 => msp430.all_cpus,
+                .powerpc, .powerpc64, .powerpc64le => powerpc.all_cpus,
+                .amdgcn => amdgpu.all_cpus,
+                .riscv32, .riscv64 => riscv.all_cpus,
+                .sparc, .sparcv9, .sparcel => sparc.all_cpus,
+                .s390x => systemz.all_cpus,
+                .i386, .x86_64 => x86.all_cpus,
+                .nvptx, .nvptx64 => nvptx.all_cpus,
+                .wasm32, .wasm64 => wasm.all_cpus,
+
+                else => &[0]*const Cpu{},
+            };
+        }
     };
 
     pub const Abi = enum {
@@ -323,6 +496,28 @@ pub const Target = union(enum) {
         macabi,
     };
 
+    pub const Cpu = struct {
+        name: []const u8,
+        llvm_name: ?[:0]const u8,
+        features: Feature.Set,
+
+        pub const Feature = struct {
+            /// The bit index into `Set`.
+            index: u8,
+            name: []const u8,
+            llvm_name: ?[:0]const u8,
+            description: []const u8,
+            dependencies: Set,
+
+            /// A bit set of all the features.
+            pub const Set = u128;
+
+            pub fn isEnabled(set: Set, arch_feature_index: u7) bool {
+                return (set & (@as(Set, 1) << arch_feature_index)) != 0;
+            }
+        };
+    };
+
     pub const ObjectFormat = enum {
         unknown,
         coff,
@@ -346,6 +541,19 @@ pub const Target = union(enum) {
         arch: Arch,
         os: Os,
         abi: Abi,
+        cpu_features: CpuFeatures = .baseline,
+
+        pub const CpuFeatures = union(enum) {
+            /// The "default" set of CPU features for cross-compiling. A conservative set
+            /// of features that is expected to be supported on most available hardware.
+            baseline,
+
+            /// Target one specific CPU.
+            cpu: *const Cpu,
+
+            /// Explicitly provide the entire CPU feature set.
+            features: Cpu.Feature.Set,
+        };
     };
 
     pub const current = Target{
@@ -353,11 +561,20 @@ pub const Target = union(enum) {
             .arch = builtin.arch,
             .os = builtin.os,
             .abi = builtin.abi,
+            .cpu_features = builtin.cpu_features,
         },
     };
 
     pub const stack_align = 16;
 
+    pub fn cpuFeatures(self: Target) []const *const Cpu.Feature {
+        return switch (self.cpu_features) {
+            .baseline => self.arch.baselineFeatures(),
+            .cpu => |cpu| cpu.features,
+            .features => |features| features,
+        };
+    }
+
     pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
         return std.fmt.allocPrint(allocator, "{}{}-{}-{}", .{
             @tagName(self.getArch()),
@@ -496,7 +713,7 @@ pub const Target = union(enum) {
     pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {
         const info = @typeInfo(Arch);
         inline for (info.Union.fields) |field| {
-            if (text.len >= field.name.len and mem.eql(u8, text[0..field.name.len], field.name)) {
+            if (mem.eql(u8, text, field.name)) {
                 if (field.field_type == void) {
                     return @as(Arch, @field(Arch, field.name));
                 } else {
@@ -514,31 +731,6 @@ pub const Target = union(enum) {
         return error.UnknownArchitecture;
     }
 
-    pub fn parseArchTag(text: []const u8) ParseArchSubError!@TagType(Arch) {
-        const info = @typeInfo(Arch);
-        inline for (info.Union.fields) |field| {
-            if (text.len >= field.name.len and mem.eql(u8, text[0..field.name.len], field.name)) {
-                if (text.len == field.name.len) return @as(@TagType(Arch), @field(Arch, field.name));
-
-                if (field.field_type == void) {
-                    return error.UnknownArchitecture;
-                }
-
-                const sub_info = @typeInfo(field.field_type);
-                inline for (sub_info.Enum.fields) |sub_field| {
-                    const combined = field.name ++ sub_field.name;
-                    if (mem.eql(u8, text, combined)) {
-                        return @as(@TagType(Arch), @field(Arch, field.name));
-                    }
-                }
-
-                return error.UnknownSubArchitecture;
-            }
-        }
-
-        return error.UnknownArchitecture;
-    }
-
     pub fn parseOs(text: []const u8) !Os {
         const info = @typeInfo(Os);
         inline for (info.Enum.fields) |field| {
@@ -841,83 +1033,3 @@ pub const Target = union(enum) {
         return .unavailable;
     }
 };
-
-pub const aarch64 = @import("target/aarch64.zig");
-pub const amdgpu = @import("target/amdgpu.zig");
-pub const arm = @import("target/arm.zig");
-pub const avr = @import("target/avr.zig");
-pub const bpf = @import("target/bpf.zig");
-pub const hexagon = @import("target/hexagon.zig");
-pub const mips = @import("target/mips.zig");
-pub const msp430 = @import("target/msp430.zig");
-pub const nvptx = @import("target/nvptx.zig");
-pub const powerpc = @import("target/powerpc.zig");
-pub const riscv = @import("target/riscv.zig");
-pub const sparc = @import("target/sparc.zig");
-pub const systemz = @import("target/systemz.zig");
-pub const wasm = @import("target/wasm.zig");
-pub const x86 = @import("target/x86.zig");
-
-pub const Feature = struct {
-    name: []const u8,
-    llvm_name: ?[]const u8,
-    description: []const u8,
-
-    dependencies: []*const Feature,
-};
-
-pub const Cpu = struct {
-    name: []const u8,
-    llvm_name: ?[]const u8,
-
-    dependencies: []*const Feature,
-};
-
-pub const TargetDetails = union(enum) {
-    cpu: *const Cpu,
-    features: []*const Feature,
-};
-
-pub fn getFeaturesForArch(arch: @TagType(Target.Arch)) []*const Feature {
-    return switch (arch) {
-        .arm, .armeb, .thumb, .thumbeb => arm.features,
-        .aarch64, .aarch64_be, .aarch64_32 => aarch64.features,
-        .avr => avr.features,
-        .bpfel, .bpfeb => bpf.features,
-        .hexagon => hexagon.features,
-        .mips, .mipsel, .mips64, .mips64el => mips.features,
-        .msp430 => msp430.features,
-        .powerpc, .powerpc64, .powerpc64le => powerpc.features,
-        .amdgcn => amdgpu.features,
-        .riscv32, .riscv64 => riscv.features,
-        .sparc, .sparcv9, .sparcel => sparc.features,
-        .s390x => systemz.features,
-        .i386, .x86_64 => x86.features,
-        .nvptx, .nvptx64 => nvptx.features,
-        .wasm32, .wasm64 => wasm.features,
-
-        else => &[_]*const Feature{},
-    };
-}
-
-pub fn getCpusForArch(arch: @TagType(Target.Arch)) []*const Cpu {
-    return switch (arch) {
-        .arm, .armeb, .thumb, .thumbeb => arm.cpus,
-        .aarch64, .aarch64_be, .aarch64_32 => aarch64.cpus,
-        .avr => avr.cpus,
-        .bpfel, .bpfeb => bpf.cpus,
-        .hexagon => hexagon.cpus,
-        .mips, .mipsel, .mips64, .mips64el => mips.cpus,
-        .msp430 => msp430.cpus,
-        .powerpc, .powerpc64, .powerpc64le => powerpc.cpus,
-        .amdgcn => amdgpu.cpus,
-        .riscv32, .riscv64 => riscv.cpus,
-        .sparc, .sparcv9, .sparcel => sparc.cpus,
-        .s390x => systemz.cpus,
-        .i386, .x86_64 => x86.cpus,
-        .nvptx, .nvptx64 => nvptx.cpus,
-        .wasm32, .wasm64 => wasm.cpus,
-
-        else => &[_]*const Cpu{},
-    };
-}
src/all_types.hpp
@@ -2215,8 +2215,6 @@ struct CodeGen {
 
     const char **clang_argv;
     size_t clang_argv_len;
-
-    Stage2TargetDetails *target_details;
 };
 
 struct ZigVar {
src/codegen.cpp
@@ -8573,6 +8573,17 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
     buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
     buf_appendf(contents, "pub const arch = %s;\n", cur_arch);
     buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
+    {
+        buf_append_str(contents, "pub const cpu_features: CpuFeatures = ");
+        if (g->zig_target->cpu_features != nullptr) {
+            const char *ptr;
+            size_t len;
+            stage2_cpu_features_get_builtin_str(g->zig_target->cpu_features, &ptr, &len);
+            buf_append_mem(contents, ptr, len);
+        } else {
+            buf_append_str(contents, ".baseline;\n");
+        }
+    }
     if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) {
         buf_appendf(contents,
             "pub const glibc_version: ?Version = Version{.major = %d, .minor = %d, .patch = %d};\n",
@@ -8602,14 +8613,6 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
             "pub var test_functions: []TestFn = undefined; // overwritten later\n"
         );
     }
-    
-    buf_appendf(contents, "pub const target_details: ?@import(\"std\").target.TargetDetails = ");
-    if (g->target_details) {
-        buf_appendf(contents, "%s", stage2_target_details_get_builtin_str(g->target_details));
-    } else {
-        buf_appendf(contents, "null;");
-    }
-    buf_appendf(contents, "\n");
 
     return contents;
 }
@@ -8648,6 +8651,12 @@ static Error define_builtin_compile_vars(CodeGen *g) {
     cache_int(&cache_hash, g->zig_target->vendor);
     cache_int(&cache_hash, g->zig_target->os);
     cache_int(&cache_hash, g->zig_target->abi);
+    if (g->zig_target->cpu_features != nullptr) {
+        const char *ptr;
+        size_t len;
+        stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
+        cache_str(&cache_hash, ptr);
+    }
     if (g->zig_target->glibc_version != nullptr) {
         cache_int(&cache_hash, g->zig_target->glibc_version->major);
         cache_int(&cache_hash, g->zig_target->glibc_version->minor);
@@ -8659,10 +8668,6 @@ static Error define_builtin_compile_vars(CodeGen *g) {
     cache_bool(&cache_hash, g->link_eh_frame_hdr);
     cache_int(&cache_hash, detect_subsystem(g));
 
-    if (g->target_details) {
-        cache_str(&cache_hash, stage2_target_details_get_cache_str(g->target_details));
-    }
-
     Buf digest = BUF_INIT;
     buf_resize(&digest, 0);
     if ((err = cache_hit(&cache_hash, &digest))) {
@@ -8793,9 +8798,9 @@ static void init(CodeGen *g) {
     }
 
     // Override CPU and features if defined by user.
-    if (g->target_details) {
-        target_specific_cpu_args = stage2_target_details_get_llvm_cpu(g->target_details);
-        target_specific_features = stage2_target_details_get_llvm_features(g->target_details);
+    if (g->zig_target->cpu_features != nullptr) {
+        target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
+        target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
     }
     
     g->target_machine = ZigLLVMCreateTargetMachine(target_ref, buf_ptr(&g->llvm_triple_str),
@@ -9123,15 +9128,19 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
         args.append("-target");
         args.append(buf_ptr(&g->llvm_triple_str));
 
-        if (g->target_details) {
+        const char *llvm_cpu = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);
+        if (llvm_cpu != nullptr) {
             args.append("-Xclang");
             args.append("-target-cpu");
             args.append("-Xclang");
-            args.append(stage2_target_details_get_llvm_cpu(g->target_details));
+            args.append(llvm_cpu);
+        }
+        const char *llvm_target_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);
+        if (llvm_target_features != nullptr) {
             args.append("-Xclang");
             args.append("-target-feature");
             args.append("-Xclang");
-            args.append(stage2_target_details_get_llvm_features(g->target_details));
+            args.append(llvm_target_features);
         }
     }
 
@@ -10328,6 +10337,12 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
     cache_int(ch, g->zig_target->vendor);
     cache_int(ch, g->zig_target->os);
     cache_int(ch, g->zig_target->abi);
+    if (g->zig_target->cpu_features != nullptr) {
+        const char *ptr;
+        size_t len;
+        stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
+        cache_str(ch, ptr);
+    }
     if (g->zig_target->glibc_version != nullptr) {
         cache_int(ch, g->zig_target->glibc_version->major);
         cache_int(ch, g->zig_target->glibc_version->minor);
@@ -10375,10 +10390,6 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
     cache_buf_opt(ch, g->dynamic_linker_path);
     cache_buf_opt(ch, g->version_script_path);
 
-    if (g->target_details) {
-        cache_str(ch, stage2_target_details_get_cache_str(g->target_details));
-    }
-
     // gen_c_objects appends objects to g->link_objects which we want to include in the hash
     gen_c_objects(g);
     cache_list_of_file(ch, g->link_objects.items, g->link_objects.length);
@@ -10661,7 +10672,6 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
 
     CodeGen *child_gen = codegen_create(nullptr, root_src_path, parent_gen->zig_target, out_type,
         parent_gen->build_mode, parent_gen->zig_lib_dir, libc, get_global_cache_dir(), false, child_progress_node);
-    child_gen->target_details = parent_gen->target_details;
     child_gen->root_out_name = buf_create_from_str(name);
     child_gen->disable_gen_h = true;
     child_gen->want_stack_check = WantStackCheckDisabled;
src/main.cpp
@@ -955,9 +955,9 @@ int main(int argc, char **argv) {
                     targets_list_features_arch = argv[i];
                 } else if (strcmp(arg, "--list-cpus") == 0) {
                     targets_list_cpus_arch = argv[i];
-                } else if (strcmp(arg, "--cpu") == 0) {
+                } else if (strcmp(arg, "-target-cpu") == 0) {
                     cpu = argv[i];
-                } else if (strcmp(arg, "--features") == 0) {
+                } else if (strcmp(arg, "-target-feature") == 0) {
                     features = argv[i];
                 }else {
                     fprintf(stderr, "Invalid argument: %s\n", arg);
@@ -1074,27 +1074,26 @@ int main(int argc, char **argv) {
         }
     }
 
-    Stage2TargetDetails *target_details = nullptr;
     if (cpu && features) {
-        fprintf(stderr, "--cpu and --features options not allowed together\n");
+        fprintf(stderr, "-target-cpu and -target-feature options not allowed together\n");
         return main_exit(root_progress_node, EXIT_FAILURE);
     } else if (cpu) {
-        target_details = stage2_target_details_parse_cpu(target_arch_name(target.arch), cpu);
-        if (!target_details) {
-            fprintf(stderr, "invalid --cpu value\n");
+        target.cpu_features = stage2_cpu_features_parse_cpu(target_arch_name(target.arch), cpu);
+        if (!target.cpu_features) {
+            fprintf(stderr, "invalid -target-cpu value\n");
             return main_exit(root_progress_node, EXIT_FAILURE);
         }
     } else if (features) {
-        target_details = stage2_target_details_parse_features(target_arch_name(target.arch), features);
-        if (!target_details) {
-            fprintf(stderr, "invalid --features value\n");
+        target.cpu_features = stage2_cpu_features_parse_features(target_arch_name(target.arch), features);
+        if (!target.cpu_features) {
+            fprintf(stderr, "invalid -target-feature value\n");
             return main_exit(root_progress_node, EXIT_FAILURE);
         }
     } else {
         // If no details are specified and we are not native, load
         // cross-compilation default features.
         if (!target.is_native) {
-            target_details = stage2_target_details_get_default(target_arch_name(target.arch), target_os_name(target.os));
+            target.cpu_features = stage2_cpu_features_baseline();
         }
     }
 
@@ -1148,7 +1147,6 @@ int main(int argc, char **argv) {
         g->want_stack_check = want_stack_check;
         g->want_sanitize_c = want_sanitize_c;
         g->want_single_threaded = want_single_threaded;
-        g->target_details = target_details;
         Buf *builtin_source = codegen_generate_builtin_source(g);
         if (fwrite(buf_ptr(builtin_source), 1, buf_len(builtin_source), stdout) != buf_len(builtin_source)) {
             fprintf(stderr, "unable to write to stdout: %s\n", strerror(ferror(stdout)));
@@ -1303,8 +1301,6 @@ int main(int argc, char **argv) {
                 codegen_add_rpath(g, rpath_list.at(i));
             }
 
-            g->target_details = target_details;
-
             codegen_set_rdynamic(g, rdynamic);
             if (mmacosx_version_min && mios_version_min) {
                 fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");
src/target.hpp
@@ -91,6 +91,7 @@ struct ZigTarget {
     Os os;
     ZigLLVM_EnvironmentType abi;
     ZigGLibCVersion *glibc_version; // null means default
+    Stage2CpuFeatures *cpu_features;
     bool is_native;
 };
 
src/userland.cpp
@@ -89,26 +89,44 @@ void stage2_progress_complete_one(Stage2ProgressNode *node) {}
 void stage2_progress_disable_tty(Stage2Progress *progress) {}
 void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
 
-void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
-void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {}
-Stage2TargetDetails *stage2_target_details_parse_cpu(const char *arch, const char *str) {
-    return nullptr;
+void stage2_list_features_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {
+    const char *msg = "stage0 called stage2_list_features_for_arch";
+    stage2_panic(msg, strlen(msg));
 }
-Stage2TargetDetails *stage2_target_details_parse_features(const char *arch, const char *str) {
-    return nullptr;
+
+void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures) {
+    const char *msg = "stage0 called stage2_list_cpus_for_arch";
+    stage2_panic(msg, strlen(msg));
 }
-const char *stage2_target_details_get_cache_str(const Stage2TargetDetails *target_details) {
-    return "";
+Stage2CpuFeatures *stage2_cpu_features_parse_cpu(const char *arch, const char *str) {
+    const char *msg = "stage0 called stage2_cpu_features_parse_cpu";
+    stage2_panic(msg, strlen(msg));
 }
-const char *stage2_target_details_get_llvm_cpu(const Stage2TargetDetails *target_details) {
-    return "";
+Stage2CpuFeatures *stage2_cpu_features_parse_features(const char *arch, const char *str) {
+    const char *msg = "stage0 called stage2_cpu_features_parse_features";
+    stage2_panic(msg, strlen(msg));
 }
-const char *stage2_target_details_get_llvm_features(const Stage2TargetDetails *target_details) {
-    return "";
+Stage2CpuFeatures *stage2_cpu_features_baseline(void) {
+    const char *msg = "stage0 called stage2_cpu_features_baseline";
+    stage2_panic(msg, strlen(msg));
 }
-const char *stage2_target_details_get_builtin_str(const Stage2TargetDetails *target_details) {
-    return "";
+void stage2_cpu_features_get_cache_hash(const Stage2CpuFeatures *cpu_features,
+        const char **ptr, size_t *len)
+{
+    const char *msg = "stage0 called stage2_cpu_features_get_cache_hash";
+    stage2_panic(msg, strlen(msg));
 }
-Stage2TargetDetails *stage2_target_details_get_default(const char *arch, const char *os) {
-    return nullptr;
+const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features) {
+    const char *msg = "stage0 called stage2_cpu_features_get_llvm_cpu";
+    stage2_panic(msg, strlen(msg));
+}
+const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features) {
+    const char *msg = "stage0 called stage2_cpu_features_get_llvm_features";
+    stage2_panic(msg, strlen(msg));
+}
+void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features, 
+        const char **ptr, size_t *len)
+{
+    const char *msg = "stage0 called stage2_cpu_features_get_builtin_str";
+    stage2_panic(msg, strlen(msg));
 }
src/userland.h
@@ -181,27 +181,29 @@ ZIG_EXTERN_C void stage2_list_features_for_arch(const char *arch_name_ptr, size_
 ZIG_EXTERN_C void stage2_list_cpus_for_arch(const char *arch_name_ptr, size_t arch_name_len, bool show_subfeatures);
 
 // ABI warning
-struct Stage2TargetDetails;
+struct Stage2CpuFeatures;
 
 // ABI warning
-ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_parse_cpu(const char *arch, const char *str);
+ZIG_EXTERN_C Stage2CpuFeatures *stage2_cpu_features_parse_cpu(const char *arch, const char *cpu_name);
 
 // ABI warning
-ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_parse_features(const char *arch, const char *str);
+ZIG_EXTERN_C Stage2CpuFeatures *stage2_cpu_features_parse_features(const char *arch, const char *features);
 
 // ABI warning
-ZIG_EXTERN_C const char *stage2_target_details_get_cache_str(const Stage2TargetDetails *target_details);
+ZIG_EXTERN_C Stage2CpuFeatures *stage2_cpu_features_baseline(void);
 
 // ABI warning
-ZIG_EXTERN_C const char *stage2_target_details_get_llvm_cpu(const Stage2TargetDetails *target_details);
+ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features);
 
 // ABI warning
-ZIG_EXTERN_C const char *stage2_target_details_get_llvm_features(const Stage2TargetDetails *target_details);
+ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features);
 
 // ABI warning
-ZIG_EXTERN_C const char *stage2_target_details_get_builtin_str(const Stage2TargetDetails *target_details);
+ZIG_EXTERN_C void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features,
+        const char **ptr, size_t *len);
 
 // ABI warning
-ZIG_EXTERN_C Stage2TargetDetails *stage2_target_details_get_default(const char *arch, const char *os);
+ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const Stage2CpuFeatures *cpu_features,
+        const char **ptr, size_t *len);
 
 #endif
src-self-hosted/stage1.zig
@@ -81,6 +81,9 @@ const Error = extern enum {
     OperationAborted,
     BrokenPipe,
     NoSpaceLeft,
+    NotLazy,
+    IsAsync,
+    ImportOutsidePkgPath,
 };
 
 const FILE = std.c.FILE;
@@ -150,7 +153,7 @@ fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
     const argc_usize = @intCast(usize, argc);
     var arg_i: usize = 0;
     while (arg_i < argc_usize) : (arg_i += 1) {
-        try args_list.append(std.mem.toSliceConst(u8, argv[arg_i]));
+        try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
     }
 
     stdout = &std.io.getStdOut().outStream().stream;
@@ -532,7 +535,7 @@ export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usiz
 // ABI warning
 export fn stage2_list_features_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_dependencies: bool) void {
     printFeaturesForArch(arch_name_ptr[0..arch_name_len], show_dependencies) catch |err| {
-        std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) });
+        std.debug.warn("Failed to list features: {}\n", .{@errorName(err)});
     };
 }
 
@@ -540,11 +543,11 @@ fn printFeaturesForArch(arch_name: []const u8, show_dependencies: bool) !void {
     const stdout_stream = &std.io.getStdOut().outStream().stream;
 
     const arch = Target.parseArchTag(arch_name) catch {
-        std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{ arch_name });
+        std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{arch_name});
         return;
     };
 
-    try stdout_stream.print("Available features for {}:\n", .{ @tagName(arch) });
+    try stdout_stream.print("Available features for {}:\n", .{@tagName(arch)});
 
     const features = std.target.getFeaturesForArch(arch);
 
@@ -556,18 +559,18 @@ fn printFeaturesForArch(arch_name: []const u8, show_dependencies: bool) !void {
     }
 
     for (features) |feature| {
-        try stdout_stream.print("  {}", .{ feature.name });
-        
+        try stdout_stream.print("  {}", .{feature.name});
+
         var i: usize = 0;
         while (i < longest_len - feature.name.len) : (i += 1) {
-            try stdout_stream.write(" ");    
+            try stdout_stream.write(" ");
         }
 
-        try stdout_stream.print(" - {}\n", .{ feature.description });
+        try stdout_stream.print(" - {}\n", .{feature.description});
 
         if (show_dependencies and feature.dependencies.len > 0) {
             for (feature.dependencies) |dependency| {
-                try stdout_stream.print("    {}\n", .{ dependency.name });
+                try stdout_stream.print("    {}\n", .{dependency.name});
             }
         }
     }
@@ -576,7 +579,7 @@ fn printFeaturesForArch(arch_name: []const u8, show_dependencies: bool) !void {
 // ABI warning
 export fn stage2_list_cpus_for_arch(arch_name_ptr: [*]const u8, arch_name_len: usize, show_dependencies: bool) void {
     printCpusForArch(arch_name_ptr[0..arch_name_len], show_dependencies) catch |err| {
-        std.debug.warn("Failed to list features: {}\n", .{ @errorName(err) });
+        std.debug.warn("Failed to list features: {}\n", .{@errorName(err)});
     };
 }
 
@@ -584,13 +587,13 @@ fn printCpusForArch(arch_name: []const u8, show_dependencies: bool) !void {
     const stdout_stream = &std.io.getStdOut().outStream().stream;
 
     const arch = Target.parseArchTag(arch_name) catch {
-        std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{ arch_name });
+        std.debug.warn("Failed to parse arch '{}'\nInvoke 'zig targets' for a list of valid architectures\n", .{arch_name});
         return;
     };
 
     const cpus = std.target.getCpusForArch(arch);
 
-    try stdout_stream.print("Available cpus for {}:\n", .{ @tagName(arch) });
+    try stdout_stream.print("Available cpus for {}:\n", .{@tagName(arch)});
 
     var longest_len: usize = 0;
     for (cpus) |cpu| {
@@ -600,78 +603,97 @@ fn printCpusForArch(arch_name: []const u8, show_dependencies: bool) !void {
     }
 
     for (cpus) |cpu| {
-        try stdout_stream.print("  {}", .{ cpu.name });
-        
+        try stdout_stream.print("  {}", .{cpu.name});
+
         var i: usize = 0;
         while (i < longest_len - cpu.name.len) : (i += 1) {
-            try stdout_stream.write(" ");    
+            try stdout_stream.write(" ");
         }
 
         try stdout_stream.write("\n");
 
         if (show_dependencies and cpu.dependencies.len > 0) {
             for (cpu.dependencies) |dependency| {
-                try stdout_stream.print("    {}\n", .{ dependency.name });
+                try stdout_stream.print("    {}\n", .{dependency.name});
             }
         }
     }
 }
 
-const null_terminated_empty_string = (&[_]u8 { 0 })[0..0 :0];
-
-fn toNullTerminatedStringAlloc(allocator: *std.mem.Allocator, str: []const u8) ![:0]const u8 {
-    var buffer = try std.Buffer.init(allocator, str);
-    
-    const len = buffer.len();
-
-    // Don't deinit since we steal all the buffer's memory here.
-    return buffer.list.toOwnedSlice()[0..len :0];
-}
+const Stage2CpuFeatures = struct {
+    allocator: *mem.Allocator,
+    cpu_features: Target.CpuFeatures,
 
-const Stage2TargetDetails = struct {
-    allocator: *std.mem.Allocator,
-    target_details: std.target.TargetDetails,
-    
-    llvm_cpu_str: [:0]const u8,
-    llvm_features_str: [:0]const u8,
+    llvm_cpu_name: ?[:0]const u8,
+    llvm_features_str: ?[:0]const u8,
 
     builtin_str: [:0]const u8,
+    cache_hash: [:0]const u8,
 
     const Self = @This();
 
-    fn initCpu(allocator: *std.mem.Allocator, arch: @TagType(std.Target.Arch), cpu: *const std.target.Cpu) !Self {
-        var builtin_str_buffer = try std.Buffer.init(
-            allocator,
-            "@import(\"std\").target.TargetDetails{.cpu=&@import(\"std\").target.");
+    fn initBaseline(allocator: *mem.Allocator) !Self {
+        const builtin_str = try std.fmt.allocPrint0(allocator, "CpuFeatures.baseline;\n");
+        errdefer allocator.free(builtin_str);
+
+        const cache_hash = try std.fmt.allocPrint0(allocator, "\n\n");
+        errdefer allocator.free(cache_hash);
+
+        return Self{
+            .allocator = allocator,
+            .cpu_features = .{ .cpu = cpu },
+            .llvm_cpu_name = null,
+            .llvm_features_str = null,
+            .builtin_str = builtin_str,
+            .cache_hash = cache_hash,
+        };
+    }
 
-        try builtin_str_buffer.append(@tagName(arch));
-        try builtin_str_buffer.append(".cpu_");
-        try builtin_str_buffer.append(cpu.name);
-        try builtin_str_buffer.append("};");
+    fn initCpu(allocator: *mem.Allocator, arch: Target.Arch, cpu: *const Target.Cpu) !Self {
+        const builtin_str = try std.fmt.allocPrint0(
+            allocator,
+            "CpuFeatures{{ .cpu = &Arch.{}.cpu.{} }};\n",
+            arch.genericName(),
+            cpu.name,
+        );
+        errdefer allocator.free(builtin_str);
 
-        const cpu_string = cpu.llvm_name orelse "";
+        const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{x}", cpu.name, cpu.features);
+        errdefer allocator.free(cache_hash);
 
         return Self{
             .allocator = allocator,
-            .target_details = .{
-                .cpu = cpu,
-            },
-            .llvm_cpu_str = try toNullTerminatedStringAlloc(allocator, cpu_string),
-            .llvm_features_str = null_terminated_empty_string,
-            .builtin_str = builtin_str_buffer.toSliceConst(),
+            .cpu_features = .{ .cpu = cpu },
+            .llvm_cpu_name = cpu.llvm_name,
+            .llvm_features_str = null,
+            .builtin_str = builtin_str,
+            .cache_hash = cache_hash,
         };
     }
 
-    fn initFeatures(allocator: *std.mem.Allocator, arch: @TagType(std.Target.Arch), features: []*const std.target.Feature) !Self {
-        var builtin_str_buffer = try std.Buffer.init(
-            allocator, 
-            "@import(\"std\").target.TargetDetails{.features=&[_]*const @import(\"std\").target.Feature{\n");
+    fn initFeatures(
+        allocator: *mem.Allocator,
+        arch: Target.Arch,
+        features: Target.Cpu.Feature.Set,
+    ) !Self {
+        const cache_hash = try std.fmt.allocPrint0(allocator, "\n{x}", features);
+        errdefer allocator.free(cache_hash);
+
+        const generic_arch_name = arch.genericName();
+        var builtin_str_buffer = try std.Buffer.allocPrint(
+            allocator,
+            "CpuFeatures{{ .features = Arch.{}.featureSet(&[_]Arch.{}.Feature{{\n",
+            generic_arch_name,
+            generic_arch_name,
+        );
+        defer builtin_str_buffer.deinit();
 
         var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
+        defer llvm_features_buffer.deinit();
 
         // First, disable all features.
         // This way, we only get the ones the user requests.
-        for (std.target.getFeaturesForArch(arch)) |feature| {
+        for (arch.allFeatures()) |feature| {
             if (feature.llvm_name) |llvm_name| {
                 try llvm_features_buffer.append("-");
                 try llvm_features_buffer.append(llvm_name);
@@ -684,232 +706,117 @@ const Stage2TargetDetails = struct {
                 try llvm_features_buffer.append("+");
                 try llvm_features_buffer.append(llvm_name);
                 try llvm_features_buffer.append(",");
-                
-                try builtin_str_buffer.append("&@import(\"std\").target.");
-                try builtin_str_buffer.append(@tagName(arch));
-                try builtin_str_buffer.append(".feature_");
-                try builtin_str_buffer.append(feature.name);
-                try builtin_str_buffer.append(",");
             }
+
+            try builtin_str_buffer.append("    .");
+            try builtin_str_buffer.append(feature.name);
+            try builtin_str_buffer.append(",\n");
         }
 
-        try builtin_str_buffer.append("}};");
+        if (mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ",")) {
+            llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
+        }
+
+        try builtin_str_buffer.append("})};\n");
 
         return Self{
             .allocator = allocator,
-            .target_details = std.target.TargetDetails{
-                .features = features,
-            },
-            .llvm_cpu_str = null_terminated_empty_string,
-            .llvm_features_str = llvm_features_buffer.toSliceConst(),
-            .builtin_str = builtin_str_buffer.toSliceConst(),
+            .cpu_features = .{ .features = features },
+            .llvm_cpu_name = null,
+            .llvm_features_str = llvm_features_buffer.toOwnedSlice(),
+            .builtin_str = builtin_str_buffer.toOwnedSlice(),
+            .cache_hash = cache_hash,
         };
     }
-};
 
-// ABI warning
-export fn stage2_target_details_parse_cpu(arch_str: ?[*:0]const u8, cpu_str: ?[*:0]const u8) ?*Stage2TargetDetails {
-    if (cpu_str == null) return null;
-    if (arch_str == null) return null;
-
-    const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch {
-        return null;
-    };
-    return parseCpu(arch, std.mem.toSliceConst(u8, cpu_str.?)) catch |err| {
-        switch (err) {
-            error.OutOfMemory => @panic("out of memory"),
-            else => return null,
-        }
-    };
-}
+    fn deinit(self: *Self) void {
+        self.allocator.free(self.cache_hash);
+        self.allocator.free(self.builtin_str);
+        if (self.llvm_features_str) |llvm_features_str| self.allocator.free(llvm_features_str);
+        self.* = undefined;
+    }
+};
 
 // ABI warning
-export fn stage2_target_details_parse_features(arch_str: ?[*:0]const u8, features_str: ?[*:0]const u8) ?*Stage2TargetDetails {
-    if (features_str == null) return null;
-    if (arch_str == null) return null;
-    
-    const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch return null;
-    return parseFeatures(arch, std.mem.toSliceConst(u8, features_str.?)) catch |err| {
-        switch (err) {
-            error.OutOfMemory => @panic("out of memory"),
-            else => return null,
-        }
+export fn stage2_cpu_features_parse_cpu(arch_name: [*:0]const u8, cpu_name: [*:0]const u8) *Stage2CpuFeatures {
+    return parseCpu(arch_name, cpu_name) catch |err| switch (err) {
+        error.OutOfMemory => @panic("out of memory"),
     };
 }
 
-fn parseCpu(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails {
-    const allocator = std.heap.c_allocator;
+fn parseCpu(arch_name: [*:0]const u8, cpu_name: [*:0]const u8) !*Stage2CpuFeatures {
+    const arch = try Target.parseArchSub(mem.toSliceConst(u8, arch_name));
+    const cpu = try arch.parseCpu(mem.toSliceConst(u8, cpu_name));
 
-    const cpus = std.target.getCpusForArch(arch);
-
-    for (cpus) |cpu| {
-        if (std.mem.eql(u8, str, cpu.name)) {
-            const ptr = try allocator.create(Stage2TargetDetails);
-            ptr.* = try Stage2TargetDetails.initCpu(std.heap.c_allocator, arch, cpu);
+    const ptr = try allocator.create(Stage2CpuFeatures);
+    errdefer std.heap.c_allocator.destroy(ptr);
 
-            return ptr;
-        }
-    }
+    ptr.* = try Stage2CpuFeatures.initCpu(std.heap.c_allocator, arch, cpu);
+    errdefer ptr.deinit();
 
-    return error.InvalidCpu;
+    return ptr;
 }
 
-fn parseFeatures(arch: @TagType(std.Target.Arch), str: []const u8) !*Stage2TargetDetails {
-    const allocator = std.heap.c_allocator;
-
-    const known_features = std.target.getFeaturesForArch(arch);
-
-    var features = std.ArrayList(*const std.target.Feature).init(allocator);
-    defer features.deinit();
-
-    var start: usize = 0;
-    while (start < str.len) {
-        const next_comma_pos = std.mem.indexOfScalar(u8, str[start..], ',') orelse str.len - start;
-        const feature_str = std.mem.trim(u8, str[start..start+next_comma_pos], " ");
-
-        start += next_comma_pos + 1;
-
-        if (feature_str.len == 0) continue;
-
-        var feature: ?*const std.target.Feature = null;
-        for (known_features) |known_feature| {
-            if (std.mem.eql(u8, feature_str, known_feature.name)) {
-                feature = known_feature;
-                break;
-            }
-        }
-
-        if (feature) |f| {
-            features.append(f) catch @panic("out of memory");
+// ABI warning
+export fn stage2_cpu_features_parse_features(
+    arch_name: [*:0]const u8,
+    features_text: [*:0]const u8,
+) *Stage2CpuFeatures {
+    return parseFeatures(arch_name, features_text) catch |err| switch (err) {
+        error.OutOfMemory => @panic("out of memory"),
+    };
+}
 
-        } else {
-            return error.InvalidFeature;
-        }
-    }
+fn parseFeatures(arch_name: [*:0]const u8, features_text: [*:0]const u8) !*Stage2CpuFeatures {
+    const arch = try Target.parseArchSub(mem.toSliceConst(u8, arch_name));
+    const set = try arch.parseCpuFeatureSet(mem.toSliceConst(u8, features_text));
 
-    const features_slice = features.toOwnedSlice();
+    const ptr = try std.heap.c_allocator.create(Stage2CpuFeatures);
+    errdefer std.heap.c_allocator.destroy(ptr);
 
-    const ptr = try allocator.create(Stage2TargetDetails);
-    ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, features_slice);
+    ptr.* = try Stage2CpuFeatures.initFeatures(std.heap.c_allocator, arch, set);
+    errdefer ptr.deinit();
 
     return ptr;
 }
 
 // ABI warning
-export fn stage2_target_details_get_cache_str(target_details: ?*const Stage2TargetDetails) [*:0]const u8 {
-    if (target_details) |td| {
-        return @as([*:0]const u8, switch (td.target_details) {
-            .cpu => td.llvm_cpu_str,
-            .features => td.llvm_features_str,
-        });
-    }
-
-    return @as([*:0]const u8, null_terminated_empty_string);
-}
+export fn stage2_cpu_features_baseline() *Stage2CpuFeatures {
+    const ptr = try std.heap.c_allocator.create(Stage2CpuFeatures);
+    errdefer std.heap.c_allocator.destroy(ptr);
 
-// ABI warning
-export fn stage2_target_details_get_llvm_cpu(target_details: ?*const Stage2TargetDetails) [*:0]const u8 {
-    if (target_details) |td| {
-        return @as([*:0]const u8, td.llvm_cpu_str);
-    }
+    ptr.* = try Stage2CpuFeatures.initBaseline(std.heap.c_allocator);
+    errdefer ptr.deinit();
 
-    return @as([*:0]const u8, null_terminated_empty_string);
+    return ptr;
 }
 
 // ABI warning
-export fn stage2_target_details_get_llvm_features(target_details: ?*const Stage2TargetDetails) [*:0]const u8 {
-    if (target_details) |td| {
-        return @as([*:0]const u8, td.llvm_features_str);
-    }
-
-    return @as([*:0]const u8, null_terminated_empty_string);
+export fn stage2_cpu_features_get_cache_hash(
+    cpu_features: *const Stage2CpuFeatures,
+    ptr: *[*:0]const u8,
+    len: *usize,
+) void {
+    ptr.* = cpu_features.cache_hash.ptr;
+    len.* = cpu_features.cache_hash.len;
 }
 
 // ABI warning
-export fn stage2_target_details_get_builtin_str(target_details: ?*const Stage2TargetDetails) [*:0]const u8 {
-    if (target_details) |td| {
-        return @as([*:0]const u8, td.builtin_str);
-    }
-
-    return @as([*:0]const u8, null_terminated_empty_string);
+export fn stage2_cpu_features_get_builtin_str(
+    cpu_features: *const Stage2CpuFeatures,
+    ptr: *[*:0]const u8,
+    len: *usize,
+) void {
+    ptr.* = cpu_features.builtin_str.ptr;
+    len.* = cpu_features.builtin_str.len;
 }
 
-const riscv32_default_features: []*const std.target.Feature = &[_]*const std.target.Feature {
-    &std.target.riscv.feature_a,
-    &std.target.riscv.feature_c,
-    &std.target.riscv.feature_d,
-    &std.target.riscv.feature_f,
-    &std.target.riscv.feature_m,
-    &std.target.riscv.feature_relax,
-};
-
-const riscv64_default_features: []*const std.target.Feature = &[_]*const std.target.Feature {
-    &std.target.riscv.feature_bit64,
-    &std.target.riscv.feature_a,
-    &std.target.riscv.feature_c,
-    &std.target.riscv.feature_d,
-    &std.target.riscv.feature_f,
-    &std.target.riscv.feature_m,
-    &std.target.riscv.feature_relax,
-};
-
-const i386_default_features: []*const std.target.Feature = &[_]*const std.target.Feature {
-    &std.target.x86.feature_cmov,
-    &std.target.x86.feature_cx8,
-    &std.target.x86.feature_fxsr,
-    &std.target.x86.feature_mmx,
-    &std.target.x86.feature_nopl,
-    &std.target.x86.feature_sse,
-    &std.target.x86.feature_sse2,
-    &std.target.x86.feature_slowUnalignedMem16,
-    &std.target.x86.feature_x87,
-};
-
-// Same as above but without sse.
-const i386_default_features_freestanding: []*const std.target.Feature = &[_]*const std.target.Feature {
-    &std.target.x86.feature_cmov,
-    &std.target.x86.feature_cx8,
-    &std.target.x86.feature_fxsr,
-    &std.target.x86.feature_mmx,
-    &std.target.x86.feature_nopl,
-    &std.target.x86.feature_slowUnalignedMem16,
-    &std.target.x86.feature_x87,
-};
-
 // ABI warning
-export fn stage2_target_details_get_default(arch_str: ?[*:0]const u8, os_str: ?[*:0]const u8) ?*Stage2TargetDetails {
-    if (arch_str == null) return null;
-    if (os_str == null) return null;
-    
-    const arch = Target.parseArchTag(std.mem.toSliceConst(u8, arch_str.?)) catch return null;
-    const os = Target.parseOs(std.mem.toSliceConst(u8, os_str.?)) catch return null;
-
-    return createDefaultTargetDetails(arch, os) catch return null;
+export fn stage2_cpu_features_get_llvm_cpu(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
+    return cpu_features.llvm_cpu_name;
 }
 
-fn createDefaultTargetDetails(arch: @TagType(std.Target.Arch), os: std.Target.Os) !?*Stage2TargetDetails {
-    const allocator = std.heap.c_allocator;
-
-    return switch (arch) {
-        .riscv32 => blk: {
-            const ptr = try allocator.create(Stage2TargetDetails);
-            ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, riscv32_default_features);
-            break :blk ptr;
-        },
-        .riscv64 => blk: {
-            const ptr = try allocator.create(Stage2TargetDetails);
-            ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, riscv64_default_features);
-            break :blk ptr;
-        },
-        .i386 => blk: {
-            const ptr = try allocator.create(Stage2TargetDetails);
-            const features = switch (os) {
-                .freestanding => i386_default_features_freestanding,
-                else => i386_default_features,
-            };
-            ptr.* = try Stage2TargetDetails.initFeatures(allocator, arch, features);
-            break :blk ptr;
-        },
-        else => null,
-    };
+// ABI warning
+export fn stage2_cpu_features_get_llvm_features(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
+    return cpu_features.llvm_features_str;
 }
BRANCH_TODO
@@ -0,0 +1,55 @@
+Finish these thigns before merging teh branch
+
+ * need to populate builtin.zig cpu_features, undefined is incorrect. I guess for zig0 it will be always baseline
+ * need to populate std.Target.current.cpu_features even for native target
+
+ * finish refactoring target/arch/*
+ * `zig builtin` integration 
+ * move target details to better location
+ * +foo,-bar vs foo,bar
+ * baseline features
+
+
+const riscv32_default_features: []*const std.target.Feature = &[_]*const std.target.Feature{
+    &std.target.riscv.feature_a,
+    &std.target.riscv.feature_c,
+    &std.target.riscv.feature_d,
+    &std.target.riscv.feature_f,
+    &std.target.riscv.feature_m,
+    &std.target.riscv.feature_relax,
+};
+
+const riscv64_default_features: []*const std.target.Feature = &[_]*const std.target.Feature{
+    &std.target.riscv.feature_bit64,
+    &std.target.riscv.feature_a,
+    &std.target.riscv.feature_c,
+    &std.target.riscv.feature_d,
+    &std.target.riscv.feature_f,
+    &std.target.riscv.feature_m,
+    &std.target.riscv.feature_relax,
+};
+
+const i386_default_features: []*const std.target.Feature = &[_]*const std.target.Feature{
+    &std.target.x86.feature_cmov,
+    &std.target.x86.feature_cx8,
+    &std.target.x86.feature_fxsr,
+    &std.target.x86.feature_mmx,
+    &std.target.x86.feature_nopl,
+    &std.target.x86.feature_sse,
+    &std.target.x86.feature_sse2,
+    &std.target.x86.feature_slowUnalignedMem16,
+    &std.target.x86.feature_x87,
+};
+
+// Same as above but without sse.
+const i386_default_features_freestanding: []*const std.target.Feature = &[_]*const std.target.Feature{
+    &std.target.x86.feature_cmov,
+    &std.target.x86.feature_cx8,
+    &std.target.x86.feature_fxsr,
+    &std.target.x86.feature_mmx,
+    &std.target.x86.feature_nopl,
+    &std.target.x86.feature_slowUnalignedMem16,
+    &std.target.x86.feature_x87,
+};
+
+