Commit a867b43366
Changed files (17)
lib
src-self-hosted
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,
+};
+
+