From 67d48b94d601521e15dd44c8789b1f528d09f10c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 4 Dec 2023 12:14:58 -0700 Subject: std.Target: flatten --- lib/std/Target/aarch64.zig | 2656 +++++++++++++++++++++++++++ lib/std/Target/amdgpu.zig | 2153 ++++++++++++++++++++++ lib/std/Target/arc.zig | 39 + lib/std/Target/arm.zig | 2604 ++++++++++++++++++++++++++ lib/std/Target/avr.zig | 2607 ++++++++++++++++++++++++++ lib/std/Target/bpf.zig | 73 + lib/std/Target/csky.zig | 3214 ++++++++++++++++++++++++++++++++ lib/std/Target/hexagon.zig | 586 ++++++ lib/std/Target/loongarch.zig | 146 ++ lib/std/Target/m68k.zig | 228 +++ lib/std/Target/mips.zig | 531 ++++++ lib/std/Target/msp430.zig | 69 + lib/std/Target/nvptx.zig | 439 +++++ lib/std/Target/powerpc.zig | 1192 ++++++++++++ lib/std/Target/riscv.zig | 1341 ++++++++++++++ lib/std/Target/s390x.zig | 667 +++++++ lib/std/Target/sparc.zig | 455 +++++ lib/std/Target/spirv.zig | 2091 +++++++++++++++++++++ lib/std/Target/ve.zig | 39 + lib/std/Target/wasm.zig | 126 ++ lib/std/Target/x86.zig | 4179 ++++++++++++++++++++++++++++++++++++++++++ lib/std/Target/xtensa.zig | 39 + 22 files changed, 25474 insertions(+) create mode 100644 lib/std/Target/aarch64.zig create mode 100644 lib/std/Target/amdgpu.zig create mode 100644 lib/std/Target/arc.zig create mode 100644 lib/std/Target/arm.zig create mode 100644 lib/std/Target/avr.zig create mode 100644 lib/std/Target/bpf.zig create mode 100644 lib/std/Target/csky.zig create mode 100644 lib/std/Target/hexagon.zig create mode 100644 lib/std/Target/loongarch.zig create mode 100644 lib/std/Target/m68k.zig create mode 100644 lib/std/Target/mips.zig create mode 100644 lib/std/Target/msp430.zig create mode 100644 lib/std/Target/nvptx.zig create mode 100644 lib/std/Target/powerpc.zig create mode 100644 lib/std/Target/riscv.zig create mode 100644 lib/std/Target/s390x.zig create mode 100644 lib/std/Target/sparc.zig create mode 100644 lib/std/Target/spirv.zig create mode 100644 lib/std/Target/ve.zig create mode 100644 lib/std/Target/wasm.zig create mode 100644 lib/std/Target/x86.zig create mode 100644 lib/std/Target/xtensa.zig (limited to 'lib/std/Target') diff --git a/lib/std/Target/aarch64.zig b/lib/std/Target/aarch64.zig new file mode 100644 index 0000000000..011cb20aef --- /dev/null +++ b/lib/std/Target/aarch64.zig @@ -0,0 +1,2656 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + a510, + a65, + a710, + a76, + a78, + a78c, + aes, + aggressive_fma, + alternate_sextload_cvt_f32_pattern, + altnzcv, + am, + amvs, + arith_bcc_fusion, + arith_cbz_fusion, + ascend_store_address, + b16b16, + balance_fp_ops, + bf16, + brbe, + bti, + call_saved_x10, + call_saved_x11, + call_saved_x12, + call_saved_x13, + call_saved_x14, + call_saved_x15, + call_saved_x18, + call_saved_x8, + call_saved_x9, + ccdp, + ccidx, + ccpp, + chk, + clrbhb, + cmp_bcc_fusion, + complxnum, + contextidr_el2, + cortex_r82, + crc, + crypto, + cssc, + custom_cheap_as_move, + d128, + disable_latency_sched_heuristic, + dit, + dotprod, + ecv, + el2vmsa, + el3, + enable_select_opt, + ete, + exynos_cheap_as_move, + f32mm, + f64mm, + fgt, + fix_cortex_a53_835769, + flagm, + fmv, + force_32bit_jump_tables, + fp16fml, + fp_armv8, + fptoint, + fullfp16, + fuse_address, + fuse_addsub_2reg_const1, + fuse_adrp_add, + fuse_aes, + fuse_arith_logic, + fuse_crypto_eor, + fuse_csel, + fuse_literals, + gcs, + harden_sls_blr, + harden_sls_nocomdat, + harden_sls_retbr, + hbc, + hcx, + i8mm, + ite, + jsconv, + lor, + ls64, + lse, + lse128, + lse2, + lsl_fast, + mec, + mops, + mpam, + mte, + neon, + nmi, + no_bti_at_return_twice, + no_neg_immediates, + no_sve_fp_ld1r, + no_zcz_fp, + nv, + outline_atomics, + pan, + pan_rwv, + pauth, + perfmon, + predictable_select_expensive, + predres, + prfm_slc_target, + rand, + ras, + rasv2, + rcpc, + rcpc3, + rcpc_immo, + rdm, + reserve_x1, + reserve_x10, + reserve_x11, + reserve_x12, + reserve_x13, + reserve_x14, + reserve_x15, + reserve_x18, + reserve_x2, + reserve_x20, + reserve_x21, + reserve_x22, + reserve_x23, + reserve_x24, + reserve_x25, + reserve_x26, + reserve_x27, + reserve_x28, + reserve_x3, + reserve_x30, + reserve_x4, + reserve_x5, + reserve_x6, + reserve_x7, + reserve_x9, + rme, + sb, + sel2, + sha2, + sha3, + slow_misaligned_128store, + slow_paired_128, + slow_strqro_store, + sm4, + sme, + sme2, + sme2p1, + sme_f16f16, + sme_f64f64, + sme_i16i64, + spe, + spe_eef, + specres2, + specrestrict, + ssbs, + strict_align, + sve, + sve2, + sve2_aes, + sve2_bitperm, + sve2_sha3, + sve2_sm4, + sve2p1, + tagged_globals, + the, + tlb_rmi, + tme, + tpidr_el1, + tpidr_el2, + tpidr_el3, + tpidrro_el0, + tracev8_4, + trbe, + uaops, + use_experimental_zeroing_pseudos, + use_postra_scheduler, + use_reciprocal_square_root, + use_scalar_inc_vl, + v8_1a, + v8_2a, + v8_3a, + v8_4a, + v8_5a, + v8_6a, + v8_7a, + v8_8a, + v8_9a, + v8a, + v8r, + v9_1a, + v9_2a, + v9_3a, + v9_4a, + v9a, + vh, + wfxt, + xs, + zcm, + zcz, + zcz_fp_workaround, + zcz_gp, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + @setEvalBranchQuota(2000); + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.a510)] = .{ + .llvm_name = "a510", + .description = "Cortex-A510 ARM processors", + .dependencies = featureSet(&[_]Feature{ + .fuse_adrp_add, + .fuse_aes, + .use_postra_scheduler, + }), + }; + result[@intFromEnum(Feature.a65)] = .{ + .llvm_name = "a65", + .description = "Cortex-A65 ARM processors", + .dependencies = featureSet(&[_]Feature{ + .enable_select_opt, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .fuse_literals, + .predictable_select_expensive, + }), + }; + result[@intFromEnum(Feature.a710)] = .{ + .llvm_name = "a710", + .description = "Cortex-A710 ARM processors", + .dependencies = featureSet(&[_]Feature{ + .cmp_bcc_fusion, + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .predictable_select_expensive, + .use_postra_scheduler, + }), + }; + result[@intFromEnum(Feature.a76)] = .{ + .llvm_name = "a76", + .description = "Cortex-A76 ARM processors", + .dependencies = featureSet(&[_]Feature{ + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .predictable_select_expensive, + }), + }; + result[@intFromEnum(Feature.a78)] = .{ + .llvm_name = "a78", + .description = "Cortex-A78 ARM processors", + .dependencies = featureSet(&[_]Feature{ + .cmp_bcc_fusion, + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .predictable_select_expensive, + .use_postra_scheduler, + }), + }; + result[@intFromEnum(Feature.a78c)] = .{ + .llvm_name = "a78c", + .description = "Cortex-A78C ARM processors", + .dependencies = featureSet(&[_]Feature{ + .cmp_bcc_fusion, + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .predictable_select_expensive, + .use_postra_scheduler, + }), + }; + result[@intFromEnum(Feature.aes)] = .{ + .llvm_name = "aes", + .description = "Enable AES support (FEAT_AES, FEAT_PMULL)", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.aggressive_fma)] = .{ + .llvm_name = "aggressive-fma", + .description = "Enable Aggressive FMA for floating-point.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.alternate_sextload_cvt_f32_pattern)] = .{ + .llvm_name = "alternate-sextload-cvt-f32-pattern", + .description = "Use alternative pattern for sextload convert to f32", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.altnzcv)] = .{ + .llvm_name = "altnzcv", + .description = "Enable alternative NZCV format for floating point comparisons (FEAT_FlagM2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.am)] = .{ + .llvm_name = "am", + .description = "Enable v8.4-A Activity Monitors extension (FEAT_AMUv1)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.amvs)] = .{ + .llvm_name = "amvs", + .description = "Enable v8.6-A Activity Monitors Virtualization support (FEAT_AMUv1p1)", + .dependencies = featureSet(&[_]Feature{ + .am, + }), + }; + result[@intFromEnum(Feature.arith_bcc_fusion)] = .{ + .llvm_name = "arith-bcc-fusion", + .description = "CPU fuses arithmetic+bcc operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.arith_cbz_fusion)] = .{ + .llvm_name = "arith-cbz-fusion", + .description = "CPU fuses arithmetic + cbz/cbnz operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ascend_store_address)] = .{ + .llvm_name = "ascend-store-address", + .description = "Schedule vector stores by ascending address", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.b16b16)] = .{ + .llvm_name = "b16b16", + .description = "Enable SVE2.1 or SME2.1 non-widening BFloat16 to BFloat16 instructions (FEAT_B16B16)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.balance_fp_ops)] = .{ + .llvm_name = "balance-fp-ops", + .description = "balance mix of odd and even D-registers for fp multiply(-accumulate) ops", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.bf16)] = .{ + .llvm_name = "bf16", + .description = "Enable BFloat16 Extension (FEAT_BF16)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.brbe)] = .{ + .llvm_name = "brbe", + .description = "Enable Branch Record Buffer Extension (FEAT_BRBE)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.bti)] = .{ + .llvm_name = "bti", + .description = "Enable Branch Target Identification (FEAT_BTI)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x10)] = .{ + .llvm_name = "call-saved-x10", + .description = "Make X10 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x11)] = .{ + .llvm_name = "call-saved-x11", + .description = "Make X11 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x12)] = .{ + .llvm_name = "call-saved-x12", + .description = "Make X12 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x13)] = .{ + .llvm_name = "call-saved-x13", + .description = "Make X13 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x14)] = .{ + .llvm_name = "call-saved-x14", + .description = "Make X14 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x15)] = .{ + .llvm_name = "call-saved-x15", + .description = "Make X15 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x18)] = .{ + .llvm_name = "call-saved-x18", + .description = "Make X18 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x8)] = .{ + .llvm_name = "call-saved-x8", + .description = "Make X8 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.call_saved_x9)] = .{ + .llvm_name = "call-saved-x9", + .description = "Make X9 callee saved.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ccdp)] = .{ + .llvm_name = "ccdp", + .description = "Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ccidx)] = .{ + .llvm_name = "ccidx", + .description = "Enable v8.3-A Extend of the CCSIDR number of sets (FEAT_CCIDX)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ccpp)] = .{ + .llvm_name = "ccpp", + .description = "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.chk)] = .{ + .llvm_name = "chk", + .description = "Enable Armv8.0-A Check Feature Status Extension (FEAT_CHK)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.clrbhb)] = .{ + .llvm_name = "clrbhb", + .description = "Enable Clear BHB instruction (FEAT_CLRBHB)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cmp_bcc_fusion)] = .{ + .llvm_name = "cmp-bcc-fusion", + .description = "CPU fuses cmp+bcc operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.complxnum)] = .{ + .llvm_name = "complxnum", + .description = "Enable v8.3-A Floating-point complex number support (FEAT_FCMA)", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.contextidr_el2)] = .{ + .llvm_name = "CONTEXTIDREL2", + .description = "Enable RW operand Context ID Register (EL2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cortex_r82)] = .{ + .llvm_name = "cortex-r82", + .description = "Cortex-R82 ARM processors", + .dependencies = featureSet(&[_]Feature{ + .use_postra_scheduler, + }), + }; + result[@intFromEnum(Feature.crc)] = .{ + .llvm_name = "crc", + .description = "Enable ARMv8 CRC-32 checksum instructions (FEAT_CRC32)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.crypto)] = .{ + .llvm_name = "crypto", + .description = "Enable cryptographic instructions", + .dependencies = featureSet(&[_]Feature{ + .aes, + .sha2, + }), + }; + result[@intFromEnum(Feature.cssc)] = .{ + .llvm_name = "cssc", + .description = "Enable Common Short Sequence Compression (CSSC) instructions (FEAT_CSSC)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.custom_cheap_as_move)] = .{ + .llvm_name = "custom-cheap-as-move", + .description = "Use custom handling of cheap instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.d128)] = .{ + .llvm_name = "d128", + .description = "Enable Armv9.4-A 128-bit Page Table Descriptors, System Registers and Instructions (FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, FEAT_SYSINSTR128)", + .dependencies = featureSet(&[_]Feature{ + .lse128, + }), + }; + result[@intFromEnum(Feature.disable_latency_sched_heuristic)] = .{ + .llvm_name = "disable-latency-sched-heuristic", + .description = "Disable latency scheduling heuristic", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dit)] = .{ + .llvm_name = "dit", + .description = "Enable v8.4-A Data Independent Timing instructions (FEAT_DIT)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dotprod)] = .{ + .llvm_name = "dotprod", + .description = "Enable dot product support (FEAT_DotProd)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ecv)] = .{ + .llvm_name = "ecv", + .description = "Enable enhanced counter virtualization extension (FEAT_ECV)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.el2vmsa)] = .{ + .llvm_name = "el2vmsa", + .description = "Enable Exception Level 2 Virtual Memory System Architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.el3)] = .{ + .llvm_name = "el3", + .description = "Enable Exception Level 3", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.enable_select_opt)] = .{ + .llvm_name = "enable-select-opt", + .description = "Enable the select optimize pass for select loop heuristics", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ete)] = .{ + .llvm_name = "ete", + .description = "Enable Embedded Trace Extension (FEAT_ETE)", + .dependencies = featureSet(&[_]Feature{ + .trbe, + }), + }; + result[@intFromEnum(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[@intFromEnum(Feature.f32mm)] = .{ + .llvm_name = "f32mm", + .description = "Enable Matrix Multiply FP32 Extension (FEAT_F32MM)", + .dependencies = featureSet(&[_]Feature{ + .sve, + }), + }; + result[@intFromEnum(Feature.f64mm)] = .{ + .llvm_name = "f64mm", + .description = "Enable Matrix Multiply FP64 Extension (FEAT_F64MM)", + .dependencies = featureSet(&[_]Feature{ + .sve, + }), + }; + result[@intFromEnum(Feature.fgt)] = .{ + .llvm_name = "fgt", + .description = "Enable fine grained virtualization traps extension (FEAT_FGT)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fix_cortex_a53_835769)] = .{ + .llvm_name = "fix-cortex-a53-835769", + .description = "Mitigate Cortex-A53 Erratum 835769", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flagm)] = .{ + .llvm_name = "flagm", + .description = "Enable v8.4-A Flag Manipulation Instructions (FEAT_FlagM)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fmv)] = .{ + .llvm_name = "fmv", + .description = "Enable Function Multi Versioning support.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(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 = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp16fml)] = .{ + .llvm_name = "fp16fml", + .description = "Enable FP16 FML instructions (FEAT_FHM)", + .dependencies = featureSet(&[_]Feature{ + .fullfp16, + }), + }; + result[@intFromEnum(Feature.fp_armv8)] = .{ + .llvm_name = "fp-armv8", + .description = "Enable ARMv8 FP (FEAT_FP)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(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 (FEAT_FRINTTS)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fullfp16)] = .{ + .llvm_name = "fullfp16", + .description = "Full FP16 (FEAT_FP16)", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8, + }), + }; + result[@intFromEnum(Feature.fuse_address)] = .{ + .llvm_name = "fuse-address", + .description = "CPU fuses address generation and memory operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_addsub_2reg_const1)] = .{ + .llvm_name = "fuse-addsub-2reg-const1", + .description = "CPU fuses (a + b + 1) and (a - b - 1)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_adrp_add)] = .{ + .llvm_name = "fuse-adrp-add", + .description = "CPU fuses adrp+add operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_aes)] = .{ + .llvm_name = "fuse-aes", + .description = "CPU fuses AES crypto operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_arith_logic)] = .{ + .llvm_name = "fuse-arith-logic", + .description = "CPU fuses arithmetic and logic operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_crypto_eor)] = .{ + .llvm_name = "fuse-crypto-eor", + .description = "CPU fuses AES/PMULL and EOR operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_csel)] = .{ + .llvm_name = "fuse-csel", + .description = "CPU fuses conditional select operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_literals)] = .{ + .llvm_name = "fuse-literals", + .description = "CPU fuses literal generation operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gcs)] = .{ + .llvm_name = "gcs", + .description = "Enable Armv9.4-A Guarded Call Stack Extension", + .dependencies = featureSet(&[_]Feature{ + .chk, + }), + }; + result[@intFromEnum(Feature.harden_sls_blr)] = .{ + .llvm_name = "harden-sls-blr", + .description = "Harden against straight line speculation across BLR instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.harden_sls_nocomdat)] = .{ + .llvm_name = "harden-sls-nocomdat", + .description = "Generate thunk code for SLS mitigation in the normal text section", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.harden_sls_retbr)] = .{ + .llvm_name = "harden-sls-retbr", + .description = "Harden against straight line speculation across RET and BR instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hbc)] = .{ + .llvm_name = "hbc", + .description = "Enable Armv8.8-A Hinted Conditional Branches Extension (FEAT_HBC)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hcx)] = .{ + .llvm_name = "hcx", + .description = "Enable Armv8.7-A HCRX_EL2 system register (FEAT_HCX)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.i8mm)] = .{ + .llvm_name = "i8mm", + .description = "Enable Matrix Multiply Int8 Extension (FEAT_I8MM)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ite)] = .{ + .llvm_name = "ite", + .description = "Enable Armv9.4-A Instrumentation Extension FEAT_ITE", + .dependencies = featureSet(&[_]Feature{ + .ete, + }), + }; + result[@intFromEnum(Feature.jsconv)] = .{ + .llvm_name = "jsconv", + .description = "Enable v8.3-A JavaScript FP conversion instructions (FEAT_JSCVT)", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8, + }), + }; + result[@intFromEnum(Feature.lor)] = .{ + .llvm_name = "lor", + .description = "Enables ARM v8.1 Limited Ordering Regions extension (FEAT_LOR)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ls64)] = .{ + .llvm_name = "ls64", + .description = "Enable Armv8.7-A LD64B/ST64B Accelerator Extension (FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lse)] = .{ + .llvm_name = "lse", + .description = "Enable ARMv8.1 Large System Extension (LSE) atomic instructions (FEAT_LSE)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lse128)] = .{ + .llvm_name = "lse128", + .description = "Enable Armv9.4-A 128-bit Atomic Instructions (FEAT_LSE128)", + .dependencies = featureSet(&[_]Feature{ + .lse, + }), + }; + result[@intFromEnum(Feature.lse2)] = .{ + .llvm_name = "lse2", + .description = "Enable ARMv8.4 Large System Extension 2 (LSE2) atomicity rules (FEAT_LSE2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lsl_fast)] = .{ + .llvm_name = "lsl-fast", + .description = "CPU has a fastpath logical shift of up to 3 places", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mec)] = .{ + .llvm_name = "mec", + .description = "Enable Memory Encryption Contexts Extension", + .dependencies = featureSet(&[_]Feature{ + .rme, + }), + }; + result[@intFromEnum(Feature.mops)] = .{ + .llvm_name = "mops", + .description = "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mpam)] = .{ + .llvm_name = "mpam", + .description = "Enable v8.4-A Memory system Partitioning and Monitoring extension (FEAT_MPAM)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mte)] = .{ + .llvm_name = "mte", + .description = "Enable Memory Tagging Extension (FEAT_MTE, FEAT_MTE2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.neon)] = .{ + .llvm_name = "neon", + .description = "Enable Advanced SIMD instructions (FEAT_AdvSIMD)", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8, + }), + }; + result[@intFromEnum(Feature.nmi)] = .{ + .llvm_name = "nmi", + .description = "Enable Armv8.8-A Non-maskable Interrupts (FEAT_NMI, FEAT_GICv3_NMI)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_bti_at_return_twice)] = .{ + .llvm_name = "no-bti-at-return-twice", + .description = "Don't place a BTI instruction after a return-twice", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(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 = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_sve_fp_ld1r)] = .{ + .llvm_name = "no-sve-fp-ld1r", + .description = "Avoid using LD1RX instructions for FP", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_zcz_fp)] = .{ + .llvm_name = "no-zcz-fp", + .description = "Has no zero-cycle zeroing instructions for FP registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nv)] = .{ + .llvm_name = "nv", + .description = "Enable v8.4-A Nested Virtualization Enchancement (FEAT_NV, FEAT_NV2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.outline_atomics)] = .{ + .llvm_name = "outline-atomics", + .description = "Enable out of line atomics to support LSE instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pan)] = .{ + .llvm_name = "pan", + .description = "Enables ARM v8.1 Privileged Access-Never extension (FEAT_PAN)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pan_rwv)] = .{ + .llvm_name = "pan-rwv", + .description = "Enable v8.2 PAN s1e1R and s1e1W Variants (FEAT_PAN2)", + .dependencies = featureSet(&[_]Feature{ + .pan, + }), + }; + result[@intFromEnum(Feature.pauth)] = .{ + .llvm_name = "pauth", + .description = "Enable v8.3-A Pointer Authentication extension (FEAT_PAuth)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.perfmon)] = .{ + .llvm_name = "perfmon", + .description = "Enable Code Generation for ARMv8 PMUv3 Performance Monitors extension (FEAT_PMUv3)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.predictable_select_expensive)] = .{ + .llvm_name = "predictable-select-expensive", + .description = "Prefer likely predicted branches over selects", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.predres)] = .{ + .llvm_name = "predres", + .description = "Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prfm_slc_target)] = .{ + .llvm_name = "prfm-slc-target", + .description = "Enable SLC target for PRFM instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rand)] = .{ + .llvm_name = "rand", + .description = "Enable Random Number generation instructions (FEAT_RNG)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ras)] = .{ + .llvm_name = "ras", + .description = "Enable ARMv8 Reliability, Availability and Serviceability Extensions (FEAT_RAS, FEAT_RASv1p1)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rasv2)] = .{ + .llvm_name = "rasv2", + .description = "Enable ARMv8.9-A Reliability, Availability and Serviceability Extensions (FEAT_RASv2)", + .dependencies = featureSet(&[_]Feature{ + .ras, + }), + }; + result[@intFromEnum(Feature.rcpc)] = .{ + .llvm_name = "rcpc", + .description = "Enable support for RCPC extension (FEAT_LRCPC)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rcpc3)] = .{ + .llvm_name = "rcpc3", + .description = "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)", + .dependencies = featureSet(&[_]Feature{ + .rcpc_immo, + }), + }; + result[@intFromEnum(Feature.rcpc_immo)] = .{ + .llvm_name = "rcpc-immo", + .description = "Enable v8.4-A RCPC instructions with Immediate Offsets (FEAT_LRCPC2)", + .dependencies = featureSet(&[_]Feature{ + .rcpc, + }), + }; + result[@intFromEnum(Feature.rdm)] = .{ + .llvm_name = "rdm", + .description = "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions (FEAT_RDM)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x1)] = .{ + .llvm_name = "reserve-x1", + .description = "Reserve X1, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x10)] = .{ + .llvm_name = "reserve-x10", + .description = "Reserve X10, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x11)] = .{ + .llvm_name = "reserve-x11", + .description = "Reserve X11, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x12)] = .{ + .llvm_name = "reserve-x12", + .description = "Reserve X12, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x13)] = .{ + .llvm_name = "reserve-x13", + .description = "Reserve X13, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x14)] = .{ + .llvm_name = "reserve-x14", + .description = "Reserve X14, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x15)] = .{ + .llvm_name = "reserve-x15", + .description = "Reserve X15, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x18)] = .{ + .llvm_name = "reserve-x18", + .description = "Reserve X18, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x2)] = .{ + .llvm_name = "reserve-x2", + .description = "Reserve X2, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x20)] = .{ + .llvm_name = "reserve-x20", + .description = "Reserve X20, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x21)] = .{ + .llvm_name = "reserve-x21", + .description = "Reserve X21, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x22)] = .{ + .llvm_name = "reserve-x22", + .description = "Reserve X22, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x23)] = .{ + .llvm_name = "reserve-x23", + .description = "Reserve X23, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x24)] = .{ + .llvm_name = "reserve-x24", + .description = "Reserve X24, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x25)] = .{ + .llvm_name = "reserve-x25", + .description = "Reserve X25, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x26)] = .{ + .llvm_name = "reserve-x26", + .description = "Reserve X26, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x27)] = .{ + .llvm_name = "reserve-x27", + .description = "Reserve X27, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x28)] = .{ + .llvm_name = "reserve-x28", + .description = "Reserve X28, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x3)] = .{ + .llvm_name = "reserve-x3", + .description = "Reserve X3, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x30)] = .{ + .llvm_name = "reserve-x30", + .description = "Reserve X30, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x4)] = .{ + .llvm_name = "reserve-x4", + .description = "Reserve X4, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x5)] = .{ + .llvm_name = "reserve-x5", + .description = "Reserve X5, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x6)] = .{ + .llvm_name = "reserve-x6", + .description = "Reserve X6, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x7)] = .{ + .llvm_name = "reserve-x7", + .description = "Reserve X7, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x9)] = .{ + .llvm_name = "reserve-x9", + .description = "Reserve X9, making it unavailable as a GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rme)] = .{ + .llvm_name = "rme", + .description = "Enable Realm Management Extension (FEAT_RME)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sb)] = .{ + .llvm_name = "sb", + .description = "Enable v8.5 Speculation Barrier (FEAT_SB)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sel2)] = .{ + .llvm_name = "sel2", + .description = "Enable v8.4-A Secure Exception Level 2 extension (FEAT_SEL2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sha2)] = .{ + .llvm_name = "sha2", + .description = "Enable SHA1 and SHA256 support (FEAT_SHA1, FEAT_SHA256)", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.sha3)] = .{ + .llvm_name = "sha3", + .description = "Enable SHA512 and SHA3 support (FEAT_SHA3, FEAT_SHA512)", + .dependencies = featureSet(&[_]Feature{ + .sha2, + }), + }; + result[@intFromEnum(Feature.slow_misaligned_128store)] = .{ + .llvm_name = "slow-misaligned-128store", + .description = "Misaligned 128 bit stores are slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_paired_128)] = .{ + .llvm_name = "slow-paired-128", + .description = "Paired 128 bit loads and stores are slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_strqro_store)] = .{ + .llvm_name = "slow-strqro-store", + .description = "STR of Q register with register offset is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm4)] = .{ + .llvm_name = "sm4", + .description = "Enable SM3 and SM4 support (FEAT_SM4, FEAT_SM3)", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.sme)] = .{ + .llvm_name = "sme", + .description = "Enable Scalable Matrix Extension (SME) (FEAT_SME)", + .dependencies = featureSet(&[_]Feature{ + .bf16, + .use_scalar_inc_vl, + }), + }; + result[@intFromEnum(Feature.sme2)] = .{ + .llvm_name = "sme2", + .description = "Enable Scalable Matrix Extension 2 (SME2) instructions", + .dependencies = featureSet(&[_]Feature{ + .sme, + }), + }; + result[@intFromEnum(Feature.sme2p1)] = .{ + .llvm_name = "sme2p1", + .description = "Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions", + .dependencies = featureSet(&[_]Feature{ + .sme2, + }), + }; + result[@intFromEnum(Feature.sme_f16f16)] = .{ + .llvm_name = "sme-f16f16", + .description = "Enable SME2.1 non-widening Float16 instructions (FEAT_SME_F16F16)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sme_f64f64)] = .{ + .llvm_name = "sme-f64f64", + .description = "Enable Scalable Matrix Extension (SME) F64F64 instructions (FEAT_SME_F64F64)", + .dependencies = featureSet(&[_]Feature{ + .sme, + }), + }; + result[@intFromEnum(Feature.sme_i16i64)] = .{ + .llvm_name = "sme-i16i64", + .description = "Enable Scalable Matrix Extension (SME) I16I64 instructions (FEAT_SME_I16I64)", + .dependencies = featureSet(&[_]Feature{ + .sme, + }), + }; + result[@intFromEnum(Feature.spe)] = .{ + .llvm_name = "spe", + .description = "Enable Statistical Profiling extension (FEAT_SPE)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.spe_eef)] = .{ + .llvm_name = "spe-eef", + .description = "Enable extra register in the Statistical Profiling Extension (FEAT_SPEv1p2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.specres2)] = .{ + .llvm_name = "specres2", + .description = "Enable Speculation Restriction Instruction (FEAT_SPECRES2)", + .dependencies = featureSet(&[_]Feature{ + .predres, + }), + }; + result[@intFromEnum(Feature.specrestrict)] = .{ + .llvm_name = "specrestrict", + .description = "Enable architectural speculation restriction (FEAT_CSV2_2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ssbs)] = .{ + .llvm_name = "ssbs", + .description = "Enable Speculative Store Bypass Safe bit (FEAT_SSBS, FEAT_SSBS2)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.strict_align)] = .{ + .llvm_name = "strict-align", + .description = "Disallow all unaligned memory access", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sve)] = .{ + .llvm_name = "sve", + .description = "Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)", + .dependencies = featureSet(&[_]Feature{ + .fullfp16, + }), + }; + result[@intFromEnum(Feature.sve2)] = .{ + .llvm_name = "sve2", + .description = "Enable Scalable Vector Extension 2 (SVE2) instructions (FEAT_SVE2)", + .dependencies = featureSet(&[_]Feature{ + .sve, + .use_scalar_inc_vl, + }), + }; + result[@intFromEnum(Feature.sve2_aes)] = .{ + .llvm_name = "sve2-aes", + .description = "Enable AES SVE2 instructions (FEAT_SVE_AES, FEAT_SVE_PMULL128)", + .dependencies = featureSet(&[_]Feature{ + .aes, + .sve2, + }), + }; + result[@intFromEnum(Feature.sve2_bitperm)] = .{ + .llvm_name = "sve2-bitperm", + .description = "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)", + .dependencies = featureSet(&[_]Feature{ + .sve2, + }), + }; + result[@intFromEnum(Feature.sve2_sha3)] = .{ + .llvm_name = "sve2-sha3", + .description = "Enable SHA3 SVE2 instructions (FEAT_SVE_SHA3)", + .dependencies = featureSet(&[_]Feature{ + .sha3, + .sve2, + }), + }; + result[@intFromEnum(Feature.sve2_sm4)] = .{ + .llvm_name = "sve2-sm4", + .description = "Enable SM4 SVE2 instructions (FEAT_SVE_SM4)", + .dependencies = featureSet(&[_]Feature{ + .sm4, + .sve2, + }), + }; + result[@intFromEnum(Feature.sve2p1)] = .{ + .llvm_name = "sve2p1", + .description = "Enable Scalable Vector Extension 2.1 instructions", + .dependencies = featureSet(&[_]Feature{ + .sve2, + }), + }; + result[@intFromEnum(Feature.tagged_globals)] = .{ + .llvm_name = "tagged-globals", + .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.the)] = .{ + .llvm_name = "the", + .description = "Enable Armv8.9-A Translation Hardening Extension (FEAT_THE)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tlb_rmi)] = .{ + .llvm_name = "tlb-rmi", + .description = "Enable v8.4-A TLB Range and Maintenance Instructions (FEAT_TLBIOS, FEAT_TLBIRANGE)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tme)] = .{ + .llvm_name = "tme", + .description = "Enable Transactional Memory Extension (FEAT_TME)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tpidr_el1)] = .{ + .llvm_name = "tpidr-el1", + .description = "Permit use of TPIDR_EL1 for the TLS base", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tpidr_el2)] = .{ + .llvm_name = "tpidr-el2", + .description = "Permit use of TPIDR_EL2 for the TLS base", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tpidr_el3)] = .{ + .llvm_name = "tpidr-el3", + .description = "Permit use of TPIDR_EL3 for the TLS base", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tpidrro_el0)] = .{ + .llvm_name = "tpidrro-el0", + .description = "Permit use of TPIDRRO_EL0 for the TLS base", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tracev8_4)] = .{ + .llvm_name = "tracev8.4", + .description = "Enable v8.4-A Trace extension (FEAT_TRF)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.trbe)] = .{ + .llvm_name = "trbe", + .description = "Enable Trace Buffer Extension (FEAT_TRBE)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.uaops)] = .{ + .llvm_name = "uaops", + .description = "Enable v8.2 UAO PState (FEAT_UAO)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_experimental_zeroing_pseudos)] = .{ + .llvm_name = "use-experimental-zeroing-pseudos", + .description = "Hint to the compiler that the MOVPRFX instruction is merged with destructive operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_postra_scheduler)] = .{ + .llvm_name = "use-postra-scheduler", + .description = "Schedule again after register allocation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_reciprocal_square_root)] = .{ + .llvm_name = "use-reciprocal-square-root", + .description = "Use the reciprocal square root approximation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_scalar_inc_vl)] = .{ + .llvm_name = "use-scalar-inc-vl", + .description = "Prefer inc/dec over add+cnt", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v8_1a)] = .{ + .llvm_name = "v8.1a", + .description = "Support ARM v8.1a instructions", + .dependencies = featureSet(&[_]Feature{ + .crc, + .lor, + .lse, + .pan, + .rdm, + .v8a, + .vh, + }), + }; + result[@intFromEnum(Feature.v8_2a)] = .{ + .llvm_name = "v8.2a", + .description = "Support ARM v8.2a instructions", + .dependencies = featureSet(&[_]Feature{ + .ccpp, + .pan_rwv, + .ras, + .uaops, + .v8_1a, + }), + }; + result[@intFromEnum(Feature.v8_3a)] = .{ + .llvm_name = "v8.3a", + .description = "Support ARM v8.3a instructions", + .dependencies = featureSet(&[_]Feature{ + .ccidx, + .complxnum, + .jsconv, + .pauth, + .rcpc, + .v8_2a, + }), + }; + result[@intFromEnum(Feature.v8_4a)] = .{ + .llvm_name = "v8.4a", + .description = "Support ARM v8.4a instructions", + .dependencies = featureSet(&[_]Feature{ + .am, + .dit, + .dotprod, + .flagm, + .lse2, + .mpam, + .nv, + .rcpc_immo, + .sel2, + .tlb_rmi, + .tracev8_4, + .v8_3a, + }), + }; + result[@intFromEnum(Feature.v8_5a)] = .{ + .llvm_name = "v8.5a", + .description = "Support ARM v8.5a instructions", + .dependencies = featureSet(&[_]Feature{ + .altnzcv, + .bti, + .ccdp, + .fptoint, + .predres, + .sb, + .specrestrict, + .ssbs, + .v8_4a, + }), + }; + result[@intFromEnum(Feature.v8_6a)] = .{ + .llvm_name = "v8.6a", + .description = "Support ARM v8.6a instructions", + .dependencies = featureSet(&[_]Feature{ + .amvs, + .bf16, + .ecv, + .fgt, + .i8mm, + .v8_5a, + }), + }; + result[@intFromEnum(Feature.v8_7a)] = .{ + .llvm_name = "v8.7a", + .description = "Support ARM v8.7a instructions", + .dependencies = featureSet(&[_]Feature{ + .hcx, + .v8_6a, + .wfxt, + .xs, + }), + }; + result[@intFromEnum(Feature.v8_8a)] = .{ + .llvm_name = "v8.8a", + .description = "Support ARM v8.8a instructions", + .dependencies = featureSet(&[_]Feature{ + .hbc, + .mops, + .nmi, + .v8_7a, + }), + }; + result[@intFromEnum(Feature.v8_9a)] = .{ + .llvm_name = "v8.9a", + .description = "Support ARM v8.9a instructions", + .dependencies = featureSet(&[_]Feature{ + .chk, + .clrbhb, + .cssc, + .prfm_slc_target, + .rasv2, + .specres2, + .v8_8a, + }), + }; + result[@intFromEnum(Feature.v8a)] = .{ + .llvm_name = "v8a", + .description = "Support ARM v8.0a instructions", + .dependencies = featureSet(&[_]Feature{ + .el2vmsa, + .el3, + .neon, + }), + }; + result[@intFromEnum(Feature.v8r)] = .{ + .llvm_name = "v8r", + .description = "Support ARM v8r instructions", + .dependencies = featureSet(&[_]Feature{ + .ccidx, + .ccpp, + .complxnum, + .contextidr_el2, + .crc, + .dit, + .dotprod, + .flagm, + .jsconv, + .lse, + .pan_rwv, + .pauth, + .ras, + .rcpc_immo, + .rdm, + .sel2, + .specrestrict, + .tlb_rmi, + .tracev8_4, + .uaops, + }), + }; + result[@intFromEnum(Feature.v9_1a)] = .{ + .llvm_name = "v9.1a", + .description = "Support ARM v9.1a instructions", + .dependencies = featureSet(&[_]Feature{ + .v8_6a, + .v9a, + }), + }; + result[@intFromEnum(Feature.v9_2a)] = .{ + .llvm_name = "v9.2a", + .description = "Support ARM v9.2a instructions", + .dependencies = featureSet(&[_]Feature{ + .v8_7a, + .v9_1a, + }), + }; + result[@intFromEnum(Feature.v9_3a)] = .{ + .llvm_name = "v9.3a", + .description = "Support ARM v9.3a instructions", + .dependencies = featureSet(&[_]Feature{ + .v8_8a, + .v9_2a, + }), + }; + result[@intFromEnum(Feature.v9_4a)] = .{ + .llvm_name = "v9.4a", + .description = "Support ARM v9.4a instructions", + .dependencies = featureSet(&[_]Feature{ + .v8_9a, + .v9_3a, + }), + }; + result[@intFromEnum(Feature.v9a)] = .{ + .llvm_name = "v9a", + .description = "Support ARM v9a instructions", + .dependencies = featureSet(&[_]Feature{ + .mec, + .sve2, + .v8_5a, + }), + }; + result[@intFromEnum(Feature.vh)] = .{ + .llvm_name = "vh", + .description = "Enables ARM v8.1 Virtual Host extension (FEAT_VHE)", + .dependencies = featureSet(&[_]Feature{ + .contextidr_el2, + }), + }; + result[@intFromEnum(Feature.wfxt)] = .{ + .llvm_name = "wfxt", + .description = "Enable Armv8.7-A WFET and WFIT instruction (FEAT_WFxT)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xs)] = .{ + .llvm_name = "xs", + .description = "Enable Armv8.7-A limited-TLB-maintenance instruction (FEAT_XS)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zcm)] = .{ + .llvm_name = "zcm", + .description = "Has zero-cycle register moves", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zcz)] = .{ + .llvm_name = "zcz", + .description = "Has zero-cycle zeroing instructions", + .dependencies = featureSet(&[_]Feature{ + .zcz_gp, + }), + }; + result[@intFromEnum(Feature.zcz_fp_workaround)] = .{ + .llvm_name = "zcz-fp-workaround", + .description = "The zero-cycle floating-point zeroing instruction has a bug", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zcz_gp)] = .{ + .llvm_name = "zcz-gp", + .description = "Has zero-cycle zeroing instructions for generic registers", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const a64fx = CpuModel{ + .name = "a64fx", + .llvm_name = "a64fx", + .features = featureSet(&[_]Feature{ + .aggressive_fma, + .arith_bcc_fusion, + .complxnum, + .perfmon, + .predictable_select_expensive, + .sha2, + .sve, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const ampere1 = CpuModel{ + .name = "ampere1", + .llvm_name = "ampere1", + .features = featureSet(&[_]Feature{ + .aes, + .aggressive_fma, + .arith_bcc_fusion, + .cmp_bcc_fusion, + .fuse_address, + .fuse_aes, + .fuse_literals, + .lsl_fast, + .perfmon, + .rand, + .sha3, + .use_postra_scheduler, + .v8_6a, + }), + }; + pub const ampere1a = CpuModel{ + .name = "ampere1a", + .llvm_name = "ampere1a", + .features = featureSet(&[_]Feature{ + .aes, + .aggressive_fma, + .arith_bcc_fusion, + .cmp_bcc_fusion, + .fuse_address, + .fuse_aes, + .fuse_literals, + .lsl_fast, + .mte, + .perfmon, + .rand, + .sha3, + .sm4, + .use_postra_scheduler, + .v8_6a, + }), + }; + pub const apple_a10 = CpuModel{ + .name = "apple_a10", + .llvm_name = "apple-a10", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crc, + .crypto, + .disable_latency_sched_heuristic, + .fuse_aes, + .fuse_crypto_eor, + .lor, + .pan, + .perfmon, + .rdm, + .v8a, + .vh, + .zcm, + .zcz, + }), + }; + pub const apple_a11 = CpuModel{ + .name = "apple_a11", + .llvm_name = "apple-a11", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fullfp16, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8_2a, + .zcm, + .zcz, + }), + }; + pub const apple_a12 = CpuModel{ + .name = "apple_a12", + .llvm_name = "apple-a12", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fullfp16, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8_3a, + .zcm, + .zcz, + }), + }; + pub const apple_a13 = CpuModel{ + .name = "apple_a13", + .llvm_name = "apple-a13", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .sha3, + .v8_4a, + .zcm, + .zcz, + }), + }; + pub const apple_a14 = CpuModel{ + .name = "apple_a14", + .llvm_name = "apple-a14", + .features = featureSet(&[_]Feature{ + .aggressive_fma, + .alternate_sextload_cvt_f32_pattern, + .altnzcv, + .arith_bcc_fusion, + .arith_cbz_fusion, + .ccdp, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fptoint, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .fuse_arith_logic, + .fuse_crypto_eor, + .fuse_csel, + .fuse_literals, + .perfmon, + .predres, + .sb, + .sha3, + .specrestrict, + .ssbs, + .v8_4a, + .zcm, + .zcz, + }), + }; + pub const apple_a15 = CpuModel{ + .name = "apple_a15", + .llvm_name = "apple-a15", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fuse_address, + .fuse_aes, + .fuse_arith_logic, + .fuse_crypto_eor, + .fuse_csel, + .fuse_literals, + .perfmon, + .sha3, + .v8_6a, + .zcm, + .zcz, + }), + }; + pub const apple_a16 = CpuModel{ + .name = "apple_a16", + .llvm_name = "apple-a16", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fuse_address, + .fuse_aes, + .fuse_arith_logic, + .fuse_crypto_eor, + .fuse_csel, + .fuse_literals, + .hcx, + .perfmon, + .sha3, + .v8_6a, + .zcm, + .zcz, + }), + }; + pub const apple_a7 = CpuModel{ + .name = "apple_a7", + .llvm_name = "apple-a7", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8a, + .zcm, + .zcz, + .zcz_fp_workaround, + }), + }; + pub const apple_a8 = CpuModel{ + .name = "apple_a8", + .llvm_name = "apple-a8", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8a, + .zcm, + .zcz, + .zcz_fp_workaround, + }), + }; + pub const apple_a9 = CpuModel{ + .name = "apple_a9", + .llvm_name = "apple-a9", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8a, + .zcm, + .zcz, + .zcz_fp_workaround, + }), + }; + pub const apple_latest = CpuModel{ + .name = "apple_latest", + .llvm_name = "apple-latest", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fuse_address, + .fuse_aes, + .fuse_arith_logic, + .fuse_crypto_eor, + .fuse_csel, + .fuse_literals, + .hcx, + .perfmon, + .sha3, + .v8_6a, + .zcm, + .zcz, + }), + }; + pub const apple_m1 = CpuModel{ + .name = "apple_m1", + .llvm_name = "apple-m1", + .features = featureSet(&[_]Feature{ + .aggressive_fma, + .alternate_sextload_cvt_f32_pattern, + .altnzcv, + .arith_bcc_fusion, + .arith_cbz_fusion, + .ccdp, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fptoint, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .fuse_arith_logic, + .fuse_crypto_eor, + .fuse_csel, + .fuse_literals, + .perfmon, + .predres, + .sb, + .sha3, + .specrestrict, + .ssbs, + .v8_4a, + .zcm, + .zcz, + }), + }; + pub const apple_m2 = CpuModel{ + .name = "apple_m2", + .llvm_name = "apple-m2", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fp16fml, + .fuse_address, + .fuse_aes, + .fuse_arith_logic, + .fuse_crypto_eor, + .fuse_csel, + .fuse_literals, + .perfmon, + .sha3, + .v8_6a, + .zcm, + .zcz, + }), + }; + pub const apple_s4 = CpuModel{ + .name = "apple_s4", + .llvm_name = "apple-s4", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fullfp16, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8_3a, + .zcm, + .zcz, + }), + }; + pub const apple_s5 = CpuModel{ + .name = "apple_s5", + .llvm_name = "apple-s5", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fullfp16, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8_3a, + .zcm, + .zcz, + }), + }; + pub const carmel = CpuModel{ + .name = "carmel", + .llvm_name = "carmel", + .features = featureSet(&[_]Feature{ + .crypto, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_a34 = CpuModel{ + .name = "cortex_a34", + .llvm_name = "cortex-a34", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .v8a, + }), + }; + pub const cortex_a35 = CpuModel{ + .name = "cortex_a35", + .llvm_name = "cortex-a35", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .v8a, + }), + }; + pub const cortex_a510 = CpuModel{ + .name = "cortex_a510", + .llvm_name = "cortex-a510", + .features = featureSet(&[_]Feature{ + .a510, + .bf16, + .ete, + .fp16fml, + .i8mm, + .mte, + .perfmon, + .sve2_bitperm, + .v9a, + }), + }; + pub const cortex_a53 = CpuModel{ + .name = "cortex_a53", + .llvm_name = "cortex-a53", + .features = featureSet(&[_]Feature{ + .balance_fp_ops, + .crc, + .crypto, + .custom_cheap_as_move, + .fuse_adrp_add, + .fuse_aes, + .perfmon, + .use_postra_scheduler, + .v8a, + }), + }; + pub const cortex_a55 = CpuModel{ + .name = "cortex_a55", + .llvm_name = "cortex-a55", + .features = featureSet(&[_]Feature{ + .crypto, + .dotprod, + .fullfp16, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .perfmon, + .rcpc, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const cortex_a57 = CpuModel{ + .name = "cortex_a57", + .llvm_name = "cortex-a57", + .features = featureSet(&[_]Feature{ + .balance_fp_ops, + .crc, + .crypto, + .custom_cheap_as_move, + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .fuse_literals, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + }), + }; + pub const cortex_a65 = CpuModel{ + .name = "cortex_a65", + .llvm_name = "cortex-a65", + .features = featureSet(&[_]Feature{ + .a65, + .crypto, + .dotprod, + .fullfp16, + .perfmon, + .rcpc, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_a65ae = CpuModel{ + .name = "cortex_a65ae", + .llvm_name = "cortex-a65ae", + .features = featureSet(&[_]Feature{ + .a65, + .crypto, + .dotprod, + .fullfp16, + .perfmon, + .rcpc, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_a710 = CpuModel{ + .name = "cortex_a710", + .llvm_name = "cortex-a710", + .features = featureSet(&[_]Feature{ + .a710, + .bf16, + .ete, + .fp16fml, + .i8mm, + .mte, + .perfmon, + .sve2_bitperm, + .v9a, + }), + }; + pub const cortex_a715 = CpuModel{ + .name = "cortex_a715", + .llvm_name = "cortex-a715", + .features = featureSet(&[_]Feature{ + .bf16, + .cmp_bcc_fusion, + .enable_select_opt, + .ete, + .fp16fml, + .fuse_adrp_add, + .fuse_aes, + .i8mm, + .lsl_fast, + .mte, + .perfmon, + .predictable_select_expensive, + .spe, + .sve2_bitperm, + .use_postra_scheduler, + .v9a, + }), + }; + pub const cortex_a72 = CpuModel{ + .name = "cortex_a72", + .llvm_name = "cortex-a72", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .fuse_literals, + .perfmon, + .predictable_select_expensive, + .v8a, + }), + }; + pub const cortex_a73 = CpuModel{ + .name = "cortex_a73", + .llvm_name = "cortex-a73", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .enable_select_opt, + .fuse_adrp_add, + .fuse_aes, + .perfmon, + .predictable_select_expensive, + .v8a, + }), + }; + pub const cortex_a75 = CpuModel{ + .name = "cortex_a75", + .llvm_name = "cortex-a75", + .features = featureSet(&[_]Feature{ + .crypto, + .dotprod, + .enable_select_opt, + .fullfp16, + .fuse_adrp_add, + .fuse_aes, + .perfmon, + .predictable_select_expensive, + .rcpc, + .v8_2a, + }), + }; + pub const cortex_a76 = CpuModel{ + .name = "cortex_a76", + .llvm_name = "cortex-a76", + .features = featureSet(&[_]Feature{ + .a76, + .crypto, + .dotprod, + .fullfp16, + .perfmon, + .rcpc, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_a76ae = CpuModel{ + .name = "cortex_a76ae", + .llvm_name = "cortex-a76ae", + .features = featureSet(&[_]Feature{ + .a76, + .crypto, + .dotprod, + .fullfp16, + .perfmon, + .rcpc, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_a77 = CpuModel{ + .name = "cortex_a77", + .llvm_name = "cortex-a77", + .features = featureSet(&[_]Feature{ + .cmp_bcc_fusion, + .crypto, + .dotprod, + .enable_select_opt, + .fullfp16, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .rcpc, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_a78 = CpuModel{ + .name = "cortex_a78", + .llvm_name = "cortex-a78", + .features = featureSet(&[_]Feature{ + .a78, + .crypto, + .dotprod, + .fullfp16, + .perfmon, + .rcpc, + .spe, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_a78c = CpuModel{ + .name = "cortex_a78c", + .llvm_name = "cortex-a78c", + .features = featureSet(&[_]Feature{ + .a78c, + .crypto, + .dotprod, + .flagm, + .fp16fml, + .pauth, + .perfmon, + .rcpc, + .spe, + .ssbs, + .v8_2a, + }), + }; + pub const cortex_r82 = CpuModel{ + .name = "cortex_r82", + .llvm_name = "cortex-r82", + .features = featureSet(&[_]Feature{ + .cortex_r82, + .fp16fml, + .perfmon, + .predres, + .sb, + .ssbs, + .v8r, + }), + }; + pub const cortex_x1 = CpuModel{ + .name = "cortex_x1", + .llvm_name = "cortex-x1", + .features = featureSet(&[_]Feature{ + .cmp_bcc_fusion, + .crypto, + .dotprod, + .enable_select_opt, + .fullfp16, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .rcpc, + .spe, + .ssbs, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const cortex_x1c = CpuModel{ + .name = "cortex_x1c", + .llvm_name = "cortex-x1c", + .features = featureSet(&[_]Feature{ + .cmp_bcc_fusion, + .crypto, + .dotprod, + .enable_select_opt, + .flagm, + .fullfp16, + .fuse_adrp_add, + .fuse_aes, + .lse2, + .lsl_fast, + .pauth, + .perfmon, + .predictable_select_expensive, + .rcpc_immo, + .spe, + .ssbs, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const cortex_x2 = CpuModel{ + .name = "cortex_x2", + .llvm_name = "cortex-x2", + .features = featureSet(&[_]Feature{ + .bf16, + .cmp_bcc_fusion, + .enable_select_opt, + .ete, + .fp16fml, + .fuse_adrp_add, + .fuse_aes, + .i8mm, + .lsl_fast, + .mte, + .perfmon, + .predictable_select_expensive, + .sve2_bitperm, + .use_postra_scheduler, + .v9a, + }), + }; + pub const cortex_x3 = CpuModel{ + .name = "cortex_x3", + .llvm_name = "cortex-x3", + .features = featureSet(&[_]Feature{ + .bf16, + .enable_select_opt, + .ete, + .fp16fml, + .fuse_adrp_add, + .fuse_aes, + .i8mm, + .lsl_fast, + .mte, + .perfmon, + .predictable_select_expensive, + .spe, + .sve2_bitperm, + .use_postra_scheduler, + .v9a, + }), + }; + pub const cyclone = CpuModel{ + .name = "cyclone", + .llvm_name = "cyclone", + .features = featureSet(&[_]Feature{ + .alternate_sextload_cvt_f32_pattern, + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .disable_latency_sched_heuristic, + .fuse_aes, + .fuse_crypto_eor, + .perfmon, + .v8a, + .zcm, + .zcz, + .zcz_fp_workaround, + }), + }; + pub const emag = CpuModel{ + .name = "emag", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .v8a, + }), + }; + pub const exynos_m1 = CpuModel{ + .name = "exynos_m1", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .exynos_cheap_as_move, + .force_32bit_jump_tables, + .fuse_aes, + .perfmon, + .slow_misaligned_128store, + .slow_paired_128, + .use_postra_scheduler, + .use_reciprocal_square_root, + .v8a, + }), + }; + pub const exynos_m2 = CpuModel{ + .name = "exynos_m2", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .exynos_cheap_as_move, + .force_32bit_jump_tables, + .fuse_aes, + .perfmon, + .slow_misaligned_128store, + .slow_paired_128, + .use_postra_scheduler, + .v8a, + }), + }; + pub const exynos_m3 = CpuModel{ + .name = "exynos_m3", + .llvm_name = "exynos-m3", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .exynos_cheap_as_move, + .force_32bit_jump_tables, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .fuse_csel, + .fuse_literals, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + }), + }; + pub const exynos_m4 = CpuModel{ + .name = "exynos_m4", + .llvm_name = "exynos-m4", + .features = featureSet(&[_]Feature{ + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .dotprod, + .exynos_cheap_as_move, + .force_32bit_jump_tables, + .fullfp16, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .fuse_arith_logic, + .fuse_csel, + .fuse_literals, + .lsl_fast, + .perfmon, + .use_postra_scheduler, + .v8_2a, + .zcz, + }), + }; + pub const exynos_m5 = CpuModel{ + .name = "exynos_m5", + .llvm_name = "exynos-m5", + .features = featureSet(&[_]Feature{ + .arith_bcc_fusion, + .arith_cbz_fusion, + .crypto, + .dotprod, + .exynos_cheap_as_move, + .force_32bit_jump_tables, + .fullfp16, + .fuse_address, + .fuse_adrp_add, + .fuse_aes, + .fuse_arith_logic, + .fuse_csel, + .fuse_literals, + .lsl_fast, + .perfmon, + .use_postra_scheduler, + .v8_2a, + .zcz, + }), + }; + pub const falkor = CpuModel{ + .name = "falkor", + .llvm_name = "falkor", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .custom_cheap_as_move, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .rdm, + .slow_strqro_store, + .use_postra_scheduler, + .v8a, + .zcz, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .enable_select_opt, + .ete, + .fuse_adrp_add, + .fuse_aes, + .neon, + .use_postra_scheduler, + }), + }; + pub const kryo = CpuModel{ + .name = "kryo", + .llvm_name = "kryo", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .custom_cheap_as_move, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + .zcz, + }), + }; + pub const neoverse_512tvb = CpuModel{ + .name = "neoverse_512tvb", + .llvm_name = "neoverse-512tvb", + .features = featureSet(&[_]Feature{ + .bf16, + .ccdp, + .crypto, + .enable_select_opt, + .fp16fml, + .fuse_adrp_add, + .fuse_aes, + .i8mm, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .rand, + .spe, + .ssbs, + .sve, + .use_postra_scheduler, + .v8_4a, + }), + }; + pub const neoverse_e1 = CpuModel{ + .name = "neoverse_e1", + .llvm_name = "neoverse-e1", + .features = featureSet(&[_]Feature{ + .crypto, + .dotprod, + .fullfp16, + .fuse_adrp_add, + .fuse_aes, + .perfmon, + .rcpc, + .ssbs, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const neoverse_n1 = CpuModel{ + .name = "neoverse_n1", + .llvm_name = "neoverse-n1", + .features = featureSet(&[_]Feature{ + .crypto, + .dotprod, + .enable_select_opt, + .fullfp16, + .fuse_adrp_add, + .fuse_aes, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .rcpc, + .spe, + .ssbs, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const neoverse_n2 = CpuModel{ + .name = "neoverse_n2", + .llvm_name = "neoverse-n2", + .features = featureSet(&[_]Feature{ + .bf16, + .crypto, + .enable_select_opt, + .ete, + .fuse_adrp_add, + .fuse_aes, + .i8mm, + .lsl_fast, + .mte, + .perfmon, + .predictable_select_expensive, + .sve2_bitperm, + .use_postra_scheduler, + .v8_5a, + }), + }; + pub const neoverse_v1 = CpuModel{ + .name = "neoverse_v1", + .llvm_name = "neoverse-v1", + .features = featureSet(&[_]Feature{ + .bf16, + .ccdp, + .crypto, + .enable_select_opt, + .fp16fml, + .fuse_adrp_add, + .fuse_aes, + .i8mm, + .lsl_fast, + .no_sve_fp_ld1r, + .perfmon, + .predictable_select_expensive, + .rand, + .spe, + .ssbs, + .sve, + .use_postra_scheduler, + .v8_4a, + }), + }; + pub const neoverse_v2 = CpuModel{ + .name = "neoverse_v2", + .llvm_name = "neoverse-v2", + .features = featureSet(&[_]Feature{ + .bf16, + .enable_select_opt, + .ete, + .fp16fml, + .fuse_aes, + .i8mm, + .lsl_fast, + .mte, + .perfmon, + .predictable_select_expensive, + .rand, + .spe, + .sve2_bitperm, + .use_postra_scheduler, + .v9a, + }), + }; + pub const saphira = CpuModel{ + .name = "saphira", + .llvm_name = "saphira", + .features = featureSet(&[_]Feature{ + .crypto, + .custom_cheap_as_move, + .lsl_fast, + .perfmon, + .predictable_select_expensive, + .spe, + .use_postra_scheduler, + .v8_4a, + .zcz, + }), + }; + pub const thunderx = CpuModel{ + .name = "thunderx", + .llvm_name = "thunderx", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + }), + }; + pub const thunderx2t99 = CpuModel{ + .name = "thunderx2t99", + .llvm_name = "thunderx2t99", + .features = featureSet(&[_]Feature{ + .aggressive_fma, + .arith_bcc_fusion, + .crypto, + .predictable_select_expensive, + .use_postra_scheduler, + .v8_1a, + }), + }; + pub const thunderx3t110 = CpuModel{ + .name = "thunderx3t110", + .llvm_name = "thunderx3t110", + .features = featureSet(&[_]Feature{ + .aggressive_fma, + .arith_bcc_fusion, + .balance_fp_ops, + .crypto, + .perfmon, + .predictable_select_expensive, + .strict_align, + .use_postra_scheduler, + .v8_3a, + }), + }; + pub const thunderxt81 = CpuModel{ + .name = "thunderxt81", + .llvm_name = "thunderxt81", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + }), + }; + pub const thunderxt83 = CpuModel{ + .name = "thunderxt83", + .llvm_name = "thunderxt83", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + }), + }; + pub const thunderxt88 = CpuModel{ + .name = "thunderxt88", + .llvm_name = "thunderxt88", + .features = featureSet(&[_]Feature{ + .crc, + .crypto, + .perfmon, + .predictable_select_expensive, + .use_postra_scheduler, + .v8a, + }), + }; + pub const tsv110 = CpuModel{ + .name = "tsv110", + .llvm_name = "tsv110", + .features = featureSet(&[_]Feature{ + .crypto, + .custom_cheap_as_move, + .dotprod, + .fp16fml, + .fuse_aes, + .perfmon, + .spe, + .use_postra_scheduler, + .v8_2a, + }), + }; + pub const xgene1 = CpuModel{ + .name = "xgene1", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .perfmon, + .v8a, + }), + }; +}; diff --git a/lib/std/Target/amdgpu.zig b/lib/std/Target/amdgpu.zig new file mode 100644 index 0000000000..012f652088 --- /dev/null +++ b/lib/std/Target/amdgpu.zig @@ -0,0 +1,2153 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"16_bit_insts", + a16, + add_no_carry_insts, + aperture_regs, + architected_flat_scratch, + architected_sgprs, + atomic_buffer_global_pk_add_f16_insts, + atomic_buffer_global_pk_add_f16_no_rtn_insts, + atomic_ds_pk_add_16_insts, + atomic_fadd_no_rtn_insts, + atomic_fadd_rtn_insts, + atomic_flat_pk_add_16_insts, + atomic_global_pk_add_bf16_inst, + auto_waitcnt_before_barrier, + back_off_barrier, + ci_insts, + cumode, + dl_insts, + dot10_insts, + dot1_insts, + dot2_insts, + dot3_insts, + dot4_insts, + dot5_insts, + dot6_insts, + dot7_insts, + dot8_insts, + dot9_insts, + dpp, + dpp8, + dpp_64bit, + ds128, + ds_src2_insts, + extended_image_insts, + fast_denormal_f32, + fast_fmaf, + flat_address_space, + flat_atomic_fadd_f32_inst, + flat_for_global, + flat_global_insts, + flat_inst_offsets, + flat_scratch, + flat_scratch_insts, + flat_segment_offset_bug, + fma_mix_insts, + fmacf64_inst, + fmaf, + force_store_sc0_sc1, + fp64, + fp8_insts, + full_rate_64_ops, + g16, + gcn3_encoding, + get_wave_id_inst, + gfx10, + gfx10_3_insts, + gfx10_a_encoding, + gfx10_b_encoding, + gfx10_insts, + gfx11, + gfx11_full_vgprs, + gfx11_insts, + gfx7_gfx8_gfx9_insts, + gfx8_insts, + gfx9, + gfx90a_insts, + gfx940_insts, + gfx9_insts, + half_rate_64_ops, + image_gather4_d16_bug, + image_insts, + image_store_d16_bug, + inst_fwd_prefetch_bug, + int_clamp_insts, + inv_2pi_inline_imm, + lds_branch_vmem_war_hazard, + lds_misaligned_bug, + ldsbankcount16, + ldsbankcount32, + load_store_opt, + localmemorysize32768, + localmemorysize65536, + mad_intra_fwd_bug, + mad_mac_f32_insts, + mad_mix_insts, + mai_insts, + max_private_element_size_16, + max_private_element_size_4, + max_private_element_size_8, + mfma_inline_literal_bug, + mimg_r128, + movrel, + negative_scratch_offset_bug, + negative_unaligned_scratch_offset_bug, + no_data_dep_hazard, + no_sdst_cmpx, + nsa_clause_bug, + nsa_encoding, + nsa_to_vmem_bug, + offset_3f_bug, + packed_fp32_ops, + packed_tid, + partial_nsa_encoding, + pk_fmac_f16_inst, + promote_alloca, + prt_strict_null, + r128_a16, + s_memrealtime, + s_memtime_inst, + scalar_atomics, + scalar_flat_scratch_insts, + scalar_stores, + sdwa, + sdwa_mav, + sdwa_omod, + sdwa_out_mods_vopc, + sdwa_scalar, + sdwa_sdst, + sea_islands, + sgpr_init_bug, + shader_cycles_register, + si_scheduler, + smem_to_vector_write_hazard, + southern_islands, + sramecc, + sramecc_support, + tgsplit, + trap_handler, + trig_reduced_range, + true16, + unaligned_access_mode, + unaligned_buffer_access, + unaligned_ds_access, + unaligned_scratch_access, + unpacked_d16_vmem, + unsafe_ds_offset_folding, + user_sgpr_init16_bug, + valu_trans_use_hazard, + vcmpx_exec_war_hazard, + vcmpx_permlane_hazard, + vgpr_index_mode, + vmem_to_scalar_write_hazard, + volcanic_islands, + vop3_literal, + vop3p, + vopd, + vscnt, + wavefrontsize16, + wavefrontsize32, + wavefrontsize64, + xnack, + xnack_support, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"16_bit_insts")] = .{ + .llvm_name = "16-bit-insts", + .description = "Has i16/f16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.a16)] = .{ + .llvm_name = "a16", + .description = "Support A16 for 16-bit coordinates/gradients/lod/clamp/mip image operands", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.add_no_carry_insts)] = .{ + .llvm_name = "add-no-carry-insts", + .description = "Have VALU add/sub instructions without carry out", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.aperture_regs)] = .{ + .llvm_name = "aperture-regs", + .description = "Has Memory Aperture Base and Size Registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.architected_flat_scratch)] = .{ + .llvm_name = "architected-flat-scratch", + .description = "Flat Scratch register is a readonly SPI initialized architected register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.architected_sgprs)] = .{ + .llvm_name = "architected-sgprs", + .description = "Enable the architected SGPRs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_insts)] = .{ + .llvm_name = "atomic-buffer-global-pk-add-f16-insts", + .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that can return original value", + .dependencies = featureSet(&[_]Feature{ + .flat_global_insts, + }), + }; + result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_no_rtn_insts)] = .{ + .llvm_name = "atomic-buffer-global-pk-add-f16-no-rtn-insts", + .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that don't return original value", + .dependencies = featureSet(&[_]Feature{ + .flat_global_insts, + }), + }; + result[@intFromEnum(Feature.atomic_ds_pk_add_16_insts)] = .{ + .llvm_name = "atomic-ds-pk-add-16-insts", + .description = "Has ds_pk_add_bf16, ds_pk_add_f16, ds_pk_add_rtn_bf16, ds_pk_add_rtn_f16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.atomic_fadd_no_rtn_insts)] = .{ + .llvm_name = "atomic-fadd-no-rtn-insts", + .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that don't return original value", + .dependencies = featureSet(&[_]Feature{ + .flat_global_insts, + }), + }; + result[@intFromEnum(Feature.atomic_fadd_rtn_insts)] = .{ + .llvm_name = "atomic-fadd-rtn-insts", + .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that return original value", + .dependencies = featureSet(&[_]Feature{ + .flat_global_insts, + }), + }; + result[@intFromEnum(Feature.atomic_flat_pk_add_16_insts)] = .{ + .llvm_name = "atomic-flat-pk-add-16-insts", + .description = "Has flat_atomic_pk_add_f16 and flat_atomic_pk_add_bf16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.atomic_global_pk_add_bf16_inst)] = .{ + .llvm_name = "atomic-global-pk-add-bf16-inst", + .description = "Has global_atomic_pk_add_bf16 instruction", + .dependencies = featureSet(&[_]Feature{ + .flat_global_insts, + }), + }; + result[@intFromEnum(Feature.auto_waitcnt_before_barrier)] = .{ + .llvm_name = "auto-waitcnt-before-barrier", + .description = "Hardware automatically inserts waitcnt before barrier", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.back_off_barrier)] = .{ + .llvm_name = "back-off-barrier", + .description = "Hardware supports backing off s_barrier if an exception occurs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ci_insts)] = .{ + .llvm_name = "ci-insts", + .description = "Additional instructions for CI+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cumode)] = .{ + .llvm_name = "cumode", + .description = "Enable CU wavefront execution mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dl_insts)] = .{ + .llvm_name = "dl-insts", + .description = "Has v_fmac_f32 and v_xnor_b32 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot10_insts)] = .{ + .llvm_name = "dot10-insts", + .description = "Has v_dot2_f32_f16 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot1_insts)] = .{ + .llvm_name = "dot1-insts", + .description = "Has v_dot4_i32_i8 and v_dot8_i32_i4 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot2_insts)] = .{ + .llvm_name = "dot2-insts", + .description = "Has v_dot2_i32_i16, v_dot2_u32_u16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot3_insts)] = .{ + .llvm_name = "dot3-insts", + .description = "Has v_dot8c_i32_i4 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot4_insts)] = .{ + .llvm_name = "dot4-insts", + .description = "Has v_dot2c_i32_i16 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot5_insts)] = .{ + .llvm_name = "dot5-insts", + .description = "Has v_dot2c_f32_f16 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot6_insts)] = .{ + .llvm_name = "dot6-insts", + .description = "Has v_dot4c_i32_i8 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot7_insts)] = .{ + .llvm_name = "dot7-insts", + .description = "Has v_dot4_u32_u8, v_dot8_u32_u4 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot8_insts)] = .{ + .llvm_name = "dot8-insts", + .description = "Has v_dot4_i32_iu8, v_dot8_i32_iu4 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dot9_insts)] = .{ + .llvm_name = "dot9-insts", + .description = "Has v_dot2_f16_f16, v_dot2_bf16_bf16, v_dot2_f32_bf16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dpp)] = .{ + .llvm_name = "dpp", + .description = "Support DPP (Data Parallel Primitives) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dpp8)] = .{ + .llvm_name = "dpp8", + .description = "Support DPP8 (Data Parallel Primitives) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dpp_64bit)] = .{ + .llvm_name = "dpp-64bit", + .description = "Support DPP (Data Parallel Primitives) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ds128)] = .{ + .llvm_name = "enable-ds128", + .description = "Use ds_{read|write}_b128", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ds_src2_insts)] = .{ + .llvm_name = "ds-src2-insts", + .description = "Has ds_*_src2 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.extended_image_insts)] = .{ + .llvm_name = "extended-image-insts", + .description = "Support mips != 0, lod != 0, gather4, and get_lod", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_denormal_f32)] = .{ + .llvm_name = "fast-denormal-f32", + .description = "Enabling denormals does not cause f32 instructions to run at f64 rates", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_fmaf)] = .{ + .llvm_name = "fast-fmaf", + .description = "Assuming f32 fma is at least as fast as mul + add", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_address_space)] = .{ + .llvm_name = "flat-address-space", + .description = "Support flat address space", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_atomic_fadd_f32_inst)] = .{ + .llvm_name = "flat-atomic-fadd-f32-inst", + .description = "Has flat_atomic_add_f32 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_for_global)] = .{ + .llvm_name = "flat-for-global", + .description = "Force to generate flat instruction for global", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_global_insts)] = .{ + .llvm_name = "flat-global-insts", + .description = "Have global_* flat memory instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_inst_offsets)] = .{ + .llvm_name = "flat-inst-offsets", + .description = "Flat instructions have immediate offset addressing mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_scratch)] = .{ + .llvm_name = "enable-flat-scratch", + .description = "Use scratch_* flat memory instructions to access scratch", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_scratch_insts)] = .{ + .llvm_name = "flat-scratch-insts", + .description = "Have scratch_* flat memory instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.flat_segment_offset_bug)] = .{ + .llvm_name = "flat-segment-offset-bug", + .description = "GFX10 bug where inst_offset is ignored when flat instructions access global memory", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fma_mix_insts)] = .{ + .llvm_name = "fma-mix-insts", + .description = "Has v_fma_mix_f32, v_fma_mixlo_f16, v_fma_mixhi_f16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fmacf64_inst)] = .{ + .llvm_name = "fmacf64-inst", + .description = "Has v_fmac_f64 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fmaf)] = .{ + .llvm_name = "fmaf", + .description = "Enable single precision FMA (not as fast as mul+add, but fused)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.force_store_sc0_sc1)] = .{ + .llvm_name = "force-store-sc0-sc1", + .description = "Has SC0 and SC1 on stores", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp64)] = .{ + .llvm_name = "fp64", + .description = "Enable double precision operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp8_insts)] = .{ + .llvm_name = "fp8-insts", + .description = "Has fp8 and bf8 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.full_rate_64_ops)] = .{ + .llvm_name = "full-rate-64-ops", + .description = "Most fp64 instructions are full rate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.g16)] = .{ + .llvm_name = "g16", + .description = "Support G16 for 16-bit gradient image operands", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gcn3_encoding)] = .{ + .llvm_name = "gcn3-encoding", + .description = "Encoding format for VI", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.get_wave_id_inst)] = .{ + .llvm_name = "get-wave-id-inst", + .description = "Has s_get_waveid_in_workgroup instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx10)] = .{ + .llvm_name = "gfx10", + .description = "GFX10 GPU generation", + .dependencies = featureSet(&[_]Feature{ + .@"16_bit_insts", + .a16, + .add_no_carry_insts, + .aperture_regs, + .ci_insts, + .dpp, + .dpp8, + .extended_image_insts, + .fast_denormal_f32, + .fast_fmaf, + .flat_address_space, + .flat_global_insts, + .flat_inst_offsets, + .flat_scratch_insts, + .fma_mix_insts, + .fp64, + .g16, + .gfx10_insts, + .gfx8_insts, + .gfx9_insts, + .image_insts, + .int_clamp_insts, + .inv_2pi_inline_imm, + .localmemorysize65536, + .mimg_r128, + .movrel, + .no_data_dep_hazard, + .no_sdst_cmpx, + .pk_fmac_f16_inst, + .s_memrealtime, + .s_memtime_inst, + .sdwa, + .sdwa_omod, + .sdwa_scalar, + .sdwa_sdst, + .unaligned_buffer_access, + .unaligned_ds_access, + .vop3_literal, + .vop3p, + .vscnt, + }), + }; + result[@intFromEnum(Feature.gfx10_3_insts)] = .{ + .llvm_name = "gfx10-3-insts", + .description = "Additional instructions for GFX10.3", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx10_a_encoding)] = .{ + .llvm_name = "gfx10_a-encoding", + .description = "Has BVH ray tracing instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx10_b_encoding)] = .{ + .llvm_name = "gfx10_b-encoding", + .description = "Encoding format GFX10_B", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx10_insts)] = .{ + .llvm_name = "gfx10-insts", + .description = "Additional instructions for GFX10+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx11)] = .{ + .llvm_name = "gfx11", + .description = "GFX11 GPU generation", + .dependencies = featureSet(&[_]Feature{ + .@"16_bit_insts", + .a16, + .add_no_carry_insts, + .aperture_regs, + .ci_insts, + .dpp, + .dpp8, + .extended_image_insts, + .fast_denormal_f32, + .fast_fmaf, + .flat_address_space, + .flat_global_insts, + .flat_inst_offsets, + .flat_scratch_insts, + .fma_mix_insts, + .fp64, + .g16, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .gfx10_insts, + .gfx11_insts, + .gfx8_insts, + .gfx9_insts, + .int_clamp_insts, + .inv_2pi_inline_imm, + .localmemorysize65536, + .mimg_r128, + .movrel, + .no_data_dep_hazard, + .no_sdst_cmpx, + .pk_fmac_f16_inst, + .true16, + .unaligned_buffer_access, + .unaligned_ds_access, + .vop3_literal, + .vop3p, + .vopd, + .vscnt, + }), + }; + result[@intFromEnum(Feature.gfx11_full_vgprs)] = .{ + .llvm_name = "gfx11-full-vgprs", + .description = "GFX11 with 50% more physical VGPRs and 50% larger allocation granule than GFX10", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx11_insts)] = .{ + .llvm_name = "gfx11-insts", + .description = "Additional instructions for GFX11+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx7_gfx8_gfx9_insts)] = .{ + .llvm_name = "gfx7-gfx8-gfx9-insts", + .description = "Instructions shared in GFX7, GFX8, GFX9", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx8_insts)] = .{ + .llvm_name = "gfx8-insts", + .description = "Additional instructions for GFX8+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx9)] = .{ + .llvm_name = "gfx9", + .description = "GFX9 GPU generation", + .dependencies = featureSet(&[_]Feature{ + .@"16_bit_insts", + .a16, + .add_no_carry_insts, + .aperture_regs, + .ci_insts, + .dpp, + .fast_denormal_f32, + .fast_fmaf, + .flat_address_space, + .flat_global_insts, + .flat_inst_offsets, + .flat_scratch_insts, + .fp64, + .gcn3_encoding, + .gfx7_gfx8_gfx9_insts, + .gfx8_insts, + .gfx9_insts, + .int_clamp_insts, + .inv_2pi_inline_imm, + .localmemorysize65536, + .negative_scratch_offset_bug, + .r128_a16, + .s_memrealtime, + .s_memtime_inst, + .scalar_atomics, + .scalar_flat_scratch_insts, + .scalar_stores, + .sdwa, + .sdwa_omod, + .sdwa_scalar, + .sdwa_sdst, + .unaligned_buffer_access, + .unaligned_ds_access, + .vgpr_index_mode, + .vop3p, + .wavefrontsize64, + .xnack_support, + }), + }; + result[@intFromEnum(Feature.gfx90a_insts)] = .{ + .llvm_name = "gfx90a-insts", + .description = "Additional instructions for GFX90A+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx940_insts)] = .{ + .llvm_name = "gfx940-insts", + .description = "Additional instructions for GFX940+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfx9_insts)] = .{ + .llvm_name = "gfx9-insts", + .description = "Additional instructions for GFX9+", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.half_rate_64_ops)] = .{ + .llvm_name = "half-rate-64-ops", + .description = "Most fp64 instructions are half rate instead of quarter", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.image_gather4_d16_bug)] = .{ + .llvm_name = "image-gather4-d16-bug", + .description = "Image Gather4 D16 hardware bug", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.image_insts)] = .{ + .llvm_name = "image-insts", + .description = "Support image instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.image_store_d16_bug)] = .{ + .llvm_name = "image-store-d16-bug", + .description = "Image Store D16 hardware bug", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.inst_fwd_prefetch_bug)] = .{ + .llvm_name = "inst-fwd-prefetch-bug", + .description = "S_INST_PREFETCH instruction causes shader to hang", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.int_clamp_insts)] = .{ + .llvm_name = "int-clamp-insts", + .description = "Support clamp for integer destination", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.inv_2pi_inline_imm)] = .{ + .llvm_name = "inv-2pi-inline-imm", + .description = "Has 1 / (2 * pi) as inline immediate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lds_branch_vmem_war_hazard)] = .{ + .llvm_name = "lds-branch-vmem-war-hazard", + .description = "Switching between LDS and VMEM-tex not waiting VM_VSRC=0", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lds_misaligned_bug)] = .{ + .llvm_name = "lds-misaligned-bug", + .description = "Some GFX10 bug with multi-dword LDS and flat access that is not naturally aligned in WGP mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ldsbankcount16)] = .{ + .llvm_name = "ldsbankcount16", + .description = "The number of LDS banks per compute unit.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ldsbankcount32)] = .{ + .llvm_name = "ldsbankcount32", + .description = "The number of LDS banks per compute unit.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.load_store_opt)] = .{ + .llvm_name = "load-store-opt", + .description = "Enable SI load/store optimizer pass", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.localmemorysize32768)] = .{ + .llvm_name = "localmemorysize32768", + .description = "The size of local memory in bytes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.localmemorysize65536)] = .{ + .llvm_name = "localmemorysize65536", + .description = "The size of local memory in bytes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mad_intra_fwd_bug)] = .{ + .llvm_name = "mad-intra-fwd-bug", + .description = "MAD_U64/I64 intra instruction forwarding bug", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mad_mac_f32_insts)] = .{ + .llvm_name = "mad-mac-f32-insts", + .description = "Has v_mad_f32/v_mac_f32/v_madak_f32/v_madmk_f32 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mad_mix_insts)] = .{ + .llvm_name = "mad-mix-insts", + .description = "Has v_mad_mix_f32, v_mad_mixlo_f16, v_mad_mixhi_f16 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mai_insts)] = .{ + .llvm_name = "mai-insts", + .description = "Has mAI instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.max_private_element_size_16)] = .{ + .llvm_name = "max-private-element-size-16", + .description = "Maximum private access size may be 16", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.max_private_element_size_4)] = .{ + .llvm_name = "max-private-element-size-4", + .description = "Maximum private access size may be 4", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.max_private_element_size_8)] = .{ + .llvm_name = "max-private-element-size-8", + .description = "Maximum private access size may be 8", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mfma_inline_literal_bug)] = .{ + .llvm_name = "mfma-inline-literal-bug", + .description = "MFMA cannot use inline literal as SrcC", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mimg_r128)] = .{ + .llvm_name = "mimg-r128", + .description = "Support 128-bit texture resources", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.movrel)] = .{ + .llvm_name = "movrel", + .description = "Has v_movrel*_b32 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.negative_scratch_offset_bug)] = .{ + .llvm_name = "negative-scratch-offset-bug", + .description = "Negative immediate offsets in scratch instructions with an SGPR offset page fault on GFX9", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.negative_unaligned_scratch_offset_bug)] = .{ + .llvm_name = "negative-unaligned-scratch-offset-bug", + .description = "Scratch instructions with a VGPR offset and a negative immediate offset that is not a multiple of 4 read wrong memory on GFX10", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_data_dep_hazard)] = .{ + .llvm_name = "no-data-dep-hazard", + .description = "Does not need SW waitstates", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_sdst_cmpx)] = .{ + .llvm_name = "no-sdst-cmpx", + .description = "V_CMPX does not write VCC/SGPR in addition to EXEC", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nsa_clause_bug)] = .{ + .llvm_name = "nsa-clause-bug", + .description = "MIMG-NSA in a hard clause has unpredictable results on GFX10.1", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nsa_encoding)] = .{ + .llvm_name = "nsa-encoding", + .description = "Support NSA encoding for image instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nsa_to_vmem_bug)] = .{ + .llvm_name = "nsa-to-vmem-bug", + .description = "MIMG-NSA followed by VMEM fail if EXEC_LO or EXEC_HI equals zero", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.offset_3f_bug)] = .{ + .llvm_name = "offset-3f-bug", + .description = "Branch offset of 3f hardware bug", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.packed_fp32_ops)] = .{ + .llvm_name = "packed-fp32-ops", + .description = "Support packed fp32 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.packed_tid)] = .{ + .llvm_name = "packed-tid", + .description = "Workitem IDs are packed into v0 at kernel launch", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.partial_nsa_encoding)] = .{ + .llvm_name = "partial-nsa-encoding", + .description = "Support partial NSA encoding for image instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pk_fmac_f16_inst)] = .{ + .llvm_name = "pk-fmac-f16-inst", + .description = "Has v_pk_fmac_f16 instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.promote_alloca)] = .{ + .llvm_name = "promote-alloca", + .description = "Enable promote alloca pass", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prt_strict_null)] = .{ + .llvm_name = "enable-prt-strict-null", + .description = "Enable zeroing of result registers for sparse texture fetches", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.r128_a16)] = .{ + .llvm_name = "r128-a16", + .description = "Support gfx9-style A16 for 16-bit coordinates/gradients/lod/clamp/mip image operands, where a16 is aliased with r128", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.s_memrealtime)] = .{ + .llvm_name = "s-memrealtime", + .description = "Has s_memrealtime instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.s_memtime_inst)] = .{ + .llvm_name = "s-memtime-inst", + .description = "Has s_memtime instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.scalar_atomics)] = .{ + .llvm_name = "scalar-atomics", + .description = "Has atomic scalar memory instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.scalar_flat_scratch_insts)] = .{ + .llvm_name = "scalar-flat-scratch-insts", + .description = "Have s_scratch_* flat memory instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.scalar_stores)] = .{ + .llvm_name = "scalar-stores", + .description = "Has store scalar memory instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sdwa)] = .{ + .llvm_name = "sdwa", + .description = "Support SDWA (Sub-DWORD Addressing) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sdwa_mav)] = .{ + .llvm_name = "sdwa-mav", + .description = "Support v_mac_f32/f16 with SDWA (Sub-DWORD Addressing) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sdwa_omod)] = .{ + .llvm_name = "sdwa-omod", + .description = "Support OMod with SDWA (Sub-DWORD Addressing) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sdwa_out_mods_vopc)] = .{ + .llvm_name = "sdwa-out-mods-vopc", + .description = "Support clamp for VOPC with SDWA (Sub-DWORD Addressing) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sdwa_scalar)] = .{ + .llvm_name = "sdwa-scalar", + .description = "Support scalar register with SDWA (Sub-DWORD Addressing) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sdwa_sdst)] = .{ + .llvm_name = "sdwa-sdst", + .description = "Support scalar dst for VOPC with SDWA (Sub-DWORD Addressing) extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sea_islands)] = .{ + .llvm_name = "sea-islands", + .description = "SEA_ISLANDS GPU generation", + .dependencies = featureSet(&[_]Feature{ + .ci_insts, + .ds_src2_insts, + .extended_image_insts, + .flat_address_space, + .fp64, + .gfx7_gfx8_gfx9_insts, + .image_insts, + .localmemorysize65536, + .mad_mac_f32_insts, + .mimg_r128, + .movrel, + .s_memtime_inst, + .trig_reduced_range, + .unaligned_buffer_access, + .wavefrontsize64, + }), + }; + result[@intFromEnum(Feature.sgpr_init_bug)] = .{ + .llvm_name = "sgpr-init-bug", + .description = "VI SGPR initialization bug requiring a fixed SGPR allocation size", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.shader_cycles_register)] = .{ + .llvm_name = "shader-cycles-register", + .description = "Has SHADER_CYCLES hardware register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.si_scheduler)] = .{ + .llvm_name = "si-scheduler", + .description = "Enable SI Machine Scheduler", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.smem_to_vector_write_hazard)] = .{ + .llvm_name = "smem-to-vector-write-hazard", + .description = "s_load_dword followed by v_cmp page faults", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.southern_islands)] = .{ + .llvm_name = "southern-islands", + .description = "SOUTHERN_ISLANDS GPU generation", + .dependencies = featureSet(&[_]Feature{ + .ds_src2_insts, + .extended_image_insts, + .fp64, + .image_insts, + .ldsbankcount32, + .localmemorysize32768, + .mad_mac_f32_insts, + .mimg_r128, + .movrel, + .s_memtime_inst, + .trig_reduced_range, + .wavefrontsize64, + }), + }; + result[@intFromEnum(Feature.sramecc)] = .{ + .llvm_name = "sramecc", + .description = "Enable SRAMECC", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sramecc_support)] = .{ + .llvm_name = "sramecc-support", + .description = "Hardware supports SRAMECC", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tgsplit)] = .{ + .llvm_name = "tgsplit", + .description = "Enable threadgroup split execution", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.trap_handler)] = .{ + .llvm_name = "trap-handler", + .description = "Trap handler support", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.trig_reduced_range)] = .{ + .llvm_name = "trig-reduced-range", + .description = "Requires use of fract on arguments to trig instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.true16)] = .{ + .llvm_name = "true16", + .description = "True 16-bit operand instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unaligned_access_mode)] = .{ + .llvm_name = "unaligned-access-mode", + .description = "Enable unaligned global, local and region loads and stores if the hardware supports it", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unaligned_buffer_access)] = .{ + .llvm_name = "unaligned-buffer-access", + .description = "Hardware supports unaligned global loads and stores", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unaligned_ds_access)] = .{ + .llvm_name = "unaligned-ds-access", + .description = "Hardware supports unaligned local and region loads and stores", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unaligned_scratch_access)] = .{ + .llvm_name = "unaligned-scratch-access", + .description = "Support unaligned scratch loads and stores", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unpacked_d16_vmem)] = .{ + .llvm_name = "unpacked-d16-vmem", + .description = "Has unpacked d16 vmem instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unsafe_ds_offset_folding)] = .{ + .llvm_name = "unsafe-ds-offset-folding", + .description = "Force using DS instruction immediate offsets on SI", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.user_sgpr_init16_bug)] = .{ + .llvm_name = "user-sgpr-init16-bug", + .description = "Bug requiring at least 16 user+system SGPRs to be enabled", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.valu_trans_use_hazard)] = .{ + .llvm_name = "valu-trans-use-hazard", + .description = "Hazard when TRANS instructions are closely followed by a use of the result", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vcmpx_exec_war_hazard)] = .{ + .llvm_name = "vcmpx-exec-war-hazard", + .description = "V_CMPX WAR hazard on EXEC (V_CMPX issue ONLY)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vcmpx_permlane_hazard)] = .{ + .llvm_name = "vcmpx-permlane-hazard", + .description = "TODO: describe me", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vgpr_index_mode)] = .{ + .llvm_name = "vgpr-index-mode", + .description = "Has VGPR mode register indexing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vmem_to_scalar_write_hazard)] = .{ + .llvm_name = "vmem-to-scalar-write-hazard", + .description = "VMEM instruction followed by scalar writing to EXEC mask, M0 or SGPR leads to incorrect execution.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.volcanic_islands)] = .{ + .llvm_name = "volcanic-islands", + .description = "VOLCANIC_ISLANDS GPU generation", + .dependencies = featureSet(&[_]Feature{ + .@"16_bit_insts", + .ci_insts, + .dpp, + .ds_src2_insts, + .extended_image_insts, + .fast_denormal_f32, + .flat_address_space, + .fp64, + .gcn3_encoding, + .gfx7_gfx8_gfx9_insts, + .gfx8_insts, + .image_insts, + .int_clamp_insts, + .inv_2pi_inline_imm, + .localmemorysize65536, + .mad_mac_f32_insts, + .mimg_r128, + .movrel, + .s_memrealtime, + .s_memtime_inst, + .scalar_stores, + .sdwa, + .sdwa_mav, + .sdwa_out_mods_vopc, + .trig_reduced_range, + .unaligned_buffer_access, + .vgpr_index_mode, + .wavefrontsize64, + }), + }; + result[@intFromEnum(Feature.vop3_literal)] = .{ + .llvm_name = "vop3-literal", + .description = "Can use one literal in VOP3", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vop3p)] = .{ + .llvm_name = "vop3p", + .description = "Has VOP3P packed instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vopd)] = .{ + .llvm_name = "vopd", + .description = "Has VOPD dual issue wave32 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vscnt)] = .{ + .llvm_name = "vscnt", + .description = "Has separate store vscnt counter", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.wavefrontsize16)] = .{ + .llvm_name = "wavefrontsize16", + .description = "The number of threads per wavefront", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.wavefrontsize32)] = .{ + .llvm_name = "wavefrontsize32", + .description = "The number of threads per wavefront", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.wavefrontsize64)] = .{ + .llvm_name = "wavefrontsize64", + .description = "The number of threads per wavefront", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xnack)] = .{ + .llvm_name = "xnack", + .description = "Enable XNACK support", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xnack_support)] = .{ + .llvm_name = "xnack-support", + .description = "Hardware supports XNACK", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const bonaire = CpuModel{ + .name = "bonaire", + .llvm_name = "bonaire", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sea_islands, + }), + }; + pub const carrizo = CpuModel{ + .name = "carrizo", + .llvm_name = "carrizo", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .half_rate_64_ops, + .ldsbankcount32, + .unpacked_d16_vmem, + .volcanic_islands, + .xnack_support, + }), + }; + pub const fiji = CpuModel{ + .name = "fiji", + .llvm_name = "fiji", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .wavefrontsize64, + }), + }; + pub const generic_hsa = CpuModel{ + .name = "generic_hsa", + .llvm_name = "generic-hsa", + .features = featureSet(&[_]Feature{ + .flat_address_space, + .wavefrontsize64, + }), + }; + pub const gfx1010 = CpuModel{ + .name = "gfx1010", + .llvm_name = "gfx1010", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .ds_src2_insts, + .flat_segment_offset_bug, + .get_wave_id_inst, + .gfx10, + .inst_fwd_prefetch_bug, + .lds_branch_vmem_war_hazard, + .lds_misaligned_bug, + .ldsbankcount32, + .mad_mac_f32_insts, + .negative_unaligned_scratch_offset_bug, + .nsa_clause_bug, + .nsa_encoding, + .nsa_to_vmem_bug, + .offset_3f_bug, + .scalar_atomics, + .scalar_flat_scratch_insts, + .scalar_stores, + .smem_to_vector_write_hazard, + .vcmpx_exec_war_hazard, + .vcmpx_permlane_hazard, + .vmem_to_scalar_write_hazard, + .wavefrontsize32, + .xnack_support, + }), + }; + pub const gfx1011 = CpuModel{ + .name = "gfx1011", + .llvm_name = "gfx1011", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .ds_src2_insts, + .flat_segment_offset_bug, + .get_wave_id_inst, + .gfx10, + .inst_fwd_prefetch_bug, + .lds_branch_vmem_war_hazard, + .lds_misaligned_bug, + .ldsbankcount32, + .mad_mac_f32_insts, + .negative_unaligned_scratch_offset_bug, + .nsa_clause_bug, + .nsa_encoding, + .nsa_to_vmem_bug, + .offset_3f_bug, + .scalar_atomics, + .scalar_flat_scratch_insts, + .scalar_stores, + .smem_to_vector_write_hazard, + .vcmpx_exec_war_hazard, + .vcmpx_permlane_hazard, + .vmem_to_scalar_write_hazard, + .wavefrontsize32, + .xnack_support, + }), + }; + pub const gfx1012 = CpuModel{ + .name = "gfx1012", + .llvm_name = "gfx1012", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .ds_src2_insts, + .flat_segment_offset_bug, + .get_wave_id_inst, + .gfx10, + .inst_fwd_prefetch_bug, + .lds_branch_vmem_war_hazard, + .lds_misaligned_bug, + .ldsbankcount32, + .mad_mac_f32_insts, + .negative_unaligned_scratch_offset_bug, + .nsa_clause_bug, + .nsa_encoding, + .nsa_to_vmem_bug, + .offset_3f_bug, + .scalar_atomics, + .scalar_flat_scratch_insts, + .scalar_stores, + .smem_to_vector_write_hazard, + .vcmpx_exec_war_hazard, + .vcmpx_permlane_hazard, + .vmem_to_scalar_write_hazard, + .wavefrontsize32, + .xnack_support, + }), + }; + pub const gfx1013 = CpuModel{ + .name = "gfx1013", + .llvm_name = "gfx1013", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .ds_src2_insts, + .flat_segment_offset_bug, + .get_wave_id_inst, + .gfx10, + .gfx10_a_encoding, + .inst_fwd_prefetch_bug, + .lds_branch_vmem_war_hazard, + .lds_misaligned_bug, + .ldsbankcount32, + .mad_mac_f32_insts, + .negative_unaligned_scratch_offset_bug, + .nsa_clause_bug, + .nsa_encoding, + .nsa_to_vmem_bug, + .offset_3f_bug, + .scalar_atomics, + .scalar_flat_scratch_insts, + .scalar_stores, + .smem_to_vector_write_hazard, + .vcmpx_exec_war_hazard, + .vcmpx_permlane_hazard, + .vmem_to_scalar_write_hazard, + .wavefrontsize32, + .xnack_support, + }), + }; + pub const gfx1030 = CpuModel{ + .name = "gfx1030", + .llvm_name = "gfx1030", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1031 = CpuModel{ + .name = "gfx1031", + .llvm_name = "gfx1031", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1032 = CpuModel{ + .name = "gfx1032", + .llvm_name = "gfx1032", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1033 = CpuModel{ + .name = "gfx1033", + .llvm_name = "gfx1033", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1034 = CpuModel{ + .name = "gfx1034", + .llvm_name = "gfx1034", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1035 = CpuModel{ + .name = "gfx1035", + .llvm_name = "gfx1035", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1036 = CpuModel{ + .name = "gfx1036", + .llvm_name = "gfx1036", + .features = featureSet(&[_]Feature{ + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .gfx10, + .gfx10_3_insts, + .gfx10_a_encoding, + .gfx10_b_encoding, + .ldsbankcount32, + .nsa_encoding, + .shader_cycles_register, + .wavefrontsize32, + }), + }; + pub const gfx1100 = CpuModel{ + .name = "gfx1100", + .llvm_name = "gfx1100", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .dl_insts, + .dot10_insts, + .dot5_insts, + .dot7_insts, + .dot8_insts, + .dot9_insts, + .flat_atomic_fadd_f32_inst, + .gfx11, + .gfx11_full_vgprs, + .image_insts, + .ldsbankcount32, + .mad_intra_fwd_bug, + .nsa_encoding, + .packed_tid, + .partial_nsa_encoding, + .shader_cycles_register, + .user_sgpr_init16_bug, + .valu_trans_use_hazard, + .vcmpx_permlane_hazard, + .wavefrontsize32, + }), + }; + pub const gfx1101 = CpuModel{ + .name = "gfx1101", + .llvm_name = "gfx1101", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .dl_insts, + .dot10_insts, + .dot5_insts, + .dot7_insts, + .dot8_insts, + .dot9_insts, + .flat_atomic_fadd_f32_inst, + .gfx11, + .gfx11_full_vgprs, + .image_insts, + .ldsbankcount32, + .mad_intra_fwd_bug, + .nsa_encoding, + .packed_tid, + .partial_nsa_encoding, + .shader_cycles_register, + .valu_trans_use_hazard, + .vcmpx_permlane_hazard, + .wavefrontsize32, + }), + }; + pub const gfx1102 = CpuModel{ + .name = "gfx1102", + .llvm_name = "gfx1102", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .dl_insts, + .dot10_insts, + .dot5_insts, + .dot7_insts, + .dot8_insts, + .dot9_insts, + .flat_atomic_fadd_f32_inst, + .gfx11, + .image_insts, + .ldsbankcount32, + .mad_intra_fwd_bug, + .nsa_encoding, + .packed_tid, + .partial_nsa_encoding, + .shader_cycles_register, + .user_sgpr_init16_bug, + .valu_trans_use_hazard, + .vcmpx_permlane_hazard, + .wavefrontsize32, + }), + }; + pub const gfx1103 = CpuModel{ + .name = "gfx1103", + .llvm_name = "gfx1103", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .dl_insts, + .dot10_insts, + .dot5_insts, + .dot7_insts, + .dot8_insts, + .dot9_insts, + .flat_atomic_fadd_f32_inst, + .gfx11, + .image_insts, + .ldsbankcount32, + .mad_intra_fwd_bug, + .nsa_encoding, + .packed_tid, + .partial_nsa_encoding, + .shader_cycles_register, + .valu_trans_use_hazard, + .vcmpx_permlane_hazard, + .wavefrontsize32, + }), + }; + pub const gfx1150 = CpuModel{ + .name = "gfx1150", + .llvm_name = "gfx1150", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .dl_insts, + .dot10_insts, + .dot5_insts, + .dot7_insts, + .dot8_insts, + .dot9_insts, + .flat_atomic_fadd_f32_inst, + .gfx11, + .image_insts, + .ldsbankcount32, + .mad_intra_fwd_bug, + .nsa_encoding, + .packed_tid, + .partial_nsa_encoding, + .shader_cycles_register, + .vcmpx_permlane_hazard, + .wavefrontsize32, + }), + }; + pub const gfx1151 = CpuModel{ + .name = "gfx1151", + .llvm_name = "gfx1151", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .dl_insts, + .dot10_insts, + .dot5_insts, + .dot7_insts, + .dot8_insts, + .dot9_insts, + .flat_atomic_fadd_f32_inst, + .gfx11, + .gfx11_full_vgprs, + .image_insts, + .ldsbankcount32, + .mad_intra_fwd_bug, + .nsa_encoding, + .packed_tid, + .partial_nsa_encoding, + .shader_cycles_register, + .vcmpx_permlane_hazard, + .wavefrontsize32, + }), + }; + pub const gfx600 = CpuModel{ + .name = "gfx600", + .llvm_name = "gfx600", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .half_rate_64_ops, + .southern_islands, + }), + }; + pub const gfx601 = CpuModel{ + .name = "gfx601", + .llvm_name = "gfx601", + .features = featureSet(&[_]Feature{ + .southern_islands, + }), + }; + pub const gfx602 = CpuModel{ + .name = "gfx602", + .llvm_name = "gfx602", + .features = featureSet(&[_]Feature{ + .southern_islands, + }), + }; + pub const gfx700 = CpuModel{ + .name = "gfx700", + .llvm_name = "gfx700", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sea_islands, + }), + }; + pub const gfx701 = CpuModel{ + .name = "gfx701", + .llvm_name = "gfx701", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .half_rate_64_ops, + .ldsbankcount32, + .sea_islands, + }), + }; + pub const gfx702 = CpuModel{ + .name = "gfx702", + .llvm_name = "gfx702", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .ldsbankcount16, + .sea_islands, + }), + }; + pub const gfx703 = CpuModel{ + .name = "gfx703", + .llvm_name = "gfx703", + .features = featureSet(&[_]Feature{ + .ldsbankcount16, + .sea_islands, + }), + }; + pub const gfx704 = CpuModel{ + .name = "gfx704", + .llvm_name = "gfx704", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sea_islands, + }), + }; + pub const gfx705 = CpuModel{ + .name = "gfx705", + .llvm_name = "gfx705", + .features = featureSet(&[_]Feature{ + .ldsbankcount16, + .sea_islands, + }), + }; + pub const gfx801 = CpuModel{ + .name = "gfx801", + .llvm_name = "gfx801", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .half_rate_64_ops, + .ldsbankcount32, + .unpacked_d16_vmem, + .volcanic_islands, + .xnack_support, + }), + }; + pub const gfx802 = CpuModel{ + .name = "gfx802", + .llvm_name = "gfx802", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sgpr_init_bug, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const gfx803 = CpuModel{ + .name = "gfx803", + .llvm_name = "gfx803", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const gfx805 = CpuModel{ + .name = "gfx805", + .llvm_name = "gfx805", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sgpr_init_bug, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const gfx810 = CpuModel{ + .name = "gfx810", + .llvm_name = "gfx810", + .features = featureSet(&[_]Feature{ + .image_gather4_d16_bug, + .image_store_d16_bug, + .ldsbankcount16, + .volcanic_islands, + .xnack_support, + }), + }; + pub const gfx900 = CpuModel{ + .name = "gfx900", + .llvm_name = "gfx900", + .features = featureSet(&[_]Feature{ + .ds_src2_insts, + .extended_image_insts, + .gfx9, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .mad_mix_insts, + }), + }; + pub const gfx902 = CpuModel{ + .name = "gfx902", + .llvm_name = "gfx902", + .features = featureSet(&[_]Feature{ + .ds_src2_insts, + .extended_image_insts, + .gfx9, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .mad_mix_insts, + }), + }; + pub const gfx904 = CpuModel{ + .name = "gfx904", + .llvm_name = "gfx904", + .features = featureSet(&[_]Feature{ + .ds_src2_insts, + .extended_image_insts, + .fma_mix_insts, + .gfx9, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + }), + }; + pub const gfx906 = CpuModel{ + .name = "gfx906", + .llvm_name = "gfx906", + .features = featureSet(&[_]Feature{ + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot7_insts, + .ds_src2_insts, + .extended_image_insts, + .fma_mix_insts, + .gfx9, + .half_rate_64_ops, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .sramecc_support, + }), + }; + pub const gfx908 = CpuModel{ + .name = "gfx908", + .llvm_name = "gfx908", + .features = featureSet(&[_]Feature{ + .atomic_buffer_global_pk_add_f16_no_rtn_insts, + .atomic_fadd_no_rtn_insts, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot3_insts, + .dot4_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .ds_src2_insts, + .extended_image_insts, + .fma_mix_insts, + .gfx9, + .half_rate_64_ops, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .mai_insts, + .mfma_inline_literal_bug, + .pk_fmac_f16_inst, + .sramecc_support, + }), + }; + pub const gfx909 = CpuModel{ + .name = "gfx909", + .llvm_name = "gfx909", + .features = featureSet(&[_]Feature{ + .ds_src2_insts, + .extended_image_insts, + .gfx9, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .mad_mix_insts, + }), + }; + pub const gfx90a = CpuModel{ + .name = "gfx90a", + .llvm_name = "gfx90a", + .features = featureSet(&[_]Feature{ + .atomic_buffer_global_pk_add_f16_insts, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot3_insts, + .dot4_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .dpp_64bit, + .fma_mix_insts, + .fmacf64_inst, + .full_rate_64_ops, + .gfx9, + .gfx90a_insts, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .mai_insts, + .packed_fp32_ops, + .packed_tid, + .pk_fmac_f16_inst, + .sramecc_support, + }), + }; + pub const gfx90c = CpuModel{ + .name = "gfx90c", + .llvm_name = "gfx90c", + .features = featureSet(&[_]Feature{ + .ds_src2_insts, + .extended_image_insts, + .gfx9, + .image_gather4_d16_bug, + .image_insts, + .ldsbankcount32, + .mad_mac_f32_insts, + .mad_mix_insts, + }), + }; + pub const gfx940 = CpuModel{ + .name = "gfx940", + .llvm_name = "gfx940", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_buffer_global_pk_add_f16_insts, + .atomic_ds_pk_add_16_insts, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .atomic_flat_pk_add_16_insts, + .atomic_global_pk_add_bf16_inst, + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot3_insts, + .dot4_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .dpp_64bit, + .flat_atomic_fadd_f32_inst, + .fma_mix_insts, + .fmacf64_inst, + .force_store_sc0_sc1, + .fp8_insts, + .full_rate_64_ops, + .gfx9, + .gfx90a_insts, + .gfx940_insts, + .ldsbankcount32, + .mai_insts, + .packed_fp32_ops, + .packed_tid, + .pk_fmac_f16_inst, + .sramecc_support, + }), + }; + pub const gfx941 = CpuModel{ + .name = "gfx941", + .llvm_name = "gfx941", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_buffer_global_pk_add_f16_insts, + .atomic_ds_pk_add_16_insts, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .atomic_flat_pk_add_16_insts, + .atomic_global_pk_add_bf16_inst, + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot3_insts, + .dot4_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .dpp_64bit, + .flat_atomic_fadd_f32_inst, + .fma_mix_insts, + .fmacf64_inst, + .force_store_sc0_sc1, + .fp8_insts, + .full_rate_64_ops, + .gfx9, + .gfx90a_insts, + .gfx940_insts, + .ldsbankcount32, + .mai_insts, + .packed_fp32_ops, + .packed_tid, + .pk_fmac_f16_inst, + .sramecc_support, + }), + }; + pub const gfx942 = CpuModel{ + .name = "gfx942", + .llvm_name = "gfx942", + .features = featureSet(&[_]Feature{ + .architected_flat_scratch, + .atomic_buffer_global_pk_add_f16_insts, + .atomic_ds_pk_add_16_insts, + .atomic_fadd_no_rtn_insts, + .atomic_fadd_rtn_insts, + .atomic_flat_pk_add_16_insts, + .atomic_global_pk_add_bf16_inst, + .back_off_barrier, + .dl_insts, + .dot10_insts, + .dot1_insts, + .dot2_insts, + .dot3_insts, + .dot4_insts, + .dot5_insts, + .dot6_insts, + .dot7_insts, + .dpp_64bit, + .flat_atomic_fadd_f32_inst, + .fma_mix_insts, + .fmacf64_inst, + .fp8_insts, + .full_rate_64_ops, + .gfx9, + .gfx90a_insts, + .gfx940_insts, + .ldsbankcount32, + .mai_insts, + .packed_fp32_ops, + .packed_tid, + .pk_fmac_f16_inst, + .sramecc_support, + }), + }; + pub const hainan = CpuModel{ + .name = "hainan", + .llvm_name = "hainan", + .features = featureSet(&[_]Feature{ + .southern_islands, + }), + }; + pub const hawaii = CpuModel{ + .name = "hawaii", + .llvm_name = "hawaii", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .half_rate_64_ops, + .ldsbankcount32, + .sea_islands, + }), + }; + pub const iceland = CpuModel{ + .name = "iceland", + .llvm_name = "iceland", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sgpr_init_bug, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const kabini = CpuModel{ + .name = "kabini", + .llvm_name = "kabini", + .features = featureSet(&[_]Feature{ + .ldsbankcount16, + .sea_islands, + }), + }; + pub const kaveri = CpuModel{ + .name = "kaveri", + .llvm_name = "kaveri", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sea_islands, + }), + }; + pub const mullins = CpuModel{ + .name = "mullins", + .llvm_name = "mullins", + .features = featureSet(&[_]Feature{ + .ldsbankcount16, + .sea_islands, + }), + }; + pub const oland = CpuModel{ + .name = "oland", + .llvm_name = "oland", + .features = featureSet(&[_]Feature{ + .southern_islands, + }), + }; + pub const pitcairn = CpuModel{ + .name = "pitcairn", + .llvm_name = "pitcairn", + .features = featureSet(&[_]Feature{ + .southern_islands, + }), + }; + pub const polaris10 = CpuModel{ + .name = "polaris10", + .llvm_name = "polaris10", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const polaris11 = CpuModel{ + .name = "polaris11", + .llvm_name = "polaris11", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const stoney = CpuModel{ + .name = "stoney", + .llvm_name = "stoney", + .features = featureSet(&[_]Feature{ + .image_gather4_d16_bug, + .image_store_d16_bug, + .ldsbankcount16, + .volcanic_islands, + .xnack_support, + }), + }; + pub const tahiti = CpuModel{ + .name = "tahiti", + .llvm_name = "tahiti", + .features = featureSet(&[_]Feature{ + .fast_fmaf, + .half_rate_64_ops, + .southern_islands, + }), + }; + pub const tonga = CpuModel{ + .name = "tonga", + .llvm_name = "tonga", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sgpr_init_bug, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const tongapro = CpuModel{ + .name = "tongapro", + .llvm_name = "tongapro", + .features = featureSet(&[_]Feature{ + .ldsbankcount32, + .sgpr_init_bug, + .unpacked_d16_vmem, + .volcanic_islands, + }), + }; + pub const verde = CpuModel{ + .name = "verde", + .llvm_name = "verde", + .features = featureSet(&[_]Feature{ + .southern_islands, + }), + }; +}; diff --git a/lib/std/Target/arc.zig b/lib/std/Target/arc.zig new file mode 100644 index 0000000000..eff13c6637 --- /dev/null +++ b/lib/std/Target/arc.zig @@ -0,0 +1,39 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + norm, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.norm)] = .{ + .llvm_name = "norm", + .description = "Enable support for norm instruction.", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; +}; diff --git a/lib/std/Target/arm.zig b/lib/std/Target/arm.zig new file mode 100644 index 0000000000..5245b3357e --- /dev/null +++ b/lib/std/Target/arm.zig @@ -0,0 +1,2604 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"32bit", + @"8msecext", + a76, + aapcs_frame_chain, + aapcs_frame_chain_leaf, + aclass, + acquire_release, + aes, + atomics_32, + avoid_movs_shop, + avoid_partial_cpsr, + bf16, + big_endian_instructions, + cde, + cdecp0, + cdecp1, + cdecp2, + cdecp3, + cdecp4, + cdecp5, + cdecp6, + cdecp7, + cheap_predicable_cpsr, + clrbhb, + crc, + crypto, + d32, + db, + dfb, + disable_postra_scheduler, + dont_widen_vmovs, + dotprod, + dsp, + execute_only, + expand_fp_mlx, + exynos, + fix_cmse_cve_2021_35465, + fix_cortex_a57_aes_1742098, + fp16, + fp16fml, + fp64, + fp_armv8, + fp_armv8d16, + fp_armv8d16sp, + fp_armv8sp, + fpao, + fpregs, + fpregs16, + fpregs64, + fullfp16, + fuse_aes, + fuse_literals, + harden_sls_blr, + harden_sls_nocomdat, + harden_sls_retbr, + has_v4t, + has_v5t, + has_v5te, + has_v6, + has_v6k, + has_v6m, + has_v6t2, + has_v7, + has_v7clrex, + has_v8, + has_v8_1a, + has_v8_1m_main, + has_v8_2a, + has_v8_3a, + has_v8_4a, + has_v8_5a, + has_v8_6a, + has_v8_7a, + has_v8_8a, + has_v8_9a, + has_v8m, + has_v8m_main, + has_v9_1a, + has_v9_2a, + has_v9_3a, + has_v9_4a, + has_v9a, + hwdiv, + hwdiv_arm, + i8mm, + iwmmxt, + iwmmxt2, + lob, + long_calls, + loop_align, + m3, + mclass, + mp, + muxed_units, + mve, + mve1beat, + mve2beat, + mve4beat, + mve_fp, + nacl_trap, + neon, + neon_fpmovs, + neonfp, + no_branch_predictor, + no_bti_at_return_twice, + no_movt, + no_neg_immediates, + noarm, + nonpipelined_vfp, + pacbti, + perfmon, + prefer_ishst, + prefer_vmovsr, + prof_unpr, + r4, + ras, + rclass, + read_tp_tpidrprw, + read_tp_tpidruro, + read_tp_tpidrurw, + reserve_r9, + ret_addr_stack, + sb, + sha2, + slow_fp_brcc, + slow_load_D_subreg, + slow_odd_reg, + slow_vdup32, + slow_vgetlni32, + slowfpvfmx, + slowfpvmlx, + soft_float, + splat_vfp_neon, + strict_align, + swift, + thumb2, + thumb_mode, + trustzone, + use_mipipeliner, + use_misched, + v2, + v2a, + v3, + v3m, + v4, + v4t, + v5t, + v5te, + v5tej, + v6, + v6j, + v6k, + v6kz, + v6m, + v6sm, + v6t2, + v7a, + v7em, + v7k, + v7m, + v7r, + v7s, + v7ve, + v8_1a, + v8_1m_main, + v8_2a, + v8_3a, + v8_4a, + v8_5a, + v8_6a, + v8_7a, + v8_8a, + v8_9a, + v8a, + v8m, + v8m_main, + v8r, + v9_1a, + v9_2a, + v9_3a, + v9_4a, + v9a, + vfp2, + vfp2sp, + vfp3, + vfp3d16, + vfp3d16sp, + vfp3sp, + vfp4, + vfp4d16, + vfp4d16sp, + vfp4sp, + virtualization, + vldn_align, + vmlx_forwarding, + vmlx_hazards, + wide_stride_vfp, + xscale, + zcz, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + @setEvalBranchQuota(10000); + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"32bit")] = .{ + .llvm_name = "32bit", + .description = "Prefer 32-bit Thumb instrs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"8msecext")] = .{ + .llvm_name = "8msecext", + .description = "Enable support for ARMv8-M Security Extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.a76)] = .{ + .llvm_name = "a76", + .description = "Cortex-A76 ARM processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.aapcs_frame_chain)] = .{ + .llvm_name = "aapcs-frame-chain", + .description = "Create an AAPCS compliant frame chain", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.aapcs_frame_chain_leaf)] = .{ + .llvm_name = "aapcs-frame-chain-leaf", + .description = "Create an AAPCS compliant frame chain for leaf functions", + .dependencies = featureSet(&[_]Feature{ + .aapcs_frame_chain, + }), + }; + result[@intFromEnum(Feature.aclass)] = .{ + .llvm_name = "aclass", + .description = "Is application profile ('A' series)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.acquire_release)] = .{ + .llvm_name = "acquire-release", + .description = "Has v8 acquire/release (lda/ldaex etc) instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.aes)] = .{ + .llvm_name = "aes", + .description = "Enable AES support", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.atomics_32)] = .{ + .llvm_name = "atomics-32", + .description = "Assume that lock-free 32-bit atomics are available", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.avoid_movs_shop)] = .{ + .llvm_name = "avoid-movs-shop", + .description = "Avoid movs instructions with shifter operand", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.avoid_partial_cpsr)] = .{ + .llvm_name = "avoid-partial-cpsr", + .description = "Avoid CPSR partial update for OOO execution", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.bf16)] = .{ + .llvm_name = "bf16", + .description = "Enable support for BFloat16 instructions", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.big_endian_instructions)] = .{ + .llvm_name = "big-endian-instructions", + .description = "Expect instructions to be stored big-endian.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cde)] = .{ + .llvm_name = "cde", + .description = "Support CDE instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8m_main, + }), + }; + result[@intFromEnum(Feature.cdecp0)] = .{ + .llvm_name = "cdecp0", + .description = "Coprocessor 0 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp1)] = .{ + .llvm_name = "cdecp1", + .description = "Coprocessor 1 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp2)] = .{ + .llvm_name = "cdecp2", + .description = "Coprocessor 2 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp3)] = .{ + .llvm_name = "cdecp3", + .description = "Coprocessor 3 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp4)] = .{ + .llvm_name = "cdecp4", + .description = "Coprocessor 4 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp5)] = .{ + .llvm_name = "cdecp5", + .description = "Coprocessor 5 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp6)] = .{ + .llvm_name = "cdecp6", + .description = "Coprocessor 6 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cdecp7)] = .{ + .llvm_name = "cdecp7", + .description = "Coprocessor 7 ISA is CDEv1", + .dependencies = featureSet(&[_]Feature{ + .cde, + }), + }; + result[@intFromEnum(Feature.cheap_predicable_cpsr)] = .{ + .llvm_name = "cheap-predicable-cpsr", + .description = "Disable +1 predication cost for instructions updating CPSR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.clrbhb)] = .{ + .llvm_name = "clrbhb", + .description = "Enable Clear BHB instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.crc)] = .{ + .llvm_name = "crc", + .description = "Enable support for CRC instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.crypto)] = .{ + .llvm_name = "crypto", + .description = "Enable support for Cryptography extensions", + .dependencies = featureSet(&[_]Feature{ + .aes, + .sha2, + }), + }; + result[@intFromEnum(Feature.d32)] = .{ + .llvm_name = "d32", + .description = "Extend FP to 32 double registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.db)] = .{ + .llvm_name = "db", + .description = "Has data barrier (dmb/dsb) instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dfb)] = .{ + .llvm_name = "dfb", + .description = "Has full data barrier (dfb) instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.disable_postra_scheduler)] = .{ + .llvm_name = "disable-postra-scheduler", + .description = "Don't schedule again after register allocation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dont_widen_vmovs)] = .{ + .llvm_name = "dont-widen-vmovs", + .description = "Don't widen VMOVS to VMOVD", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dotprod)] = .{ + .llvm_name = "dotprod", + .description = "Enable support for dot product instructions", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.dsp)] = .{ + .llvm_name = "dsp", + .description = "Supports DSP instructions in ARM and/or Thumb2", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.execute_only)] = .{ + .llvm_name = "execute-only", + .description = "Enable the generation of execute only code.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.expand_fp_mlx)] = .{ + .llvm_name = "expand-fp-mlx", + .description = "Expand VFP/NEON MLA/MLS instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.exynos)] = .{ + .llvm_name = "exynos", + .description = "Samsung Exynos processors", + .dependencies = featureSet(&[_]Feature{ + .crc, + .crypto, + .expand_fp_mlx, + .fuse_aes, + .fuse_literals, + .hwdiv, + .hwdiv_arm, + .prof_unpr, + .ret_addr_stack, + .slow_fp_brcc, + .slow_vdup32, + .slow_vgetlni32, + .slowfpvfmx, + .slowfpvmlx, + .splat_vfp_neon, + .wide_stride_vfp, + .zcz, + }), + }; + result[@intFromEnum(Feature.fix_cmse_cve_2021_35465)] = .{ + .llvm_name = "fix-cmse-cve-2021-35465", + .description = "Mitigate against the cve-2021-35465 security vulnurability", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fix_cortex_a57_aes_1742098)] = .{ + .llvm_name = "fix-cortex-a57-aes-1742098", + .description = "Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp16)] = .{ + .llvm_name = "fp16", + .description = "Enable half-precision floating point", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp16fml)] = .{ + .llvm_name = "fp16fml", + .description = "Enable full half-precision floating point fml instructions", + .dependencies = featureSet(&[_]Feature{ + .fullfp16, + }), + }; + result[@intFromEnum(Feature.fp64)] = .{ + .llvm_name = "fp64", + .description = "Floating point unit supports double precision", + .dependencies = featureSet(&[_]Feature{ + .fpregs64, + }), + }; + result[@intFromEnum(Feature.fp_armv8)] = .{ + .llvm_name = "fp-armv8", + .description = "Enable ARMv8 FP", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8d16, + .fp_armv8sp, + .vfp4, + }), + }; + result[@intFromEnum(Feature.fp_armv8d16)] = .{ + .llvm_name = "fp-armv8d16", + .description = "Enable ARMv8 FP with only 16 d-registers", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8d16sp, + .vfp4d16, + }), + }; + result[@intFromEnum(Feature.fp_armv8d16sp)] = .{ + .llvm_name = "fp-armv8d16sp", + .description = "Enable ARMv8 FP with only 16 d-registers and no double precision", + .dependencies = featureSet(&[_]Feature{ + .vfp4d16sp, + }), + }; + result[@intFromEnum(Feature.fp_armv8sp)] = .{ + .llvm_name = "fp-armv8sp", + .description = "Enable ARMv8 FP with no double precision", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8d16sp, + .vfp4sp, + }), + }; + result[@intFromEnum(Feature.fpao)] = .{ + .llvm_name = "fpao", + .description = "Enable fast computation of positive address offsets", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpregs)] = .{ + .llvm_name = "fpregs", + .description = "Enable FP registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpregs16)] = .{ + .llvm_name = "fpregs16", + .description = "Enable 16-bit FP registers", + .dependencies = featureSet(&[_]Feature{ + .fpregs, + }), + }; + result[@intFromEnum(Feature.fpregs64)] = .{ + .llvm_name = "fpregs64", + .description = "Enable 64-bit FP registers", + .dependencies = featureSet(&[_]Feature{ + .fpregs, + }), + }; + result[@intFromEnum(Feature.fullfp16)] = .{ + .llvm_name = "fullfp16", + .description = "Enable full half-precision floating point", + .dependencies = featureSet(&[_]Feature{ + .fp_armv8d16sp, + .fpregs16, + }), + }; + result[@intFromEnum(Feature.fuse_aes)] = .{ + .llvm_name = "fuse-aes", + .description = "CPU fuses AES crypto operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fuse_literals)] = .{ + .llvm_name = "fuse-literals", + .description = "CPU fuses literal generation operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.harden_sls_blr)] = .{ + .llvm_name = "harden-sls-blr", + .description = "Harden against straight line speculation across indirect calls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.harden_sls_nocomdat)] = .{ + .llvm_name = "harden-sls-nocomdat", + .description = "Generate thunk code for SLS mitigation in the normal text section", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.harden_sls_retbr)] = .{ + .llvm_name = "harden-sls-retbr", + .description = "Harden against straight line speculation across RETurn and BranchRegister instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.has_v4t)] = .{ + .llvm_name = "v4t", + .description = "Support ARM v4T instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.has_v5t)] = .{ + .llvm_name = "v5t", + .description = "Support ARM v5T instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v4t, + }), + }; + result[@intFromEnum(Feature.has_v5te)] = .{ + .llvm_name = "v5te", + .description = "Support ARM v5TE, v5TEj, and v5TExp instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v5t, + }), + }; + result[@intFromEnum(Feature.has_v6)] = .{ + .llvm_name = "v6", + .description = "Support ARM v6 instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v5te, + }), + }; + result[@intFromEnum(Feature.has_v6k)] = .{ + .llvm_name = "v6k", + .description = "Support ARM v6k instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v6, + }), + }; + result[@intFromEnum(Feature.has_v6m)] = .{ + .llvm_name = "v6m", + .description = "Support ARM v6M instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v6, + }), + }; + result[@intFromEnum(Feature.has_v6t2)] = .{ + .llvm_name = "v6t2", + .description = "Support ARM v6t2 instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v6k, + .has_v8m, + .thumb2, + }), + }; + result[@intFromEnum(Feature.has_v7)] = .{ + .llvm_name = "v7", + .description = "Support ARM v7 instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v6t2, + .has_v7clrex, + }), + }; + result[@intFromEnum(Feature.has_v7clrex)] = .{ + .llvm_name = "v7clrex", + .description = "Has v7 clrex instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.has_v8)] = .{ + .llvm_name = "v8", + .description = "Support ARM v8 instructions", + .dependencies = featureSet(&[_]Feature{ + .acquire_release, + .has_v7, + .perfmon, + }), + }; + result[@intFromEnum(Feature.has_v8_1a)] = .{ + .llvm_name = "v8.1a", + .description = "Support ARM v8.1a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8, + }), + }; + result[@intFromEnum(Feature.has_v8_1m_main)] = .{ + .llvm_name = "v8.1m.main", + .description = "Support ARM v8-1M Mainline instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8m_main, + }), + }; + result[@intFromEnum(Feature.has_v8_2a)] = .{ + .llvm_name = "v8.2a", + .description = "Support ARM v8.2a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_1a, + }), + }; + result[@intFromEnum(Feature.has_v8_3a)] = .{ + .llvm_name = "v8.3a", + .description = "Support ARM v8.3a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_2a, + }), + }; + result[@intFromEnum(Feature.has_v8_4a)] = .{ + .llvm_name = "v8.4a", + .description = "Support ARM v8.4a instructions", + .dependencies = featureSet(&[_]Feature{ + .dotprod, + .has_v8_3a, + }), + }; + result[@intFromEnum(Feature.has_v8_5a)] = .{ + .llvm_name = "v8.5a", + .description = "Support ARM v8.5a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_4a, + .sb, + }), + }; + result[@intFromEnum(Feature.has_v8_6a)] = .{ + .llvm_name = "v8.6a", + .description = "Support ARM v8.6a instructions", + .dependencies = featureSet(&[_]Feature{ + .bf16, + .has_v8_5a, + .i8mm, + }), + }; + result[@intFromEnum(Feature.has_v8_7a)] = .{ + .llvm_name = "v8.7a", + .description = "Support ARM v8.7a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_6a, + }), + }; + result[@intFromEnum(Feature.has_v8_8a)] = .{ + .llvm_name = "v8.8a", + .description = "Support ARM v8.8a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_7a, + }), + }; + result[@intFromEnum(Feature.has_v8_9a)] = .{ + .llvm_name = "v8.9a", + .description = "Support ARM v8.9a instructions", + .dependencies = featureSet(&[_]Feature{ + .clrbhb, + .has_v8_8a, + }), + }; + result[@intFromEnum(Feature.has_v8m)] = .{ + .llvm_name = "v8m", + .description = "Support ARM v8M Baseline instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v6m, + }), + }; + result[@intFromEnum(Feature.has_v8m_main)] = .{ + .llvm_name = "v8m.main", + .description = "Support ARM v8M Mainline instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v7, + }), + }; + result[@intFromEnum(Feature.has_v9_1a)] = .{ + .llvm_name = "v9.1a", + .description = "Support ARM v9.1a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_6a, + .has_v9a, + }), + }; + result[@intFromEnum(Feature.has_v9_2a)] = .{ + .llvm_name = "v9.2a", + .description = "Support ARM v9.2a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_7a, + .has_v9_1a, + }), + }; + result[@intFromEnum(Feature.has_v9_3a)] = .{ + .llvm_name = "v9.3a", + .description = "Support ARM v9.3a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_8a, + .has_v9_2a, + }), + }; + result[@intFromEnum(Feature.has_v9_4a)] = .{ + .llvm_name = "v9.4a", + .description = "Support ARM v9.4a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_9a, + .has_v9_3a, + }), + }; + result[@intFromEnum(Feature.has_v9a)] = .{ + .llvm_name = "v9a", + .description = "Support ARM v9a instructions", + .dependencies = featureSet(&[_]Feature{ + .has_v8_5a, + }), + }; + result[@intFromEnum(Feature.hwdiv)] = .{ + .llvm_name = "hwdiv", + .description = "Enable divide instructions in Thumb", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hwdiv_arm)] = .{ + .llvm_name = "hwdiv-arm", + .description = "Enable divide instructions in ARM mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.i8mm)] = .{ + .llvm_name = "i8mm", + .description = "Enable Matrix Multiply Int8 Extension", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.iwmmxt)] = .{ + .llvm_name = "iwmmxt", + .description = "ARMv5te architecture", + .dependencies = featureSet(&[_]Feature{ + .v5te, + }), + }; + result[@intFromEnum(Feature.iwmmxt2)] = .{ + .llvm_name = "iwmmxt2", + .description = "ARMv5te architecture", + .dependencies = featureSet(&[_]Feature{ + .v5te, + }), + }; + result[@intFromEnum(Feature.lob)] = .{ + .llvm_name = "lob", + .description = "Enable Low Overhead Branch extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.long_calls)] = .{ + .llvm_name = "long-calls", + .description = "Generate calls via indirect call instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.loop_align)] = .{ + .llvm_name = "loop-align", + .description = "Prefer 32-bit alignment for loops", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.m3)] = .{ + .llvm_name = "m3", + .description = "Cortex-M3 ARM processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mclass)] = .{ + .llvm_name = "mclass", + .description = "Is microcontroller profile ('M' series)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mp)] = .{ + .llvm_name = "mp", + .description = "Supports Multiprocessing extension", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.muxed_units)] = .{ + .llvm_name = "muxed-units", + .description = "Has muxed AGU and NEON/FPU", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mve)] = .{ + .llvm_name = "mve", + .description = "Support M-Class Vector Extension with integer ops", + .dependencies = featureSet(&[_]Feature{ + .dsp, + .fpregs16, + .fpregs64, + .has_v8_1m_main, + }), + }; + result[@intFromEnum(Feature.mve1beat)] = .{ + .llvm_name = "mve1beat", + .description = "Model MVE instructions as a 1 beat per tick architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mve2beat)] = .{ + .llvm_name = "mve2beat", + .description = "Model MVE instructions as a 2 beats per tick architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mve4beat)] = .{ + .llvm_name = "mve4beat", + .description = "Model MVE instructions as a 4 beats per tick architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mve_fp)] = .{ + .llvm_name = "mve.fp", + .description = "Support M-Class Vector Extension with integer and floating ops", + .dependencies = featureSet(&[_]Feature{ + .fullfp16, + .mve, + }), + }; + result[@intFromEnum(Feature.nacl_trap)] = .{ + .llvm_name = "nacl-trap", + .description = "NaCl trap", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.neon)] = .{ + .llvm_name = "neon", + .description = "Enable NEON instructions", + .dependencies = featureSet(&[_]Feature{ + .vfp3, + }), + }; + result[@intFromEnum(Feature.neon_fpmovs)] = .{ + .llvm_name = "neon-fpmovs", + .description = "Convert VMOVSR, VMOVRS, VMOVS to NEON", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.neonfp)] = .{ + .llvm_name = "neonfp", + .description = "Use NEON for single precision FP", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_branch_predictor)] = .{ + .llvm_name = "no-branch-predictor", + .description = "Has no branch predictor", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_bti_at_return_twice)] = .{ + .llvm_name = "no-bti-at-return-twice", + .description = "Don't place a BTI instruction after a return-twice", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_movt)] = .{ + .llvm_name = "no-movt", + .description = "Don't use movt/movw pairs for 32-bit imms", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(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 = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.noarm)] = .{ + .llvm_name = "noarm", + .description = "Does not support ARM mode execution", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nonpipelined_vfp)] = .{ + .llvm_name = "nonpipelined-vfp", + .description = "VFP instructions are not pipelined", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pacbti)] = .{ + .llvm_name = "pacbti", + .description = "Enable Pointer Authentication and Branch Target Identification", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.perfmon)] = .{ + .llvm_name = "perfmon", + .description = "Enable support for Performance Monitor extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefer_ishst)] = .{ + .llvm_name = "prefer-ishst", + .description = "Prefer ISHST barriers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefer_vmovsr)] = .{ + .llvm_name = "prefer-vmovsr", + .description = "Prefer VMOVSR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prof_unpr)] = .{ + .llvm_name = "prof-unpr", + .description = "Is profitable to unpredicate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.r4)] = .{ + .llvm_name = "r4", + .description = "Cortex-R4 ARM processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ras)] = .{ + .llvm_name = "ras", + .description = "Enable Reliability, Availability and Serviceability extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rclass)] = .{ + .llvm_name = "rclass", + .description = "Is realtime profile ('R' series)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.read_tp_tpidrprw)] = .{ + .llvm_name = "read-tp-tpidrprw", + .description = "Reading thread pointer from TPIDRPRW register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.read_tp_tpidruro)] = .{ + .llvm_name = "read-tp-tpidruro", + .description = "Reading thread pointer from TPIDRURO register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.read_tp_tpidrurw)] = .{ + .llvm_name = "read-tp-tpidrurw", + .description = "Reading thread pointer from TPIDRURW register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_r9)] = .{ + .llvm_name = "reserve-r9", + .description = "Reserve R9, making it unavailable as GPR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ret_addr_stack)] = .{ + .llvm_name = "ret-addr-stack", + .description = "Has return address stack", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sb)] = .{ + .llvm_name = "sb", + .description = "Enable v8.5a Speculation Barrier", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sha2)] = .{ + .llvm_name = "sha2", + .description = "Enable SHA1 and SHA256 support", + .dependencies = featureSet(&[_]Feature{ + .neon, + }), + }; + result[@intFromEnum(Feature.slow_fp_brcc)] = .{ + .llvm_name = "slow-fp-brcc", + .description = "FP compare + branch is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_load_D_subreg)] = .{ + .llvm_name = "slow-load-D-subreg", + .description = "Loading into D subregs is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_odd_reg)] = .{ + .llvm_name = "slow-odd-reg", + .description = "VLDM/VSTM starting with an odd register is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_vdup32)] = .{ + .llvm_name = "slow-vdup32", + .description = "Has slow VDUP32 - prefer VMOV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_vgetlni32)] = .{ + .llvm_name = "slow-vgetlni32", + .description = "Has slow VGETLNi32 - prefer VMOV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slowfpvfmx)] = .{ + .llvm_name = "slowfpvfmx", + .description = "Disable VFP / NEON FMA instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slowfpvmlx)] = .{ + .llvm_name = "slowfpvmlx", + .description = "Disable VFP / NEON MAC instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.soft_float)] = .{ + .llvm_name = "soft-float", + .description = "Use software floating point features.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.splat_vfp_neon)] = .{ + .llvm_name = "splat-vfp-neon", + .description = "Splat register from VFP to NEON", + .dependencies = featureSet(&[_]Feature{ + .dont_widen_vmovs, + }), + }; + result[@intFromEnum(Feature.strict_align)] = .{ + .llvm_name = "strict-align", + .description = "Disallow all unaligned memory access", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.swift)] = .{ + .llvm_name = "swift", + .description = "Swift ARM processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.thumb2)] = .{ + .llvm_name = "thumb2", + .description = "Enable Thumb2 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.thumb_mode)] = .{ + .llvm_name = "thumb-mode", + .description = "Thumb mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.trustzone)] = .{ + .llvm_name = "trustzone", + .description = "Enable support for TrustZone security extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_mipipeliner)] = .{ + .llvm_name = "use-mipipeliner", + .description = "Use the MachinePipeliner", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_misched)] = .{ + .llvm_name = "use-misched", + .description = "Use the MachineScheduler", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v2)] = .{ + .llvm_name = null, + .description = "ARMv2 architecture", + .dependencies = featureSet(&[_]Feature{ + .strict_align, + }), + }; + result[@intFromEnum(Feature.v2a)] = .{ + .llvm_name = null, + .description = "ARMv2a architecture", + .dependencies = featureSet(&[_]Feature{ + .strict_align, + }), + }; + result[@intFromEnum(Feature.v3)] = .{ + .llvm_name = null, + .description = "ARMv3 architecture", + .dependencies = featureSet(&[_]Feature{ + .strict_align, + }), + }; + result[@intFromEnum(Feature.v3m)] = .{ + .llvm_name = null, + .description = "ARMv3m architecture", + .dependencies = featureSet(&[_]Feature{ + .strict_align, + }), + }; + result[@intFromEnum(Feature.v4)] = .{ + .llvm_name = "armv4", + .description = "ARMv4 architecture", + .dependencies = featureSet(&[_]Feature{ + .strict_align, + }), + }; + result[@intFromEnum(Feature.v4t)] = .{ + .llvm_name = "armv4t", + .description = "ARMv4t architecture", + .dependencies = featureSet(&[_]Feature{ + .has_v4t, + .strict_align, + }), + }; + result[@intFromEnum(Feature.v5t)] = .{ + .llvm_name = "armv5t", + .description = "ARMv5t architecture", + .dependencies = featureSet(&[_]Feature{ + .has_v5t, + .strict_align, + }), + }; + result[@intFromEnum(Feature.v5te)] = .{ + .llvm_name = "armv5te", + .description = "ARMv5te architecture", + .dependencies = featureSet(&[_]Feature{ + .has_v5te, + .strict_align, + }), + }; + result[@intFromEnum(Feature.v5tej)] = .{ + .llvm_name = "armv5tej", + .description = "ARMv5tej architecture", + .dependencies = featureSet(&[_]Feature{ + .has_v5te, + .strict_align, + }), + }; + result[@intFromEnum(Feature.v6)] = .{ + .llvm_name = "armv6", + .description = "ARMv6 architecture", + .dependencies = featureSet(&[_]Feature{ + .dsp, + .has_v6, + }), + }; + result[@intFromEnum(Feature.v6j)] = .{ + .llvm_name = "armv6j", + .description = "ARMv7a architecture", + .dependencies = featureSet(&[_]Feature{ + .v6, + }), + }; + result[@intFromEnum(Feature.v6k)] = .{ + .llvm_name = "armv6k", + .description = "ARMv6k architecture", + .dependencies = featureSet(&[_]Feature{ + .has_v6k, + }), + }; + result[@intFromEnum(Feature.v6kz)] = .{ + .llvm_name = "armv6kz", + .description = "ARMv6kz architecture", + .dependencies = featureSet(&[_]Feature{ + .has_v6k, + .trustzone, + }), + }; + result[@intFromEnum(Feature.v6m)] = .{ + .llvm_name = "armv6-m", + .description = "ARMv6m architecture", + .dependencies = featureSet(&[_]Feature{ + .db, + .has_v6m, + .mclass, + .noarm, + .strict_align, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v6sm)] = .{ + .llvm_name = "armv6s-m", + .description = "ARMv6sm architecture", + .dependencies = featureSet(&[_]Feature{ + .db, + .has_v6m, + .mclass, + .noarm, + .strict_align, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v6t2)] = .{ + .llvm_name = "armv6t2", + .description = "ARMv6t2 architecture", + .dependencies = featureSet(&[_]Feature{ + .dsp, + .has_v6t2, + }), + }; + result[@intFromEnum(Feature.v7a)] = .{ + .llvm_name = "armv7-a", + .description = "ARMv7a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .db, + .dsp, + .has_v7, + .neon, + .perfmon, + }), + }; + result[@intFromEnum(Feature.v7em)] = .{ + .llvm_name = "armv7e-m", + .description = "ARMv7em architecture", + .dependencies = featureSet(&[_]Feature{ + .db, + .dsp, + .has_v7, + .hwdiv, + .mclass, + .noarm, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v7k)] = .{ + .llvm_name = "armv7k", + .description = "ARMv7a architecture", + .dependencies = featureSet(&[_]Feature{ + .v7a, + }), + }; + result[@intFromEnum(Feature.v7m)] = .{ + .llvm_name = "armv7-m", + .description = "ARMv7m architecture", + .dependencies = featureSet(&[_]Feature{ + .db, + .has_v7, + .hwdiv, + .mclass, + .noarm, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v7r)] = .{ + .llvm_name = "armv7-r", + .description = "ARMv7r architecture", + .dependencies = featureSet(&[_]Feature{ + .db, + .dsp, + .has_v7, + .hwdiv, + .perfmon, + .rclass, + }), + }; + result[@intFromEnum(Feature.v7s)] = .{ + .llvm_name = "armv7s", + .description = "ARMv7a architecture", + .dependencies = featureSet(&[_]Feature{ + .v7a, + }), + }; + result[@intFromEnum(Feature.v7ve)] = .{ + .llvm_name = "armv7ve", + .description = "ARMv7ve architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .db, + .dsp, + .has_v7, + .mp, + .neon, + .perfmon, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_1a)] = .{ + .llvm_name = "armv8.1-a", + .description = "ARMv81a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_1a, + .mp, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_1m_main)] = .{ + .llvm_name = "armv8.1-m.main", + .description = "ARMv81mMainline architecture", + .dependencies = featureSet(&[_]Feature{ + .@"8msecext", + .acquire_release, + .db, + .has_v8_1m_main, + .hwdiv, + .lob, + .mclass, + .noarm, + .ras, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v8_2a)] = .{ + .llvm_name = "armv8.2-a", + .description = "ARMv82a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_2a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_3a)] = .{ + .llvm_name = "armv8.3-a", + .description = "ARMv83a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_3a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_4a)] = .{ + .llvm_name = "armv8.4-a", + .description = "ARMv84a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_4a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_5a)] = .{ + .llvm_name = "armv8.5-a", + .description = "ARMv85a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_5a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_6a)] = .{ + .llvm_name = "armv8.6-a", + .description = "ARMv86a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_6a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_7a)] = .{ + .llvm_name = "armv8.7-a", + .description = "ARMv87a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_7a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_8a)] = .{ + .llvm_name = "armv8.8-a", + .description = "ARMv88a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_8a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8_9a)] = .{ + .llvm_name = "armv8.9-a", + .description = "ARMv89a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8_9a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8a)] = .{ + .llvm_name = "armv8-a", + .description = "ARMv8a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v8, + .mp, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v8m)] = .{ + .llvm_name = "armv8-m.base", + .description = "ARMv8mBaseline architecture", + .dependencies = featureSet(&[_]Feature{ + .@"8msecext", + .acquire_release, + .db, + .has_v7clrex, + .has_v8m, + .hwdiv, + .mclass, + .noarm, + .strict_align, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v8m_main)] = .{ + .llvm_name = "armv8-m.main", + .description = "ARMv8mMainline architecture", + .dependencies = featureSet(&[_]Feature{ + .@"8msecext", + .acquire_release, + .db, + .has_v8m_main, + .hwdiv, + .mclass, + .noarm, + .thumb_mode, + }), + }; + result[@intFromEnum(Feature.v8r)] = .{ + .llvm_name = "armv8-r", + .description = "ARMv8r architecture", + .dependencies = featureSet(&[_]Feature{ + .crc, + .db, + .dfb, + .dsp, + .fp_armv8, + .has_v8, + .mp, + .neon, + .rclass, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v9_1a)] = .{ + .llvm_name = "armv9.1-a", + .description = "ARMv91a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .db, + .dsp, + .fp_armv8, + .has_v9_1a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v9_2a)] = .{ + .llvm_name = "armv9.2-a", + .description = "ARMv92a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .db, + .dsp, + .fp_armv8, + .has_v9_2a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v9_3a)] = .{ + .llvm_name = "armv9.3-a", + .description = "ARMv93a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .crypto, + .db, + .dsp, + .fp_armv8, + .has_v9_3a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v9_4a)] = .{ + .llvm_name = "armv9.4-a", + .description = "ARMv94a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .db, + .dsp, + .fp_armv8, + .has_v9_4a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.v9a)] = .{ + .llvm_name = "armv9-a", + .description = "ARMv9a architecture", + .dependencies = featureSet(&[_]Feature{ + .aclass, + .crc, + .db, + .dsp, + .fp_armv8, + .has_v9a, + .mp, + .ras, + .trustzone, + .virtualization, + }), + }; + result[@intFromEnum(Feature.vfp2)] = .{ + .llvm_name = "vfp2", + .description = "Enable VFP2 instructions", + .dependencies = featureSet(&[_]Feature{ + .fp64, + .vfp2sp, + }), + }; + result[@intFromEnum(Feature.vfp2sp)] = .{ + .llvm_name = "vfp2sp", + .description = "Enable VFP2 instructions with no double precision", + .dependencies = featureSet(&[_]Feature{ + .fpregs, + }), + }; + result[@intFromEnum(Feature.vfp3)] = .{ + .llvm_name = "vfp3", + .description = "Enable VFP3 instructions", + .dependencies = featureSet(&[_]Feature{ + .vfp3d16, + .vfp3sp, + }), + }; + result[@intFromEnum(Feature.vfp3d16)] = .{ + .llvm_name = "vfp3d16", + .description = "Enable VFP3 instructions with only 16 d-registers", + .dependencies = featureSet(&[_]Feature{ + .vfp2, + .vfp3d16sp, + }), + }; + result[@intFromEnum(Feature.vfp3d16sp)] = .{ + .llvm_name = "vfp3d16sp", + .description = "Enable VFP3 instructions with only 16 d-registers and no double precision", + .dependencies = featureSet(&[_]Feature{ + .vfp2sp, + }), + }; + result[@intFromEnum(Feature.vfp3sp)] = .{ + .llvm_name = "vfp3sp", + .description = "Enable VFP3 instructions with no double precision", + .dependencies = featureSet(&[_]Feature{ + .d32, + .vfp3d16sp, + }), + }; + result[@intFromEnum(Feature.vfp4)] = .{ + .llvm_name = "vfp4", + .description = "Enable VFP4 instructions", + .dependencies = featureSet(&[_]Feature{ + .vfp3, + .vfp4d16, + .vfp4sp, + }), + }; + result[@intFromEnum(Feature.vfp4d16)] = .{ + .llvm_name = "vfp4d16", + .description = "Enable VFP4 instructions with only 16 d-registers", + .dependencies = featureSet(&[_]Feature{ + .vfp3d16, + .vfp4d16sp, + }), + }; + result[@intFromEnum(Feature.vfp4d16sp)] = .{ + .llvm_name = "vfp4d16sp", + .description = "Enable VFP4 instructions with only 16 d-registers and no double precision", + .dependencies = featureSet(&[_]Feature{ + .fp16, + .vfp3d16sp, + }), + }; + result[@intFromEnum(Feature.vfp4sp)] = .{ + .llvm_name = "vfp4sp", + .description = "Enable VFP4 instructions with no double precision", + .dependencies = featureSet(&[_]Feature{ + .vfp3sp, + .vfp4d16sp, + }), + }; + result[@intFromEnum(Feature.virtualization)] = .{ + .llvm_name = "virtualization", + .description = "Supports Virtualization extension", + .dependencies = featureSet(&[_]Feature{ + .hwdiv, + .hwdiv_arm, + }), + }; + result[@intFromEnum(Feature.vldn_align)] = .{ + .llvm_name = "vldn-align", + .description = "Check for VLDn unaligned access", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vmlx_forwarding)] = .{ + .llvm_name = "vmlx-forwarding", + .description = "Has multiplier accumulator forwarding", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vmlx_hazards)] = .{ + .llvm_name = "vmlx-hazards", + .description = "Has VMLx hazards", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.wide_stride_vfp)] = .{ + .llvm_name = "wide-stride-vfp", + .description = "Use a wide stride when allocating VFP registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xscale)] = .{ + .llvm_name = "xscale", + .description = "ARMv5te architecture", + .dependencies = featureSet(&[_]Feature{ + .v5te, + }), + }; + result[@intFromEnum(Feature.zcz)] = .{ + .llvm_name = "zcz", + .description = "Has zero-cycle zeroing instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const arm1020e = CpuModel{ + .name = "arm1020e", + .llvm_name = "arm1020e", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm1020t = CpuModel{ + .name = "arm1020t", + .llvm_name = "arm1020t", + .features = featureSet(&[_]Feature{ + .v5t, + }), + }; + pub const arm1022e = CpuModel{ + .name = "arm1022e", + .llvm_name = "arm1022e", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm10e = CpuModel{ + .name = "arm10e", + .llvm_name = "arm10e", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm10tdmi = CpuModel{ + .name = "arm10tdmi", + .llvm_name = "arm10tdmi", + .features = featureSet(&[_]Feature{ + .v5t, + }), + }; + pub const arm1136j_s = CpuModel{ + .name = "arm1136j_s", + .llvm_name = "arm1136j-s", + .features = featureSet(&[_]Feature{ + .v6, + }), + }; + pub const arm1136jf_s = CpuModel{ + .name = "arm1136jf_s", + .llvm_name = "arm1136jf-s", + .features = featureSet(&[_]Feature{ + .slowfpvmlx, + .v6, + .vfp2, + }), + }; + pub const arm1156t2_s = CpuModel{ + .name = "arm1156t2_s", + .llvm_name = "arm1156t2-s", + .features = featureSet(&[_]Feature{ + .v6t2, + }), + }; + pub const arm1156t2f_s = CpuModel{ + .name = "arm1156t2f_s", + .llvm_name = "arm1156t2f-s", + .features = featureSet(&[_]Feature{ + .slowfpvmlx, + .v6t2, + .vfp2, + }), + }; + pub const arm1176jz_s = CpuModel{ + .name = "arm1176jz_s", + .llvm_name = "arm1176jz-s", + .features = featureSet(&[_]Feature{ + .v6kz, + }), + }; + pub const arm1176jzf_s = CpuModel{ + .name = "arm1176jzf_s", + .llvm_name = "arm1176jzf-s", + .features = featureSet(&[_]Feature{ + .slowfpvmlx, + .v6kz, + .vfp2, + }), + }; + pub const arm710t = CpuModel{ + .name = "arm710t", + .llvm_name = "arm710t", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm720t = CpuModel{ + .name = "arm720t", + .llvm_name = "arm720t", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm7tdmi = CpuModel{ + .name = "arm7tdmi", + .llvm_name = "arm7tdmi", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm7tdmi_s = CpuModel{ + .name = "arm7tdmi_s", + .llvm_name = "arm7tdmi-s", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm8 = CpuModel{ + .name = "arm8", + .llvm_name = "arm8", + .features = featureSet(&[_]Feature{ + .v4, + }), + }; + pub const arm810 = CpuModel{ + .name = "arm810", + .llvm_name = "arm810", + .features = featureSet(&[_]Feature{ + .v4, + }), + }; + pub const arm9 = CpuModel{ + .name = "arm9", + .llvm_name = "arm9", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm920 = CpuModel{ + .name = "arm920", + .llvm_name = "arm920", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm920t = CpuModel{ + .name = "arm920t", + .llvm_name = "arm920t", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm922t = CpuModel{ + .name = "arm922t", + .llvm_name = "arm922t", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm926ej_s = CpuModel{ + .name = "arm926ej_s", + .llvm_name = "arm926ej-s", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm940t = CpuModel{ + .name = "arm940t", + .llvm_name = "arm940t", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const arm946e_s = CpuModel{ + .name = "arm946e_s", + .llvm_name = "arm946e-s", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm966e_s = CpuModel{ + .name = "arm966e_s", + .llvm_name = "arm966e-s", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm968e_s = CpuModel{ + .name = "arm968e_s", + .llvm_name = "arm968e-s", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm9e = CpuModel{ + .name = "arm9e", + .llvm_name = "arm9e", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const arm9tdmi = CpuModel{ + .name = "arm9tdmi", + .llvm_name = "arm9tdmi", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const baseline = CpuModel{ + .name = "baseline", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .v7a, + }), + }; + pub const cortex_a12 = CpuModel{ + .name = "cortex_a12", + .llvm_name = "cortex-a12", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .mp, + .ret_addr_stack, + .trustzone, + .v7a, + .vfp4, + .virtualization, + .vmlx_forwarding, + }), + }; + pub const cortex_a15 = CpuModel{ + .name = "cortex_a15", + .llvm_name = "cortex-a15", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .mp, + .muxed_units, + .ret_addr_stack, + .splat_vfp_neon, + .trustzone, + .v7a, + .vfp4, + .virtualization, + .vldn_align, + }), + }; + pub const cortex_a17 = CpuModel{ + .name = "cortex_a17", + .llvm_name = "cortex-a17", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .mp, + .ret_addr_stack, + .trustzone, + .v7a, + .vfp4, + .virtualization, + .vmlx_forwarding, + }), + }; + pub const cortex_a32 = CpuModel{ + .name = "cortex_a32", + .llvm_name = "cortex-a32", + .features = featureSet(&[_]Feature{ + .v8a, + }), + }; + pub const cortex_a35 = CpuModel{ + .name = "cortex_a35", + .llvm_name = "cortex-a35", + .features = featureSet(&[_]Feature{ + .v8a, + }), + }; + pub const cortex_a5 = CpuModel{ + .name = "cortex_a5", + .llvm_name = "cortex-a5", + .features = featureSet(&[_]Feature{ + .mp, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .trustzone, + .v7a, + .vfp4, + .vmlx_forwarding, + }), + }; + pub const cortex_a53 = CpuModel{ + .name = "cortex_a53", + .llvm_name = "cortex-a53", + .features = featureSet(&[_]Feature{ + .fpao, + .v8a, + }), + }; + pub const cortex_a55 = CpuModel{ + .name = "cortex_a55", + .llvm_name = "cortex-a55", + .features = featureSet(&[_]Feature{ + .dotprod, + .v8_2a, + }), + }; + pub const cortex_a57 = CpuModel{ + .name = "cortex_a57", + .llvm_name = "cortex-a57", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .cheap_predicable_cpsr, + .fix_cortex_a57_aes_1742098, + .fpao, + .v8a, + }), + }; + pub const cortex_a7 = CpuModel{ + .name = "cortex_a7", + .llvm_name = "cortex-a7", + .features = featureSet(&[_]Feature{ + .mp, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .trustzone, + .v7a, + .vfp4, + .virtualization, + .vmlx_forwarding, + .vmlx_hazards, + }), + }; + pub const cortex_a710 = CpuModel{ + .name = "cortex_a710", + .llvm_name = "cortex-a710", + .features = featureSet(&[_]Feature{ + .bf16, + .fp16fml, + .i8mm, + .v9a, + }), + }; + pub const cortex_a72 = CpuModel{ + .name = "cortex_a72", + .llvm_name = "cortex-a72", + .features = featureSet(&[_]Feature{ + .fix_cortex_a57_aes_1742098, + .v8a, + }), + }; + pub const cortex_a73 = CpuModel{ + .name = "cortex_a73", + .llvm_name = "cortex-a73", + .features = featureSet(&[_]Feature{ + .v8a, + }), + }; + pub const cortex_a75 = CpuModel{ + .name = "cortex_a75", + .llvm_name = "cortex-a75", + .features = featureSet(&[_]Feature{ + .dotprod, + .v8_2a, + }), + }; + pub const cortex_a76 = CpuModel{ + .name = "cortex_a76", + .llvm_name = "cortex-a76", + .features = featureSet(&[_]Feature{ + .a76, + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_a76ae = CpuModel{ + .name = "cortex_a76ae", + .llvm_name = "cortex-a76ae", + .features = featureSet(&[_]Feature{ + .a76, + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_a77 = CpuModel{ + .name = "cortex_a77", + .llvm_name = "cortex-a77", + .features = featureSet(&[_]Feature{ + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_a78 = CpuModel{ + .name = "cortex_a78", + .llvm_name = "cortex-a78", + .features = featureSet(&[_]Feature{ + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_a78c = CpuModel{ + .name = "cortex_a78c", + .llvm_name = "cortex-a78c", + .features = featureSet(&[_]Feature{ + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_a8 = CpuModel{ + .name = "cortex_a8", + .llvm_name = "cortex-a8", + .features = featureSet(&[_]Feature{ + .nonpipelined_vfp, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .trustzone, + .v7a, + .vmlx_forwarding, + .vmlx_hazards, + }), + }; + pub const cortex_a9 = CpuModel{ + .name = "cortex_a9", + .llvm_name = "cortex-a9", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .expand_fp_mlx, + .fp16, + .mp, + .muxed_units, + .neon_fpmovs, + .prefer_vmovsr, + .ret_addr_stack, + .trustzone, + .v7a, + .vldn_align, + .vmlx_forwarding, + .vmlx_hazards, + }), + }; + pub const cortex_m0 = CpuModel{ + .name = "cortex_m0", + .llvm_name = "cortex-m0", + .features = featureSet(&[_]Feature{ + .no_branch_predictor, + .v6m, + }), + }; + pub const cortex_m0plus = CpuModel{ + .name = "cortex_m0plus", + .llvm_name = "cortex-m0plus", + .features = featureSet(&[_]Feature{ + .no_branch_predictor, + .v6m, + }), + }; + pub const cortex_m1 = CpuModel{ + .name = "cortex_m1", + .llvm_name = "cortex-m1", + .features = featureSet(&[_]Feature{ + .no_branch_predictor, + .v6m, + }), + }; + pub const cortex_m23 = CpuModel{ + .name = "cortex_m23", + .llvm_name = "cortex-m23", + .features = featureSet(&[_]Feature{ + .no_branch_predictor, + .no_movt, + .v8m, + }), + }; + pub const cortex_m3 = CpuModel{ + .name = "cortex_m3", + .llvm_name = "cortex-m3", + .features = featureSet(&[_]Feature{ + .loop_align, + .m3, + .no_branch_predictor, + .use_misched, + .v7m, + }), + }; + pub const cortex_m33 = CpuModel{ + .name = "cortex_m33", + .llvm_name = "cortex-m33", + .features = featureSet(&[_]Feature{ + .dsp, + .fix_cmse_cve_2021_35465, + .fp_armv8d16sp, + .loop_align, + .no_branch_predictor, + .slowfpvfmx, + .slowfpvmlx, + .use_misched, + .v8m_main, + }), + }; + pub const cortex_m35p = CpuModel{ + .name = "cortex_m35p", + .llvm_name = "cortex-m35p", + .features = featureSet(&[_]Feature{ + .dsp, + .fix_cmse_cve_2021_35465, + .fp_armv8d16sp, + .loop_align, + .no_branch_predictor, + .slowfpvfmx, + .slowfpvmlx, + .use_misched, + .v8m_main, + }), + }; + pub const cortex_m4 = CpuModel{ + .name = "cortex_m4", + .llvm_name = "cortex-m4", + .features = featureSet(&[_]Feature{ + .loop_align, + .no_branch_predictor, + .slowfpvfmx, + .slowfpvmlx, + .use_misched, + .v7em, + .vfp4d16sp, + }), + }; + pub const cortex_m55 = CpuModel{ + .name = "cortex_m55", + .llvm_name = "cortex-m55", + .features = featureSet(&[_]Feature{ + .fix_cmse_cve_2021_35465, + .fp_armv8d16, + .loop_align, + .mve_fp, + .no_branch_predictor, + .slowfpvmlx, + .use_misched, + .v8_1m_main, + }), + }; + pub const cortex_m7 = CpuModel{ + .name = "cortex_m7", + .llvm_name = "cortex-m7", + .features = featureSet(&[_]Feature{ + .fp_armv8d16, + .use_mipipeliner, + .use_misched, + .v7em, + }), + }; + pub const cortex_m85 = CpuModel{ + .name = "cortex_m85", + .llvm_name = "cortex-m85", + .features = featureSet(&[_]Feature{ + .fp_armv8d16, + .mve_fp, + .pacbti, + .use_misched, + .v8_1m_main, + }), + }; + pub const cortex_r4 = CpuModel{ + .name = "cortex_r4", + .llvm_name = "cortex-r4", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .r4, + .ret_addr_stack, + .v7r, + }), + }; + pub const cortex_r4f = CpuModel{ + .name = "cortex_r4f", + .llvm_name = "cortex-r4f", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .r4, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .v7r, + .vfp3d16, + }), + }; + pub const cortex_r5 = CpuModel{ + .name = "cortex_r5", + .llvm_name = "cortex-r5", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .hwdiv_arm, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .v7r, + .vfp3d16, + }), + }; + pub const cortex_r52 = CpuModel{ + .name = "cortex_r52", + .llvm_name = "cortex-r52", + .features = featureSet(&[_]Feature{ + .fpao, + .use_misched, + .v8r, + }), + }; + pub const cortex_r7 = CpuModel{ + .name = "cortex_r7", + .llvm_name = "cortex-r7", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .fp16, + .hwdiv_arm, + .mp, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .v7r, + .vfp3d16, + }), + }; + pub const cortex_r8 = CpuModel{ + .name = "cortex_r8", + .llvm_name = "cortex-r8", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .fp16, + .hwdiv_arm, + .mp, + .ret_addr_stack, + .slow_fp_brcc, + .slowfpvfmx, + .slowfpvmlx, + .v7r, + .vfp3d16, + }), + }; + pub const cortex_x1 = CpuModel{ + .name = "cortex_x1", + .llvm_name = "cortex-x1", + .features = featureSet(&[_]Feature{ + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cortex_x1c = CpuModel{ + .name = "cortex_x1c", + .llvm_name = "cortex-x1c", + .features = featureSet(&[_]Feature{ + .dotprod, + .fullfp16, + .v8_2a, + }), + }; + pub const cyclone = CpuModel{ + .name = "cyclone", + .llvm_name = "cyclone", + .features = featureSet(&[_]Feature{ + .avoid_movs_shop, + .avoid_partial_cpsr, + .disable_postra_scheduler, + .neonfp, + .ret_addr_stack, + .slowfpvfmx, + .slowfpvmlx, + .swift, + .use_misched, + .v8a, + .zcz, + }), + }; + pub const ep9312 = CpuModel{ + .name = "ep9312", + .llvm_name = "ep9312", + .features = featureSet(&[_]Feature{ + .v4t, + }), + }; + pub const exynos_m1 = CpuModel{ + .name = "exynos_m1", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .exynos, + .v8a, + }), + }; + pub const exynos_m2 = CpuModel{ + .name = "exynos_m2", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .exynos, + .v8a, + }), + }; + pub const exynos_m3 = CpuModel{ + .name = "exynos_m3", + .llvm_name = "exynos-m3", + .features = featureSet(&[_]Feature{ + .exynos, + .v8a, + }), + }; + pub const exynos_m4 = CpuModel{ + .name = "exynos_m4", + .llvm_name = "exynos-m4", + .features = featureSet(&[_]Feature{ + .dotprod, + .exynos, + .fullfp16, + .v8_2a, + }), + }; + pub const exynos_m5 = CpuModel{ + .name = "exynos_m5", + .llvm_name = "exynos-m5", + .features = featureSet(&[_]Feature{ + .dotprod, + .exynos, + .fullfp16, + .v8_2a, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const iwmmxt = CpuModel{ + .name = "iwmmxt", + .llvm_name = "iwmmxt", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; + pub const krait = CpuModel{ + .name = "krait", + .llvm_name = "krait", + .features = featureSet(&[_]Feature{ + .avoid_partial_cpsr, + .hwdiv, + .hwdiv_arm, + .muxed_units, + .ret_addr_stack, + .v7a, + .vfp4, + .vldn_align, + .vmlx_forwarding, + }), + }; + pub const kryo = CpuModel{ + .name = "kryo", + .llvm_name = "kryo", + .features = featureSet(&[_]Feature{ + .v8a, + }), + }; + pub const mpcore = CpuModel{ + .name = "mpcore", + .llvm_name = "mpcore", + .features = featureSet(&[_]Feature{ + .slowfpvmlx, + .v6k, + .vfp2, + }), + }; + pub const mpcorenovfp = CpuModel{ + .name = "mpcorenovfp", + .llvm_name = "mpcorenovfp", + .features = featureSet(&[_]Feature{ + .v6k, + }), + }; + pub const neoverse_n1 = CpuModel{ + .name = "neoverse_n1", + .llvm_name = "neoverse-n1", + .features = featureSet(&[_]Feature{ + .dotprod, + .v8_2a, + }), + }; + pub const neoverse_n2 = CpuModel{ + .name = "neoverse_n2", + .llvm_name = "neoverse-n2", + .features = featureSet(&[_]Feature{ + .bf16, + .i8mm, + .v8_5a, + }), + }; + pub const neoverse_v1 = CpuModel{ + .name = "neoverse_v1", + .llvm_name = "neoverse-v1", + .features = featureSet(&[_]Feature{ + .bf16, + .fullfp16, + .i8mm, + .v8_4a, + }), + }; + pub const sc000 = CpuModel{ + .name = "sc000", + .llvm_name = "sc000", + .features = featureSet(&[_]Feature{ + .no_branch_predictor, + .v6m, + }), + }; + pub const sc300 = CpuModel{ + .name = "sc300", + .llvm_name = "sc300", + .features = featureSet(&[_]Feature{ + .m3, + .no_branch_predictor, + .use_misched, + .v7m, + }), + }; + pub const strongarm = CpuModel{ + .name = "strongarm", + .llvm_name = "strongarm", + .features = featureSet(&[_]Feature{ + .v4, + }), + }; + pub const strongarm110 = CpuModel{ + .name = "strongarm110", + .llvm_name = "strongarm110", + .features = featureSet(&[_]Feature{ + .v4, + }), + }; + pub const strongarm1100 = CpuModel{ + .name = "strongarm1100", + .llvm_name = "strongarm1100", + .features = featureSet(&[_]Feature{ + .v4, + }), + }; + pub const strongarm1110 = CpuModel{ + .name = "strongarm1110", + .llvm_name = "strongarm1110", + .features = featureSet(&[_]Feature{ + .v4, + }), + }; + pub const swift = CpuModel{ + .name = "swift", + .llvm_name = "swift", + .features = featureSet(&[_]Feature{ + .avoid_movs_shop, + .avoid_partial_cpsr, + .disable_postra_scheduler, + .hwdiv, + .hwdiv_arm, + .mp, + .neonfp, + .prefer_ishst, + .prof_unpr, + .ret_addr_stack, + .slow_load_D_subreg, + .slow_odd_reg, + .slow_vdup32, + .slow_vgetlni32, + .slowfpvfmx, + .slowfpvmlx, + .swift, + .use_misched, + .v7a, + .vfp4, + .vmlx_hazards, + .wide_stride_vfp, + }), + }; + pub const xscale = CpuModel{ + .name = "xscale", + .llvm_name = "xscale", + .features = featureSet(&[_]Feature{ + .v5te, + }), + }; +}; diff --git a/lib/std/Target/avr.zig b/lib/std/Target/avr.zig new file mode 100644 index 0000000000..bda274d2e6 --- /dev/null +++ b/lib/std/Target/avr.zig @@ -0,0 +1,2607 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + addsubiw, + avr0, + avr1, + avr2, + avr25, + avr3, + avr31, + avr35, + avr4, + avr5, + avr51, + avr6, + avrtiny, + @"break", + des, + eijmpcall, + elpm, + elpmx, + ijmpcall, + jmpcall, + lowbytefirst, + lpm, + lpmx, + memmappedregs, + movw, + mul, + rmw, + smallstack, + special, + spm, + spmx, + sram, + tinyencoding, + xmega, + xmega3, + xmegau, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.addsubiw)] = .{ + .llvm_name = "addsubiw", + .description = "Enable 16-bit register-immediate addition and subtraction instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.avr0)] = .{ + .llvm_name = "avr0", + .description = "The device is a part of the avr0 family", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.avr1)] = .{ + .llvm_name = "avr1", + .description = "The device is a part of the avr1 family", + .dependencies = featureSet(&[_]Feature{ + .avr0, + .lpm, + .memmappedregs, + }), + }; + result[@intFromEnum(Feature.avr2)] = .{ + .llvm_name = "avr2", + .description = "The device is a part of the avr2 family", + .dependencies = featureSet(&[_]Feature{ + .addsubiw, + .avr1, + .ijmpcall, + .sram, + }), + }; + result[@intFromEnum(Feature.avr25)] = .{ + .llvm_name = "avr25", + .description = "The device is a part of the avr25 family", + .dependencies = featureSet(&[_]Feature{ + .avr2, + .@"break", + .lpmx, + .movw, + .spm, + }), + }; + result[@intFromEnum(Feature.avr3)] = .{ + .llvm_name = "avr3", + .description = "The device is a part of the avr3 family", + .dependencies = featureSet(&[_]Feature{ + .avr2, + .jmpcall, + }), + }; + result[@intFromEnum(Feature.avr31)] = .{ + .llvm_name = "avr31", + .description = "The device is a part of the avr31 family", + .dependencies = featureSet(&[_]Feature{ + .avr3, + .elpm, + }), + }; + result[@intFromEnum(Feature.avr35)] = .{ + .llvm_name = "avr35", + .description = "The device is a part of the avr35 family", + .dependencies = featureSet(&[_]Feature{ + .avr3, + .@"break", + .lpmx, + .movw, + .spm, + }), + }; + result[@intFromEnum(Feature.avr4)] = .{ + .llvm_name = "avr4", + .description = "The device is a part of the avr4 family", + .dependencies = featureSet(&[_]Feature{ + .avr2, + .@"break", + .lpmx, + .movw, + .mul, + .spm, + }), + }; + result[@intFromEnum(Feature.avr5)] = .{ + .llvm_name = "avr5", + .description = "The device is a part of the avr5 family", + .dependencies = featureSet(&[_]Feature{ + .avr3, + .@"break", + .lpmx, + .movw, + .mul, + .spm, + }), + }; + result[@intFromEnum(Feature.avr51)] = .{ + .llvm_name = "avr51", + .description = "The device is a part of the avr51 family", + .dependencies = featureSet(&[_]Feature{ + .avr5, + .elpm, + .elpmx, + }), + }; + result[@intFromEnum(Feature.avr6)] = .{ + .llvm_name = "avr6", + .description = "The device is a part of the avr6 family", + .dependencies = featureSet(&[_]Feature{ + .avr51, + .eijmpcall, + }), + }; + result[@intFromEnum(Feature.avrtiny)] = .{ + .llvm_name = "avrtiny", + .description = "The device is a part of the avrtiny family", + .dependencies = featureSet(&[_]Feature{ + .avr0, + .@"break", + .smallstack, + .sram, + .tinyencoding, + }), + }; + result[@intFromEnum(Feature.@"break")] = .{ + .llvm_name = "break", + .description = "The device supports the `BREAK` debugging instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.des)] = .{ + .llvm_name = "des", + .description = "The device supports the `DES k` encryption instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.eijmpcall)] = .{ + .llvm_name = "eijmpcall", + .description = "The device supports the `EIJMP`/`EICALL` instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.elpm)] = .{ + .llvm_name = "elpm", + .description = "The device supports the ELPM instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.elpmx)] = .{ + .llvm_name = "elpmx", + .description = "The device supports the `ELPM Rd, Z[+]` instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ijmpcall)] = .{ + .llvm_name = "ijmpcall", + .description = "The device supports `IJMP`/`ICALL`instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.jmpcall)] = .{ + .llvm_name = "jmpcall", + .description = "The device supports the `JMP` and `CALL` instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lowbytefirst)] = .{ + .llvm_name = "lowbytefirst", + .description = "Do the low byte first when writing a 16-bit port or storing a 16-bit word", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lpm)] = .{ + .llvm_name = "lpm", + .description = "The device supports the `LPM` instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lpmx)] = .{ + .llvm_name = "lpmx", + .description = "The device supports the `LPM Rd, Z[+]` instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.memmappedregs)] = .{ + .llvm_name = "memmappedregs", + .description = "The device has CPU registers mapped in data address space", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.movw)] = .{ + .llvm_name = "movw", + .description = "The device supports the 16-bit MOVW instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mul)] = .{ + .llvm_name = "mul", + .description = "The device supports the multiplication instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rmw)] = .{ + .llvm_name = "rmw", + .description = "The device supports the read-write-modify instructions: XCH, LAS, LAC, LAT", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.smallstack)] = .{ + .llvm_name = "smallstack", + .description = "The device has an 8-bit stack pointer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.special)] = .{ + .llvm_name = "special", + .description = "Enable use of the entire instruction set - used for debugging", + .dependencies = featureSet(&[_]Feature{ + .addsubiw, + .@"break", + .des, + .eijmpcall, + .elpm, + .elpmx, + .ijmpcall, + .jmpcall, + .lpm, + .lpmx, + .memmappedregs, + .movw, + .mul, + .rmw, + .spm, + .spmx, + .sram, + }), + }; + result[@intFromEnum(Feature.spm)] = .{ + .llvm_name = "spm", + .description = "The device supports the `SPM` instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.spmx)] = .{ + .llvm_name = "spmx", + .description = "The device supports the `SPM Z+` instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sram)] = .{ + .llvm_name = "sram", + .description = "The device has random access memory", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tinyencoding)] = .{ + .llvm_name = "tinyencoding", + .description = "The device has Tiny core specific instruction encodings", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xmega)] = .{ + .llvm_name = "xmega", + .description = "The device is a part of the xmega family", + .dependencies = featureSet(&[_]Feature{ + .addsubiw, + .avr0, + .@"break", + .des, + .eijmpcall, + .elpm, + .elpmx, + .ijmpcall, + .jmpcall, + .lowbytefirst, + .lpm, + .lpmx, + .movw, + .mul, + .spm, + .spmx, + .sram, + }), + }; + result[@intFromEnum(Feature.xmega3)] = .{ + .llvm_name = "xmega3", + .description = "The device is a part of the xmega3 family", + .dependencies = featureSet(&[_]Feature{ + .addsubiw, + .avr0, + .@"break", + .ijmpcall, + .jmpcall, + .lowbytefirst, + .lpm, + .lpmx, + .movw, + .mul, + .sram, + }), + }; + result[@intFromEnum(Feature.xmegau)] = .{ + .llvm_name = "xmegau", + .description = "The device is a part of the xmegau family", + .dependencies = featureSet(&[_]Feature{ + .rmw, + .xmega, + }), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const at43usb320 = CpuModel{ + .name = "at43usb320", + .llvm_name = "at43usb320", + .features = featureSet(&[_]Feature{ + .avr31, + }), + }; + pub const at43usb355 = CpuModel{ + .name = "at43usb355", + .llvm_name = "at43usb355", + .features = featureSet(&[_]Feature{ + .avr3, + }), + }; + pub const at76c711 = CpuModel{ + .name = "at76c711", + .llvm_name = "at76c711", + .features = featureSet(&[_]Feature{ + .avr3, + }), + }; + pub const at86rf401 = CpuModel{ + .name = "at86rf401", + .llvm_name = "at86rf401", + .features = featureSet(&[_]Feature{ + .avr2, + .lpmx, + .movw, + }), + }; + pub const at90c8534 = CpuModel{ + .name = "at90c8534", + .llvm_name = "at90c8534", + .features = featureSet(&[_]Feature{ + .avr2, + }), + }; + pub const at90can128 = CpuModel{ + .name = "at90can128", + .llvm_name = "at90can128", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const at90can32 = CpuModel{ + .name = "at90can32", + .llvm_name = "at90can32", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90can64 = CpuModel{ + .name = "at90can64", + .llvm_name = "at90can64", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90pwm1 = CpuModel{ + .name = "at90pwm1", + .llvm_name = "at90pwm1", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const at90pwm161 = CpuModel{ + .name = "at90pwm161", + .llvm_name = "at90pwm161", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90pwm2 = CpuModel{ + .name = "at90pwm2", + .llvm_name = "at90pwm2", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const at90pwm216 = CpuModel{ + .name = "at90pwm216", + .llvm_name = "at90pwm216", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90pwm2b = CpuModel{ + .name = "at90pwm2b", + .llvm_name = "at90pwm2b", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const at90pwm3 = CpuModel{ + .name = "at90pwm3", + .llvm_name = "at90pwm3", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const at90pwm316 = CpuModel{ + .name = "at90pwm316", + .llvm_name = "at90pwm316", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90pwm3b = CpuModel{ + .name = "at90pwm3b", + .llvm_name = "at90pwm3b", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const at90pwm81 = CpuModel{ + .name = "at90pwm81", + .llvm_name = "at90pwm81", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const at90s1200 = CpuModel{ + .name = "at90s1200", + .llvm_name = "at90s1200", + .features = featureSet(&[_]Feature{ + .avr0, + .smallstack, + }), + }; + pub const at90s2313 = CpuModel{ + .name = "at90s2313", + .llvm_name = "at90s2313", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s2323 = CpuModel{ + .name = "at90s2323", + .llvm_name = "at90s2323", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s2333 = CpuModel{ + .name = "at90s2333", + .llvm_name = "at90s2333", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s2343 = CpuModel{ + .name = "at90s2343", + .llvm_name = "at90s2343", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s4414 = CpuModel{ + .name = "at90s4414", + .llvm_name = "at90s4414", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s4433 = CpuModel{ + .name = "at90s4433", + .llvm_name = "at90s4433", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s4434 = CpuModel{ + .name = "at90s4434", + .llvm_name = "at90s4434", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const at90s8515 = CpuModel{ + .name = "at90s8515", + .llvm_name = "at90s8515", + .features = featureSet(&[_]Feature{ + .avr2, + }), + }; + pub const at90s8535 = CpuModel{ + .name = "at90s8535", + .llvm_name = "at90s8535", + .features = featureSet(&[_]Feature{ + .avr2, + }), + }; + pub const at90scr100 = CpuModel{ + .name = "at90scr100", + .llvm_name = "at90scr100", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90usb1286 = CpuModel{ + .name = "at90usb1286", + .llvm_name = "at90usb1286", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const at90usb1287 = CpuModel{ + .name = "at90usb1287", + .llvm_name = "at90usb1287", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const at90usb162 = CpuModel{ + .name = "at90usb162", + .llvm_name = "at90usb162", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const at90usb646 = CpuModel{ + .name = "at90usb646", + .llvm_name = "at90usb646", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90usb647 = CpuModel{ + .name = "at90usb647", + .llvm_name = "at90usb647", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const at90usb82 = CpuModel{ + .name = "at90usb82", + .llvm_name = "at90usb82", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const at94k = CpuModel{ + .name = "at94k", + .llvm_name = "at94k", + .features = featureSet(&[_]Feature{ + .avr3, + .lpmx, + .movw, + .mul, + }), + }; + pub const ata5272 = CpuModel{ + .name = "ata5272", + .llvm_name = "ata5272", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const ata5505 = CpuModel{ + .name = "ata5505", + .llvm_name = "ata5505", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const ata5702m322 = CpuModel{ + .name = "ata5702m322", + .llvm_name = "ata5702m322", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata5782 = CpuModel{ + .name = "ata5782", + .llvm_name = "ata5782", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata5790 = CpuModel{ + .name = "ata5790", + .llvm_name = "ata5790", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata5790n = CpuModel{ + .name = "ata5790n", + .llvm_name = "ata5790n", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata5791 = CpuModel{ + .name = "ata5791", + .llvm_name = "ata5791", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata5795 = CpuModel{ + .name = "ata5795", + .llvm_name = "ata5795", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata5831 = CpuModel{ + .name = "ata5831", + .llvm_name = "ata5831", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata6285 = CpuModel{ + .name = "ata6285", + .llvm_name = "ata6285", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const ata6286 = CpuModel{ + .name = "ata6286", + .llvm_name = "ata6286", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const ata6289 = CpuModel{ + .name = "ata6289", + .llvm_name = "ata6289", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const ata6612c = CpuModel{ + .name = "ata6612c", + .llvm_name = "ata6612c", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const ata6613c = CpuModel{ + .name = "ata6613c", + .llvm_name = "ata6613c", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata6614q = CpuModel{ + .name = "ata6614q", + .llvm_name = "ata6614q", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata6616c = CpuModel{ + .name = "ata6616c", + .llvm_name = "ata6616c", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const ata6617c = CpuModel{ + .name = "ata6617c", + .llvm_name = "ata6617c", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const ata664251 = CpuModel{ + .name = "ata664251", + .llvm_name = "ata664251", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const ata8210 = CpuModel{ + .name = "ata8210", + .llvm_name = "ata8210", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const ata8510 = CpuModel{ + .name = "ata8510", + .llvm_name = "ata8510", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega103 = CpuModel{ + .name = "atmega103", + .llvm_name = "atmega103", + .features = featureSet(&[_]Feature{ + .avr31, + }), + }; + pub const atmega128 = CpuModel{ + .name = "atmega128", + .llvm_name = "atmega128", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega1280 = CpuModel{ + .name = "atmega1280", + .llvm_name = "atmega1280", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega1281 = CpuModel{ + .name = "atmega1281", + .llvm_name = "atmega1281", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega1284 = CpuModel{ + .name = "atmega1284", + .llvm_name = "atmega1284", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega1284p = CpuModel{ + .name = "atmega1284p", + .llvm_name = "atmega1284p", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega1284rfr2 = CpuModel{ + .name = "atmega1284rfr2", + .llvm_name = "atmega1284rfr2", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega128a = CpuModel{ + .name = "atmega128a", + .llvm_name = "atmega128a", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega128rfa1 = CpuModel{ + .name = "atmega128rfa1", + .llvm_name = "atmega128rfa1", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega128rfr2 = CpuModel{ + .name = "atmega128rfr2", + .llvm_name = "atmega128rfr2", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const atmega16 = CpuModel{ + .name = "atmega16", + .llvm_name = "atmega16", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega1608 = CpuModel{ + .name = "atmega1608", + .llvm_name = "atmega1608", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega1609 = CpuModel{ + .name = "atmega1609", + .llvm_name = "atmega1609", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega161 = CpuModel{ + .name = "atmega161", + .llvm_name = "atmega161", + .features = featureSet(&[_]Feature{ + .avr3, + .lpmx, + .movw, + .mul, + .spm, + }), + }; + pub const atmega162 = CpuModel{ + .name = "atmega162", + .llvm_name = "atmega162", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega163 = CpuModel{ + .name = "atmega163", + .llvm_name = "atmega163", + .features = featureSet(&[_]Feature{ + .avr3, + .lpmx, + .movw, + .mul, + .spm, + }), + }; + pub const atmega164a = CpuModel{ + .name = "atmega164a", + .llvm_name = "atmega164a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega164p = CpuModel{ + .name = "atmega164p", + .llvm_name = "atmega164p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega164pa = CpuModel{ + .name = "atmega164pa", + .llvm_name = "atmega164pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega165 = CpuModel{ + .name = "atmega165", + .llvm_name = "atmega165", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega165a = CpuModel{ + .name = "atmega165a", + .llvm_name = "atmega165a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega165p = CpuModel{ + .name = "atmega165p", + .llvm_name = "atmega165p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega165pa = CpuModel{ + .name = "atmega165pa", + .llvm_name = "atmega165pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega168 = CpuModel{ + .name = "atmega168", + .llvm_name = "atmega168", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega168a = CpuModel{ + .name = "atmega168a", + .llvm_name = "atmega168a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega168p = CpuModel{ + .name = "atmega168p", + .llvm_name = "atmega168p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega168pa = CpuModel{ + .name = "atmega168pa", + .llvm_name = "atmega168pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega168pb = CpuModel{ + .name = "atmega168pb", + .llvm_name = "atmega168pb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega169 = CpuModel{ + .name = "atmega169", + .llvm_name = "atmega169", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega169a = CpuModel{ + .name = "atmega169a", + .llvm_name = "atmega169a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega169p = CpuModel{ + .name = "atmega169p", + .llvm_name = "atmega169p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega169pa = CpuModel{ + .name = "atmega169pa", + .llvm_name = "atmega169pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16a = CpuModel{ + .name = "atmega16a", + .llvm_name = "atmega16a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16hva = CpuModel{ + .name = "atmega16hva", + .llvm_name = "atmega16hva", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16hva2 = CpuModel{ + .name = "atmega16hva2", + .llvm_name = "atmega16hva2", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16hvb = CpuModel{ + .name = "atmega16hvb", + .llvm_name = "atmega16hvb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16hvbrevb = CpuModel{ + .name = "atmega16hvbrevb", + .llvm_name = "atmega16hvbrevb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16m1 = CpuModel{ + .name = "atmega16m1", + .llvm_name = "atmega16m1", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega16u2 = CpuModel{ + .name = "atmega16u2", + .llvm_name = "atmega16u2", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const atmega16u4 = CpuModel{ + .name = "atmega16u4", + .llvm_name = "atmega16u4", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega2560 = CpuModel{ + .name = "atmega2560", + .llvm_name = "atmega2560", + .features = featureSet(&[_]Feature{ + .avr6, + }), + }; + pub const atmega2561 = CpuModel{ + .name = "atmega2561", + .llvm_name = "atmega2561", + .features = featureSet(&[_]Feature{ + .avr6, + }), + }; + pub const atmega2564rfr2 = CpuModel{ + .name = "atmega2564rfr2", + .llvm_name = "atmega2564rfr2", + .features = featureSet(&[_]Feature{ + .avr6, + }), + }; + pub const atmega256rfr2 = CpuModel{ + .name = "atmega256rfr2", + .llvm_name = "atmega256rfr2", + .features = featureSet(&[_]Feature{ + .avr6, + }), + }; + pub const atmega32 = CpuModel{ + .name = "atmega32", + .llvm_name = "atmega32", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3208 = CpuModel{ + .name = "atmega3208", + .llvm_name = "atmega3208", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega3209 = CpuModel{ + .name = "atmega3209", + .llvm_name = "atmega3209", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega323 = CpuModel{ + .name = "atmega323", + .llvm_name = "atmega323", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega324a = CpuModel{ + .name = "atmega324a", + .llvm_name = "atmega324a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega324p = CpuModel{ + .name = "atmega324p", + .llvm_name = "atmega324p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega324pa = CpuModel{ + .name = "atmega324pa", + .llvm_name = "atmega324pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega324pb = CpuModel{ + .name = "atmega324pb", + .llvm_name = "atmega324pb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega325 = CpuModel{ + .name = "atmega325", + .llvm_name = "atmega325", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3250 = CpuModel{ + .name = "atmega3250", + .llvm_name = "atmega3250", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3250a = CpuModel{ + .name = "atmega3250a", + .llvm_name = "atmega3250a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3250p = CpuModel{ + .name = "atmega3250p", + .llvm_name = "atmega3250p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3250pa = CpuModel{ + .name = "atmega3250pa", + .llvm_name = "atmega3250pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega325a = CpuModel{ + .name = "atmega325a", + .llvm_name = "atmega325a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega325p = CpuModel{ + .name = "atmega325p", + .llvm_name = "atmega325p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega325pa = CpuModel{ + .name = "atmega325pa", + .llvm_name = "atmega325pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega328 = CpuModel{ + .name = "atmega328", + .llvm_name = "atmega328", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega328p = CpuModel{ + .name = "atmega328p", + .llvm_name = "atmega328p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega328pb = CpuModel{ + .name = "atmega328pb", + .llvm_name = "atmega328pb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega329 = CpuModel{ + .name = "atmega329", + .llvm_name = "atmega329", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3290 = CpuModel{ + .name = "atmega3290", + .llvm_name = "atmega3290", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3290a = CpuModel{ + .name = "atmega3290a", + .llvm_name = "atmega3290a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3290p = CpuModel{ + .name = "atmega3290p", + .llvm_name = "atmega3290p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega3290pa = CpuModel{ + .name = "atmega3290pa", + .llvm_name = "atmega3290pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega329a = CpuModel{ + .name = "atmega329a", + .llvm_name = "atmega329a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega329p = CpuModel{ + .name = "atmega329p", + .llvm_name = "atmega329p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega329pa = CpuModel{ + .name = "atmega329pa", + .llvm_name = "atmega329pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32a = CpuModel{ + .name = "atmega32a", + .llvm_name = "atmega32a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32c1 = CpuModel{ + .name = "atmega32c1", + .llvm_name = "atmega32c1", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32hvb = CpuModel{ + .name = "atmega32hvb", + .llvm_name = "atmega32hvb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32hvbrevb = CpuModel{ + .name = "atmega32hvbrevb", + .llvm_name = "atmega32hvbrevb", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32m1 = CpuModel{ + .name = "atmega32m1", + .llvm_name = "atmega32m1", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32u2 = CpuModel{ + .name = "atmega32u2", + .llvm_name = "atmega32u2", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const atmega32u4 = CpuModel{ + .name = "atmega32u4", + .llvm_name = "atmega32u4", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega32u6 = CpuModel{ + .name = "atmega32u6", + .llvm_name = "atmega32u6", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega406 = CpuModel{ + .name = "atmega406", + .llvm_name = "atmega406", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega48 = CpuModel{ + .name = "atmega48", + .llvm_name = "atmega48", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega4808 = CpuModel{ + .name = "atmega4808", + .llvm_name = "atmega4808", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega4809 = CpuModel{ + .name = "atmega4809", + .llvm_name = "atmega4809", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega48a = CpuModel{ + .name = "atmega48a", + .llvm_name = "atmega48a", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega48p = CpuModel{ + .name = "atmega48p", + .llvm_name = "atmega48p", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega48pa = CpuModel{ + .name = "atmega48pa", + .llvm_name = "atmega48pa", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega48pb = CpuModel{ + .name = "atmega48pb", + .llvm_name = "atmega48pb", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega64 = CpuModel{ + .name = "atmega64", + .llvm_name = "atmega64", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega640 = CpuModel{ + .name = "atmega640", + .llvm_name = "atmega640", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega644 = CpuModel{ + .name = "atmega644", + .llvm_name = "atmega644", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega644a = CpuModel{ + .name = "atmega644a", + .llvm_name = "atmega644a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega644p = CpuModel{ + .name = "atmega644p", + .llvm_name = "atmega644p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega644pa = CpuModel{ + .name = "atmega644pa", + .llvm_name = "atmega644pa", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega644rfr2 = CpuModel{ + .name = "atmega644rfr2", + .llvm_name = "atmega644rfr2", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega645 = CpuModel{ + .name = "atmega645", + .llvm_name = "atmega645", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega6450 = CpuModel{ + .name = "atmega6450", + .llvm_name = "atmega6450", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega6450a = CpuModel{ + .name = "atmega6450a", + .llvm_name = "atmega6450a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega6450p = CpuModel{ + .name = "atmega6450p", + .llvm_name = "atmega6450p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega645a = CpuModel{ + .name = "atmega645a", + .llvm_name = "atmega645a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega645p = CpuModel{ + .name = "atmega645p", + .llvm_name = "atmega645p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega649 = CpuModel{ + .name = "atmega649", + .llvm_name = "atmega649", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega6490 = CpuModel{ + .name = "atmega6490", + .llvm_name = "atmega6490", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega6490a = CpuModel{ + .name = "atmega6490a", + .llvm_name = "atmega6490a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega6490p = CpuModel{ + .name = "atmega6490p", + .llvm_name = "atmega6490p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega649a = CpuModel{ + .name = "atmega649a", + .llvm_name = "atmega649a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega649p = CpuModel{ + .name = "atmega649p", + .llvm_name = "atmega649p", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega64a = CpuModel{ + .name = "atmega64a", + .llvm_name = "atmega64a", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega64c1 = CpuModel{ + .name = "atmega64c1", + .llvm_name = "atmega64c1", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega64hve = CpuModel{ + .name = "atmega64hve", + .llvm_name = "atmega64hve", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega64hve2 = CpuModel{ + .name = "atmega64hve2", + .llvm_name = "atmega64hve2", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega64m1 = CpuModel{ + .name = "atmega64m1", + .llvm_name = "atmega64m1", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega64rfr2 = CpuModel{ + .name = "atmega64rfr2", + .llvm_name = "atmega64rfr2", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const atmega8 = CpuModel{ + .name = "atmega8", + .llvm_name = "atmega8", + .features = featureSet(&[_]Feature{ + .avr2, + .lpmx, + .movw, + .mul, + .spm, + }), + }; + pub const atmega808 = CpuModel{ + .name = "atmega808", + .llvm_name = "atmega808", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega809 = CpuModel{ + .name = "atmega809", + .llvm_name = "atmega809", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const atmega8515 = CpuModel{ + .name = "atmega8515", + .llvm_name = "atmega8515", + .features = featureSet(&[_]Feature{ + .avr2, + .lpmx, + .movw, + .mul, + .spm, + }), + }; + pub const atmega8535 = CpuModel{ + .name = "atmega8535", + .llvm_name = "atmega8535", + .features = featureSet(&[_]Feature{ + .avr2, + .lpmx, + .movw, + .mul, + .spm, + }), + }; + pub const atmega88 = CpuModel{ + .name = "atmega88", + .llvm_name = "atmega88", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega88a = CpuModel{ + .name = "atmega88a", + .llvm_name = "atmega88a", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega88p = CpuModel{ + .name = "atmega88p", + .llvm_name = "atmega88p", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega88pa = CpuModel{ + .name = "atmega88pa", + .llvm_name = "atmega88pa", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega88pb = CpuModel{ + .name = "atmega88pb", + .llvm_name = "atmega88pb", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega8a = CpuModel{ + .name = "atmega8a", + .llvm_name = "atmega8a", + .features = featureSet(&[_]Feature{ + .avr2, + .lpmx, + .movw, + .mul, + .spm, + }), + }; + pub const atmega8hva = CpuModel{ + .name = "atmega8hva", + .llvm_name = "atmega8hva", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const atmega8u2 = CpuModel{ + .name = "atmega8u2", + .llvm_name = "atmega8u2", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const attiny10 = CpuModel{ + .name = "attiny10", + .llvm_name = "attiny10", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny102 = CpuModel{ + .name = "attiny102", + .llvm_name = "attiny102", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny104 = CpuModel{ + .name = "attiny104", + .llvm_name = "attiny104", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny11 = CpuModel{ + .name = "attiny11", + .llvm_name = "attiny11", + .features = featureSet(&[_]Feature{ + .avr1, + .smallstack, + }), + }; + pub const attiny12 = CpuModel{ + .name = "attiny12", + .llvm_name = "attiny12", + .features = featureSet(&[_]Feature{ + .avr1, + .smallstack, + }), + }; + pub const attiny13 = CpuModel{ + .name = "attiny13", + .llvm_name = "attiny13", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny13a = CpuModel{ + .name = "attiny13a", + .llvm_name = "attiny13a", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny15 = CpuModel{ + .name = "attiny15", + .llvm_name = "attiny15", + .features = featureSet(&[_]Feature{ + .avr1, + .smallstack, + }), + }; + pub const attiny1604 = CpuModel{ + .name = "attiny1604", + .llvm_name = "attiny1604", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1606 = CpuModel{ + .name = "attiny1606", + .llvm_name = "attiny1606", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1607 = CpuModel{ + .name = "attiny1607", + .llvm_name = "attiny1607", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1614 = CpuModel{ + .name = "attiny1614", + .llvm_name = "attiny1614", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1616 = CpuModel{ + .name = "attiny1616", + .llvm_name = "attiny1616", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1617 = CpuModel{ + .name = "attiny1617", + .llvm_name = "attiny1617", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1624 = CpuModel{ + .name = "attiny1624", + .llvm_name = "attiny1624", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1626 = CpuModel{ + .name = "attiny1626", + .llvm_name = "attiny1626", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1627 = CpuModel{ + .name = "attiny1627", + .llvm_name = "attiny1627", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny1634 = CpuModel{ + .name = "attiny1634", + .llvm_name = "attiny1634", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const attiny167 = CpuModel{ + .name = "attiny167", + .llvm_name = "attiny167", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const attiny20 = CpuModel{ + .name = "attiny20", + .llvm_name = "attiny20", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny202 = CpuModel{ + .name = "attiny202", + .llvm_name = "attiny202", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny204 = CpuModel{ + .name = "attiny204", + .llvm_name = "attiny204", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny212 = CpuModel{ + .name = "attiny212", + .llvm_name = "attiny212", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny214 = CpuModel{ + .name = "attiny214", + .llvm_name = "attiny214", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny22 = CpuModel{ + .name = "attiny22", + .llvm_name = "attiny22", + .features = featureSet(&[_]Feature{ + .avr2, + .smallstack, + }), + }; + pub const attiny2313 = CpuModel{ + .name = "attiny2313", + .llvm_name = "attiny2313", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny2313a = CpuModel{ + .name = "attiny2313a", + .llvm_name = "attiny2313a", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny24 = CpuModel{ + .name = "attiny24", + .llvm_name = "attiny24", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny24a = CpuModel{ + .name = "attiny24a", + .llvm_name = "attiny24a", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny25 = CpuModel{ + .name = "attiny25", + .llvm_name = "attiny25", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny26 = CpuModel{ + .name = "attiny26", + .llvm_name = "attiny26", + .features = featureSet(&[_]Feature{ + .avr2, + .lpmx, + .smallstack, + }), + }; + pub const attiny261 = CpuModel{ + .name = "attiny261", + .llvm_name = "attiny261", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny261a = CpuModel{ + .name = "attiny261a", + .llvm_name = "attiny261a", + .features = featureSet(&[_]Feature{ + .avr25, + .smallstack, + }), + }; + pub const attiny28 = CpuModel{ + .name = "attiny28", + .llvm_name = "attiny28", + .features = featureSet(&[_]Feature{ + .avr1, + .smallstack, + }), + }; + pub const attiny3216 = CpuModel{ + .name = "attiny3216", + .llvm_name = "attiny3216", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny3217 = CpuModel{ + .name = "attiny3217", + .llvm_name = "attiny3217", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny4 = CpuModel{ + .name = "attiny4", + .llvm_name = "attiny4", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny40 = CpuModel{ + .name = "attiny40", + .llvm_name = "attiny40", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny402 = CpuModel{ + .name = "attiny402", + .llvm_name = "attiny402", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny404 = CpuModel{ + .name = "attiny404", + .llvm_name = "attiny404", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny406 = CpuModel{ + .name = "attiny406", + .llvm_name = "attiny406", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny412 = CpuModel{ + .name = "attiny412", + .llvm_name = "attiny412", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny414 = CpuModel{ + .name = "attiny414", + .llvm_name = "attiny414", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny416 = CpuModel{ + .name = "attiny416", + .llvm_name = "attiny416", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny417 = CpuModel{ + .name = "attiny417", + .llvm_name = "attiny417", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny4313 = CpuModel{ + .name = "attiny4313", + .llvm_name = "attiny4313", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny43u = CpuModel{ + .name = "attiny43u", + .llvm_name = "attiny43u", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny44 = CpuModel{ + .name = "attiny44", + .llvm_name = "attiny44", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny441 = CpuModel{ + .name = "attiny441", + .llvm_name = "attiny441", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny44a = CpuModel{ + .name = "attiny44a", + .llvm_name = "attiny44a", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny45 = CpuModel{ + .name = "attiny45", + .llvm_name = "attiny45", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny461 = CpuModel{ + .name = "attiny461", + .llvm_name = "attiny461", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny461a = CpuModel{ + .name = "attiny461a", + .llvm_name = "attiny461a", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny48 = CpuModel{ + .name = "attiny48", + .llvm_name = "attiny48", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny5 = CpuModel{ + .name = "attiny5", + .llvm_name = "attiny5", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const attiny804 = CpuModel{ + .name = "attiny804", + .llvm_name = "attiny804", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny806 = CpuModel{ + .name = "attiny806", + .llvm_name = "attiny806", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny807 = CpuModel{ + .name = "attiny807", + .llvm_name = "attiny807", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny814 = CpuModel{ + .name = "attiny814", + .llvm_name = "attiny814", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny816 = CpuModel{ + .name = "attiny816", + .llvm_name = "attiny816", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny817 = CpuModel{ + .name = "attiny817", + .llvm_name = "attiny817", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const attiny828 = CpuModel{ + .name = "attiny828", + .llvm_name = "attiny828", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny84 = CpuModel{ + .name = "attiny84", + .llvm_name = "attiny84", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny841 = CpuModel{ + .name = "attiny841", + .llvm_name = "attiny841", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny84a = CpuModel{ + .name = "attiny84a", + .llvm_name = "attiny84a", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny85 = CpuModel{ + .name = "attiny85", + .llvm_name = "attiny85", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny861 = CpuModel{ + .name = "attiny861", + .llvm_name = "attiny861", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny861a = CpuModel{ + .name = "attiny861a", + .llvm_name = "attiny861a", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny87 = CpuModel{ + .name = "attiny87", + .llvm_name = "attiny87", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny88 = CpuModel{ + .name = "attiny88", + .llvm_name = "attiny88", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const attiny9 = CpuModel{ + .name = "attiny9", + .llvm_name = "attiny9", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const atxmega128a1 = CpuModel{ + .name = "atxmega128a1", + .llvm_name = "atxmega128a1", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega128a1u = CpuModel{ + .name = "atxmega128a1u", + .llvm_name = "atxmega128a1u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega128a3 = CpuModel{ + .name = "atxmega128a3", + .llvm_name = "atxmega128a3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega128a3u = CpuModel{ + .name = "atxmega128a3u", + .llvm_name = "atxmega128a3u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega128a4u = CpuModel{ + .name = "atxmega128a4u", + .llvm_name = "atxmega128a4u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega128b1 = CpuModel{ + .name = "atxmega128b1", + .llvm_name = "atxmega128b1", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega128b3 = CpuModel{ + .name = "atxmega128b3", + .llvm_name = "atxmega128b3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega128c3 = CpuModel{ + .name = "atxmega128c3", + .llvm_name = "atxmega128c3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega128d3 = CpuModel{ + .name = "atxmega128d3", + .llvm_name = "atxmega128d3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega128d4 = CpuModel{ + .name = "atxmega128d4", + .llvm_name = "atxmega128d4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega16a4 = CpuModel{ + .name = "atxmega16a4", + .llvm_name = "atxmega16a4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega16a4u = CpuModel{ + .name = "atxmega16a4u", + .llvm_name = "atxmega16a4u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega16c4 = CpuModel{ + .name = "atxmega16c4", + .llvm_name = "atxmega16c4", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega16d4 = CpuModel{ + .name = "atxmega16d4", + .llvm_name = "atxmega16d4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega16e5 = CpuModel{ + .name = "atxmega16e5", + .llvm_name = "atxmega16e5", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega192a3 = CpuModel{ + .name = "atxmega192a3", + .llvm_name = "atxmega192a3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega192a3u = CpuModel{ + .name = "atxmega192a3u", + .llvm_name = "atxmega192a3u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega192c3 = CpuModel{ + .name = "atxmega192c3", + .llvm_name = "atxmega192c3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega192d3 = CpuModel{ + .name = "atxmega192d3", + .llvm_name = "atxmega192d3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega256a3 = CpuModel{ + .name = "atxmega256a3", + .llvm_name = "atxmega256a3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega256a3b = CpuModel{ + .name = "atxmega256a3b", + .llvm_name = "atxmega256a3b", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega256a3bu = CpuModel{ + .name = "atxmega256a3bu", + .llvm_name = "atxmega256a3bu", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega256a3u = CpuModel{ + .name = "atxmega256a3u", + .llvm_name = "atxmega256a3u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega256c3 = CpuModel{ + .name = "atxmega256c3", + .llvm_name = "atxmega256c3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega256d3 = CpuModel{ + .name = "atxmega256d3", + .llvm_name = "atxmega256d3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega32a4 = CpuModel{ + .name = "atxmega32a4", + .llvm_name = "atxmega32a4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega32a4u = CpuModel{ + .name = "atxmega32a4u", + .llvm_name = "atxmega32a4u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega32c3 = CpuModel{ + .name = "atxmega32c3", + .llvm_name = "atxmega32c3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega32c4 = CpuModel{ + .name = "atxmega32c4", + .llvm_name = "atxmega32c4", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega32d3 = CpuModel{ + .name = "atxmega32d3", + .llvm_name = "atxmega32d3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega32d4 = CpuModel{ + .name = "atxmega32d4", + .llvm_name = "atxmega32d4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega32e5 = CpuModel{ + .name = "atxmega32e5", + .llvm_name = "atxmega32e5", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega384c3 = CpuModel{ + .name = "atxmega384c3", + .llvm_name = "atxmega384c3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega384d3 = CpuModel{ + .name = "atxmega384d3", + .llvm_name = "atxmega384d3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega64a1 = CpuModel{ + .name = "atxmega64a1", + .llvm_name = "atxmega64a1", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega64a1u = CpuModel{ + .name = "atxmega64a1u", + .llvm_name = "atxmega64a1u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega64a3 = CpuModel{ + .name = "atxmega64a3", + .llvm_name = "atxmega64a3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega64a3u = CpuModel{ + .name = "atxmega64a3u", + .llvm_name = "atxmega64a3u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega64a4u = CpuModel{ + .name = "atxmega64a4u", + .llvm_name = "atxmega64a4u", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega64b1 = CpuModel{ + .name = "atxmega64b1", + .llvm_name = "atxmega64b1", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega64b3 = CpuModel{ + .name = "atxmega64b3", + .llvm_name = "atxmega64b3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega64c3 = CpuModel{ + .name = "atxmega64c3", + .llvm_name = "atxmega64c3", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const atxmega64d3 = CpuModel{ + .name = "atxmega64d3", + .llvm_name = "atxmega64d3", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega64d4 = CpuModel{ + .name = "atxmega64d4", + .llvm_name = "atxmega64d4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const atxmega8e5 = CpuModel{ + .name = "atxmega8e5", + .llvm_name = "atxmega8e5", + .features = featureSet(&[_]Feature{ + .xmegau, + }), + }; + pub const avr1 = CpuModel{ + .name = "avr1", + .llvm_name = "avr1", + .features = featureSet(&[_]Feature{ + .avr1, + }), + }; + pub const avr2 = CpuModel{ + .name = "avr2", + .llvm_name = "avr2", + .features = featureSet(&[_]Feature{ + .avr2, + }), + }; + pub const avr25 = CpuModel{ + .name = "avr25", + .llvm_name = "avr25", + .features = featureSet(&[_]Feature{ + .avr25, + }), + }; + pub const avr3 = CpuModel{ + .name = "avr3", + .llvm_name = "avr3", + .features = featureSet(&[_]Feature{ + .avr3, + }), + }; + pub const avr31 = CpuModel{ + .name = "avr31", + .llvm_name = "avr31", + .features = featureSet(&[_]Feature{ + .avr31, + }), + }; + pub const avr35 = CpuModel{ + .name = "avr35", + .llvm_name = "avr35", + .features = featureSet(&[_]Feature{ + .avr35, + }), + }; + pub const avr4 = CpuModel{ + .name = "avr4", + .llvm_name = "avr4", + .features = featureSet(&[_]Feature{ + .avr4, + }), + }; + pub const avr5 = CpuModel{ + .name = "avr5", + .llvm_name = "avr5", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; + pub const avr51 = CpuModel{ + .name = "avr51", + .llvm_name = "avr51", + .features = featureSet(&[_]Feature{ + .avr51, + }), + }; + pub const avr6 = CpuModel{ + .name = "avr6", + .llvm_name = "avr6", + .features = featureSet(&[_]Feature{ + .avr6, + }), + }; + pub const avrtiny = CpuModel{ + .name = "avrtiny", + .llvm_name = "avrtiny", + .features = featureSet(&[_]Feature{ + .avrtiny, + }), + }; + pub const avrxmega1 = CpuModel{ + .name = "avrxmega1", + .llvm_name = "avrxmega1", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const avrxmega2 = CpuModel{ + .name = "avrxmega2", + .llvm_name = "avrxmega2", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const avrxmega3 = CpuModel{ + .name = "avrxmega3", + .llvm_name = "avrxmega3", + .features = featureSet(&[_]Feature{ + .xmega3, + }), + }; + pub const avrxmega4 = CpuModel{ + .name = "avrxmega4", + .llvm_name = "avrxmega4", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const avrxmega5 = CpuModel{ + .name = "avrxmega5", + .llvm_name = "avrxmega5", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const avrxmega6 = CpuModel{ + .name = "avrxmega6", + .llvm_name = "avrxmega6", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const avrxmega7 = CpuModel{ + .name = "avrxmega7", + .llvm_name = "avrxmega7", + .features = featureSet(&[_]Feature{ + .xmega, + }), + }; + pub const m3000 = CpuModel{ + .name = "m3000", + .llvm_name = "m3000", + .features = featureSet(&[_]Feature{ + .avr5, + }), + }; +}; diff --git a/lib/std/Target/bpf.zig b/lib/std/Target/bpf.zig new file mode 100644 index 0000000000..40dc2d1c7e --- /dev/null +++ b/lib/std/Target/bpf.zig @@ -0,0 +1,73 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + alu32, + dummy, + dwarfris, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.alu32)] = .{ + .llvm_name = "alu32", + .description = "Enable ALU32 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dummy)] = .{ + .llvm_name = "dummy", + .description = "unused feature", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dwarfris)] = .{ + .llvm_name = "dwarfris", + .description = "Disable MCAsmInfo DwarfUsesRelocationsAcrossSections", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const probe = CpuModel{ + .name = "probe", + .llvm_name = "probe", + .features = featureSet(&[_]Feature{}), + }; + pub const v1 = CpuModel{ + .name = "v1", + .llvm_name = "v1", + .features = featureSet(&[_]Feature{}), + }; + pub const v2 = CpuModel{ + .name = "v2", + .llvm_name = "v2", + .features = featureSet(&[_]Feature{}), + }; + pub const v3 = CpuModel{ + .name = "v3", + .llvm_name = "v3", + .features = featureSet(&[_]Feature{ + .alu32, + }), + }; +}; diff --git a/lib/std/Target/csky.zig b/lib/std/Target/csky.zig new file mode 100644 index 0000000000..331e8057bf --- /dev/null +++ b/lib/std/Target/csky.zig @@ -0,0 +1,3214 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"10e60", + @"2e3", + @"3e3r1", + @"3e3r2", + @"3e3r3", + @"3e7", + @"7e10", + btst16, + cache, + ccrt, + ck801, + ck802, + ck803, + ck803s, + ck804, + ck805, + ck807, + ck810, + ck810v, + ck860, + ck860v, + constpool, + doloop, + dsp1e2, + dsp_silan, + dspe60, + dspv2, + e1, + e2, + edsp, + elrw, + fdivdu, + float1e2, + float1e3, + float3e4, + float7e60, + floate1, + fpuv2_df, + fpuv2_sf, + fpuv3_df, + fpuv3_hf, + fpuv3_hi, + fpuv3_sf, + hard_float, + hard_float_abi, + hard_tp, + high_registers, + hwdiv, + istack, + java, + mp, + mp1e2, + multiple_stld, + nvic, + pushpop, + smart, + soft_tp, + stack_size, + trust, + vdsp2e3, + vdsp2e60f, + vdspv1, + vdspv2, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"10e60")] = .{ + .llvm_name = "10e60", + .description = "Support CSKY 10e60 instructions", + .dependencies = featureSet(&[_]Feature{ + .@"7e10", + }), + }; + result[@intFromEnum(Feature.@"2e3")] = .{ + .llvm_name = "2e3", + .description = "Support CSKY 2e3 instructions", + .dependencies = featureSet(&[_]Feature{ + .e2, + }), + }; + result[@intFromEnum(Feature.@"3e3r1")] = .{ + .llvm_name = "3e3r1", + .description = "Support CSKY 3e3r1 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"3e3r2")] = .{ + .llvm_name = "3e3r2", + .description = "Support CSKY 3e3r2 instructions", + .dependencies = featureSet(&[_]Feature{ + .@"3e3r1", + .doloop, + }), + }; + result[@intFromEnum(Feature.@"3e3r3")] = .{ + .llvm_name = "3e3r3", + .description = "Support CSKY 3e3r3 instructions", + .dependencies = featureSet(&[_]Feature{ + .doloop, + }), + }; + result[@intFromEnum(Feature.@"3e7")] = .{ + .llvm_name = "3e7", + .description = "Support CSKY 3e7 instructions", + .dependencies = featureSet(&[_]Feature{ + .@"2e3", + }), + }; + result[@intFromEnum(Feature.@"7e10")] = .{ + .llvm_name = "7e10", + .description = "Support CSKY 7e10 instructions", + .dependencies = featureSet(&[_]Feature{ + .@"3e7", + }), + }; + result[@intFromEnum(Feature.btst16)] = .{ + .llvm_name = "btst16", + .description = "Use the 16-bit btsti instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cache)] = .{ + .llvm_name = "cache", + .description = "Enable cache", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ccrt)] = .{ + .llvm_name = "ccrt", + .description = "Use CSKY compiler runtime", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck801)] = .{ + .llvm_name = "ck801", + .description = "CSKY ck801 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck802)] = .{ + .llvm_name = "ck802", + .description = "CSKY ck802 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck803)] = .{ + .llvm_name = "ck803", + .description = "CSKY ck803 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck803s)] = .{ + .llvm_name = "ck803s", + .description = "CSKY ck803s processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck804)] = .{ + .llvm_name = "ck804", + .description = "CSKY ck804 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck805)] = .{ + .llvm_name = "ck805", + .description = "CSKY ck805 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck807)] = .{ + .llvm_name = "ck807", + .description = "CSKY ck807 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck810)] = .{ + .llvm_name = "ck810", + .description = "CSKY ck810 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck810v)] = .{ + .llvm_name = "ck810v", + .description = "CSKY ck810v processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck860)] = .{ + .llvm_name = "ck860", + .description = "CSKY ck860 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ck860v)] = .{ + .llvm_name = "ck860v", + .description = "CSKY ck860v processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.constpool)] = .{ + .llvm_name = "constpool", + .description = "Dump the constant pool by compiler", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.doloop)] = .{ + .llvm_name = "doloop", + .description = "Enable doloop instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dsp1e2)] = .{ + .llvm_name = "dsp1e2", + .description = "Support CSKY dsp1e2 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dsp_silan)] = .{ + .llvm_name = "dsp_silan", + .description = "Enable DSP Silan instrutions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dspe60)] = .{ + .llvm_name = "dspe60", + .description = "Support CSKY dspe60 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dspv2)] = .{ + .llvm_name = "dspv2", + .description = "Enable DSP V2.0 instrutions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.e1)] = .{ + .llvm_name = "e1", + .description = "Support CSKY e1 instructions", + .dependencies = featureSet(&[_]Feature{ + .elrw, + }), + }; + result[@intFromEnum(Feature.e2)] = .{ + .llvm_name = "e2", + .description = "Support CSKY e2 instructions", + .dependencies = featureSet(&[_]Feature{ + .e1, + }), + }; + result[@intFromEnum(Feature.edsp)] = .{ + .llvm_name = "edsp", + .description = "Enable DSP instrutions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.elrw)] = .{ + .llvm_name = "elrw", + .description = "Use the extend LRW instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fdivdu)] = .{ + .llvm_name = "fdivdu", + .description = "Enable float divide instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.float1e2)] = .{ + .llvm_name = "float1e2", + .description = "Support CSKY float1e2 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.float1e3)] = .{ + .llvm_name = "float1e3", + .description = "Support CSKY float1e3 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.float3e4)] = .{ + .llvm_name = "float3e4", + .description = "Support CSKY float3e4 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.float7e60)] = .{ + .llvm_name = "float7e60", + .description = "Support CSKY float7e60 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.floate1)] = .{ + .llvm_name = "floate1", + .description = "Support CSKY floate1 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpuv2_df)] = .{ + .llvm_name = "fpuv2_df", + .description = "Enable FPUv2 double float instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpuv2_sf)] = .{ + .llvm_name = "fpuv2_sf", + .description = "Enable FPUv2 single float instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpuv3_df)] = .{ + .llvm_name = "fpuv3_df", + .description = "Enable FPUv3 double float instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpuv3_hf)] = .{ + .llvm_name = "fpuv3_hf", + .description = "Enable FPUv3 half precision operate instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpuv3_hi)] = .{ + .llvm_name = "fpuv3_hi", + .description = "Enable FPUv3 half word converting instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpuv3_sf)] = .{ + .llvm_name = "fpuv3_sf", + .description = "Enable FPUv3 single float instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hard_float)] = .{ + .llvm_name = "hard-float", + .description = "Use hard floating point features", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hard_float_abi)] = .{ + .llvm_name = "hard-float-abi", + .description = "Use hard floating point ABI to pass args", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hard_tp)] = .{ + .llvm_name = "hard-tp", + .description = "Enable TLS Pointer register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.high_registers)] = .{ + .llvm_name = "high-registers", + .description = "Enable r16-r31 registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hwdiv)] = .{ + .llvm_name = "hwdiv", + .description = "Enable divide instrutions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.istack)] = .{ + .llvm_name = "istack", + .description = "Enable interrput attribute", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.java)] = .{ + .llvm_name = "java", + .description = "Enable java instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mp)] = .{ + .llvm_name = "mp", + .description = "Support CSKY mp instructions", + .dependencies = featureSet(&[_]Feature{ + .@"2e3", + }), + }; + result[@intFromEnum(Feature.mp1e2)] = .{ + .llvm_name = "mp1e2", + .description = "Support CSKY mp1e2 instructions", + .dependencies = featureSet(&[_]Feature{ + .@"3e7", + }), + }; + result[@intFromEnum(Feature.multiple_stld)] = .{ + .llvm_name = "multiple_stld", + .description = "Enable multiple load/store instrutions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nvic)] = .{ + .llvm_name = "nvic", + .description = "Enable NVIC", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pushpop)] = .{ + .llvm_name = "pushpop", + .description = "Enable push/pop instrutions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.smart)] = .{ + .llvm_name = "smart", + .description = "Let CPU work in Smart Mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.soft_tp)] = .{ + .llvm_name = "soft-tp", + .description = "Disable TLS Pointer register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.stack_size)] = .{ + .llvm_name = "stack-size", + .description = "Output stack size information", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.trust)] = .{ + .llvm_name = "trust", + .description = "Enable trust instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vdsp2e3)] = .{ + .llvm_name = "vdsp2e3", + .description = "Support CSKY vdsp2e3 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vdsp2e60f)] = .{ + .llvm_name = "vdsp2e60f", + .description = "Support CSKY vdsp2e60f instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vdspv1)] = .{ + .llvm_name = "vdspv1", + .description = "Enable 128bit vdsp-v1 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vdspv2)] = .{ + .llvm_name = "vdspv2", + .description = "Enable vdsp-v2 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const c807 = CpuModel{ + .name = "c807", + .llvm_name = "c807", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const c807f = CpuModel{ + .name = "c807f", + .llvm_name = "c807f", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .float1e3, + .float3e4, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const c810 = CpuModel{ + .name = "c810", + .llvm_name = "c810", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const c810t = CpuModel{ + .name = "c810t", + .llvm_name = "c810t", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const c810tv = CpuModel{ + .name = "c810tv", + .llvm_name = "c810tv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const c810v = CpuModel{ + .name = "c810v", + .llvm_name = "c810v", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const c860 = CpuModel{ + .name = "c860", + .llvm_name = "c860", + .features = featureSet(&[_]Feature{ + .@"10e60", + .@"3e3r2", + .@"3e3r3", + .btst16, + .cache, + .ck860, + .dspe60, + .float7e60, + .fpuv3_df, + .fpuv3_hf, + .fpuv3_hi, + .fpuv3_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const c860v = CpuModel{ + .name = "c860v", + .llvm_name = "c860v", + .features = featureSet(&[_]Feature{ + .@"10e60", + .@"3e3r2", + .@"3e3r3", + .btst16, + .cache, + .ck860, + .ck860v, + .dspe60, + .float7e60, + .fpuv3_df, + .fpuv3_hf, + .fpuv3_hi, + .fpuv3_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdsp2e60f, + .vdspv2, + }), + }; + pub const ck801 = CpuModel{ + .name = "ck801", + .llvm_name = "ck801", + .features = featureSet(&[_]Feature{ + .btst16, + .ck801, + .e1, + .trust, + }), + }; + pub const ck801t = CpuModel{ + .name = "ck801t", + .llvm_name = "ck801t", + .features = featureSet(&[_]Feature{ + .btst16, + .ck801, + .e1, + .trust, + }), + }; + pub const ck802 = CpuModel{ + .name = "ck802", + .llvm_name = "ck802", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .nvic, + .trust, + }), + }; + pub const ck802j = CpuModel{ + .name = "ck802j", + .llvm_name = "ck802j", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .java, + .nvic, + .trust, + }), + }; + pub const ck802t = CpuModel{ + .name = "ck802t", + .llvm_name = "ck802t", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .nvic, + .trust, + }), + }; + pub const ck803 = CpuModel{ + .name = "ck803", + .llvm_name = "ck803", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803e = CpuModel{ + .name = "ck803e", + .llvm_name = "ck803e", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ef = CpuModel{ + .name = "ck803ef", + .llvm_name = "ck803ef", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efh = CpuModel{ + .name = "ck803efh", + .llvm_name = "ck803efh", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efhr1 = CpuModel{ + .name = "ck803efhr1", + .llvm_name = "ck803efhr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efhr2 = CpuModel{ + .name = "ck803efhr2", + .llvm_name = "ck803efhr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efhr3 = CpuModel{ + .name = "ck803efhr3", + .llvm_name = "ck803efhr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efht = CpuModel{ + .name = "ck803efht", + .llvm_name = "ck803efht", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efhtr1 = CpuModel{ + .name = "ck803efhtr1", + .llvm_name = "ck803efhtr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efhtr2 = CpuModel{ + .name = "ck803efhtr2", + .llvm_name = "ck803efhtr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efhtr3 = CpuModel{ + .name = "ck803efhtr3", + .llvm_name = "ck803efhtr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efr1 = CpuModel{ + .name = "ck803efr1", + .llvm_name = "ck803efr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efr2 = CpuModel{ + .name = "ck803efr2", + .llvm_name = "ck803efr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803efr3 = CpuModel{ + .name = "ck803efr3", + .llvm_name = "ck803efr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803eft = CpuModel{ + .name = "ck803eft", + .llvm_name = "ck803eft", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803eftr1 = CpuModel{ + .name = "ck803eftr1", + .llvm_name = "ck803eftr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803eftr2 = CpuModel{ + .name = "ck803eftr2", + .llvm_name = "ck803eftr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803eftr3 = CpuModel{ + .name = "ck803eftr3", + .llvm_name = "ck803eftr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803eh = CpuModel{ + .name = "ck803eh", + .llvm_name = "ck803eh", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ehr1 = CpuModel{ + .name = "ck803ehr1", + .llvm_name = "ck803ehr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ehr2 = CpuModel{ + .name = "ck803ehr2", + .llvm_name = "ck803ehr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ehr3 = CpuModel{ + .name = "ck803ehr3", + .llvm_name = "ck803ehr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803eht = CpuModel{ + .name = "ck803eht", + .llvm_name = "ck803eht", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ehtr1 = CpuModel{ + .name = "ck803ehtr1", + .llvm_name = "ck803ehtr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ehtr2 = CpuModel{ + .name = "ck803ehtr2", + .llvm_name = "ck803ehtr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ehtr3 = CpuModel{ + .name = "ck803ehtr3", + .llvm_name = "ck803ehtr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803er1 = CpuModel{ + .name = "ck803er1", + .llvm_name = "ck803er1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803er2 = CpuModel{ + .name = "ck803er2", + .llvm_name = "ck803er2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803er3 = CpuModel{ + .name = "ck803er3", + .llvm_name = "ck803er3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803et = CpuModel{ + .name = "ck803et", + .llvm_name = "ck803et", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .edsp, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803etr1 = CpuModel{ + .name = "ck803etr1", + .llvm_name = "ck803etr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803etr2 = CpuModel{ + .name = "ck803etr2", + .llvm_name = "ck803etr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803etr3 = CpuModel{ + .name = "ck803etr3", + .llvm_name = "ck803etr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dsp1e2, + .dspe60, + .dspv2, + .edsp, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803f = CpuModel{ + .name = "ck803f", + .llvm_name = "ck803f", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fh = CpuModel{ + .name = "ck803fh", + .llvm_name = "ck803fh", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fhr1 = CpuModel{ + .name = "ck803fhr1", + .llvm_name = "ck803fhr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fhr2 = CpuModel{ + .name = "ck803fhr2", + .llvm_name = "ck803fhr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fhr3 = CpuModel{ + .name = "ck803fhr3", + .llvm_name = "ck803fhr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fr1 = CpuModel{ + .name = "ck803fr1", + .llvm_name = "ck803fr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fr2 = CpuModel{ + .name = "ck803fr2", + .llvm_name = "ck803fr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803fr3 = CpuModel{ + .name = "ck803fr3", + .llvm_name = "ck803fr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ft = CpuModel{ + .name = "ck803ft", + .llvm_name = "ck803ft", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ftr1 = CpuModel{ + .name = "ck803ftr1", + .llvm_name = "ck803ftr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ftr2 = CpuModel{ + .name = "ck803ftr2", + .llvm_name = "ck803ftr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ftr3 = CpuModel{ + .name = "ck803ftr3", + .llvm_name = "ck803ftr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803h = CpuModel{ + .name = "ck803h", + .llvm_name = "ck803h", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803hr1 = CpuModel{ + .name = "ck803hr1", + .llvm_name = "ck803hr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803hr2 = CpuModel{ + .name = "ck803hr2", + .llvm_name = "ck803hr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803hr3 = CpuModel{ + .name = "ck803hr3", + .llvm_name = "ck803hr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803ht = CpuModel{ + .name = "ck803ht", + .llvm_name = "ck803ht", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803htr1 = CpuModel{ + .name = "ck803htr1", + .llvm_name = "ck803htr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803htr2 = CpuModel{ + .name = "ck803htr2", + .llvm_name = "ck803htr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803htr3 = CpuModel{ + .name = "ck803htr3", + .llvm_name = "ck803htr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803r1 = CpuModel{ + .name = "ck803r1", + .llvm_name = "ck803r1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803r2 = CpuModel{ + .name = "ck803r2", + .llvm_name = "ck803r2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803r3 = CpuModel{ + .name = "ck803r3", + .llvm_name = "ck803r3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803s = CpuModel{ + .name = "ck803s", + .llvm_name = "ck803s", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803se = CpuModel{ + .name = "ck803se", + .llvm_name = "ck803se", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp1e2, + .dspe60, + .edsp, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sef = CpuModel{ + .name = "ck803sef", + .llvm_name = "ck803sef", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp1e2, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sefn = CpuModel{ + .name = "ck803sefn", + .llvm_name = "ck803sefn", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp1e2, + .dsp_silan, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sefnt = CpuModel{ + .name = "ck803sefnt", + .llvm_name = "ck803sefnt", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp1e2, + .dsp_silan, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803seft = CpuModel{ + .name = "ck803seft", + .llvm_name = "ck803seft", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp1e2, + .dspe60, + .edsp, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sen = CpuModel{ + .name = "ck803sen", + .llvm_name = "ck803sen", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp1e2, + .dsp_silan, + .dspe60, + .edsp, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sf = CpuModel{ + .name = "ck803sf", + .llvm_name = "ck803sf", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sfn = CpuModel{ + .name = "ck803sfn", + .llvm_name = "ck803sfn", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp_silan, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803sn = CpuModel{ + .name = "ck803sn", + .llvm_name = "ck803sn", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp_silan, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803snt = CpuModel{ + .name = "ck803snt", + .llvm_name = "ck803snt", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .dsp_silan, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803st = CpuModel{ + .name = "ck803st", + .llvm_name = "ck803st", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .btst16, + .ck803, + .ck803s, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803t = CpuModel{ + .name = "ck803t", + .llvm_name = "ck803t", + .features = featureSet(&[_]Feature{ + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803tr1 = CpuModel{ + .name = "ck803tr1", + .llvm_name = "ck803tr1", + .features = featureSet(&[_]Feature{ + .@"3e3r1", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803tr2 = CpuModel{ + .name = "ck803tr2", + .llvm_name = "ck803tr2", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck803tr3 = CpuModel{ + .name = "ck803tr3", + .llvm_name = "ck803tr3", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .dspv2, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804 = CpuModel{ + .name = "ck804", + .llvm_name = "ck804", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804e = CpuModel{ + .name = "ck804e", + .llvm_name = "ck804e", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804ef = CpuModel{ + .name = "ck804ef", + .llvm_name = "ck804ef", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804efh = CpuModel{ + .name = "ck804efh", + .llvm_name = "ck804efh", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804efht = CpuModel{ + .name = "ck804efht", + .llvm_name = "ck804efht", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804eft = CpuModel{ + .name = "ck804eft", + .llvm_name = "ck804eft", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804eh = CpuModel{ + .name = "ck804eh", + .llvm_name = "ck804eh", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804eht = CpuModel{ + .name = "ck804eht", + .llvm_name = "ck804eht", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804et = CpuModel{ + .name = "ck804et", + .llvm_name = "ck804et", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804f = CpuModel{ + .name = "ck804f", + .llvm_name = "ck804f", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804fh = CpuModel{ + .name = "ck804fh", + .llvm_name = "ck804fh", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804ft = CpuModel{ + .name = "ck804ft", + .llvm_name = "ck804ft", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804h = CpuModel{ + .name = "ck804h", + .llvm_name = "ck804h", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804ht = CpuModel{ + .name = "ck804ht", + .llvm_name = "ck804ht", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck804t = CpuModel{ + .name = "ck804t", + .llvm_name = "ck804t", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const ck805 = CpuModel{ + .name = "ck805", + .llvm_name = "ck805", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805e = CpuModel{ + .name = "ck805e", + .llvm_name = "ck805e", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805ef = CpuModel{ + .name = "ck805ef", + .llvm_name = "ck805ef", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805eft = CpuModel{ + .name = "ck805eft", + .llvm_name = "ck805eft", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805et = CpuModel{ + .name = "ck805et", + .llvm_name = "ck805et", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805f = CpuModel{ + .name = "ck805f", + .llvm_name = "ck805f", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805ft = CpuModel{ + .name = "ck805ft", + .llvm_name = "ck805ft", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck805t = CpuModel{ + .name = "ck805t", + .llvm_name = "ck805t", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const ck807 = CpuModel{ + .name = "ck807", + .llvm_name = "ck807", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck807e = CpuModel{ + .name = "ck807e", + .llvm_name = "ck807e", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck807ef = CpuModel{ + .name = "ck807ef", + .llvm_name = "ck807ef", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .float1e3, + .float3e4, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck807f = CpuModel{ + .name = "ck807f", + .llvm_name = "ck807f", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .float1e3, + .float3e4, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810 = CpuModel{ + .name = "ck810", + .llvm_name = "ck810", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810e = CpuModel{ + .name = "ck810e", + .llvm_name = "ck810e", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810ef = CpuModel{ + .name = "ck810ef", + .llvm_name = "ck810ef", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810eft = CpuModel{ + .name = "ck810eft", + .llvm_name = "ck810eft", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810eftv = CpuModel{ + .name = "ck810eftv", + .llvm_name = "ck810eftv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810efv = CpuModel{ + .name = "ck810efv", + .llvm_name = "ck810efv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810et = CpuModel{ + .name = "ck810et", + .llvm_name = "ck810et", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810etv = CpuModel{ + .name = "ck810etv", + .llvm_name = "ck810etv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810ev = CpuModel{ + .name = "ck810ev", + .llvm_name = "ck810ev", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810f = CpuModel{ + .name = "ck810f", + .llvm_name = "ck810f", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810ft = CpuModel{ + .name = "ck810ft", + .llvm_name = "ck810ft", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810ftv = CpuModel{ + .name = "ck810ftv", + .llvm_name = "ck810ftv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810fv = CpuModel{ + .name = "ck810fv", + .llvm_name = "ck810fv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810t = CpuModel{ + .name = "ck810t", + .llvm_name = "ck810t", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck810tv = CpuModel{ + .name = "ck810tv", + .llvm_name = "ck810tv", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck810v = CpuModel{ + .name = "ck810v", + .llvm_name = "ck810v", + .features = featureSet(&[_]Feature{ + .@"7e10", + .cache, + .ck810, + .ck810v, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdspv1, + }), + }; + pub const ck860 = CpuModel{ + .name = "ck860", + .llvm_name = "ck860", + .features = featureSet(&[_]Feature{ + .@"10e60", + .@"3e3r2", + .@"3e3r3", + .btst16, + .cache, + .ck860, + .dspe60, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck860f = CpuModel{ + .name = "ck860f", + .llvm_name = "ck860f", + .features = featureSet(&[_]Feature{ + .@"10e60", + .@"3e3r2", + .@"3e3r3", + .btst16, + .cache, + .ck860, + .dspe60, + .float7e60, + .fpuv3_df, + .fpuv3_hf, + .fpuv3_hi, + .fpuv3_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const ck860fv = CpuModel{ + .name = "ck860fv", + .llvm_name = "ck860fv", + .features = featureSet(&[_]Feature{ + .@"10e60", + .@"3e3r2", + .@"3e3r3", + .btst16, + .cache, + .ck860, + .ck860v, + .dspe60, + .float7e60, + .fpuv3_df, + .fpuv3_hf, + .fpuv3_hi, + .fpuv3_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdsp2e60f, + .vdspv2, + }), + }; + pub const ck860v = CpuModel{ + .name = "ck860v", + .llvm_name = "ck860v", + .features = featureSet(&[_]Feature{ + .@"10e60", + .@"3e3r2", + .@"3e3r3", + .btst16, + .cache, + .ck860, + .ck860v, + .dspe60, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + .vdsp2e60f, + .vdspv2, + }), + }; + pub const e801 = CpuModel{ + .name = "e801", + .llvm_name = "e801", + .features = featureSet(&[_]Feature{ + .btst16, + .ck801, + .e1, + .trust, + }), + }; + pub const e802 = CpuModel{ + .name = "e802", + .llvm_name = "e802", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .nvic, + .trust, + }), + }; + pub const e802t = CpuModel{ + .name = "e802t", + .llvm_name = "e802t", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .nvic, + .trust, + }), + }; + pub const e803 = CpuModel{ + .name = "e803", + .llvm_name = "e803", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e803t = CpuModel{ + .name = "e803t", + .llvm_name = "e803t", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e804d = CpuModel{ + .name = "e804d", + .llvm_name = "e804d", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e804df = CpuModel{ + .name = "e804df", + .llvm_name = "e804df", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e804dft = CpuModel{ + .name = "e804dft", + .llvm_name = "e804dft", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e804dt = CpuModel{ + .name = "e804dt", + .llvm_name = "e804dt", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .dspv2, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e804f = CpuModel{ + .name = "e804f", + .llvm_name = "e804f", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const e804ft = CpuModel{ + .name = "e804ft", + .llvm_name = "e804ft", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck804, + .float1e3, + .floate1, + .fpuv2_sf, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .btst16, + }), + }; + pub const @"i805" = CpuModel{ + .name = "i805", + .llvm_name = "i805", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const i805f = CpuModel{ + .name = "i805f", + .llvm_name = "i805f", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .ck805, + .float1e3, + .floate1, + .fpuv2_sf, + .high_registers, + .hwdiv, + .mp, + .nvic, + .trust, + .vdsp2e3, + .vdspv2, + }), + }; + pub const r807 = CpuModel{ + .name = "r807", + .llvm_name = "r807", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const r807f = CpuModel{ + .name = "r807f", + .llvm_name = "r807f", + .features = featureSet(&[_]Feature{ + .cache, + .ck807, + .dsp1e2, + .dspe60, + .edsp, + .fdivdu, + .float1e2, + .float1e3, + .float3e4, + .floate1, + .fpuv2_df, + .fpuv2_sf, + .hard_tp, + .high_registers, + .hwdiv, + .mp, + .mp1e2, + .nvic, + .trust, + }), + }; + pub const s802 = CpuModel{ + .name = "s802", + .llvm_name = "s802", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .nvic, + .trust, + }), + }; + pub const s802t = CpuModel{ + .name = "s802t", + .llvm_name = "s802t", + .features = featureSet(&[_]Feature{ + .btst16, + .ck802, + .e2, + .nvic, + .trust, + }), + }; + pub const s803 = CpuModel{ + .name = "s803", + .llvm_name = "s803", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; + pub const s803t = CpuModel{ + .name = "s803t", + .llvm_name = "s803t", + .features = featureSet(&[_]Feature{ + .@"3e3r2", + .@"3e3r3", + .btst16, + .ck803, + .hwdiv, + .mp, + .nvic, + .trust, + }), + }; +}; diff --git a/lib/std/Target/hexagon.zig b/lib/std/Target/hexagon.zig new file mode 100644 index 0000000000..c84b2cb0c8 --- /dev/null +++ b/lib/std/Target/hexagon.zig @@ -0,0 +1,586 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + audio, + cabac, + compound, + duplex, + hvx, + hvx_ieee_fp, + hvx_length128b, + hvx_length64b, + hvx_qfloat, + hvxv60, + hvxv62, + hvxv65, + hvxv66, + hvxv67, + hvxv68, + hvxv69, + hvxv71, + hvxv73, + long_calls, + mem_noshuf, + memops, + noreturn_stack_elim, + nvj, + nvs, + packets, + prev65, + reserved_r19, + small_data, + tinycore, + unsafe_fp, + v5, + v55, + v60, + v62, + v65, + v66, + v67, + v68, + v69, + v71, + v73, + zreg, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.audio)] = .{ + .llvm_name = "audio", + .description = "Hexagon Audio extension instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cabac)] = .{ + .llvm_name = "cabac", + .description = "Emit the CABAC instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.compound)] = .{ + .llvm_name = "compound", + .description = "Use compound instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.duplex)] = .{ + .llvm_name = "duplex", + .description = "Enable generation of duplex instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hvx)] = .{ + .llvm_name = "hvx", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hvx_ieee_fp)] = .{ + .llvm_name = "hvx-ieee-fp", + .description = "Hexagon HVX IEEE floating point instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hvx_length128b)] = .{ + .llvm_name = "hvx-length128b", + .description = "Hexagon HVX 128B instructions", + .dependencies = featureSet(&[_]Feature{ + .hvx, + }), + }; + result[@intFromEnum(Feature.hvx_length64b)] = .{ + .llvm_name = "hvx-length64b", + .description = "Hexagon HVX 64B instructions", + .dependencies = featureSet(&[_]Feature{ + .hvx, + }), + }; + result[@intFromEnum(Feature.hvx_qfloat)] = .{ + .llvm_name = "hvx-qfloat", + .description = "Hexagon HVX QFloating point instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hvxv60)] = .{ + .llvm_name = "hvxv60", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvx, + }), + }; + result[@intFromEnum(Feature.hvxv62)] = .{ + .llvm_name = "hvxv62", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv60, + }), + }; + result[@intFromEnum(Feature.hvxv65)] = .{ + .llvm_name = "hvxv65", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv62, + }), + }; + result[@intFromEnum(Feature.hvxv66)] = .{ + .llvm_name = "hvxv66", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv65, + .zreg, + }), + }; + result[@intFromEnum(Feature.hvxv67)] = .{ + .llvm_name = "hvxv67", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv66, + }), + }; + result[@intFromEnum(Feature.hvxv68)] = .{ + .llvm_name = "hvxv68", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv67, + }), + }; + result[@intFromEnum(Feature.hvxv69)] = .{ + .llvm_name = "hvxv69", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv68, + }), + }; + result[@intFromEnum(Feature.hvxv71)] = .{ + .llvm_name = "hvxv71", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv69, + }), + }; + result[@intFromEnum(Feature.hvxv73)] = .{ + .llvm_name = "hvxv73", + .description = "Hexagon HVX instructions", + .dependencies = featureSet(&[_]Feature{ + .hvxv71, + }), + }; + result[@intFromEnum(Feature.long_calls)] = .{ + .llvm_name = "long-calls", + .description = "Use constant-extended calls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mem_noshuf)] = .{ + .llvm_name = "mem_noshuf", + .description = "Supports mem_noshuf feature", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.memops)] = .{ + .llvm_name = "memops", + .description = "Use memop instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.noreturn_stack_elim)] = .{ + .llvm_name = "noreturn-stack-elim", + .description = "Eliminate stack allocation in a noreturn function when possible", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nvj)] = .{ + .llvm_name = "nvj", + .description = "Support for new-value jumps", + .dependencies = featureSet(&[_]Feature{ + .packets, + }), + }; + result[@intFromEnum(Feature.nvs)] = .{ + .llvm_name = "nvs", + .description = "Support for new-value stores", + .dependencies = featureSet(&[_]Feature{ + .packets, + }), + }; + result[@intFromEnum(Feature.packets)] = .{ + .llvm_name = "packets", + .description = "Support for instruction packets", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prev65)] = .{ + .llvm_name = "prev65", + .description = "Support features deprecated in v65", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserved_r19)] = .{ + .llvm_name = "reserved-r19", + .description = "Reserve register R19", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.small_data)] = .{ + .llvm_name = "small-data", + .description = "Allow GP-relative addressing of global variables", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tinycore)] = .{ + .llvm_name = "tinycore", + .description = "Hexagon Tiny Core", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unsafe_fp)] = .{ + .llvm_name = "unsafe-fp", + .description = "Use unsafe FP math", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v5)] = .{ + .llvm_name = "v5", + .description = "Enable Hexagon V5 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v55)] = .{ + .llvm_name = "v55", + .description = "Enable Hexagon V55 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v60)] = .{ + .llvm_name = "v60", + .description = "Enable Hexagon V60 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v62)] = .{ + .llvm_name = "v62", + .description = "Enable Hexagon V62 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v65)] = .{ + .llvm_name = "v65", + .description = "Enable Hexagon V65 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v66)] = .{ + .llvm_name = "v66", + .description = "Enable Hexagon V66 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v67)] = .{ + .llvm_name = "v67", + .description = "Enable Hexagon V67 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v68)] = .{ + .llvm_name = "v68", + .description = "Enable Hexagon V68 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v69)] = .{ + .llvm_name = "v69", + .description = "Enable Hexagon V69 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v71)] = .{ + .llvm_name = "v71", + .description = "Enable Hexagon V71 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v73)] = .{ + .llvm_name = "v73", + .description = "Enable Hexagon V73 architecture", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zreg)] = .{ + .llvm_name = "zreg", + .description = "Hexagon ZReg extension instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .memops, + .nvj, + .nvs, + .prev65, + .small_data, + .v5, + .v55, + .v60, + }), + }; + pub const hexagonv5 = CpuModel{ + .name = "hexagonv5", + .llvm_name = "hexagonv5", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .memops, + .nvj, + .nvs, + .prev65, + .small_data, + .v5, + }), + }; + pub const hexagonv55 = CpuModel{ + .name = "hexagonv55", + .llvm_name = "hexagonv55", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .memops, + .nvj, + .nvs, + .prev65, + .small_data, + .v5, + .v55, + }), + }; + pub const hexagonv60 = CpuModel{ + .name = "hexagonv60", + .llvm_name = "hexagonv60", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .memops, + .nvj, + .nvs, + .prev65, + .small_data, + .v5, + .v55, + .v60, + }), + }; + pub const hexagonv62 = CpuModel{ + .name = "hexagonv62", + .llvm_name = "hexagonv62", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .memops, + .nvj, + .nvs, + .prev65, + .small_data, + .v5, + .v55, + .v60, + .v62, + }), + }; + pub const hexagonv65 = CpuModel{ + .name = "hexagonv65", + .llvm_name = "hexagonv65", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + }), + }; + pub const hexagonv66 = CpuModel{ + .name = "hexagonv66", + .llvm_name = "hexagonv66", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + }), + }; + pub const hexagonv67 = CpuModel{ + .name = "hexagonv67", + .llvm_name = "hexagonv67", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + }), + }; + pub const hexagonv67t = CpuModel{ + .name = "hexagonv67t", + .llvm_name = "hexagonv67t", + .features = featureSet(&[_]Feature{ + .audio, + .compound, + .mem_noshuf, + .memops, + .nvs, + .small_data, + .tinycore, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + }), + }; + pub const hexagonv68 = CpuModel{ + .name = "hexagonv68", + .llvm_name = "hexagonv68", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + .v68, + }), + }; + pub const hexagonv69 = CpuModel{ + .name = "hexagonv69", + .llvm_name = "hexagonv69", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + .v68, + .v69, + }), + }; + pub const hexagonv71 = CpuModel{ + .name = "hexagonv71", + .llvm_name = "hexagonv71", + .features = featureSet(&[_]Feature{ + .cabac, + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + .v68, + .v69, + .v71, + }), + }; + pub const hexagonv71t = CpuModel{ + .name = "hexagonv71t", + .llvm_name = "hexagonv71t", + .features = featureSet(&[_]Feature{ + .audio, + .compound, + .mem_noshuf, + .memops, + .nvs, + .small_data, + .tinycore, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + .v68, + .v69, + .v71, + }), + }; + pub const hexagonv73 = CpuModel{ + .name = "hexagonv73", + .llvm_name = "hexagonv73", + .features = featureSet(&[_]Feature{ + .compound, + .duplex, + .mem_noshuf, + .memops, + .nvj, + .nvs, + .small_data, + .v5, + .v55, + .v60, + .v62, + .v65, + .v66, + .v67, + .v68, + .v69, + .v71, + .v73, + }), + }; +}; diff --git a/lib/std/Target/loongarch.zig b/lib/std/Target/loongarch.zig new file mode 100644 index 0000000000..65dc33d784 --- /dev/null +++ b/lib/std/Target/loongarch.zig @@ -0,0 +1,146 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"32bit", + @"64bit", + d, + f, + la_global_with_abs, + la_global_with_pcrel, + la_local_with_abs, + lasx, + lbt, + lsx, + lvz, + ual, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"32bit")] = .{ + .llvm_name = "32bit", + .description = "LA32 Basic Integer and Privilege Instruction Set", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"64bit")] = .{ + .llvm_name = "64bit", + .description = "LA64 Basic Integer and Privilege Instruction Set", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.d)] = .{ + .llvm_name = "d", + .description = "'D' (Double-Precision Floating-Point)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.f)] = .{ + .llvm_name = "f", + .description = "'F' (Single-Precision Floating-Point)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.la_global_with_abs)] = .{ + .llvm_name = "la-global-with-abs", + .description = "Expand la.global as la.abs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.la_global_with_pcrel)] = .{ + .llvm_name = "la-global-with-pcrel", + .description = "Expand la.global as la.pcrel", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.la_local_with_abs)] = .{ + .llvm_name = "la-local-with-abs", + .description = "Expand la.local as la.abs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lasx)] = .{ + .llvm_name = "lasx", + .description = "'LASX' (Loongson Advanced SIMD Extension)", + .dependencies = featureSet(&[_]Feature{ + .lsx, + }), + }; + result[@intFromEnum(Feature.lbt)] = .{ + .llvm_name = "lbt", + .description = "'LBT' (Loongson Binary Translation Extension)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lsx)] = .{ + .llvm_name = "lsx", + .description = "'LSX' (Loongson SIMD Extension)", + .dependencies = featureSet(&[_]Feature{ + .d, + }), + }; + result[@intFromEnum(Feature.lvz)] = .{ + .llvm_name = "lvz", + .description = "'LVZ' (Loongson Virtualization Extension)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ual)] = .{ + .llvm_name = "ual", + .description = "Allow memory accesses to be unaligned", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const generic_la32 = CpuModel{ + .name = "generic_la32", + .llvm_name = "generic-la32", + .features = featureSet(&[_]Feature{ + .@"32bit", + }), + }; + pub const generic_la64 = CpuModel{ + .name = "generic_la64", + .llvm_name = "generic-la64", + .features = featureSet(&[_]Feature{ + .@"64bit", + .ual, + }), + }; + pub const la464 = CpuModel{ + .name = "la464", + .llvm_name = "la464", + .features = featureSet(&[_]Feature{ + .@"64bit", + .lasx, + .lbt, + .lvz, + .ual, + }), + }; + pub const loongarch64 = CpuModel{ + .name = "loongarch64", + .llvm_name = "loongarch64", + .features = featureSet(&[_]Feature{ + .@"64bit", + .d, + .ual, + }), + }; +}; diff --git a/lib/std/Target/m68k.zig b/lib/std/Target/m68k.zig new file mode 100644 index 0000000000..054b3974d1 --- /dev/null +++ b/lib/std/Target/m68k.zig @@ -0,0 +1,228 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + isa_68000, + isa_68010, + isa_68020, + isa_68030, + isa_68040, + isa_68060, + isa_68881, + isa_68882, + reserve_a0, + reserve_a1, + reserve_a2, + reserve_a3, + reserve_a4, + reserve_a5, + reserve_a6, + reserve_d0, + reserve_d1, + reserve_d2, + reserve_d3, + reserve_d4, + reserve_d5, + reserve_d6, + reserve_d7, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.isa_68000)] = .{ + .llvm_name = "isa-68000", + .description = "Is M68000 ISA supported", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.isa_68010)] = .{ + .llvm_name = "isa-68010", + .description = "Is M68010 ISA supported", + .dependencies = featureSet(&[_]Feature{ + .isa_68000, + }), + }; + result[@intFromEnum(Feature.isa_68020)] = .{ + .llvm_name = "isa-68020", + .description = "Is M68020 ISA supported", + .dependencies = featureSet(&[_]Feature{ + .isa_68010, + }), + }; + result[@intFromEnum(Feature.isa_68030)] = .{ + .llvm_name = "isa-68030", + .description = "Is M68030 ISA supported", + .dependencies = featureSet(&[_]Feature{ + .isa_68020, + }), + }; + result[@intFromEnum(Feature.isa_68040)] = .{ + .llvm_name = "isa-68040", + .description = "Is M68040 ISA supported", + .dependencies = featureSet(&[_]Feature{ + .isa_68030, + .isa_68882, + }), + }; + result[@intFromEnum(Feature.isa_68060)] = .{ + .llvm_name = "isa-68060", + .description = "Is M68060 ISA supported", + .dependencies = featureSet(&[_]Feature{ + .isa_68040, + }), + }; + result[@intFromEnum(Feature.isa_68881)] = .{ + .llvm_name = "isa-68881", + .description = "Is M68881 (FPU) ISA supported", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.isa_68882)] = .{ + .llvm_name = "isa-68882", + .description = "Is M68882 (FPU) ISA supported", + .dependencies = featureSet(&[_]Feature{ + .isa_68881, + }), + }; + result[@intFromEnum(Feature.reserve_a0)] = .{ + .llvm_name = "reserve-a0", + .description = "Reserve A0 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_a1)] = .{ + .llvm_name = "reserve-a1", + .description = "Reserve A1 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_a2)] = .{ + .llvm_name = "reserve-a2", + .description = "Reserve A2 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_a3)] = .{ + .llvm_name = "reserve-a3", + .description = "Reserve A3 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_a4)] = .{ + .llvm_name = "reserve-a4", + .description = "Reserve A4 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_a5)] = .{ + .llvm_name = "reserve-a5", + .description = "Reserve A5 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_a6)] = .{ + .llvm_name = "reserve-a6", + .description = "Reserve A6 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d0)] = .{ + .llvm_name = "reserve-d0", + .description = "Reserve D0 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d1)] = .{ + .llvm_name = "reserve-d1", + .description = "Reserve D1 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d2)] = .{ + .llvm_name = "reserve-d2", + .description = "Reserve D2 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d3)] = .{ + .llvm_name = "reserve-d3", + .description = "Reserve D3 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d4)] = .{ + .llvm_name = "reserve-d4", + .description = "Reserve D4 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d5)] = .{ + .llvm_name = "reserve-d5", + .description = "Reserve D5 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d6)] = .{ + .llvm_name = "reserve-d6", + .description = "Reserve D6 register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_d7)] = .{ + .llvm_name = "reserve-d7", + .description = "Reserve D7 register", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .isa_68000, + }), + }; + pub const M68000 = CpuModel{ + .name = "M68000", + .llvm_name = "M68000", + .features = featureSet(&[_]Feature{ + .isa_68000, + }), + }; + pub const M68010 = CpuModel{ + .name = "M68010", + .llvm_name = "M68010", + .features = featureSet(&[_]Feature{ + .isa_68010, + }), + }; + pub const M68020 = CpuModel{ + .name = "M68020", + .llvm_name = "M68020", + .features = featureSet(&[_]Feature{ + .isa_68020, + }), + }; + pub const M68030 = CpuModel{ + .name = "M68030", + .llvm_name = "M68030", + .features = featureSet(&[_]Feature{ + .isa_68030, + }), + }; + pub const M68040 = CpuModel{ + .name = "M68040", + .llvm_name = "M68040", + .features = featureSet(&[_]Feature{ + .isa_68040, + }), + }; + pub const M68060 = CpuModel{ + .name = "M68060", + .llvm_name = "M68060", + .features = featureSet(&[_]Feature{ + .isa_68060, + }), + }; +}; diff --git a/lib/std/Target/mips.zig b/lib/std/Target/mips.zig new file mode 100644 index 0000000000..8f3c0994d1 --- /dev/null +++ b/lib/std/Target/mips.zig @@ -0,0 +1,531 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + abs2008, + cnmips, + cnmipsp, + crc, + dsp, + dspr2, + dspr3, + eva, + fp64, + fpxx, + ginv, + gp64, + long_calls, + micromips, + mips1, + mips16, + mips2, + mips3, + mips32, + mips32r2, + mips32r3, + mips32r5, + mips32r6, + mips3_32, + mips3_32r2, + mips3d, + mips4, + mips4_32, + mips4_32r2, + mips5, + mips5_32r2, + mips64, + mips64r2, + mips64r3, + mips64r5, + mips64r6, + msa, + mt, + nan2008, + noabicalls, + nomadd4, + nooddspreg, + p5600, + ptr64, + single_float, + soft_float, + sym32, + use_indirect_jump_hazard, + use_tcc_in_div, + vfpu, + virt, + xgot, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.abs2008)] = .{ + .llvm_name = "abs2008", + .description = "Disable IEEE 754-2008 abs.fmt mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cnmips)] = .{ + .llvm_name = "cnmips", + .description = "Octeon cnMIPS Support", + .dependencies = featureSet(&[_]Feature{ + .mips64r2, + }), + }; + result[@intFromEnum(Feature.cnmipsp)] = .{ + .llvm_name = "cnmipsp", + .description = "Octeon+ cnMIPS Support", + .dependencies = featureSet(&[_]Feature{ + .cnmips, + }), + }; + result[@intFromEnum(Feature.crc)] = .{ + .llvm_name = "crc", + .description = "Mips R6 CRC ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dsp)] = .{ + .llvm_name = "dsp", + .description = "Mips DSP ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dspr2)] = .{ + .llvm_name = "dspr2", + .description = "Mips DSP-R2 ASE", + .dependencies = featureSet(&[_]Feature{ + .dsp, + }), + }; + result[@intFromEnum(Feature.dspr3)] = .{ + .llvm_name = "dspr3", + .description = "Mips DSP-R3 ASE", + .dependencies = featureSet(&[_]Feature{ + .dspr2, + }), + }; + result[@intFromEnum(Feature.eva)] = .{ + .llvm_name = "eva", + .description = "Mips EVA ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp64)] = .{ + .llvm_name = "fp64", + .description = "Support 64-bit FP registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fpxx)] = .{ + .llvm_name = "fpxx", + .description = "Support for FPXX", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ginv)] = .{ + .llvm_name = "ginv", + .description = "Mips Global Invalidate ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gp64)] = .{ + .llvm_name = "gp64", + .description = "General Purpose Registers are 64-bit wide", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.long_calls)] = .{ + .llvm_name = "long-calls", + .description = "Disable use of the jal instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.micromips)] = .{ + .llvm_name = "micromips", + .description = "microMips mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips1)] = .{ + .llvm_name = "mips1", + .description = "Mips I ISA Support [highly experimental]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips16)] = .{ + .llvm_name = "mips16", + .description = "Mips16 mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips2)] = .{ + .llvm_name = "mips2", + .description = "Mips II ISA Support [highly experimental]", + .dependencies = featureSet(&[_]Feature{ + .mips1, + }), + }; + result[@intFromEnum(Feature.mips3)] = .{ + .llvm_name = "mips3", + .description = "MIPS III ISA Support [highly experimental]", + .dependencies = featureSet(&[_]Feature{ + .fp64, + .gp64, + .mips2, + .mips3_32, + .mips3_32r2, + }), + }; + result[@intFromEnum(Feature.mips32)] = .{ + .llvm_name = "mips32", + .description = "Mips32 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips2, + .mips3_32, + .mips4_32, + }), + }; + result[@intFromEnum(Feature.mips32r2)] = .{ + .llvm_name = "mips32r2", + .description = "Mips32r2 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32, + .mips3_32r2, + .mips4_32r2, + .mips5_32r2, + }), + }; + result[@intFromEnum(Feature.mips32r3)] = .{ + .llvm_name = "mips32r3", + .description = "Mips32r3 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32r2, + }), + }; + result[@intFromEnum(Feature.mips32r5)] = .{ + .llvm_name = "mips32r5", + .description = "Mips32r5 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32r3, + }), + }; + result[@intFromEnum(Feature.mips32r6)] = .{ + .llvm_name = "mips32r6", + .description = "Mips32r6 ISA Support [experimental]", + .dependencies = featureSet(&[_]Feature{ + .abs2008, + .fp64, + .mips32r5, + .nan2008, + }), + }; + result[@intFromEnum(Feature.mips3_32)] = .{ + .llvm_name = "mips3_32", + .description = "Subset of MIPS-III that is also in MIPS32 [highly experimental]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips3_32r2)] = .{ + .llvm_name = "mips3_32r2", + .description = "Subset of MIPS-III that is also in MIPS32r2 [highly experimental]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips3d)] = .{ + .llvm_name = "mips3d", + .description = "Mips 3D ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips4)] = .{ + .llvm_name = "mips4", + .description = "MIPS IV ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips3, + .mips4_32, + .mips4_32r2, + }), + }; + result[@intFromEnum(Feature.mips4_32)] = .{ + .llvm_name = "mips4_32", + .description = "Subset of MIPS-IV that is also in MIPS32 [highly experimental]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips4_32r2)] = .{ + .llvm_name = "mips4_32r2", + .description = "Subset of MIPS-IV that is also in MIPS32r2 [highly experimental]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips5)] = .{ + .llvm_name = "mips5", + .description = "MIPS V ISA Support [highly experimental]", + .dependencies = featureSet(&[_]Feature{ + .mips4, + .mips5_32r2, + }), + }; + result[@intFromEnum(Feature.mips5_32r2)] = .{ + .llvm_name = "mips5_32r2", + .description = "Subset of MIPS-V that is also in MIPS32r2 [highly experimental]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mips64)] = .{ + .llvm_name = "mips64", + .description = "Mips64 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32, + .mips5, + }), + }; + result[@intFromEnum(Feature.mips64r2)] = .{ + .llvm_name = "mips64r2", + .description = "Mips64r2 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32r2, + .mips64, + }), + }; + result[@intFromEnum(Feature.mips64r3)] = .{ + .llvm_name = "mips64r3", + .description = "Mips64r3 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32r3, + .mips64r2, + }), + }; + result[@intFromEnum(Feature.mips64r5)] = .{ + .llvm_name = "mips64r5", + .description = "Mips64r5 ISA Support", + .dependencies = featureSet(&[_]Feature{ + .mips32r5, + .mips64r3, + }), + }; + result[@intFromEnum(Feature.mips64r6)] = .{ + .llvm_name = "mips64r6", + .description = "Mips64r6 ISA Support [experimental]", + .dependencies = featureSet(&[_]Feature{ + .mips32r6, + .mips64r5, + }), + }; + result[@intFromEnum(Feature.msa)] = .{ + .llvm_name = "msa", + .description = "Mips MSA ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mt)] = .{ + .llvm_name = "mt", + .description = "Mips MT ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nan2008)] = .{ + .llvm_name = "nan2008", + .description = "IEEE 754-2008 NaN encoding", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.noabicalls)] = .{ + .llvm_name = "noabicalls", + .description = "Disable SVR4-style position-independent code", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nomadd4)] = .{ + .llvm_name = "nomadd4", + .description = "Disable 4-operand madd.fmt and related instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nooddspreg)] = .{ + .llvm_name = "nooddspreg", + .description = "Disable odd numbered single-precision registers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.p5600)] = .{ + .llvm_name = "p5600", + .description = "The P5600 Processor", + .dependencies = featureSet(&[_]Feature{ + .mips32r5, + }), + }; + result[@intFromEnum(Feature.ptr64)] = .{ + .llvm_name = "ptr64", + .description = "Pointers are 64-bit wide", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.single_float)] = .{ + .llvm_name = "single-float", + .description = "Only supports single precision float", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.soft_float)] = .{ + .llvm_name = "soft-float", + .description = "Does not support floating point instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sym32)] = .{ + .llvm_name = "sym32", + .description = "Symbols are 32 bit on Mips64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_indirect_jump_hazard)] = .{ + .llvm_name = "use-indirect-jump-hazard", + .description = "Use indirect jump guards to prevent certain speculation based attacks", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_tcc_in_div)] = .{ + .llvm_name = "use-tcc-in-div", + .description = "Force the assembler to use trapping", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vfpu)] = .{ + .llvm_name = "vfpu", + .description = "Enable vector FPU instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.virt)] = .{ + .llvm_name = "virt", + .description = "Mips Virtualization ASE", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xgot)] = .{ + .llvm_name = "xgot", + .description = "Assume 32-bit GOT", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .mips32, + }), + }; + pub const mips1 = CpuModel{ + .name = "mips1", + .llvm_name = "mips1", + .features = featureSet(&[_]Feature{ + .mips1, + }), + }; + pub const mips2 = CpuModel{ + .name = "mips2", + .llvm_name = "mips2", + .features = featureSet(&[_]Feature{ + .mips2, + }), + }; + pub const mips3 = CpuModel{ + .name = "mips3", + .llvm_name = "mips3", + .features = featureSet(&[_]Feature{ + .mips3, + }), + }; + pub const mips32 = CpuModel{ + .name = "mips32", + .llvm_name = "mips32", + .features = featureSet(&[_]Feature{ + .mips32, + }), + }; + pub const mips32r2 = CpuModel{ + .name = "mips32r2", + .llvm_name = "mips32r2", + .features = featureSet(&[_]Feature{ + .mips32r2, + }), + }; + pub const mips32r3 = CpuModel{ + .name = "mips32r3", + .llvm_name = "mips32r3", + .features = featureSet(&[_]Feature{ + .mips32r3, + }), + }; + pub const mips32r5 = CpuModel{ + .name = "mips32r5", + .llvm_name = "mips32r5", + .features = featureSet(&[_]Feature{ + .mips32r5, + }), + }; + pub const mips32r6 = CpuModel{ + .name = "mips32r6", + .llvm_name = "mips32r6", + .features = featureSet(&[_]Feature{ + .mips32r6, + }), + }; + pub const mips4 = CpuModel{ + .name = "mips4", + .llvm_name = "mips4", + .features = featureSet(&[_]Feature{ + .mips4, + }), + }; + pub const mips5 = CpuModel{ + .name = "mips5", + .llvm_name = "mips5", + .features = featureSet(&[_]Feature{ + .mips5, + }), + }; + pub const mips64 = CpuModel{ + .name = "mips64", + .llvm_name = "mips64", + .features = featureSet(&[_]Feature{ + .mips64, + }), + }; + pub const mips64r2 = CpuModel{ + .name = "mips64r2", + .llvm_name = "mips64r2", + .features = featureSet(&[_]Feature{ + .mips64r2, + }), + }; + pub const mips64r3 = CpuModel{ + .name = "mips64r3", + .llvm_name = "mips64r3", + .features = featureSet(&[_]Feature{ + .mips64r3, + }), + }; + pub const mips64r5 = CpuModel{ + .name = "mips64r5", + .llvm_name = "mips64r5", + .features = featureSet(&[_]Feature{ + .mips64r5, + }), + }; + pub const mips64r6 = CpuModel{ + .name = "mips64r6", + .llvm_name = "mips64r6", + .features = featureSet(&[_]Feature{ + .mips64r6, + }), + }; + pub const octeon = CpuModel{ + .name = "octeon", + .llvm_name = "octeon", + .features = featureSet(&[_]Feature{ + .cnmips, + }), + }; + pub const @"octeon+" = CpuModel{ + .name = "octeon+", + .llvm_name = "octeon+", + .features = featureSet(&[_]Feature{ + .cnmipsp, + }), + }; + pub const p5600 = CpuModel{ + .name = "p5600", + .llvm_name = "p5600", + .features = featureSet(&[_]Feature{ + .p5600, + }), + }; +}; diff --git a/lib/std/Target/msp430.zig b/lib/std/Target/msp430.zig new file mode 100644 index 0000000000..98ea32d17f --- /dev/null +++ b/lib/std/Target/msp430.zig @@ -0,0 +1,69 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + ext, + hwmult16, + hwmult32, + hwmultf5, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.ext)] = .{ + .llvm_name = "ext", + .description = "Enable MSP430-X extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hwmult16)] = .{ + .llvm_name = "hwmult16", + .description = "Enable 16-bit hardware multiplier", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hwmult32)] = .{ + .llvm_name = "hwmult32", + .description = "Enable 32-bit hardware multiplier", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hwmultf5)] = .{ + .llvm_name = "hwmultf5", + .description = "Enable F5 series hardware multiplier", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const msp430 = CpuModel{ + .name = "msp430", + .llvm_name = "msp430", + .features = featureSet(&[_]Feature{}), + }; + pub const msp430x = CpuModel{ + .name = "msp430x", + .llvm_name = "msp430x", + .features = featureSet(&[_]Feature{ + .ext, + }), + }; +}; diff --git a/lib/std/Target/nvptx.zig b/lib/std/Target/nvptx.zig new file mode 100644 index 0000000000..99a281604b --- /dev/null +++ b/lib/std/Target/nvptx.zig @@ -0,0 +1,439 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + ptx32, + ptx40, + ptx41, + ptx42, + ptx43, + ptx50, + ptx60, + ptx61, + ptx63, + ptx64, + ptx65, + ptx70, + ptx71, + ptx72, + ptx73, + ptx74, + ptx75, + ptx76, + ptx77, + ptx78, + ptx80, + ptx81, + sm_20, + sm_21, + sm_30, + sm_32, + sm_35, + sm_37, + sm_50, + sm_52, + sm_53, + sm_60, + sm_61, + sm_62, + sm_70, + sm_72, + sm_75, + sm_80, + sm_86, + sm_87, + sm_89, + sm_90, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.ptx32)] = .{ + .llvm_name = "ptx32", + .description = "Use PTX version 32", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx40)] = .{ + .llvm_name = "ptx40", + .description = "Use PTX version 40", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx41)] = .{ + .llvm_name = "ptx41", + .description = "Use PTX version 41", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx42)] = .{ + .llvm_name = "ptx42", + .description = "Use PTX version 42", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx43)] = .{ + .llvm_name = "ptx43", + .description = "Use PTX version 43", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx50)] = .{ + .llvm_name = "ptx50", + .description = "Use PTX version 50", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx60)] = .{ + .llvm_name = "ptx60", + .description = "Use PTX version 60", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx61)] = .{ + .llvm_name = "ptx61", + .description = "Use PTX version 61", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx63)] = .{ + .llvm_name = "ptx63", + .description = "Use PTX version 63", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx64)] = .{ + .llvm_name = "ptx64", + .description = "Use PTX version 64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx65)] = .{ + .llvm_name = "ptx65", + .description = "Use PTX version 65", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx70)] = .{ + .llvm_name = "ptx70", + .description = "Use PTX version 70", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx71)] = .{ + .llvm_name = "ptx71", + .description = "Use PTX version 71", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx72)] = .{ + .llvm_name = "ptx72", + .description = "Use PTX version 72", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx73)] = .{ + .llvm_name = "ptx73", + .description = "Use PTX version 73", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx74)] = .{ + .llvm_name = "ptx74", + .description = "Use PTX version 74", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx75)] = .{ + .llvm_name = "ptx75", + .description = "Use PTX version 75", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx76)] = .{ + .llvm_name = "ptx76", + .description = "Use PTX version 76", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx77)] = .{ + .llvm_name = "ptx77", + .description = "Use PTX version 77", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx78)] = .{ + .llvm_name = "ptx78", + .description = "Use PTX version 78", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx80)] = .{ + .llvm_name = "ptx80", + .description = "Use PTX version 80", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptx81)] = .{ + .llvm_name = "ptx81", + .description = "Use PTX version 81", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_20)] = .{ + .llvm_name = "sm_20", + .description = "Target SM 20", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_21)] = .{ + .llvm_name = "sm_21", + .description = "Target SM 21", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_30)] = .{ + .llvm_name = "sm_30", + .description = "Target SM 30", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_32)] = .{ + .llvm_name = "sm_32", + .description = "Target SM 32", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_35)] = .{ + .llvm_name = "sm_35", + .description = "Target SM 35", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_37)] = .{ + .llvm_name = "sm_37", + .description = "Target SM 37", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_50)] = .{ + .llvm_name = "sm_50", + .description = "Target SM 50", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_52)] = .{ + .llvm_name = "sm_52", + .description = "Target SM 52", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_53)] = .{ + .llvm_name = "sm_53", + .description = "Target SM 53", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_60)] = .{ + .llvm_name = "sm_60", + .description = "Target SM 60", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_61)] = .{ + .llvm_name = "sm_61", + .description = "Target SM 61", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_62)] = .{ + .llvm_name = "sm_62", + .description = "Target SM 62", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_70)] = .{ + .llvm_name = "sm_70", + .description = "Target SM 70", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_72)] = .{ + .llvm_name = "sm_72", + .description = "Target SM 72", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_75)] = .{ + .llvm_name = "sm_75", + .description = "Target SM 75", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_80)] = .{ + .llvm_name = "sm_80", + .description = "Target SM 80", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_86)] = .{ + .llvm_name = "sm_86", + .description = "Target SM 86", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_87)] = .{ + .llvm_name = "sm_87", + .description = "Target SM 87", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_89)] = .{ + .llvm_name = "sm_89", + .description = "Target SM 89", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm_90)] = .{ + .llvm_name = "sm_90", + .description = "Target SM 90", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const sm_20 = CpuModel{ + .name = "sm_20", + .llvm_name = "sm_20", + .features = featureSet(&[_]Feature{ + .ptx32, + .sm_20, + }), + }; + pub const sm_21 = CpuModel{ + .name = "sm_21", + .llvm_name = "sm_21", + .features = featureSet(&[_]Feature{ + .ptx32, + .sm_21, + }), + }; + pub const sm_30 = CpuModel{ + .name = "sm_30", + .llvm_name = "sm_30", + .features = featureSet(&[_]Feature{ + .sm_30, + }), + }; + pub const sm_32 = CpuModel{ + .name = "sm_32", + .llvm_name = "sm_32", + .features = featureSet(&[_]Feature{ + .ptx40, + .sm_32, + }), + }; + pub const sm_35 = CpuModel{ + .name = "sm_35", + .llvm_name = "sm_35", + .features = featureSet(&[_]Feature{ + .ptx32, + .sm_35, + }), + }; + pub const sm_37 = CpuModel{ + .name = "sm_37", + .llvm_name = "sm_37", + .features = featureSet(&[_]Feature{ + .ptx41, + .sm_37, + }), + }; + pub const sm_50 = CpuModel{ + .name = "sm_50", + .llvm_name = "sm_50", + .features = featureSet(&[_]Feature{ + .ptx40, + .sm_50, + }), + }; + pub const sm_52 = CpuModel{ + .name = "sm_52", + .llvm_name = "sm_52", + .features = featureSet(&[_]Feature{ + .ptx41, + .sm_52, + }), + }; + pub const sm_53 = CpuModel{ + .name = "sm_53", + .llvm_name = "sm_53", + .features = featureSet(&[_]Feature{ + .ptx42, + .sm_53, + }), + }; + pub const sm_60 = CpuModel{ + .name = "sm_60", + .llvm_name = "sm_60", + .features = featureSet(&[_]Feature{ + .ptx50, + .sm_60, + }), + }; + pub const sm_61 = CpuModel{ + .name = "sm_61", + .llvm_name = "sm_61", + .features = featureSet(&[_]Feature{ + .ptx50, + .sm_61, + }), + }; + pub const sm_62 = CpuModel{ + .name = "sm_62", + .llvm_name = "sm_62", + .features = featureSet(&[_]Feature{ + .ptx50, + .sm_62, + }), + }; + pub const sm_70 = CpuModel{ + .name = "sm_70", + .llvm_name = "sm_70", + .features = featureSet(&[_]Feature{ + .ptx60, + .sm_70, + }), + }; + pub const sm_72 = CpuModel{ + .name = "sm_72", + .llvm_name = "sm_72", + .features = featureSet(&[_]Feature{ + .ptx61, + .sm_72, + }), + }; + pub const sm_75 = CpuModel{ + .name = "sm_75", + .llvm_name = "sm_75", + .features = featureSet(&[_]Feature{ + .ptx63, + .sm_75, + }), + }; + pub const sm_80 = CpuModel{ + .name = "sm_80", + .llvm_name = "sm_80", + .features = featureSet(&[_]Feature{ + .ptx70, + .sm_80, + }), + }; + pub const sm_86 = CpuModel{ + .name = "sm_86", + .llvm_name = "sm_86", + .features = featureSet(&[_]Feature{ + .ptx71, + .sm_86, + }), + }; + pub const sm_87 = CpuModel{ + .name = "sm_87", + .llvm_name = "sm_87", + .features = featureSet(&[_]Feature{ + .ptx74, + .sm_87, + }), + }; + pub const sm_89 = CpuModel{ + .name = "sm_89", + .llvm_name = "sm_89", + .features = featureSet(&[_]Feature{ + .ptx78, + .sm_89, + }), + }; + pub const sm_90 = CpuModel{ + .name = "sm_90", + .llvm_name = "sm_90", + .features = featureSet(&[_]Feature{ + .ptx78, + .sm_90, + }), + }; +}; diff --git a/lib/std/Target/powerpc.zig b/lib/std/Target/powerpc.zig new file mode 100644 index 0000000000..c350c166ba --- /dev/null +++ b/lib/std/Target/powerpc.zig @@ -0,0 +1,1192 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"64bit", + @"64bitregs", + aix, + allow_unaligned_fp_access, + altivec, + booke, + bpermd, + cmpb, + crbits, + crypto, + direct_move, + e500, + efpu2, + extdiv, + fast_MFLR, + fcpsgn, + float128, + fpcvt, + fprnd, + fpu, + fre, + fres, + frsqrte, + frsqrtes, + fsqrt, + fuse_add_logical, + fuse_addi_load, + fuse_addis_load, + fuse_arith_add, + fuse_back2back, + fuse_cmp, + fuse_logical, + fuse_logical_add, + fuse_sha3, + fuse_store, + fuse_wideimm, + fuse_zeromove, + fusion, + hard_float, + htm, + icbt, + invariant_function_descriptors, + isa_future_instructions, + isa_v206_instructions, + isa_v207_instructions, + isa_v30_instructions, + isa_v31_instructions, + isel, + ldbrx, + lfiwax, + longcall, + mfocrf, + mma, + modern_aix_as, + msync, + paired_vector_memops, + partword_atomics, + pcrelative_memops, + popcntd, + power10_vector, + power8_altivec, + power8_vector, + power9_altivec, + power9_vector, + ppc4xx, + ppc6xx, + ppc_postra_sched, + ppc_prera_sched, + predictable_select_expensive, + prefix_instrs, + privileged, + quadword_atomics, + recipprec, + rop_protect, + secure_plt, + slow_popcntd, + spe, + stfiwx, + two_const_nr, + vectors_use_two_units, + vsx, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"64bit")] = .{ + .llvm_name = "64bit", + .description = "Enable 64-bit instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"64bitregs")] = .{ + .llvm_name = "64bitregs", + .description = "Enable 64-bit registers usage for ppc32 [beta]", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.aix)] = .{ + .llvm_name = "aix", + .description = "AIX OS", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.allow_unaligned_fp_access)] = .{ + .llvm_name = "allow-unaligned-fp-access", + .description = "CPU does not trap on unaligned FP access", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.altivec)] = .{ + .llvm_name = "altivec", + .description = "Enable Altivec instructions", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.booke)] = .{ + .llvm_name = "booke", + .description = "Enable Book E instructions", + .dependencies = featureSet(&[_]Feature{ + .icbt, + }), + }; + result[@intFromEnum(Feature.bpermd)] = .{ + .llvm_name = "bpermd", + .description = "Enable the bpermd instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cmpb)] = .{ + .llvm_name = "cmpb", + .description = "Enable the cmpb instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.crbits)] = .{ + .llvm_name = "crbits", + .description = "Use condition-register bits individually", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.crypto)] = .{ + .llvm_name = "crypto", + .description = "Enable POWER8 Crypto instructions", + .dependencies = featureSet(&[_]Feature{ + .power8_altivec, + }), + }; + result[@intFromEnum(Feature.direct_move)] = .{ + .llvm_name = "direct-move", + .description = "Enable Power8 direct move instructions", + .dependencies = featureSet(&[_]Feature{ + .vsx, + }), + }; + result[@intFromEnum(Feature.e500)] = .{ + .llvm_name = "e500", + .description = "Enable E500/E500mc instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.efpu2)] = .{ + .llvm_name = "efpu2", + .description = "Enable Embedded Floating-Point APU 2 instructions", + .dependencies = featureSet(&[_]Feature{ + .spe, + }), + }; + result[@intFromEnum(Feature.extdiv)] = .{ + .llvm_name = "extdiv", + .description = "Enable extended divide instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_MFLR)] = .{ + .llvm_name = "fast-MFLR", + .description = "MFLR is a fast instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fcpsgn)] = .{ + .llvm_name = "fcpsgn", + .description = "Enable the fcpsgn instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.float128)] = .{ + .llvm_name = "float128", + .description = "Enable the __float128 data type for IEEE-754R Binary128.", + .dependencies = featureSet(&[_]Feature{ + .vsx, + }), + }; + result[@intFromEnum(Feature.fpcvt)] = .{ + .llvm_name = "fpcvt", + .description = "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.fprnd)] = .{ + .llvm_name = "fprnd", + .description = "Enable the fri[mnpz] instructions", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.fpu)] = .{ + .llvm_name = "fpu", + .description = "Enable classic FPU instructions", + .dependencies = featureSet(&[_]Feature{ + .hard_float, + }), + }; + result[@intFromEnum(Feature.fre)] = .{ + .llvm_name = "fre", + .description = "Enable the fre instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.fres)] = .{ + .llvm_name = "fres", + .description = "Enable the fres instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.frsqrte)] = .{ + .llvm_name = "frsqrte", + .description = "Enable the frsqrte instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.frsqrtes)] = .{ + .llvm_name = "frsqrtes", + .description = "Enable the frsqrtes instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.fsqrt)] = .{ + .llvm_name = "fsqrt", + .description = "Enable the fsqrt instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.fuse_add_logical)] = .{ + .llvm_name = "fuse-add-logical", + .description = "Target supports Add with Logical Operations fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_addi_load)] = .{ + .llvm_name = "fuse-addi-load", + .description = "Power8 Addi-Load fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_addis_load)] = .{ + .llvm_name = "fuse-addis-load", + .description = "Power8 Addis-Load fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_arith_add)] = .{ + .llvm_name = "fuse-arith-add", + .description = "Target supports Arithmetic Operations with Add fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_back2back)] = .{ + .llvm_name = "fuse-back2back", + .description = "Target supports general back to back fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_cmp)] = .{ + .llvm_name = "fuse-cmp", + .description = "Target supports Comparison Operations fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_logical)] = .{ + .llvm_name = "fuse-logical", + .description = "Target supports Logical Operations fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_logical_add)] = .{ + .llvm_name = "fuse-logical-add", + .description = "Target supports Logical with Add Operations fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_sha3)] = .{ + .llvm_name = "fuse-sha3", + .description = "Target supports SHA3 assist fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_store)] = .{ + .llvm_name = "fuse-store", + .description = "Target supports store clustering", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_wideimm)] = .{ + .llvm_name = "fuse-wideimm", + .description = "Target supports Wide-Immediate fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fuse_zeromove)] = .{ + .llvm_name = "fuse-zeromove", + .description = "Target supports move to SPR with branch fusion", + .dependencies = featureSet(&[_]Feature{ + .fusion, + }), + }; + result[@intFromEnum(Feature.fusion)] = .{ + .llvm_name = "fusion", + .description = "Target supports instruction fusion", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hard_float)] = .{ + .llvm_name = "hard-float", + .description = "Enable floating-point instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.htm)] = .{ + .llvm_name = "htm", + .description = "Enable Hardware Transactional Memory instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.icbt)] = .{ + .llvm_name = "icbt", + .description = "Enable icbt instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.invariant_function_descriptors)] = .{ + .llvm_name = "invariant-function-descriptors", + .description = "Assume function descriptors are invariant", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.isa_future_instructions)] = .{ + .llvm_name = "isa-future-instructions", + .description = "Enable instructions for Future ISA.", + .dependencies = featureSet(&[_]Feature{ + .isa_v31_instructions, + }), + }; + result[@intFromEnum(Feature.isa_v206_instructions)] = .{ + .llvm_name = "isa-v206-instructions", + .description = "Enable instructions in ISA 2.06.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.isa_v207_instructions)] = .{ + .llvm_name = "isa-v207-instructions", + .description = "Enable instructions in ISA 2.07.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.isa_v30_instructions)] = .{ + .llvm_name = "isa-v30-instructions", + .description = "Enable instructions in ISA 3.0.", + .dependencies = featureSet(&[_]Feature{ + .isa_v207_instructions, + }), + }; + result[@intFromEnum(Feature.isa_v31_instructions)] = .{ + .llvm_name = "isa-v31-instructions", + .description = "Enable instructions in ISA 3.1.", + .dependencies = featureSet(&[_]Feature{ + .isa_v30_instructions, + }), + }; + result[@intFromEnum(Feature.isel)] = .{ + .llvm_name = "isel", + .description = "Enable the isel instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ldbrx)] = .{ + .llvm_name = "ldbrx", + .description = "Enable the ldbrx instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lfiwax)] = .{ + .llvm_name = "lfiwax", + .description = "Enable the lfiwax instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.longcall)] = .{ + .llvm_name = "longcall", + .description = "Always use indirect calls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mfocrf)] = .{ + .llvm_name = "mfocrf", + .description = "Enable the MFOCRF instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mma)] = .{ + .llvm_name = "mma", + .description = "Enable MMA instructions", + .dependencies = featureSet(&[_]Feature{ + .paired_vector_memops, + .power8_vector, + .power9_altivec, + }), + }; + result[@intFromEnum(Feature.modern_aix_as)] = .{ + .llvm_name = "modern-aix-as", + .description = "AIX system assembler is modern enough to support new mnes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.msync)] = .{ + .llvm_name = "msync", + .description = "Has only the msync instruction instead of sync", + .dependencies = featureSet(&[_]Feature{ + .booke, + }), + }; + result[@intFromEnum(Feature.paired_vector_memops)] = .{ + .llvm_name = "paired-vector-memops", + .description = "32Byte load and store instructions", + .dependencies = featureSet(&[_]Feature{ + .isa_v30_instructions, + }), + }; + result[@intFromEnum(Feature.partword_atomics)] = .{ + .llvm_name = "partword-atomics", + .description = "Enable l[bh]arx and st[bh]cx.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pcrelative_memops)] = .{ + .llvm_name = "pcrelative-memops", + .description = "Enable PC relative Memory Ops", + .dependencies = featureSet(&[_]Feature{ + .prefix_instrs, + }), + }; + result[@intFromEnum(Feature.popcntd)] = .{ + .llvm_name = "popcntd", + .description = "Enable the popcnt[dw] instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.power10_vector)] = .{ + .llvm_name = "power10-vector", + .description = "Enable POWER10 vector instructions", + .dependencies = featureSet(&[_]Feature{ + .isa_v31_instructions, + .power9_vector, + }), + }; + result[@intFromEnum(Feature.power8_altivec)] = .{ + .llvm_name = "power8-altivec", + .description = "Enable POWER8 Altivec instructions", + .dependencies = featureSet(&[_]Feature{ + .altivec, + }), + }; + result[@intFromEnum(Feature.power8_vector)] = .{ + .llvm_name = "power8-vector", + .description = "Enable POWER8 vector instructions", + .dependencies = featureSet(&[_]Feature{ + .power8_altivec, + .vsx, + }), + }; + result[@intFromEnum(Feature.power9_altivec)] = .{ + .llvm_name = "power9-altivec", + .description = "Enable POWER9 Altivec instructions", + .dependencies = featureSet(&[_]Feature{ + .isa_v30_instructions, + .power8_altivec, + }), + }; + result[@intFromEnum(Feature.power9_vector)] = .{ + .llvm_name = "power9-vector", + .description = "Enable POWER9 vector instructions", + .dependencies = featureSet(&[_]Feature{ + .power8_vector, + .power9_altivec, + }), + }; + result[@intFromEnum(Feature.ppc4xx)] = .{ + .llvm_name = "ppc4xx", + .description = "Enable PPC 4xx instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ppc6xx)] = .{ + .llvm_name = "ppc6xx", + .description = "Enable PPC 6xx instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ppc_postra_sched)] = .{ + .llvm_name = "ppc-postra-sched", + .description = "Use PowerPC post-RA scheduling strategy", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ppc_prera_sched)] = .{ + .llvm_name = "ppc-prera-sched", + .description = "Use PowerPC pre-RA scheduling strategy", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.predictable_select_expensive)] = .{ + .llvm_name = "predictable-select-expensive", + .description = "Prefer likely predicted branches over selects", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefix_instrs)] = .{ + .llvm_name = "prefix-instrs", + .description = "Enable prefixed instructions", + .dependencies = featureSet(&[_]Feature{ + .power8_vector, + .power9_altivec, + }), + }; + result[@intFromEnum(Feature.privileged)] = .{ + .llvm_name = "privileged", + .description = "Add privileged instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.quadword_atomics)] = .{ + .llvm_name = "quadword-atomics", + .description = "Enable lqarx and stqcx.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.recipprec)] = .{ + .llvm_name = "recipprec", + .description = "Assume higher precision reciprocal estimates", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rop_protect)] = .{ + .llvm_name = "rop-protect", + .description = "Add ROP protect", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.secure_plt)] = .{ + .llvm_name = "secure-plt", + .description = "Enable secure plt mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_popcntd)] = .{ + .llvm_name = "slow-popcntd", + .description = "Has slow popcnt[dw] instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.spe)] = .{ + .llvm_name = "spe", + .description = "Enable SPE instructions", + .dependencies = featureSet(&[_]Feature{ + .hard_float, + }), + }; + result[@intFromEnum(Feature.stfiwx)] = .{ + .llvm_name = "stfiwx", + .description = "Enable the stfiwx instruction", + .dependencies = featureSet(&[_]Feature{ + .fpu, + }), + }; + result[@intFromEnum(Feature.two_const_nr)] = .{ + .llvm_name = "two-const-nr", + .description = "Requires two constant Newton-Raphson computation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vectors_use_two_units)] = .{ + .llvm_name = "vectors-use-two-units", + .description = "Vectors use two units", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vsx)] = .{ + .llvm_name = "vsx", + .description = "Enable VSX instructions", + .dependencies = featureSet(&[_]Feature{ + .altivec, + }), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const @"440" = CpuModel{ + .name = "440", + .llvm_name = "440", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + .isel, + .msync, + }), + }; + pub const @"450" = CpuModel{ + .name = "450", + .llvm_name = "450", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + .isel, + .msync, + }), + }; + pub const @"601" = CpuModel{ + .name = "601", + .llvm_name = "601", + .features = featureSet(&[_]Feature{ + .fpu, + }), + }; + pub const @"602" = CpuModel{ + .name = "602", + .llvm_name = "602", + .features = featureSet(&[_]Feature{ + .fpu, + }), + }; + pub const @"603" = CpuModel{ + .name = "603", + .llvm_name = "603", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"603e" = CpuModel{ + .name = "603e", + .llvm_name = "603e", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"603ev" = CpuModel{ + .name = "603ev", + .llvm_name = "603ev", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"604" = CpuModel{ + .name = "604", + .llvm_name = "604", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"604e" = CpuModel{ + .name = "604e", + .llvm_name = "604e", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"620" = CpuModel{ + .name = "620", + .llvm_name = "620", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"7400" = CpuModel{ + .name = "7400", + .llvm_name = "7400", + .features = featureSet(&[_]Feature{ + .altivec, + .fres, + .frsqrte, + }), + }; + pub const @"7450" = CpuModel{ + .name = "7450", + .llvm_name = "7450", + .features = featureSet(&[_]Feature{ + .altivec, + .fres, + .frsqrte, + }), + }; + pub const @"750" = CpuModel{ + .name = "750", + .llvm_name = "750", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const @"970" = CpuModel{ + .name = "970", + .llvm_name = "970", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fres, + .frsqrte, + .fsqrt, + .mfocrf, + .stfiwx, + }), + }; + pub const a2 = CpuModel{ + .name = "a2", + .llvm_name = "a2", + .features = featureSet(&[_]Feature{ + .@"64bit", + .booke, + .cmpb, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .isa_v206_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .recipprec, + .slow_popcntd, + .stfiwx, + }), + }; + pub const e500 = CpuModel{ + .name = "e500", + .llvm_name = "e500", + .features = featureSet(&[_]Feature{ + .isel, + .msync, + .spe, + }), + }; + pub const e500mc = CpuModel{ + .name = "e500mc", + .llvm_name = "e500mc", + .features = featureSet(&[_]Feature{ + .booke, + .isel, + .stfiwx, + }), + }; + pub const e5500 = CpuModel{ + .name = "e5500", + .llvm_name = "e5500", + .features = featureSet(&[_]Feature{ + .@"64bit", + .booke, + .isel, + .mfocrf, + .stfiwx, + }), + }; + pub const future = CpuModel{ + .name = "future", + .llvm_name = "future", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_unaligned_fp_access, + .bpermd, + .cmpb, + .crbits, + .crypto, + .direct_move, + .extdiv, + .fast_MFLR, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .fuse_add_logical, + .fuse_arith_add, + .fuse_logical, + .fuse_logical_add, + .fuse_sha3, + .fuse_store, + .htm, + .icbt, + .isa_future_instructions, + .isa_v206_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .mma, + .partword_atomics, + .pcrelative_memops, + .popcntd, + .power10_vector, + .ppc_postra_sched, + .ppc_prera_sched, + .predictable_select_expensive, + .quadword_atomics, + .recipprec, + .stfiwx, + .two_const_nr, + }), + }; + pub const g3 = CpuModel{ + .name = "g3", + .llvm_name = "g3", + .features = featureSet(&[_]Feature{ + .fres, + .frsqrte, + }), + }; + pub const g4 = CpuModel{ + .name = "g4", + .llvm_name = "g4", + .features = featureSet(&[_]Feature{ + .altivec, + .fres, + .frsqrte, + }), + }; + pub const @"g4+" = CpuModel{ + .name = "g4+", + .llvm_name = "g4+", + .features = featureSet(&[_]Feature{ + .altivec, + .fres, + .frsqrte, + }), + }; + pub const g5 = CpuModel{ + .name = "g5", + .llvm_name = "g5", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fres, + .frsqrte, + .fsqrt, + .mfocrf, + .stfiwx, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .hard_float, + }), + }; + pub const ppc = CpuModel{ + .name = "ppc", + .llvm_name = "ppc", + .features = featureSet(&[_]Feature{ + .hard_float, + }), + }; + pub const ppc64 = CpuModel{ + .name = "ppc64", + .llvm_name = "ppc64", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fres, + .frsqrte, + .fsqrt, + .mfocrf, + .stfiwx, + }), + }; + pub const ppc64le = CpuModel{ + .name = "ppc64le", + .llvm_name = "ppc64le", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_unaligned_fp_access, + .bpermd, + .cmpb, + .crbits, + .crypto, + .direct_move, + .extdiv, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .fuse_addi_load, + .fuse_addis_load, + .htm, + .icbt, + .isa_v206_instructions, + .isa_v207_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .partword_atomics, + .popcntd, + .power8_vector, + .predictable_select_expensive, + .quadword_atomics, + .recipprec, + .stfiwx, + .two_const_nr, + }), + }; + pub const pwr10 = CpuModel{ + .name = "pwr10", + .llvm_name = "pwr10", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_unaligned_fp_access, + .bpermd, + .cmpb, + .crbits, + .crypto, + .direct_move, + .extdiv, + .fast_MFLR, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .fuse_add_logical, + .fuse_arith_add, + .fuse_logical, + .fuse_logical_add, + .fuse_sha3, + .fuse_store, + .htm, + .icbt, + .isa_v206_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .mma, + .partword_atomics, + .pcrelative_memops, + .popcntd, + .power10_vector, + .ppc_postra_sched, + .ppc_prera_sched, + .predictable_select_expensive, + .quadword_atomics, + .recipprec, + .stfiwx, + .two_const_nr, + }), + }; + pub const pwr3 = CpuModel{ + .name = "pwr3", + .llvm_name = "pwr3", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fres, + .frsqrte, + .mfocrf, + .stfiwx, + }), + }; + pub const pwr4 = CpuModel{ + .name = "pwr4", + .llvm_name = "pwr4", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fres, + .frsqrte, + .fsqrt, + .mfocrf, + .stfiwx, + }), + }; + pub const pwr5 = CpuModel{ + .name = "pwr5", + .llvm_name = "pwr5", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .mfocrf, + .stfiwx, + }), + }; + pub const pwr5x = CpuModel{ + .name = "pwr5x", + .llvm_name = "pwr5x", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .mfocrf, + .stfiwx, + }), + }; + pub const pwr6 = CpuModel{ + .name = "pwr6", + .llvm_name = "pwr6", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .cmpb, + .fcpsgn, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .lfiwax, + .mfocrf, + .recipprec, + .stfiwx, + }), + }; + pub const pwr6x = CpuModel{ + .name = "pwr6x", + .llvm_name = "pwr6x", + .features = featureSet(&[_]Feature{ + .@"64bit", + .altivec, + .cmpb, + .fcpsgn, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .lfiwax, + .mfocrf, + .recipprec, + .stfiwx, + }), + }; + pub const pwr7 = CpuModel{ + .name = "pwr7", + .llvm_name = "pwr7", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_unaligned_fp_access, + .bpermd, + .cmpb, + .extdiv, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .isa_v206_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .popcntd, + .recipprec, + .stfiwx, + .two_const_nr, + .vsx, + }), + }; + pub const pwr8 = CpuModel{ + .name = "pwr8", + .llvm_name = "pwr8", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_unaligned_fp_access, + .bpermd, + .cmpb, + .crbits, + .crypto, + .direct_move, + .extdiv, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .fuse_addi_load, + .fuse_addis_load, + .htm, + .icbt, + .isa_v206_instructions, + .isa_v207_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .partword_atomics, + .popcntd, + .power8_vector, + .predictable_select_expensive, + .quadword_atomics, + .recipprec, + .stfiwx, + .two_const_nr, + }), + }; + pub const pwr9 = CpuModel{ + .name = "pwr9", + .llvm_name = "pwr9", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_unaligned_fp_access, + .bpermd, + .cmpb, + .crbits, + .crypto, + .direct_move, + .extdiv, + .fcpsgn, + .fpcvt, + .fprnd, + .fre, + .fres, + .frsqrte, + .frsqrtes, + .fsqrt, + .htm, + .icbt, + .isa_v206_instructions, + .isel, + .ldbrx, + .lfiwax, + .mfocrf, + .partword_atomics, + .popcntd, + .power9_vector, + .ppc_postra_sched, + .ppc_prera_sched, + .predictable_select_expensive, + .quadword_atomics, + .recipprec, + .stfiwx, + .two_const_nr, + .vectors_use_two_units, + }), + }; +}; diff --git a/lib/std/Target/riscv.zig b/lib/std/Target/riscv.zig new file mode 100644 index 0000000000..66c02ae6d0 --- /dev/null +++ b/lib/std/Target/riscv.zig @@ -0,0 +1,1341 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"32bit", + @"64bit", + a, + c, + d, + dlen_factor_2, + e, + experimental_smaia, + experimental_ssaia, + experimental_zacas, + experimental_zfa, + experimental_zfbfmin, + experimental_zicond, + experimental_zihintntl, + experimental_ztso, + experimental_zvbb, + experimental_zvbc, + experimental_zvfbfmin, + experimental_zvfbfwma, + experimental_zvkg, + experimental_zvkn, + experimental_zvknc, + experimental_zvkned, + experimental_zvkng, + experimental_zvknha, + experimental_zvknhb, + experimental_zvks, + experimental_zvksc, + experimental_zvksed, + experimental_zvksg, + experimental_zvksh, + experimental_zvkt, + f, + forced_atomics, + h, + lui_addi_fusion, + m, + no_default_unroll, + no_optimized_zero_stride_load, + no_rvc_hints, + relax, + reserve_x1, + reserve_x10, + reserve_x11, + reserve_x12, + reserve_x13, + reserve_x14, + reserve_x15, + reserve_x16, + reserve_x17, + reserve_x18, + reserve_x19, + reserve_x2, + reserve_x20, + reserve_x21, + reserve_x22, + reserve_x23, + reserve_x24, + reserve_x25, + reserve_x26, + reserve_x27, + reserve_x28, + reserve_x29, + reserve_x3, + reserve_x30, + reserve_x31, + reserve_x4, + reserve_x5, + reserve_x6, + reserve_x7, + reserve_x8, + reserve_x9, + save_restore, + seq_cst_trailing_fence, + short_forward_branch_opt, + svinval, + svnapot, + svpbmt, + tagged_globals, + unaligned_scalar_mem, + unaligned_vector_mem, + v, + xcvbitmanip, + xcvmac, + xsfcie, + xsfvcp, + xtheadba, + xtheadbb, + xtheadbs, + xtheadcmo, + xtheadcondmov, + xtheadfmemidx, + xtheadmac, + xtheadmemidx, + xtheadmempair, + xtheadsync, + xtheadvdot, + xventanacondops, + zawrs, + zba, + zbb, + zbc, + zbkb, + zbkc, + zbkx, + zbs, + zca, + zcb, + zcd, + zce, + zcf, + zcmp, + zcmt, + zdinx, + zfh, + zfhmin, + zfinx, + zhinx, + zhinxmin, + zicbom, + zicbop, + zicboz, + zicntr, + zicsr, + zifencei, + zihintpause, + zihpm, + zk, + zkn, + zknd, + zkne, + zknh, + zkr, + zks, + zksed, + zksh, + zkt, + zmmul, + zve32f, + zve32x, + zve64d, + zve64f, + zve64x, + zvfh, + zvl1024b, + zvl128b, + zvl16384b, + zvl2048b, + zvl256b, + zvl32768b, + zvl32b, + zvl4096b, + zvl512b, + zvl64b, + zvl65536b, + zvl8192b, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"32bit")] = .{ + .llvm_name = "32bit", + .description = "Implements RV32", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"64bit")] = .{ + .llvm_name = "64bit", + .description = "Implements RV64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.a)] = .{ + .llvm_name = "a", + .description = "'A' (Atomic Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.c)] = .{ + .llvm_name = "c", + .description = "'C' (Compressed Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.d)] = .{ + .llvm_name = "d", + .description = "'D' (Double-Precision Floating-Point)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.dlen_factor_2)] = .{ + .llvm_name = "dlen-factor-2", + .description = "Vector unit DLEN(data path width) is half of VLEN", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.e)] = .{ + .llvm_name = "e", + .description = "Implements RV{32,64}E (provides 16 rather than 32 GPRs)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_smaia)] = .{ + .llvm_name = "experimental-smaia", + .description = "'Smaia' (Smaia encompasses all added CSRs and all modifications to interrupt response behavior that the AIA specifies for a hart, over all privilege levels.)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_ssaia)] = .{ + .llvm_name = "experimental-ssaia", + .description = "'Ssaia' (Ssaia is essentially the same as Smaia except excluding the machine-level CSRs and behavior not directly visible to supervisor level.)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zacas)] = .{ + .llvm_name = "experimental-zacas", + .description = "'Zacas' (Atomic Compare-And-Swap Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zfa)] = .{ + .llvm_name = "experimental-zfa", + .description = "'Zfa' (Additional Floating-Point)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.experimental_zfbfmin)] = .{ + .llvm_name = "experimental-zfbfmin", + .description = "'Zfbfmin' (Scalar BF16 Converts)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.experimental_zicond)] = .{ + .llvm_name = "experimental-zicond", + .description = "'Zicond' (Integer Conditional Operations)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zihintntl)] = .{ + .llvm_name = "experimental-zihintntl", + .description = "'Zihintntl' (Non-Temporal Locality Hints)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_ztso)] = .{ + .llvm_name = "experimental-ztso", + .description = "'Ztso' (Memory Model - Total Store Order)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvbb)] = .{ + .llvm_name = "experimental-zvbb", + .description = "'Zvbb' (Vector Bit-manipulation used in Cryptography)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvbc)] = .{ + .llvm_name = "experimental-zvbc", + .description = "'Zvbc' (Vector Carryless Multiplication)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvfbfmin)] = .{ + .llvm_name = "experimental-zvfbfmin", + .description = "'Zvbfmin' (Vector BF16 Converts)", + .dependencies = featureSet(&[_]Feature{ + .zve32f, + }), + }; + result[@intFromEnum(Feature.experimental_zvfbfwma)] = .{ + .llvm_name = "experimental-zvfbfwma", + .description = "'Zvfbfwma' (Vector BF16 widening mul-add)", + .dependencies = featureSet(&[_]Feature{ + .zve32f, + }), + }; + result[@intFromEnum(Feature.experimental_zvkg)] = .{ + .llvm_name = "experimental-zvkg", + .description = "'Zvkg' (Vector GCM instructions for Cryptography)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvkn)] = .{ + .llvm_name = "experimental-zvkn", + .description = "This extension is shorthand for the following set of other extensions: Zvkned, Zvknhb, Zvbb, Zvbc, and Zvkt.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvknc)] = .{ + .llvm_name = "experimental-zvknc", + .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvbc.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvkned)] = .{ + .llvm_name = "experimental-zvkned", + .description = "'Zvkned' (Vector AES Encryption & Decryption (Single Round))", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvkng)] = .{ + .llvm_name = "experimental-zvkng", + .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvkg.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvknha)] = .{ + .llvm_name = "experimental-zvknha", + .description = "'Zvknha' (Vector SHA-2 (SHA-256 only))", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvknhb)] = .{ + .llvm_name = "experimental-zvknhb", + .description = "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))", + .dependencies = featureSet(&[_]Feature{ + .experimental_zvknha, + }), + }; + result[@intFromEnum(Feature.experimental_zvks)] = .{ + .llvm_name = "experimental-zvks", + .description = "This extension is shorthand for the following set of other extensions: Zvksed, Zvksh, Zvbb, Zvbc, and Zvkt.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvksc)] = .{ + .llvm_name = "experimental-zvksc", + .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvbc.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvksed)] = .{ + .llvm_name = "experimental-zvksed", + .description = "'Zvksed' (SM4 Block Cipher Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvksg)] = .{ + .llvm_name = "experimental-zvksg", + .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvkg.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvksh)] = .{ + .llvm_name = "experimental-zvksh", + .description = "'Zvksh' (SM3 Hash Function Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.experimental_zvkt)] = .{ + .llvm_name = "experimental-zvkt", + .description = "'Zvkt' (Vector Data-Independent Execution Latency)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.f)] = .{ + .llvm_name = "f", + .description = "'F' (Single-Precision Floating-Point)", + .dependencies = featureSet(&[_]Feature{ + .zicsr, + }), + }; + result[@intFromEnum(Feature.forced_atomics)] = .{ + .llvm_name = "forced-atomics", + .description = "Assume that lock-free native-width atomics are available", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.h)] = .{ + .llvm_name = "h", + .description = "'H' (Hypervisor)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lui_addi_fusion)] = .{ + .llvm_name = "lui-addi-fusion", + .description = "Enable LUI+ADDI macrofusion", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.m)] = .{ + .llvm_name = "m", + .description = "'M' (Integer Multiplication and Division)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_default_unroll)] = .{ + .llvm_name = "no-default-unroll", + .description = "Disable default unroll preference.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_optimized_zero_stride_load)] = .{ + .llvm_name = "no-optimized-zero-stride-load", + .description = "Hasn't optimized (perform fewer memory operations)zero-stride vector load", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_rvc_hints)] = .{ + .llvm_name = "no-rvc-hints", + .description = "Disable RVC Hint Instructions.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.relax)] = .{ + .llvm_name = "relax", + .description = "Enable Linker relaxation.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x1)] = .{ + .llvm_name = "reserve-x1", + .description = "Reserve X1", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x10)] = .{ + .llvm_name = "reserve-x10", + .description = "Reserve X10", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x11)] = .{ + .llvm_name = "reserve-x11", + .description = "Reserve X11", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x12)] = .{ + .llvm_name = "reserve-x12", + .description = "Reserve X12", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x13)] = .{ + .llvm_name = "reserve-x13", + .description = "Reserve X13", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x14)] = .{ + .llvm_name = "reserve-x14", + .description = "Reserve X14", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x15)] = .{ + .llvm_name = "reserve-x15", + .description = "Reserve X15", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x16)] = .{ + .llvm_name = "reserve-x16", + .description = "Reserve X16", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x17)] = .{ + .llvm_name = "reserve-x17", + .description = "Reserve X17", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x18)] = .{ + .llvm_name = "reserve-x18", + .description = "Reserve X18", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x19)] = .{ + .llvm_name = "reserve-x19", + .description = "Reserve X19", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x2)] = .{ + .llvm_name = "reserve-x2", + .description = "Reserve X2", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x20)] = .{ + .llvm_name = "reserve-x20", + .description = "Reserve X20", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x21)] = .{ + .llvm_name = "reserve-x21", + .description = "Reserve X21", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x22)] = .{ + .llvm_name = "reserve-x22", + .description = "Reserve X22", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x23)] = .{ + .llvm_name = "reserve-x23", + .description = "Reserve X23", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x24)] = .{ + .llvm_name = "reserve-x24", + .description = "Reserve X24", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x25)] = .{ + .llvm_name = "reserve-x25", + .description = "Reserve X25", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x26)] = .{ + .llvm_name = "reserve-x26", + .description = "Reserve X26", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x27)] = .{ + .llvm_name = "reserve-x27", + .description = "Reserve X27", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x28)] = .{ + .llvm_name = "reserve-x28", + .description = "Reserve X28", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x29)] = .{ + .llvm_name = "reserve-x29", + .description = "Reserve X29", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x3)] = .{ + .llvm_name = "reserve-x3", + .description = "Reserve X3", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x30)] = .{ + .llvm_name = "reserve-x30", + .description = "Reserve X30", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x31)] = .{ + .llvm_name = "reserve-x31", + .description = "Reserve X31", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x4)] = .{ + .llvm_name = "reserve-x4", + .description = "Reserve X4", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x5)] = .{ + .llvm_name = "reserve-x5", + .description = "Reserve X5", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x6)] = .{ + .llvm_name = "reserve-x6", + .description = "Reserve X6", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x7)] = .{ + .llvm_name = "reserve-x7", + .description = "Reserve X7", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x8)] = .{ + .llvm_name = "reserve-x8", + .description = "Reserve X8", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reserve_x9)] = .{ + .llvm_name = "reserve-x9", + .description = "Reserve X9", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.save_restore)] = .{ + .llvm_name = "save-restore", + .description = "Enable save/restore.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.seq_cst_trailing_fence)] = .{ + .llvm_name = "seq-cst-trailing-fence", + .description = "Enable trailing fence for seq-cst store.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.short_forward_branch_opt)] = .{ + .llvm_name = "short-forward-branch-opt", + .description = "Enable short forward branch optimization", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.svinval)] = .{ + .llvm_name = "svinval", + .description = "'Svinval' (Fine-Grained Address-Translation Cache Invalidation)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.svnapot)] = .{ + .llvm_name = "svnapot", + .description = "'Svnapot' (NAPOT Translation Contiguity)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.svpbmt)] = .{ + .llvm_name = "svpbmt", + .description = "'Svpbmt' (Page-Based Memory Types)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tagged_globals)] = .{ + .llvm_name = "tagged-globals", + .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unaligned_scalar_mem)] = .{ + .llvm_name = "unaligned-scalar-mem", + .description = "Has reasonably performant unaligned scalar loads and stores", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.unaligned_vector_mem)] = .{ + .llvm_name = "unaligned-vector-mem", + .description = "Has reasonably performant unaligned vector loads and stores", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v)] = .{ + .llvm_name = "v", + .description = "'V' (Vector Extension for Application Processors)", + .dependencies = featureSet(&[_]Feature{ + .zve64d, + .zvl128b, + }), + }; + result[@intFromEnum(Feature.xcvbitmanip)] = .{ + .llvm_name = "xcvbitmanip", + .description = "'XCVbitmanip' (CORE-V Bit Manipulation)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xcvmac)] = .{ + .llvm_name = "xcvmac", + .description = "'XCVmac' (CORE-V Multiply-Accumulate)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xsfcie)] = .{ + .llvm_name = "xsfcie", + .description = "'XSfcie' (SiFive Custom Instruction Extension SCIE.)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xsfvcp)] = .{ + .llvm_name = "xsfvcp", + .description = "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)", + .dependencies = featureSet(&[_]Feature{ + .zve32x, + }), + }; + result[@intFromEnum(Feature.xtheadba)] = .{ + .llvm_name = "xtheadba", + .description = "'xtheadba' (T-Head address calculation instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadbb)] = .{ + .llvm_name = "xtheadbb", + .description = "'xtheadbb' (T-Head basic bit-manipulation instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadbs)] = .{ + .llvm_name = "xtheadbs", + .description = "'xtheadbs' (T-Head single-bit instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadcmo)] = .{ + .llvm_name = "xtheadcmo", + .description = "'xtheadcmo' (T-Head cache management instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadcondmov)] = .{ + .llvm_name = "xtheadcondmov", + .description = "'xtheadcondmov' (T-Head conditional move instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadfmemidx)] = .{ + .llvm_name = "xtheadfmemidx", + .description = "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.xtheadmac)] = .{ + .llvm_name = "xtheadmac", + .description = "'xtheadmac' (T-Head Multiply-Accumulate Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadmemidx)] = .{ + .llvm_name = "xtheadmemidx", + .description = "'xtheadmemidx' (T-Head Indexed Memory Operations)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadmempair)] = .{ + .llvm_name = "xtheadmempair", + .description = "'xtheadmempair' (T-Head two-GPR Memory Operations)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadsync)] = .{ + .llvm_name = "xtheadsync", + .description = "'xtheadsync' (T-Head multicore synchronization instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xtheadvdot)] = .{ + .llvm_name = "xtheadvdot", + .description = "'xtheadvdot' (T-Head Vector Extensions for Dot)", + .dependencies = featureSet(&[_]Feature{ + .v, + }), + }; + result[@intFromEnum(Feature.xventanacondops)] = .{ + .llvm_name = "xventanacondops", + .description = "'XVentanaCondOps' (Ventana Conditional Ops)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zawrs)] = .{ + .llvm_name = "zawrs", + .description = "'Zawrs' (Wait on Reservation Set)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zba)] = .{ + .llvm_name = "zba", + .description = "'Zba' (Address Generation Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zbb)] = .{ + .llvm_name = "zbb", + .description = "'Zbb' (Basic Bit-Manipulation)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zbc)] = .{ + .llvm_name = "zbc", + .description = "'Zbc' (Carry-Less Multiplication)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zbkb)] = .{ + .llvm_name = "zbkb", + .description = "'Zbkb' (Bitmanip instructions for Cryptography)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zbkc)] = .{ + .llvm_name = "zbkc", + .description = "'Zbkc' (Carry-less multiply instructions for Cryptography)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zbkx)] = .{ + .llvm_name = "zbkx", + .description = "'Zbkx' (Crossbar permutation instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zbs)] = .{ + .llvm_name = "zbs", + .description = "'Zbs' (Single-Bit Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zca)] = .{ + .llvm_name = "zca", + .description = "'Zca' (part of the C extension, excluding compressed floating point loads/stores)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zcb)] = .{ + .llvm_name = "zcb", + .description = "'Zcb' (Compressed basic bit manipulation instructions)", + .dependencies = featureSet(&[_]Feature{ + .zca, + }), + }; + result[@intFromEnum(Feature.zcd)] = .{ + .llvm_name = "zcd", + .description = "'Zcd' (Compressed Double-Precision Floating-Point Instructions)", + .dependencies = featureSet(&[_]Feature{ + .zca, + }), + }; + result[@intFromEnum(Feature.zce)] = .{ + .llvm_name = "zce", + .description = "'Zce' (Compressed extensions for microcontrollers)", + .dependencies = featureSet(&[_]Feature{ + .zcb, + .zcmp, + .zcmt, + }), + }; + result[@intFromEnum(Feature.zcf)] = .{ + .llvm_name = "zcf", + .description = "'Zcf' (Compressed Single-Precision Floating-Point Instructions)", + .dependencies = featureSet(&[_]Feature{ + .zca, + }), + }; + result[@intFromEnum(Feature.zcmp)] = .{ + .llvm_name = "zcmp", + .description = "'Zcmp' (sequenced instuctions for code-size reduction)", + .dependencies = featureSet(&[_]Feature{ + .zca, + }), + }; + result[@intFromEnum(Feature.zcmt)] = .{ + .llvm_name = "zcmt", + .description = "'Zcmt' (table jump instuctions for code-size reduction)", + .dependencies = featureSet(&[_]Feature{ + .zca, + .zicsr, + }), + }; + result[@intFromEnum(Feature.zdinx)] = .{ + .llvm_name = "zdinx", + .description = "'Zdinx' (Double in Integer)", + .dependencies = featureSet(&[_]Feature{ + .zfinx, + }), + }; + result[@intFromEnum(Feature.zfh)] = .{ + .llvm_name = "zfh", + .description = "'Zfh' (Half-Precision Floating-Point)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.zfhmin)] = .{ + .llvm_name = "zfhmin", + .description = "'Zfhmin' (Half-Precision Floating-Point Minimal)", + .dependencies = featureSet(&[_]Feature{ + .f, + }), + }; + result[@intFromEnum(Feature.zfinx)] = .{ + .llvm_name = "zfinx", + .description = "'Zfinx' (Float in Integer)", + .dependencies = featureSet(&[_]Feature{ + .zicsr, + }), + }; + result[@intFromEnum(Feature.zhinx)] = .{ + .llvm_name = "zhinx", + .description = "'Zhinx' (Half Float in Integer)", + .dependencies = featureSet(&[_]Feature{ + .zfinx, + }), + }; + result[@intFromEnum(Feature.zhinxmin)] = .{ + .llvm_name = "zhinxmin", + .description = "'Zhinxmin' (Half Float in Integer Minimal)", + .dependencies = featureSet(&[_]Feature{ + .zfinx, + }), + }; + result[@intFromEnum(Feature.zicbom)] = .{ + .llvm_name = "zicbom", + .description = "'Zicbom' (Cache-Block Management Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zicbop)] = .{ + .llvm_name = "zicbop", + .description = "'Zicbop' (Cache-Block Prefetch Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zicboz)] = .{ + .llvm_name = "zicboz", + .description = "'Zicboz' (Cache-Block Zero Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zicntr)] = .{ + .llvm_name = "zicntr", + .description = "'Zicntr' (Base Counters and Timers)", + .dependencies = featureSet(&[_]Feature{ + .zicsr, + }), + }; + result[@intFromEnum(Feature.zicsr)] = .{ + .llvm_name = "zicsr", + .description = "'zicsr' (CSRs)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zifencei)] = .{ + .llvm_name = "zifencei", + .description = "'Zifencei' (fence.i)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zihintpause)] = .{ + .llvm_name = "zihintpause", + .description = "'Zihintpause' (Pause Hint)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zihpm)] = .{ + .llvm_name = "zihpm", + .description = "'Zihpm' (Hardware Performance Counters)", + .dependencies = featureSet(&[_]Feature{ + .zicsr, + }), + }; + result[@intFromEnum(Feature.zk)] = .{ + .llvm_name = "zk", + .description = "'Zk' (Standard scalar cryptography extension)", + .dependencies = featureSet(&[_]Feature{ + .zkn, + .zkr, + .zkt, + }), + }; + result[@intFromEnum(Feature.zkn)] = .{ + .llvm_name = "zkn", + .description = "'Zkn' (NIST Algorithm Suite)", + .dependencies = featureSet(&[_]Feature{ + .zbkb, + .zbkc, + .zbkx, + .zknd, + .zkne, + .zknh, + }), + }; + result[@intFromEnum(Feature.zknd)] = .{ + .llvm_name = "zknd", + .description = "'Zknd' (NIST Suite: AES Decryption)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zkne)] = .{ + .llvm_name = "zkne", + .description = "'Zkne' (NIST Suite: AES Encryption)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zknh)] = .{ + .llvm_name = "zknh", + .description = "'Zknh' (NIST Suite: Hash Function Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zkr)] = .{ + .llvm_name = "zkr", + .description = "'Zkr' (Entropy Source Extension)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zks)] = .{ + .llvm_name = "zks", + .description = "'Zks' (ShangMi Algorithm Suite)", + .dependencies = featureSet(&[_]Feature{ + .zbkb, + .zbkc, + .zbkx, + .zksed, + .zksh, + }), + }; + result[@intFromEnum(Feature.zksed)] = .{ + .llvm_name = "zksed", + .description = "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zksh)] = .{ + .llvm_name = "zksh", + .description = "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zkt)] = .{ + .llvm_name = "zkt", + .description = "'Zkt' (Data Independent Execution Latency)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zmmul)] = .{ + .llvm_name = "zmmul", + .description = "'Zmmul' (Integer Multiplication)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zve32f)] = .{ + .llvm_name = "zve32f", + .description = "'Zve32f' (Vector Extensions for Embedded Processors with maximal 32 EEW and F extension)", + .dependencies = featureSet(&[_]Feature{ + .f, + .zve32x, + }), + }; + result[@intFromEnum(Feature.zve32x)] = .{ + .llvm_name = "zve32x", + .description = "'Zve32x' (Vector Extensions for Embedded Processors with maximal 32 EEW)", + .dependencies = featureSet(&[_]Feature{ + .zicsr, + .zvl32b, + }), + }; + result[@intFromEnum(Feature.zve64d)] = .{ + .llvm_name = "zve64d", + .description = "'Zve64d' (Vector Extensions for Embedded Processors with maximal 64 EEW, F and D extension)", + .dependencies = featureSet(&[_]Feature{ + .d, + .zve64f, + }), + }; + result[@intFromEnum(Feature.zve64f)] = .{ + .llvm_name = "zve64f", + .description = "'Zve64f' (Vector Extensions for Embedded Processors with maximal 64 EEW and F extension)", + .dependencies = featureSet(&[_]Feature{ + .zve32f, + .zve64x, + }), + }; + result[@intFromEnum(Feature.zve64x)] = .{ + .llvm_name = "zve64x", + .description = "'Zve64x' (Vector Extensions for Embedded Processors with maximal 64 EEW)", + .dependencies = featureSet(&[_]Feature{ + .zve32x, + .zvl64b, + }), + }; + result[@intFromEnum(Feature.zvfh)] = .{ + .llvm_name = "zvfh", + .description = "'Zvfh' (Vector Half-Precision Floating-Point)", + .dependencies = featureSet(&[_]Feature{ + .zfhmin, + .zve32f, + }), + }; + result[@intFromEnum(Feature.zvl1024b)] = .{ + .llvm_name = "zvl1024b", + .description = "'Zvl' (Minimum Vector Length) 1024", + .dependencies = featureSet(&[_]Feature{ + .zvl512b, + }), + }; + result[@intFromEnum(Feature.zvl128b)] = .{ + .llvm_name = "zvl128b", + .description = "'Zvl' (Minimum Vector Length) 128", + .dependencies = featureSet(&[_]Feature{ + .zvl64b, + }), + }; + result[@intFromEnum(Feature.zvl16384b)] = .{ + .llvm_name = "zvl16384b", + .description = "'Zvl' (Minimum Vector Length) 16384", + .dependencies = featureSet(&[_]Feature{ + .zvl8192b, + }), + }; + result[@intFromEnum(Feature.zvl2048b)] = .{ + .llvm_name = "zvl2048b", + .description = "'Zvl' (Minimum Vector Length) 2048", + .dependencies = featureSet(&[_]Feature{ + .zvl1024b, + }), + }; + result[@intFromEnum(Feature.zvl256b)] = .{ + .llvm_name = "zvl256b", + .description = "'Zvl' (Minimum Vector Length) 256", + .dependencies = featureSet(&[_]Feature{ + .zvl128b, + }), + }; + result[@intFromEnum(Feature.zvl32768b)] = .{ + .llvm_name = "zvl32768b", + .description = "'Zvl' (Minimum Vector Length) 32768", + .dependencies = featureSet(&[_]Feature{ + .zvl16384b, + }), + }; + result[@intFromEnum(Feature.zvl32b)] = .{ + .llvm_name = "zvl32b", + .description = "'Zvl' (Minimum Vector Length) 32", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.zvl4096b)] = .{ + .llvm_name = "zvl4096b", + .description = "'Zvl' (Minimum Vector Length) 4096", + .dependencies = featureSet(&[_]Feature{ + .zvl2048b, + }), + }; + result[@intFromEnum(Feature.zvl512b)] = .{ + .llvm_name = "zvl512b", + .description = "'Zvl' (Minimum Vector Length) 512", + .dependencies = featureSet(&[_]Feature{ + .zvl256b, + }), + }; + result[@intFromEnum(Feature.zvl64b)] = .{ + .llvm_name = "zvl64b", + .description = "'Zvl' (Minimum Vector Length) 64", + .dependencies = featureSet(&[_]Feature{ + .zvl32b, + }), + }; + result[@intFromEnum(Feature.zvl65536b)] = .{ + .llvm_name = "zvl65536b", + .description = "'Zvl' (Minimum Vector Length) 65536", + .dependencies = featureSet(&[_]Feature{ + .zvl32768b, + }), + }; + result[@intFromEnum(Feature.zvl8192b)] = .{ + .llvm_name = "zvl8192b", + .description = "'Zvl' (Minimum Vector Length) 8192", + .dependencies = featureSet(&[_]Feature{ + .zvl4096b, + }), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const baseline_rv32 = CpuModel{ + .name = "baseline_rv32", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .@"32bit", + .a, + .c, + .d, + .m, + }), + }; + pub const baseline_rv64 = CpuModel{ + .name = "baseline_rv64", + .llvm_name = null, + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .d, + .m, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const generic_rv32 = CpuModel{ + .name = "generic_rv32", + .llvm_name = "generic-rv32", + .features = featureSet(&[_]Feature{ + .@"32bit", + }), + }; + pub const generic_rv64 = CpuModel{ + .name = "generic_rv64", + .llvm_name = "generic-rv64", + .features = featureSet(&[_]Feature{ + .@"64bit", + }), + }; + pub const rocket = CpuModel{ + .name = "rocket", + .llvm_name = "rocket", + .features = featureSet(&[_]Feature{}), + }; + pub const rocket_rv32 = CpuModel{ + .name = "rocket_rv32", + .llvm_name = "rocket-rv32", + .features = featureSet(&[_]Feature{ + .@"32bit", + .zicsr, + .zifencei, + }), + }; + pub const rocket_rv64 = CpuModel{ + .name = "rocket_rv64", + .llvm_name = "rocket-rv64", + .features = featureSet(&[_]Feature{ + .@"64bit", + .zicsr, + .zifencei, + }), + }; + pub const sifive_7_series = CpuModel{ + .name = "sifive_7_series", + .llvm_name = "sifive-7-series", + .features = featureSet(&[_]Feature{ + .no_default_unroll, + .short_forward_branch_opt, + }), + }; + pub const sifive_e20 = CpuModel{ + .name = "sifive_e20", + .llvm_name = "sifive-e20", + .features = featureSet(&[_]Feature{ + .@"32bit", + .c, + .m, + .zicsr, + .zifencei, + }), + }; + pub const sifive_e21 = CpuModel{ + .name = "sifive_e21", + .llvm_name = "sifive-e21", + .features = featureSet(&[_]Feature{ + .@"32bit", + .a, + .c, + .m, + .zicsr, + .zifencei, + }), + }; + pub const sifive_e24 = CpuModel{ + .name = "sifive_e24", + .llvm_name = "sifive-e24", + .features = featureSet(&[_]Feature{ + .@"32bit", + .a, + .c, + .f, + .m, + .zifencei, + }), + }; + pub const sifive_e31 = CpuModel{ + .name = "sifive_e31", + .llvm_name = "sifive-e31", + .features = featureSet(&[_]Feature{ + .@"32bit", + .a, + .c, + .m, + .zicsr, + .zifencei, + }), + }; + pub const sifive_e34 = CpuModel{ + .name = "sifive_e34", + .llvm_name = "sifive-e34", + .features = featureSet(&[_]Feature{ + .@"32bit", + .a, + .c, + .f, + .m, + .zifencei, + }), + }; + pub const sifive_e76 = CpuModel{ + .name = "sifive_e76", + .llvm_name = "sifive-e76", + .features = featureSet(&[_]Feature{ + .@"32bit", + .a, + .c, + .f, + .m, + .no_default_unroll, + .short_forward_branch_opt, + .zifencei, + }), + }; + pub const sifive_s21 = CpuModel{ + .name = "sifive_s21", + .llvm_name = "sifive-s21", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .m, + .zicsr, + .zifencei, + }), + }; + pub const sifive_s51 = CpuModel{ + .name = "sifive_s51", + .llvm_name = "sifive-s51", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .m, + .zicsr, + .zifencei, + }), + }; + pub const sifive_s54 = CpuModel{ + .name = "sifive_s54", + .llvm_name = "sifive-s54", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .d, + .m, + .zifencei, + }), + }; + pub const sifive_s76 = CpuModel{ + .name = "sifive_s76", + .llvm_name = "sifive-s76", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .d, + .m, + .no_default_unroll, + .short_forward_branch_opt, + .xsfcie, + .zifencei, + .zihintpause, + }), + }; + pub const sifive_u54 = CpuModel{ + .name = "sifive_u54", + .llvm_name = "sifive-u54", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .d, + .m, + .zifencei, + }), + }; + pub const sifive_u74 = CpuModel{ + .name = "sifive_u74", + .llvm_name = "sifive-u74", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .d, + .m, + .no_default_unroll, + .short_forward_branch_opt, + .zifencei, + }), + }; + pub const sifive_x280 = CpuModel{ + .name = "sifive_x280", + .llvm_name = "sifive-x280", + .features = featureSet(&[_]Feature{ + .@"64bit", + .a, + .c, + .dlen_factor_2, + .m, + .no_default_unroll, + .short_forward_branch_opt, + .v, + .zba, + .zbb, + .zfh, + .zifencei, + .zvfh, + .zvl512b, + }), + }; + pub const syntacore_scr1_base = CpuModel{ + .name = "syntacore_scr1_base", + .llvm_name = "syntacore-scr1-base", + .features = featureSet(&[_]Feature{ + .@"32bit", + .c, + .no_default_unroll, + .zicsr, + .zifencei, + }), + }; + pub const syntacore_scr1_max = CpuModel{ + .name = "syntacore_scr1_max", + .llvm_name = "syntacore-scr1-max", + .features = featureSet(&[_]Feature{ + .@"32bit", + .c, + .m, + .no_default_unroll, + .zicsr, + .zifencei, + }), + }; +}; diff --git a/lib/std/Target/s390x.zig b/lib/std/Target/s390x.zig new file mode 100644 index 0000000000..b642847258 --- /dev/null +++ b/lib/std/Target/s390x.zig @@ -0,0 +1,667 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + bear_enhancement, + deflate_conversion, + dfp_packed_conversion, + dfp_zoned_conversion, + distinct_ops, + enhanced_dat_2, + enhanced_sort, + execution_hint, + fast_serialization, + fp_extension, + guarded_storage, + high_word, + insert_reference_bits_multiple, + interlocked_access1, + load_and_trap, + load_and_zero_rightmost_byte, + load_store_on_cond, + load_store_on_cond_2, + message_security_assist_extension3, + message_security_assist_extension4, + message_security_assist_extension5, + message_security_assist_extension7, + message_security_assist_extension8, + message_security_assist_extension9, + miscellaneous_extensions, + miscellaneous_extensions_2, + miscellaneous_extensions_3, + nnp_assist, + population_count, + processor_activity_instrumentation, + processor_assist, + reset_dat_protection, + reset_reference_bits_multiple, + soft_float, + transactional_execution, + vector, + vector_enhancements_1, + vector_enhancements_2, + vector_packed_decimal, + vector_packed_decimal_enhancement, + vector_packed_decimal_enhancement_2, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.bear_enhancement)] = .{ + .llvm_name = "bear-enhancement", + .description = "Assume that the BEAR-enhancement facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.deflate_conversion)] = .{ + .llvm_name = "deflate-conversion", + .description = "Assume that the deflate-conversion facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dfp_packed_conversion)] = .{ + .llvm_name = "dfp-packed-conversion", + .description = "Assume that the DFP packed-conversion facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.dfp_zoned_conversion)] = .{ + .llvm_name = "dfp-zoned-conversion", + .description = "Assume that the DFP zoned-conversion facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.distinct_ops)] = .{ + .llvm_name = "distinct-ops", + .description = "Assume that the distinct-operands facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.enhanced_dat_2)] = .{ + .llvm_name = "enhanced-dat-2", + .description = "Assume that the enhanced-DAT facility 2 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.enhanced_sort)] = .{ + .llvm_name = "enhanced-sort", + .description = "Assume that the enhanced-sort facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.execution_hint)] = .{ + .llvm_name = "execution-hint", + .description = "Assume that the execution-hint facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_serialization)] = .{ + .llvm_name = "fast-serialization", + .description = "Assume that the fast-serialization facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fp_extension)] = .{ + .llvm_name = "fp-extension", + .description = "Assume that the floating-point extension facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.guarded_storage)] = .{ + .llvm_name = "guarded-storage", + .description = "Assume that the guarded-storage facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.high_word)] = .{ + .llvm_name = "high-word", + .description = "Assume that the high-word facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.insert_reference_bits_multiple)] = .{ + .llvm_name = "insert-reference-bits-multiple", + .description = "Assume that the insert-reference-bits-multiple facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.interlocked_access1)] = .{ + .llvm_name = "interlocked-access1", + .description = "Assume that interlocked-access facility 1 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.load_and_trap)] = .{ + .llvm_name = "load-and-trap", + .description = "Assume that the load-and-trap facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.load_and_zero_rightmost_byte)] = .{ + .llvm_name = "load-and-zero-rightmost-byte", + .description = "Assume that the load-and-zero-rightmost-byte facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.load_store_on_cond)] = .{ + .llvm_name = "load-store-on-cond", + .description = "Assume that the load/store-on-condition facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.load_store_on_cond_2)] = .{ + .llvm_name = "load-store-on-cond-2", + .description = "Assume that the load/store-on-condition facility 2 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.message_security_assist_extension3)] = .{ + .llvm_name = "message-security-assist-extension3", + .description = "Assume that the message-security-assist extension facility 3 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.message_security_assist_extension4)] = .{ + .llvm_name = "message-security-assist-extension4", + .description = "Assume that the message-security-assist extension facility 4 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.message_security_assist_extension5)] = .{ + .llvm_name = "message-security-assist-extension5", + .description = "Assume that the message-security-assist extension facility 5 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.message_security_assist_extension7)] = .{ + .llvm_name = "message-security-assist-extension7", + .description = "Assume that the message-security-assist extension facility 7 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.message_security_assist_extension8)] = .{ + .llvm_name = "message-security-assist-extension8", + .description = "Assume that the message-security-assist extension facility 8 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.message_security_assist_extension9)] = .{ + .llvm_name = "message-security-assist-extension9", + .description = "Assume that the message-security-assist extension facility 9 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.miscellaneous_extensions)] = .{ + .llvm_name = "miscellaneous-extensions", + .description = "Assume that the miscellaneous-extensions facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.miscellaneous_extensions_2)] = .{ + .llvm_name = "miscellaneous-extensions-2", + .description = "Assume that the miscellaneous-extensions facility 2 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.miscellaneous_extensions_3)] = .{ + .llvm_name = "miscellaneous-extensions-3", + .description = "Assume that the miscellaneous-extensions facility 3 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nnp_assist)] = .{ + .llvm_name = "nnp-assist", + .description = "Assume that the NNP-assist facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.population_count)] = .{ + .llvm_name = "population-count", + .description = "Assume that the population-count facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.processor_activity_instrumentation)] = .{ + .llvm_name = "processor-activity-instrumentation", + .description = "Assume that the processor-activity-instrumentation facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.processor_assist)] = .{ + .llvm_name = "processor-assist", + .description = "Assume that the processor-assist facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reset_dat_protection)] = .{ + .llvm_name = "reset-dat-protection", + .description = "Assume that the reset-DAT-protection facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reset_reference_bits_multiple)] = .{ + .llvm_name = "reset-reference-bits-multiple", + .description = "Assume that the reset-reference-bits-multiple facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.soft_float)] = .{ + .llvm_name = "soft-float", + .description = "Use software emulation for floating point", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.transactional_execution)] = .{ + .llvm_name = "transactional-execution", + .description = "Assume that the transactional-execution facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vector)] = .{ + .llvm_name = "vector", + .description = "Assume that the vectory facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vector_enhancements_1)] = .{ + .llvm_name = "vector-enhancements-1", + .description = "Assume that the vector enhancements facility 1 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vector_enhancements_2)] = .{ + .llvm_name = "vector-enhancements-2", + .description = "Assume that the vector enhancements facility 2 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vector_packed_decimal)] = .{ + .llvm_name = "vector-packed-decimal", + .description = "Assume that the vector packed decimal facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vector_packed_decimal_enhancement)] = .{ + .llvm_name = "vector-packed-decimal-enhancement", + .description = "Assume that the vector packed decimal enhancement facility is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vector_packed_decimal_enhancement_2)] = .{ + .llvm_name = "vector-packed-decimal-enhancement-2", + .description = "Assume that the vector packed decimal enhancement facility 2 is installed", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const arch10 = CpuModel{ + .name = "arch10", + .llvm_name = "arch10", + .features = featureSet(&[_]Feature{ + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .execution_hint, + .fast_serialization, + .fp_extension, + .high_word, + .interlocked_access1, + .load_and_trap, + .load_store_on_cond, + .message_security_assist_extension3, + .message_security_assist_extension4, + .miscellaneous_extensions, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + }), + }; + pub const arch11 = CpuModel{ + .name = "arch11", + .llvm_name = "arch11", + .features = featureSet(&[_]Feature{ + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .execution_hint, + .fast_serialization, + .fp_extension, + .high_word, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .miscellaneous_extensions, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + }), + }; + pub const arch12 = CpuModel{ + .name = "arch12", + .llvm_name = "arch12", + .features = featureSet(&[_]Feature{ + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .execution_hint, + .fast_serialization, + .fp_extension, + .guarded_storage, + .high_word, + .insert_reference_bits_multiple, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .message_security_assist_extension7, + .message_security_assist_extension8, + .miscellaneous_extensions, + .miscellaneous_extensions_2, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + .vector_enhancements_1, + .vector_packed_decimal, + }), + }; + pub const arch13 = CpuModel{ + .name = "arch13", + .llvm_name = "arch13", + .features = featureSet(&[_]Feature{ + .deflate_conversion, + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .enhanced_sort, + .execution_hint, + .fast_serialization, + .fp_extension, + .guarded_storage, + .high_word, + .insert_reference_bits_multiple, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .message_security_assist_extension7, + .message_security_assist_extension8, + .message_security_assist_extension9, + .miscellaneous_extensions, + .miscellaneous_extensions_2, + .miscellaneous_extensions_3, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + .vector_enhancements_1, + .vector_enhancements_2, + .vector_packed_decimal, + .vector_packed_decimal_enhancement, + }), + }; + pub const arch14 = CpuModel{ + .name = "arch14", + .llvm_name = "arch14", + .features = featureSet(&[_]Feature{ + .bear_enhancement, + .deflate_conversion, + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .enhanced_sort, + .execution_hint, + .fast_serialization, + .fp_extension, + .guarded_storage, + .high_word, + .insert_reference_bits_multiple, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .message_security_assist_extension7, + .message_security_assist_extension8, + .message_security_assist_extension9, + .miscellaneous_extensions, + .miscellaneous_extensions_2, + .miscellaneous_extensions_3, + .nnp_assist, + .population_count, + .processor_activity_instrumentation, + .processor_assist, + .reset_dat_protection, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + .vector_enhancements_1, + .vector_enhancements_2, + .vector_packed_decimal, + .vector_packed_decimal_enhancement, + .vector_packed_decimal_enhancement_2, + }), + }; + pub const arch8 = CpuModel{ + .name = "arch8", + .llvm_name = "arch8", + .features = featureSet(&[_]Feature{}), + }; + pub const arch9 = CpuModel{ + .name = "arch9", + .llvm_name = "arch9", + .features = featureSet(&[_]Feature{ + .distinct_ops, + .fast_serialization, + .fp_extension, + .high_word, + .interlocked_access1, + .load_store_on_cond, + .message_security_assist_extension3, + .message_security_assist_extension4, + .population_count, + .reset_reference_bits_multiple, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const z10 = CpuModel{ + .name = "z10", + .llvm_name = "z10", + .features = featureSet(&[_]Feature{}), + }; + pub const z13 = CpuModel{ + .name = "z13", + .llvm_name = "z13", + .features = featureSet(&[_]Feature{ + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .execution_hint, + .fast_serialization, + .fp_extension, + .high_word, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .miscellaneous_extensions, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + }), + }; + pub const z14 = CpuModel{ + .name = "z14", + .llvm_name = "z14", + .features = featureSet(&[_]Feature{ + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .execution_hint, + .fast_serialization, + .fp_extension, + .guarded_storage, + .high_word, + .insert_reference_bits_multiple, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .message_security_assist_extension7, + .message_security_assist_extension8, + .miscellaneous_extensions, + .miscellaneous_extensions_2, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + .vector_enhancements_1, + .vector_packed_decimal, + }), + }; + pub const z15 = CpuModel{ + .name = "z15", + .llvm_name = "z15", + .features = featureSet(&[_]Feature{ + .deflate_conversion, + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .enhanced_sort, + .execution_hint, + .fast_serialization, + .fp_extension, + .guarded_storage, + .high_word, + .insert_reference_bits_multiple, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .message_security_assist_extension7, + .message_security_assist_extension8, + .message_security_assist_extension9, + .miscellaneous_extensions, + .miscellaneous_extensions_2, + .miscellaneous_extensions_3, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + .vector_enhancements_1, + .vector_enhancements_2, + .vector_packed_decimal, + .vector_packed_decimal_enhancement, + }), + }; + pub const z16 = CpuModel{ + .name = "z16", + .llvm_name = "z16", + .features = featureSet(&[_]Feature{ + .bear_enhancement, + .deflate_conversion, + .dfp_packed_conversion, + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .enhanced_sort, + .execution_hint, + .fast_serialization, + .fp_extension, + .guarded_storage, + .high_word, + .insert_reference_bits_multiple, + .interlocked_access1, + .load_and_trap, + .load_and_zero_rightmost_byte, + .load_store_on_cond, + .load_store_on_cond_2, + .message_security_assist_extension3, + .message_security_assist_extension4, + .message_security_assist_extension5, + .message_security_assist_extension7, + .message_security_assist_extension8, + .message_security_assist_extension9, + .miscellaneous_extensions, + .miscellaneous_extensions_2, + .miscellaneous_extensions_3, + .nnp_assist, + .population_count, + .processor_activity_instrumentation, + .processor_assist, + .reset_dat_protection, + .reset_reference_bits_multiple, + .transactional_execution, + .vector, + .vector_enhancements_1, + .vector_enhancements_2, + .vector_packed_decimal, + .vector_packed_decimal_enhancement, + .vector_packed_decimal_enhancement_2, + }), + }; + pub const z196 = CpuModel{ + .name = "z196", + .llvm_name = "z196", + .features = featureSet(&[_]Feature{ + .distinct_ops, + .fast_serialization, + .fp_extension, + .high_word, + .interlocked_access1, + .load_store_on_cond, + .message_security_assist_extension3, + .message_security_assist_extension4, + .population_count, + .reset_reference_bits_multiple, + }), + }; + pub const zEC12 = CpuModel{ + .name = "zEC12", + .llvm_name = "zEC12", + .features = featureSet(&[_]Feature{ + .dfp_zoned_conversion, + .distinct_ops, + .enhanced_dat_2, + .execution_hint, + .fast_serialization, + .fp_extension, + .high_word, + .interlocked_access1, + .load_and_trap, + .load_store_on_cond, + .message_security_assist_extension3, + .message_security_assist_extension4, + .miscellaneous_extensions, + .population_count, + .processor_assist, + .reset_reference_bits_multiple, + .transactional_execution, + }), + }; +}; diff --git a/lib/std/Target/sparc.zig b/lib/std/Target/sparc.zig new file mode 100644 index 0000000000..87bd95697c --- /dev/null +++ b/lib/std/Target/sparc.zig @@ -0,0 +1,455 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + deprecated_v8, + detectroundchange, + fixallfdivsqrt, + hard_quad_float, + hasleoncasa, + hasumacsmac, + insertnopload, + leon, + leoncyclecounter, + leonpwrpsr, + no_fmuls, + no_fsmuld, + popc, + soft_float, + soft_mul_div, + v9, + vis, + vis2, + vis3, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.deprecated_v8)] = .{ + .llvm_name = "deprecated-v8", + .description = "Enable deprecated V8 instructions in V9 mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.detectroundchange)] = .{ + .llvm_name = "detectroundchange", + .description = "LEON3 erratum detection: Detects any rounding mode change request: use only the round-to-nearest rounding mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fixallfdivsqrt)] = .{ + .llvm_name = "fixallfdivsqrt", + .description = "LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hard_quad_float)] = .{ + .llvm_name = "hard-quad-float", + .description = "Enable quad-word floating point instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hasleoncasa)] = .{ + .llvm_name = "hasleoncasa", + .description = "Enable CASA instruction for LEON3 and LEON4 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hasumacsmac)] = .{ + .llvm_name = "hasumacsmac", + .description = "Enable UMAC and SMAC for LEON3 and LEON4 processors", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.insertnopload)] = .{ + .llvm_name = "insertnopload", + .description = "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.leon)] = .{ + .llvm_name = "leon", + .description = "Enable LEON extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.leoncyclecounter)] = .{ + .llvm_name = "leoncyclecounter", + .description = "Use the Leon cycle counter register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.leonpwrpsr)] = .{ + .llvm_name = "leonpwrpsr", + .description = "Enable the PWRPSR instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_fmuls)] = .{ + .llvm_name = "no-fmuls", + .description = "Disable the fmuls instruction.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_fsmuld)] = .{ + .llvm_name = "no-fsmuld", + .description = "Disable the fsmuld instruction.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.popc)] = .{ + .llvm_name = "popc", + .description = "Use the popc (population count) instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.soft_float)] = .{ + .llvm_name = "soft-float", + .description = "Use software emulation for floating point", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.soft_mul_div)] = .{ + .llvm_name = "soft-mul-div", + .description = "Use software emulation for integer multiply and divide", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v9)] = .{ + .llvm_name = "v9", + .description = "Enable SPARC-V9 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vis)] = .{ + .llvm_name = "vis", + .description = "Enable UltraSPARC Visual Instruction Set extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vis2)] = .{ + .llvm_name = "vis2", + .description = "Enable Visual Instruction Set extensions II", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vis3)] = .{ + .llvm_name = "vis3", + .description = "Enable Visual Instruction Set extensions III", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const at697e = CpuModel{ + .name = "at697e", + .llvm_name = "at697e", + .features = featureSet(&[_]Feature{ + .insertnopload, + .leon, + }), + }; + pub const at697f = CpuModel{ + .name = "at697f", + .llvm_name = "at697f", + .features = featureSet(&[_]Feature{ + .insertnopload, + .leon, + }), + }; + pub const f934 = CpuModel{ + .name = "f934", + .llvm_name = "f934", + .features = featureSet(&[_]Feature{}), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; + pub const gr712rc = CpuModel{ + .name = "gr712rc", + .llvm_name = "gr712rc", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const gr740 = CpuModel{ + .name = "gr740", + .llvm_name = "gr740", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .hasumacsmac, + .leon, + .leoncyclecounter, + .leonpwrpsr, + }), + }; + pub const hypersparc = CpuModel{ + .name = "hypersparc", + .llvm_name = "hypersparc", + .features = featureSet(&[_]Feature{}), + }; + pub const leon2 = CpuModel{ + .name = "leon2", + .llvm_name = "leon2", + .features = featureSet(&[_]Feature{ + .leon, + }), + }; + pub const leon3 = CpuModel{ + .name = "leon3", + .llvm_name = "leon3", + .features = featureSet(&[_]Feature{ + .hasumacsmac, + .leon, + }), + }; + pub const leon4 = CpuModel{ + .name = "leon4", + .llvm_name = "leon4", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .hasumacsmac, + .leon, + }), + }; + pub const ma2080 = CpuModel{ + .name = "ma2080", + .llvm_name = "ma2080", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2085 = CpuModel{ + .name = "ma2085", + .llvm_name = "ma2085", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2100 = CpuModel{ + .name = "ma2100", + .llvm_name = "ma2100", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2150 = CpuModel{ + .name = "ma2150", + .llvm_name = "ma2150", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2155 = CpuModel{ + .name = "ma2155", + .llvm_name = "ma2155", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2450 = CpuModel{ + .name = "ma2450", + .llvm_name = "ma2450", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2455 = CpuModel{ + .name = "ma2455", + .llvm_name = "ma2455", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2480 = CpuModel{ + .name = "ma2480", + .llvm_name = "ma2480", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2485 = CpuModel{ + .name = "ma2485", + .llvm_name = "ma2485", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2x5x = CpuModel{ + .name = "ma2x5x", + .llvm_name = "ma2x5x", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const ma2x8x = CpuModel{ + .name = "ma2x8x", + .llvm_name = "ma2x8x", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const myriad2 = CpuModel{ + .name = "myriad2", + .llvm_name = "myriad2", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const myriad2_1 = CpuModel{ + .name = "myriad2_1", + .llvm_name = "myriad2.1", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const myriad2_2 = CpuModel{ + .name = "myriad2_2", + .llvm_name = "myriad2.2", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const myriad2_3 = CpuModel{ + .name = "myriad2_3", + .llvm_name = "myriad2.3", + .features = featureSet(&[_]Feature{ + .hasleoncasa, + .leon, + }), + }; + pub const niagara = CpuModel{ + .name = "niagara", + .llvm_name = "niagara", + .features = featureSet(&[_]Feature{ + .deprecated_v8, + .v9, + .vis, + .vis2, + }), + }; + pub const niagara2 = CpuModel{ + .name = "niagara2", + .llvm_name = "niagara2", + .features = featureSet(&[_]Feature{ + .deprecated_v8, + .popc, + .v9, + .vis, + .vis2, + }), + }; + pub const niagara3 = CpuModel{ + .name = "niagara3", + .llvm_name = "niagara3", + .features = featureSet(&[_]Feature{ + .deprecated_v8, + .popc, + .v9, + .vis, + .vis2, + }), + }; + pub const niagara4 = CpuModel{ + .name = "niagara4", + .llvm_name = "niagara4", + .features = featureSet(&[_]Feature{ + .deprecated_v8, + .popc, + .v9, + .vis, + .vis2, + .vis3, + }), + }; + pub const sparclet = CpuModel{ + .name = "sparclet", + .llvm_name = "sparclet", + .features = featureSet(&[_]Feature{}), + }; + pub const sparclite = CpuModel{ + .name = "sparclite", + .llvm_name = "sparclite", + .features = featureSet(&[_]Feature{}), + }; + pub const sparclite86x = CpuModel{ + .name = "sparclite86x", + .llvm_name = "sparclite86x", + .features = featureSet(&[_]Feature{}), + }; + pub const supersparc = CpuModel{ + .name = "supersparc", + .llvm_name = "supersparc", + .features = featureSet(&[_]Feature{}), + }; + pub const tsc701 = CpuModel{ + .name = "tsc701", + .llvm_name = "tsc701", + .features = featureSet(&[_]Feature{}), + }; + pub const ultrasparc = CpuModel{ + .name = "ultrasparc", + .llvm_name = "ultrasparc", + .features = featureSet(&[_]Feature{ + .deprecated_v8, + .v9, + .vis, + }), + }; + pub const ultrasparc3 = CpuModel{ + .name = "ultrasparc3", + .llvm_name = "ultrasparc3", + .features = featureSet(&[_]Feature{ + .deprecated_v8, + .v9, + .vis, + .vis2, + }), + }; + pub const ut699 = CpuModel{ + .name = "ut699", + .llvm_name = "ut699", + .features = featureSet(&[_]Feature{ + .fixallfdivsqrt, + .insertnopload, + .leon, + .no_fmuls, + .no_fsmuld, + }), + }; + pub const v7 = CpuModel{ + .name = "v7", + .llvm_name = "v7", + .features = featureSet(&[_]Feature{ + .no_fsmuld, + .soft_mul_div, + }), + }; + pub const v8 = CpuModel{ + .name = "v8", + .llvm_name = "v8", + .features = featureSet(&[_]Feature{}), + }; + pub const v9 = CpuModel{ + .name = "v9", + .llvm_name = "v9", + .features = featureSet(&[_]Feature{ + .v9, + }), + }; +}; diff --git a/lib/std/Target/spirv.zig b/lib/std/Target/spirv.zig new file mode 100644 index 0000000000..9d79aff221 --- /dev/null +++ b/lib/std/Target/spirv.zig @@ -0,0 +1,2091 @@ +//! This file is auto-generated by tools/update_spirv_features.zig. +//! TODO: Dependencies of capabilities on extensions. +//! TODO: Dependencies of extensions on extensions. +//! TODO: Dependencies of extensions on versions. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + v1_1, + v1_2, + v1_3, + v1_4, + v1_5, + SPV_AMD_shader_fragment_mask, + SPV_AMD_gpu_shader_int16, + SPV_AMD_gpu_shader_half_float, + SPV_AMD_texture_gather_bias_lod, + SPV_AMD_shader_ballot, + SPV_AMD_gcn_shader, + SPV_AMD_shader_image_load_store_lod, + SPV_AMD_shader_explicit_vertex_parameter, + SPV_AMD_shader_trinary_minmax, + SPV_AMD_gpu_shader_half_float_fetch, + SPV_GOOGLE_hlsl_functionality1, + SPV_GOOGLE_user_type, + SPV_GOOGLE_decorate_string, + SPV_EXT_demote_to_helper_invocation, + SPV_EXT_descriptor_indexing, + SPV_EXT_fragment_fully_covered, + SPV_EXT_shader_stencil_export, + SPV_EXT_physical_storage_buffer, + SPV_EXT_shader_atomic_float_add, + SPV_EXT_shader_atomic_float_min_max, + SPV_EXT_shader_image_int64, + SPV_EXT_fragment_shader_interlock, + SPV_EXT_fragment_invocation_density, + SPV_EXT_shader_viewport_index_layer, + SPV_INTEL_loop_fuse, + SPV_INTEL_fpga_dsp_control, + SPV_INTEL_fpga_reg, + SPV_INTEL_fpga_memory_accesses, + SPV_INTEL_fpga_loop_controls, + SPV_INTEL_io_pipes, + SPV_INTEL_unstructured_loop_controls, + SPV_INTEL_blocking_pipes, + SPV_INTEL_device_side_avc_motion_estimation, + SPV_INTEL_fpga_memory_attributes, + SPV_INTEL_fp_fast_math_mode, + SPV_INTEL_media_block_io, + SPV_INTEL_shader_integer_functions2, + SPV_INTEL_subgroups, + SPV_INTEL_fpga_cluster_attributes, + SPV_INTEL_kernel_attributes, + SPV_INTEL_arbitrary_precision_integers, + SPV_KHR_8bit_storage, + SPV_KHR_shader_clock, + SPV_KHR_device_group, + SPV_KHR_16bit_storage, + SPV_KHR_variable_pointers, + SPV_KHR_no_integer_wrap_decoration, + SPV_KHR_subgroup_vote, + SPV_KHR_multiview, + SPV_KHR_shader_ballot, + SPV_KHR_vulkan_memory_model, + SPV_KHR_physical_storage_buffer, + SPV_KHR_workgroup_memory_explicit_layout, + SPV_KHR_fragment_shading_rate, + SPV_KHR_shader_atomic_counter_ops, + SPV_KHR_shader_draw_parameters, + SPV_KHR_storage_buffer_storage_class, + SPV_KHR_linkonce_odr, + SPV_KHR_terminate_invocation, + SPV_KHR_non_semantic_info, + SPV_KHR_post_depth_coverage, + SPV_KHR_expect_assume, + SPV_KHR_ray_tracing, + SPV_KHR_ray_query, + SPV_KHR_float_controls, + SPV_NV_viewport_array2, + SPV_NV_shader_subgroup_partitioned, + SPV_NVX_multiview_per_view_attributes, + SPV_NV_ray_tracing, + SPV_NV_shader_image_footprint, + SPV_NV_shading_rate, + SPV_NV_stereo_view_rendering, + SPV_NV_compute_shader_derivatives, + SPV_NV_shader_sm_builtins, + SPV_NV_mesh_shader, + SPV_NV_geometry_shader_passthrough, + SPV_NV_fragment_shader_barycentric, + SPV_NV_cooperative_matrix, + SPV_NV_sample_mask_override_coverage, + Matrix, + Shader, + Geometry, + Tessellation, + Addresses, + Linkage, + Kernel, + Vector16, + Float16Buffer, + Float16, + Float64, + Int64, + Int64Atomics, + ImageBasic, + ImageReadWrite, + ImageMipmap, + Pipes, + Groups, + DeviceEnqueue, + LiteralSampler, + AtomicStorage, + Int16, + TessellationPointSize, + GeometryPointSize, + ImageGatherExtended, + StorageImageMultisample, + UniformBufferArrayDynamicIndexing, + SampledImageArrayDynamicIndexing, + StorageBufferArrayDynamicIndexing, + StorageImageArrayDynamicIndexing, + ClipDistance, + CullDistance, + ImageCubeArray, + SampleRateShading, + ImageRect, + SampledRect, + GenericPointer, + Int8, + InputAttachment, + SparseResidency, + MinLod, + Sampled1D, + Image1D, + SampledCubeArray, + SampledBuffer, + ImageBuffer, + ImageMSArray, + StorageImageExtendedFormats, + ImageQuery, + DerivativeControl, + InterpolationFunction, + TransformFeedback, + GeometryStreams, + StorageImageReadWithoutFormat, + StorageImageWriteWithoutFormat, + MultiViewport, + SubgroupDispatch, + NamedBarrier, + PipeStorage, + GroupNonUniform, + GroupNonUniformVote, + GroupNonUniformArithmetic, + GroupNonUniformBallot, + GroupNonUniformShuffle, + GroupNonUniformShuffleRelative, + GroupNonUniformClustered, + GroupNonUniformQuad, + ShaderLayer, + ShaderViewportIndex, + FragmentShadingRateKHR, + SubgroupBallotKHR, + DrawParameters, + WorkgroupMemoryExplicitLayoutKHR, + WorkgroupMemoryExplicitLayout8BitAccessKHR, + WorkgroupMemoryExplicitLayout16BitAccessKHR, + SubgroupVoteKHR, + StorageBuffer16BitAccess, + StorageUniformBufferBlock16, + UniformAndStorageBuffer16BitAccess, + StorageUniform16, + StoragePushConstant16, + StorageInputOutput16, + DeviceGroup, + MultiView, + VariablePointersStorageBuffer, + VariablePointers, + AtomicStorageOps, + SampleMaskPostDepthCoverage, + StorageBuffer8BitAccess, + UniformAndStorageBuffer8BitAccess, + StoragePushConstant8, + DenormPreserve, + DenormFlushToZero, + SignedZeroInfNanPreserve, + RoundingModeRTE, + RoundingModeRTZ, + RayQueryProvisionalKHR, + RayQueryKHR, + RayTraversalPrimitiveCullingKHR, + RayTracingKHR, + Float16ImageAMD, + ImageGatherBiasLodAMD, + FragmentMaskAMD, + StencilExportEXT, + ImageReadWriteLodAMD, + Int64ImageEXT, + ShaderClockKHR, + SampleMaskOverrideCoverageNV, + GeometryShaderPassthroughNV, + ShaderViewportIndexLayerEXT, + ShaderViewportIndexLayerNV, + ShaderViewportMaskNV, + ShaderStereoViewNV, + PerViewAttributesNV, + FragmentFullyCoveredEXT, + MeshShadingNV, + ImageFootprintNV, + FragmentBarycentricNV, + ComputeDerivativeGroupQuadsNV, + FragmentDensityEXT, + ShadingRateNV, + GroupNonUniformPartitionedNV, + ShaderNonUniform, + ShaderNonUniformEXT, + RuntimeDescriptorArray, + RuntimeDescriptorArrayEXT, + InputAttachmentArrayDynamicIndexing, + InputAttachmentArrayDynamicIndexingEXT, + UniformTexelBufferArrayDynamicIndexing, + UniformTexelBufferArrayDynamicIndexingEXT, + StorageTexelBufferArrayDynamicIndexing, + StorageTexelBufferArrayDynamicIndexingEXT, + UniformBufferArrayNonUniformIndexing, + UniformBufferArrayNonUniformIndexingEXT, + SampledImageArrayNonUniformIndexing, + SampledImageArrayNonUniformIndexingEXT, + StorageBufferArrayNonUniformIndexing, + StorageBufferArrayNonUniformIndexingEXT, + StorageImageArrayNonUniformIndexing, + StorageImageArrayNonUniformIndexingEXT, + InputAttachmentArrayNonUniformIndexing, + InputAttachmentArrayNonUniformIndexingEXT, + UniformTexelBufferArrayNonUniformIndexing, + UniformTexelBufferArrayNonUniformIndexingEXT, + StorageTexelBufferArrayNonUniformIndexing, + StorageTexelBufferArrayNonUniformIndexingEXT, + RayTracingNV, + VulkanMemoryModel, + VulkanMemoryModelKHR, + VulkanMemoryModelDeviceScope, + VulkanMemoryModelDeviceScopeKHR, + PhysicalStorageBufferAddresses, + PhysicalStorageBufferAddressesEXT, + ComputeDerivativeGroupLinearNV, + RayTracingProvisionalKHR, + CooperativeMatrixNV, + FragmentShaderSampleInterlockEXT, + FragmentShaderShadingRateInterlockEXT, + ShaderSMBuiltinsNV, + FragmentShaderPixelInterlockEXT, + DemoteToHelperInvocationEXT, + SubgroupShuffleINTEL, + SubgroupBufferBlockIOINTEL, + SubgroupImageBlockIOINTEL, + SubgroupImageMediaBlockIOINTEL, + RoundToInfinityINTEL, + FloatingPointModeINTEL, + IntegerFunctions2INTEL, + FunctionPointersINTEL, + IndirectReferencesINTEL, + AsmINTEL, + AtomicFloat32MinMaxEXT, + AtomicFloat64MinMaxEXT, + AtomicFloat16MinMaxEXT, + VectorComputeINTEL, + VectorAnyINTEL, + ExpectAssumeKHR, + SubgroupAvcMotionEstimationINTEL, + SubgroupAvcMotionEstimationIntraINTEL, + SubgroupAvcMotionEstimationChromaINTEL, + VariableLengthArrayINTEL, + FunctionFloatControlINTEL, + FPGAMemoryAttributesINTEL, + FPFastMathModeINTEL, + ArbitraryPrecisionIntegersINTEL, + UnstructuredLoopControlsINTEL, + FPGALoopControlsINTEL, + KernelAttributesINTEL, + FPGAKernelAttributesINTEL, + FPGAMemoryAccessesINTEL, + FPGAClusterAttributesINTEL, + LoopFuseINTEL, + FPGABufferLocationINTEL, + USMStorageClassesINTEL, + IOPipesINTEL, + BlockingPipesINTEL, + FPGARegINTEL, + AtomicFloat32AddEXT, + AtomicFloat64AddEXT, + LongConstantCompositeINTEL, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + @setEvalBranchQuota(2000); + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.v1_1)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.1", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.v1_2)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.2", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + }), + }; + result[@intFromEnum(Feature.v1_3)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.3", + .dependencies = featureSet(&[_]Feature{ + .v1_2, + }), + }; + result[@intFromEnum(Feature.v1_4)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.4", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.v1_5)] = .{ + .llvm_name = null, + .description = "SPIR-V version 1.5", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@intFromEnum(Feature.SPV_AMD_shader_fragment_mask)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_fragment_mask", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_gpu_shader_int16)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gpu_shader_int16", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_gpu_shader_half_float)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_texture_gather_bias_lod)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_texture_gather_bias_lod", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_shader_ballot)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_ballot", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_gcn_shader)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gcn_shader", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_shader_image_load_store_lod)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_image_load_store_lod", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_shader_explicit_vertex_parameter)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_explicit_vertex_parameter", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_shader_trinary_minmax)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_shader_trinary_minmax", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_AMD_gpu_shader_half_float_fetch)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float_fetch", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_GOOGLE_hlsl_functionality1)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_GOOGLE_hlsl_functionality1", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_GOOGLE_user_type)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_GOOGLE_user_type", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_GOOGLE_decorate_string)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_GOOGLE_decorate_string", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_demote_to_helper_invocation)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_demote_to_helper_invocation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_descriptor_indexing)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_descriptor_indexing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_fragment_fully_covered)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_fragment_fully_covered", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_shader_stencil_export)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_stencil_export", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_physical_storage_buffer)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_physical_storage_buffer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_shader_atomic_float_add)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_atomic_float_add", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_shader_atomic_float_min_max)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_atomic_float_min_max", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_shader_image_int64)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_image_int64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_fragment_shader_interlock)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_fragment_shader_interlock", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_fragment_invocation_density)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_fragment_invocation_density", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_EXT_shader_viewport_index_layer)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_EXT_shader_viewport_index_layer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_loop_fuse)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_loop_fuse", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fpga_dsp_control)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_dsp_control", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fpga_reg)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_reg", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fpga_memory_accesses)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_memory_accesses", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fpga_loop_controls)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_loop_controls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_io_pipes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_io_pipes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_unstructured_loop_controls)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_unstructured_loop_controls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_blocking_pipes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_blocking_pipes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_device_side_avc_motion_estimation)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_device_side_avc_motion_estimation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fpga_memory_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_memory_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fp_fast_math_mode)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fp_fast_math_mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_media_block_io)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_media_block_io", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_shader_integer_functions2)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_shader_integer_functions2", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_subgroups)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_subgroups", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_fpga_cluster_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_fpga_cluster_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_kernel_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_kernel_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_INTEL_arbitrary_precision_integers)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_INTEL_arbitrary_precision_integers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_8bit_storage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_8bit_storage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_shader_clock)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_clock", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_device_group)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_device_group", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_16bit_storage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_16bit_storage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_variable_pointers)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_variable_pointers", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_no_integer_wrap_decoration)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_no_integer_wrap_decoration", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_subgroup_vote)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_subgroup_vote", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_multiview)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_multiview", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_shader_ballot)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_ballot", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_vulkan_memory_model)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_vulkan_memory_model", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_physical_storage_buffer)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_physical_storage_buffer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_workgroup_memory_explicit_layout)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_workgroup_memory_explicit_layout", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_fragment_shading_rate)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_fragment_shading_rate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_shader_atomic_counter_ops)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_atomic_counter_ops", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_shader_draw_parameters)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_shader_draw_parameters", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_storage_buffer_storage_class)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_storage_buffer_storage_class", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_linkonce_odr)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_linkonce_odr", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_terminate_invocation)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_terminate_invocation", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_non_semantic_info)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_non_semantic_info", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_post_depth_coverage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_post_depth_coverage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_expect_assume)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_expect_assume", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_ray_tracing)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_ray_tracing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_ray_query)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_ray_query", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_KHR_float_controls)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_KHR_float_controls", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_viewport_array2)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_viewport_array2", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_shader_subgroup_partitioned)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shader_subgroup_partitioned", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NVX_multiview_per_view_attributes)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NVX_multiview_per_view_attributes", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_ray_tracing)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_ray_tracing", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_shader_image_footprint)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shader_image_footprint", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_shading_rate)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shading_rate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_stereo_view_rendering)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_stereo_view_rendering", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_compute_shader_derivatives)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_compute_shader_derivatives", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_shader_sm_builtins)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_shader_sm_builtins", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_mesh_shader)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_mesh_shader", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_geometry_shader_passthrough)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_geometry_shader_passthrough", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_fragment_shader_barycentric)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_fragment_shader_barycentric", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_cooperative_matrix)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_cooperative_matrix", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SPV_NV_sample_mask_override_coverage)] = .{ + .llvm_name = null, + .description = "SPIR-V extension SPV_NV_sample_mask_override_coverage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Matrix)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Matrix", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Shader)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Shader", + .dependencies = featureSet(&[_]Feature{ + .Matrix, + }), + }; + result[@intFromEnum(Feature.Geometry)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Geometry", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.Tessellation)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Tessellation", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.Addresses)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Addresses", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Linkage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Linkage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Kernel)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Kernel", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Vector16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Vector16", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.Float16Buffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float16Buffer", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.Float16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float16", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Float64)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Int64)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int64", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Int64Atomics)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int64Atomics", + .dependencies = featureSet(&[_]Feature{ + .Int64, + }), + }; + result[@intFromEnum(Feature.ImageBasic)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageBasic", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.ImageReadWrite)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageReadWrite", + .dependencies = featureSet(&[_]Feature{ + .ImageBasic, + }), + }; + result[@intFromEnum(Feature.ImageMipmap)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageMipmap", + .dependencies = featureSet(&[_]Feature{ + .ImageBasic, + }), + }; + result[@intFromEnum(Feature.Pipes)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Pipes", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.Groups)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Groups", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.DeviceEnqueue)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DeviceEnqueue", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.LiteralSampler)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability LiteralSampler", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.AtomicStorage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicStorage", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.Int16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int16", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.TessellationPointSize)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability TessellationPointSize", + .dependencies = featureSet(&[_]Feature{ + .Tessellation, + }), + }; + result[@intFromEnum(Feature.GeometryPointSize)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GeometryPointSize", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@intFromEnum(Feature.ImageGatherExtended)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageGatherExtended", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.StorageImageMultisample)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageMultisample", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.UniformBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SampledImageArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledImageArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.StorageBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.StorageImageArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ClipDistance)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ClipDistance", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.CullDistance)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability CullDistance", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ImageCubeArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageCubeArray", + .dependencies = featureSet(&[_]Feature{ + .SampledCubeArray, + }), + }; + result[@intFromEnum(Feature.SampleRateShading)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampleRateShading", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ImageRect)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageRect", + .dependencies = featureSet(&[_]Feature{ + .SampledRect, + }), + }; + result[@intFromEnum(Feature.SampledRect)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledRect", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.GenericPointer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GenericPointer", + .dependencies = featureSet(&[_]Feature{ + .Addresses, + }), + }; + result[@intFromEnum(Feature.Int8)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int8", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.InputAttachment)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachment", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SparseResidency)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SparseResidency", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.MinLod)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MinLod", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.Sampled1D)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Sampled1D", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.Image1D)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Image1D", + .dependencies = featureSet(&[_]Feature{ + .Sampled1D, + }), + }; + result[@intFromEnum(Feature.SampledCubeArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledCubeArray", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SampledBuffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledBuffer", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ImageBuffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageBuffer", + .dependencies = featureSet(&[_]Feature{ + .SampledBuffer, + }), + }; + result[@intFromEnum(Feature.ImageMSArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageMSArray", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.StorageImageExtendedFormats)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageExtendedFormats", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ImageQuery)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageQuery", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.DerivativeControl)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DerivativeControl", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.InterpolationFunction)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InterpolationFunction", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.TransformFeedback)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability TransformFeedback", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.GeometryStreams)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GeometryStreams", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@intFromEnum(Feature.StorageImageReadWithoutFormat)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageReadWithoutFormat", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.StorageImageWriteWithoutFormat)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageWriteWithoutFormat", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.MultiViewport)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MultiViewport", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@intFromEnum(Feature.SubgroupDispatch)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupDispatch", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + .DeviceEnqueue, + }), + }; + result[@intFromEnum(Feature.NamedBarrier)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability NamedBarrier", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + .Kernel, + }), + }; + result[@intFromEnum(Feature.PipeStorage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PipeStorage", + .dependencies = featureSet(&[_]Feature{ + .v1_1, + .Pipes, + }), + }; + result[@intFromEnum(Feature.GroupNonUniform)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniform", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformVote)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformVote", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformArithmetic)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformArithmetic", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformBallot)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformBallot", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformShuffle)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformShuffle", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformShuffleRelative)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformShuffleRelative", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformClustered)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformClustered", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformQuad)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformQuad", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .GroupNonUniform, + }), + }; + result[@intFromEnum(Feature.ShaderLayer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderLayer", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.ShaderViewportIndex)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportIndex", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.FragmentShadingRateKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShadingRateKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SubgroupBallotKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupBallotKHR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.DrawParameters)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DrawParameters", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .Shader, + }), + }; + result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayoutKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayoutKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayout8BitAccessKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout8BitAccessKHR", + .dependencies = featureSet(&[_]Feature{ + .WorkgroupMemoryExplicitLayoutKHR, + }), + }; + result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayout16BitAccessKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout16BitAccessKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SubgroupVoteKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupVoteKHR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.StorageBuffer16BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBuffer16BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.StorageUniformBufferBlock16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageUniformBufferBlock16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.UniformAndStorageBuffer16BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformAndStorageBuffer16BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .StorageBuffer16BitAccess, + .StorageUniformBufferBlock16, + }), + }; + result[@intFromEnum(Feature.StorageUniform16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageUniform16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .StorageBuffer16BitAccess, + .StorageUniformBufferBlock16, + }), + }; + result[@intFromEnum(Feature.StoragePushConstant16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StoragePushConstant16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.StorageInputOutput16)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageInputOutput16", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.DeviceGroup)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DeviceGroup", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + }), + }; + result[@intFromEnum(Feature.MultiView)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MultiView", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .Shader, + }), + }; + result[@intFromEnum(Feature.VariablePointersStorageBuffer)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VariablePointersStorageBuffer", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .Shader, + }), + }; + result[@intFromEnum(Feature.VariablePointers)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VariablePointers", + .dependencies = featureSet(&[_]Feature{ + .v1_3, + .VariablePointersStorageBuffer, + }), + }; + result[@intFromEnum(Feature.AtomicStorageOps)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicStorageOps", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SampleMaskPostDepthCoverage)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampleMaskPostDepthCoverage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.StorageBuffer8BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBuffer8BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.UniformAndStorageBuffer8BitAccess)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformAndStorageBuffer8BitAccess", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .StorageBuffer8BitAccess, + }), + }; + result[@intFromEnum(Feature.StoragePushConstant8)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StoragePushConstant8", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.DenormPreserve)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DenormPreserve", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@intFromEnum(Feature.DenormFlushToZero)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DenormFlushToZero", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@intFromEnum(Feature.SignedZeroInfNanPreserve)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SignedZeroInfNanPreserve", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@intFromEnum(Feature.RoundingModeRTE)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RoundingModeRTE", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@intFromEnum(Feature.RoundingModeRTZ)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RoundingModeRTZ", + .dependencies = featureSet(&[_]Feature{ + .v1_4, + }), + }; + result[@intFromEnum(Feature.RayQueryProvisionalKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayQueryProvisionalKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.RayQueryKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayQueryKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.RayTraversalPrimitiveCullingKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTraversalPrimitiveCullingKHR", + .dependencies = featureSet(&[_]Feature{ + .RayQueryKHR, + .RayTracingKHR, + }), + }; + result[@intFromEnum(Feature.RayTracingKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTracingKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.Float16ImageAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Float16ImageAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ImageGatherBiasLodAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageGatherBiasLodAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.FragmentMaskAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentMaskAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.StencilExportEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StencilExportEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ImageReadWriteLodAMD)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageReadWriteLodAMD", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.Int64ImageEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability Int64ImageEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ShaderClockKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderClockKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SampleMaskOverrideCoverageNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampleMaskOverrideCoverageNV", + .dependencies = featureSet(&[_]Feature{ + .SampleRateShading, + }), + }; + result[@intFromEnum(Feature.GeometryShaderPassthroughNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GeometryShaderPassthroughNV", + .dependencies = featureSet(&[_]Feature{ + .Geometry, + }), + }; + result[@intFromEnum(Feature.ShaderViewportIndexLayerEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportIndexLayerEXT", + .dependencies = featureSet(&[_]Feature{ + .MultiViewport, + }), + }; + result[@intFromEnum(Feature.ShaderViewportIndexLayerNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportIndexLayerNV", + .dependencies = featureSet(&[_]Feature{ + .MultiViewport, + }), + }; + result[@intFromEnum(Feature.ShaderViewportMaskNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderViewportMaskNV", + .dependencies = featureSet(&[_]Feature{ + .ShaderViewportIndexLayerNV, + }), + }; + result[@intFromEnum(Feature.ShaderStereoViewNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderStereoViewNV", + .dependencies = featureSet(&[_]Feature{ + .ShaderViewportMaskNV, + }), + }; + result[@intFromEnum(Feature.PerViewAttributesNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PerViewAttributesNV", + .dependencies = featureSet(&[_]Feature{ + .MultiView, + }), + }; + result[@intFromEnum(Feature.FragmentFullyCoveredEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentFullyCoveredEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.MeshShadingNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability MeshShadingNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ImageFootprintNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ImageFootprintNV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FragmentBarycentricNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentBarycentricNV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ComputeDerivativeGroupQuadsNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ComputeDerivativeGroupQuadsNV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FragmentDensityEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentDensityEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ShadingRateNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShadingRateNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.GroupNonUniformPartitionedNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability GroupNonUniformPartitionedNV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ShaderNonUniform)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderNonUniform", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@intFromEnum(Feature.ShaderNonUniformEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderNonUniformEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@intFromEnum(Feature.RuntimeDescriptorArray)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RuntimeDescriptorArray", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@intFromEnum(Feature.RuntimeDescriptorArrayEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RuntimeDescriptorArrayEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@intFromEnum(Feature.InputAttachmentArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + }), + }; + result[@intFromEnum(Feature.InputAttachmentArrayDynamicIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + }), + }; + result[@intFromEnum(Feature.UniformTexelBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + }), + }; + result[@intFromEnum(Feature.UniformTexelBufferArrayDynamicIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + }), + }; + result[@intFromEnum(Feature.StorageTexelBufferArrayDynamicIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + }), + }; + result[@intFromEnum(Feature.StorageTexelBufferArrayDynamicIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + }), + }; + result[@intFromEnum(Feature.UniformBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.UniformBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.SampledImageArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.SampledImageArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.StorageBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.StorageBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.StorageImageArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.StorageImageArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.InputAttachmentArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.InputAttachmentArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .InputAttachment, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.UniformTexelBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.UniformTexelBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .SampledBuffer, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.StorageTexelBufferArrayNonUniformIndexing)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexing", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.StorageTexelBufferArrayNonUniformIndexingEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexingEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .ImageBuffer, + .ShaderNonUniform, + }), + }; + result[@intFromEnum(Feature.RayTracingNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTracingNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.VulkanMemoryModel)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModel", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.VulkanMemoryModelKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModelKHR", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.VulkanMemoryModelDeviceScope)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScope", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.VulkanMemoryModelDeviceScopeKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScopeKHR", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + }), + }; + result[@intFromEnum(Feature.PhysicalStorageBufferAddresses)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PhysicalStorageBufferAddresses", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@intFromEnum(Feature.PhysicalStorageBufferAddressesEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability PhysicalStorageBufferAddressesEXT", + .dependencies = featureSet(&[_]Feature{ + .v1_5, + .Shader, + }), + }; + result[@intFromEnum(Feature.ComputeDerivativeGroupLinearNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ComputeDerivativeGroupLinearNV", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.RayTracingProvisionalKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RayTracingProvisionalKHR", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.CooperativeMatrixNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability CooperativeMatrixNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.FragmentShaderSampleInterlockEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShaderSampleInterlockEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.FragmentShaderShadingRateInterlockEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShaderShadingRateInterlockEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.ShaderSMBuiltinsNV)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ShaderSMBuiltinsNV", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.FragmentShaderPixelInterlockEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FragmentShaderPixelInterlockEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.DemoteToHelperInvocationEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability DemoteToHelperInvocationEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.SubgroupShuffleINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupShuffleINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SubgroupBufferBlockIOINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupBufferBlockIOINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SubgroupImageBlockIOINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupImageBlockIOINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SubgroupImageMediaBlockIOINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupImageMediaBlockIOINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.RoundToInfinityINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability RoundToInfinityINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FloatingPointModeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FloatingPointModeINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.IntegerFunctions2INTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability IntegerFunctions2INTEL", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.FunctionPointersINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FunctionPointersINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.IndirectReferencesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability IndirectReferencesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.AsmINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AsmINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.AtomicFloat32MinMaxEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat32MinMaxEXT", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.AtomicFloat64MinMaxEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat64MinMaxEXT", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.AtomicFloat16MinMaxEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat16MinMaxEXT", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.VectorComputeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VectorComputeINTEL", + .dependencies = featureSet(&[_]Feature{ + .VectorAnyINTEL, + }), + }; + result[@intFromEnum(Feature.VectorAnyINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VectorAnyINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ExpectAssumeKHR)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ExpectAssumeKHR", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SubgroupAvcMotionEstimationINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SubgroupAvcMotionEstimationIntraINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationIntraINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.SubgroupAvcMotionEstimationChromaINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationChromaINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.VariableLengthArrayINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability VariableLengthArrayINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FunctionFloatControlINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FunctionFloatControlINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGAMemoryAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAMemoryAttributesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPFastMathModeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPFastMathModeINTEL", + .dependencies = featureSet(&[_]Feature{ + .Kernel, + }), + }; + result[@intFromEnum(Feature.ArbitraryPrecisionIntegersINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability ArbitraryPrecisionIntegersINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.UnstructuredLoopControlsINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability UnstructuredLoopControlsINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGALoopControlsINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGALoopControlsINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.KernelAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability KernelAttributesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGAKernelAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAKernelAttributesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGAMemoryAccessesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAMemoryAccessesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGAClusterAttributesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGAClusterAttributesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.LoopFuseINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability LoopFuseINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGABufferLocationINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGABufferLocationINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.USMStorageClassesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability USMStorageClassesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.IOPipesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability IOPipesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.BlockingPipesINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability BlockingPipesINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.FPGARegINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability FPGARegINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.AtomicFloat32AddEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat32AddEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.AtomicFloat64AddEXT)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability AtomicFloat64AddEXT", + .dependencies = featureSet(&[_]Feature{ + .Shader, + }), + }; + result[@intFromEnum(Feature.LongConstantCompositeINTEL)] = .{ + .llvm_name = null, + .description = "Enable SPIR-V capability LongConstantCompositeINTEL", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; +}; diff --git a/lib/std/Target/ve.zig b/lib/std/Target/ve.zig new file mode 100644 index 0000000000..09ee056ef9 --- /dev/null +++ b/lib/std/Target/ve.zig @@ -0,0 +1,39 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + vpu, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.vpu)] = .{ + .llvm_name = "vpu", + .description = "Enable the VPU", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; +}; diff --git a/lib/std/Target/wasm.zig b/lib/std/Target/wasm.zig new file mode 100644 index 0000000000..a06d37cf7d --- /dev/null +++ b/lib/std/Target/wasm.zig @@ -0,0 +1,126 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + atomics, + bulk_memory, + exception_handling, + extended_const, + multivalue, + mutable_globals, + nontrapping_fptoint, + reference_types, + relaxed_simd, + sign_ext, + simd128, + tail_call, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.atomics)] = .{ + .llvm_name = "atomics", + .description = "Enable Atomics", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.bulk_memory)] = .{ + .llvm_name = "bulk-memory", + .description = "Enable bulk memory operations", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.exception_handling)] = .{ + .llvm_name = "exception-handling", + .description = "Enable Wasm exception handling", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.extended_const)] = .{ + .llvm_name = "extended-const", + .description = "Enable extended const expressions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.multivalue)] = .{ + .llvm_name = "multivalue", + .description = "Enable multivalue blocks, instructions, and functions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mutable_globals)] = .{ + .llvm_name = "mutable-globals", + .description = "Enable mutable globals", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nontrapping_fptoint)] = .{ + .llvm_name = "nontrapping-fptoint", + .description = "Enable non-trapping float-to-int conversion operators", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.reference_types)] = .{ + .llvm_name = "reference-types", + .description = "Enable reference types", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.relaxed_simd)] = .{ + .llvm_name = "relaxed-simd", + .description = "Enable relaxed-simd instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sign_ext)] = .{ + .llvm_name = "sign-ext", + .description = "Enable sign extension operators", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.simd128)] = .{ + .llvm_name = "simd128", + .description = "Enable 128-bit SIMD", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tail_call)] = .{ + .llvm_name = "tail-call", + .description = "Enable tail call instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const bleeding_edge = CpuModel{ + .name = "bleeding_edge", + .llvm_name = "bleeding-edge", + .features = featureSet(&[_]Feature{ + .atomics, + .bulk_memory, + .mutable_globals, + .nontrapping_fptoint, + .sign_ext, + .simd128, + .tail_call, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .mutable_globals, + .sign_ext, + }), + }; + pub const mvp = CpuModel{ + .name = "mvp", + .llvm_name = "mvp", + .features = featureSet(&[_]Feature{}), + }; +}; diff --git a/lib/std/Target/x86.zig b/lib/std/Target/x86.zig new file mode 100644 index 0000000000..43ec04f41c --- /dev/null +++ b/lib/std/Target/x86.zig @@ -0,0 +1,4179 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + @"16bit_mode", + @"32bit_mode", + @"3dnow", + @"3dnowa", + @"64bit", + adx, + aes, + allow_light_256_bit, + amx_bf16, + amx_complex, + amx_fp16, + amx_int8, + amx_tile, + avx, + avx2, + avx512bf16, + avx512bitalg, + avx512bw, + avx512cd, + avx512dq, + avx512er, + avx512f, + avx512fp16, + avx512ifma, + avx512pf, + avx512vbmi, + avx512vbmi2, + avx512vl, + avx512vnni, + avx512vp2intersect, + avx512vpopcntdq, + avxifma, + avxneconvert, + avxvnni, + avxvnniint16, + avxvnniint8, + bmi, + bmi2, + branchfusion, + cldemote, + clflushopt, + clwb, + clzero, + cmov, + cmpccxadd, + crc32, + cx16, + cx8, + enqcmd, + ermsb, + f16c, + false_deps_getmant, + false_deps_lzcnt_tzcnt, + false_deps_mulc, + false_deps_mullq, + false_deps_perm, + false_deps_popcnt, + false_deps_range, + fast_11bytenop, + fast_15bytenop, + fast_7bytenop, + fast_bextr, + fast_gather, + fast_hops, + fast_lzcnt, + fast_movbe, + fast_scalar_fsqrt, + fast_scalar_shift_masks, + fast_shld_rotate, + fast_variable_crosslane_shuffle, + fast_variable_perlane_shuffle, + fast_vector_fsqrt, + fast_vector_shift_masks, + faster_shift_than_shuffle, + fma, + fma4, + fsgsbase, + fsrm, + fxsr, + gfni, + harden_sls_ijmp, + harden_sls_ret, + hreset, + idivl_to_divb, + idivq_to_divl, + invpcid, + kl, + lea_sp, + lea_uses_ag, + lvi_cfi, + lvi_load_hardening, + lwp, + lzcnt, + macrofusion, + mmx, + movbe, + movdir64b, + movdiri, + mwaitx, + no_bypass_delay, + no_bypass_delay_blend, + no_bypass_delay_mov, + no_bypass_delay_shuffle, + nopl, + pad_short_functions, + pclmul, + pconfig, + pku, + popcnt, + prefer_128_bit, + prefer_256_bit, + prefer_mask_registers, + prefer_movmsk_over_vtest, + prefetchi, + prefetchwt1, + prfchw, + ptwrite, + raoint, + rdpid, + rdpru, + rdrnd, + rdseed, + retpoline, + retpoline_external_thunk, + retpoline_indirect_branches, + retpoline_indirect_calls, + rtm, + sahf, + sbb_dep_breaking, + serialize, + seses, + sgx, + sha, + sha512, + shstk, + slow_3ops_lea, + slow_incdec, + slow_lea, + slow_pmaddwd, + slow_pmulld, + slow_shld, + slow_two_mem_ops, + slow_unaligned_mem_16, + slow_unaligned_mem_32, + sm3, + sm4, + soft_float, + sse, + sse2, + sse3, + sse4_1, + sse4_2, + sse4a, + sse_unaligned_mem, + ssse3, + tagged_globals, + tbm, + tsxldtrk, + tuning_fast_imm_vector_shift, + uintr, + use_glm_div_sqrt_costs, + use_slm_arith_costs, + vaes, + vpclmulqdq, + vzeroupper, + waitpkg, + wbnoinvd, + widekl, + x87, + xop, + xsave, + xsavec, + xsaveopt, + xsaves, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.@"16bit_mode")] = .{ + .llvm_name = "16bit-mode", + .description = "16-bit mode (i8086)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"32bit_mode")] = .{ + .llvm_name = "32bit-mode", + .description = "32-bit mode (80386)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.@"3dnow")] = .{ + .llvm_name = "3dnow", + .description = "Enable 3DNow! instructions", + .dependencies = featureSet(&[_]Feature{ + .mmx, + }), + }; + result[@intFromEnum(Feature.@"3dnowa")] = .{ + .llvm_name = "3dnowa", + .description = "Enable 3DNow! Athlon instructions", + .dependencies = featureSet(&[_]Feature{ + .@"3dnow", + }), + }; + result[@intFromEnum(Feature.@"64bit")] = .{ + .llvm_name = "64bit", + .description = "Support 64-bit instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.adx)] = .{ + .llvm_name = "adx", + .description = "Support ADX instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.aes)] = .{ + .llvm_name = "aes", + .description = "Enable AES instructions", + .dependencies = featureSet(&[_]Feature{ + .sse2, + }), + }; + result[@intFromEnum(Feature.allow_light_256_bit)] = .{ + .llvm_name = "allow-light-256-bit", + .description = "Enable generation of 256-bit load/stores even if we prefer 128-bit", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.amx_bf16)] = .{ + .llvm_name = "amx-bf16", + .description = "Support AMX-BF16 instructions", + .dependencies = featureSet(&[_]Feature{ + .amx_tile, + }), + }; + result[@intFromEnum(Feature.amx_complex)] = .{ + .llvm_name = "amx-complex", + .description = "Support AMX-COMPLEX instructions", + .dependencies = featureSet(&[_]Feature{ + .amx_tile, + }), + }; + result[@intFromEnum(Feature.amx_fp16)] = .{ + .llvm_name = "amx-fp16", + .description = "Support AMX amx-fp16 instructions", + .dependencies = featureSet(&[_]Feature{ + .amx_tile, + }), + }; + result[@intFromEnum(Feature.amx_int8)] = .{ + .llvm_name = "amx-int8", + .description = "Support AMX-INT8 instructions", + .dependencies = featureSet(&[_]Feature{ + .amx_tile, + }), + }; + result[@intFromEnum(Feature.amx_tile)] = .{ + .llvm_name = "amx-tile", + .description = "Support AMX-TILE instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.avx)] = .{ + .llvm_name = "avx", + .description = "Enable AVX instructions", + .dependencies = featureSet(&[_]Feature{ + .sse4_2, + }), + }; + result[@intFromEnum(Feature.avx2)] = .{ + .llvm_name = "avx2", + .description = "Enable AVX2 instructions", + .dependencies = featureSet(&[_]Feature{ + .avx, + }), + }; + result[@intFromEnum(Feature.avx512bf16)] = .{ + .llvm_name = "avx512bf16", + .description = "Support bfloat16 floating point", + .dependencies = featureSet(&[_]Feature{ + .avx512bw, + }), + }; + result[@intFromEnum(Feature.avx512bitalg)] = .{ + .llvm_name = "avx512bitalg", + .description = "Enable AVX-512 Bit Algorithms", + .dependencies = featureSet(&[_]Feature{ + .avx512bw, + }), + }; + result[@intFromEnum(Feature.avx512bw)] = .{ + .llvm_name = "avx512bw", + .description = "Enable AVX-512 Byte and Word Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512cd)] = .{ + .llvm_name = "avx512cd", + .description = "Enable AVX-512 Conflict Detection Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512dq)] = .{ + .llvm_name = "avx512dq", + .description = "Enable AVX-512 Doubleword and Quadword Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512er)] = .{ + .llvm_name = "avx512er", + .description = "Enable AVX-512 Exponential and Reciprocal Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512f)] = .{ + .llvm_name = "avx512f", + .description = "Enable AVX-512 instructions", + .dependencies = featureSet(&[_]Feature{ + .avx2, + .f16c, + .fma, + }), + }; + result[@intFromEnum(Feature.avx512fp16)] = .{ + .llvm_name = "avx512fp16", + .description = "Support 16-bit floating point", + .dependencies = featureSet(&[_]Feature{ + .avx512bw, + .avx512dq, + .avx512vl, + }), + }; + result[@intFromEnum(Feature.avx512ifma)] = .{ + .llvm_name = "avx512ifma", + .description = "Enable AVX-512 Integer Fused Multiple-Add", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512pf)] = .{ + .llvm_name = "avx512pf", + .description = "Enable AVX-512 PreFetch Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512vbmi)] = .{ + .llvm_name = "avx512vbmi", + .description = "Enable AVX-512 Vector Byte Manipulation Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512bw, + }), + }; + result[@intFromEnum(Feature.avx512vbmi2)] = .{ + .llvm_name = "avx512vbmi2", + .description = "Enable AVX-512 further Vector Byte Manipulation Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512bw, + }), + }; + result[@intFromEnum(Feature.avx512vl)] = .{ + .llvm_name = "avx512vl", + .description = "Enable AVX-512 Vector Length eXtensions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512vnni)] = .{ + .llvm_name = "avx512vnni", + .description = "Enable AVX-512 Vector Neural Network Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512vp2intersect)] = .{ + .llvm_name = "avx512vp2intersect", + .description = "Enable AVX-512 vp2intersect", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avx512vpopcntdq)] = .{ + .llvm_name = "avx512vpopcntdq", + .description = "Enable AVX-512 Population Count Instructions", + .dependencies = featureSet(&[_]Feature{ + .avx512f, + }), + }; + result[@intFromEnum(Feature.avxifma)] = .{ + .llvm_name = "avxifma", + .description = "Enable AVX-IFMA", + .dependencies = featureSet(&[_]Feature{ + .avx2, + }), + }; + result[@intFromEnum(Feature.avxneconvert)] = .{ + .llvm_name = "avxneconvert", + .description = "Support AVX-NE-CONVERT instructions", + .dependencies = featureSet(&[_]Feature{ + .avx2, + }), + }; + result[@intFromEnum(Feature.avxvnni)] = .{ + .llvm_name = "avxvnni", + .description = "Support AVX_VNNI encoding", + .dependencies = featureSet(&[_]Feature{ + .avx2, + }), + }; + result[@intFromEnum(Feature.avxvnniint16)] = .{ + .llvm_name = "avxvnniint16", + .description = "Enable AVX-VNNI-INT16", + .dependencies = featureSet(&[_]Feature{ + .avx2, + }), + }; + result[@intFromEnum(Feature.avxvnniint8)] = .{ + .llvm_name = "avxvnniint8", + .description = "Enable AVX-VNNI-INT8", + .dependencies = featureSet(&[_]Feature{ + .avx2, + }), + }; + result[@intFromEnum(Feature.bmi)] = .{ + .llvm_name = "bmi", + .description = "Support BMI instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.bmi2)] = .{ + .llvm_name = "bmi2", + .description = "Support BMI2 instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.branchfusion)] = .{ + .llvm_name = "branchfusion", + .description = "CMP/TEST can be fused with conditional branches", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cldemote)] = .{ + .llvm_name = "cldemote", + .description = "Enable Cache Line Demote", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.clflushopt)] = .{ + .llvm_name = "clflushopt", + .description = "Flush A Cache Line Optimized", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.clwb)] = .{ + .llvm_name = "clwb", + .description = "Cache Line Write Back", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.clzero)] = .{ + .llvm_name = "clzero", + .description = "Enable Cache Line Zero", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cmov)] = .{ + .llvm_name = "cmov", + .description = "Enable conditional move instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cmpccxadd)] = .{ + .llvm_name = "cmpccxadd", + .description = "Support CMPCCXADD instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.crc32)] = .{ + .llvm_name = "crc32", + .description = "Enable SSE 4.2 CRC32 instruction (used when SSE4.2 is supported but function is GPR only)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.cx16)] = .{ + .llvm_name = "cx16", + .description = "64-bit with cmpxchg16b (this is true for most x86-64 chips, but not the first AMD chips)", + .dependencies = featureSet(&[_]Feature{ + .cx8, + }), + }; + result[@intFromEnum(Feature.cx8)] = .{ + .llvm_name = "cx8", + .description = "Support CMPXCHG8B instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.enqcmd)] = .{ + .llvm_name = "enqcmd", + .description = "Has ENQCMD instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ermsb)] = .{ + .llvm_name = "ermsb", + .description = "REP MOVS/STOS are fast", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.f16c)] = .{ + .llvm_name = "f16c", + .description = "Support 16-bit floating point conversion instructions", + .dependencies = featureSet(&[_]Feature{ + .avx, + }), + }; + result[@intFromEnum(Feature.false_deps_getmant)] = .{ + .llvm_name = "false-deps-getmant", + .description = "VGETMANTSS/SD/SH and VGETMANDPS/PD(memory version) has a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.false_deps_lzcnt_tzcnt)] = .{ + .llvm_name = "false-deps-lzcnt-tzcnt", + .description = "LZCNT/TZCNT have a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.false_deps_mulc)] = .{ + .llvm_name = "false-deps-mulc", + .description = "VF[C]MULCPH/SH has a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.false_deps_mullq)] = .{ + .llvm_name = "false-deps-mullq", + .description = "VPMULLQ has a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.false_deps_perm)] = .{ + .llvm_name = "false-deps-perm", + .description = "VPERMD/Q/PS/PD has a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.false_deps_popcnt)] = .{ + .llvm_name = "false-deps-popcnt", + .description = "POPCNT has a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.false_deps_range)] = .{ + .llvm_name = "false-deps-range", + .description = "VRANGEPD/PS/SD/SS has a false dependency on dest register", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_11bytenop)] = .{ + .llvm_name = "fast-11bytenop", + .description = "Target can quickly decode up to 11 byte NOPs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_15bytenop)] = .{ + .llvm_name = "fast-15bytenop", + .description = "Target can quickly decode up to 15 byte NOPs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_7bytenop)] = .{ + .llvm_name = "fast-7bytenop", + .description = "Target can quickly decode up to 7 byte NOPs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_bextr)] = .{ + .llvm_name = "fast-bextr", + .description = "Indicates that the BEXTR instruction is implemented as a single uop with good throughput", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_gather)] = .{ + .llvm_name = "fast-gather", + .description = "Indicates if gather is reasonably fast (this is true for Skylake client and all AVX-512 CPUs)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_hops)] = .{ + .llvm_name = "fast-hops", + .description = "Prefer horizontal vector math instructions (haddp, phsub, etc.) over normal vector instructions with shuffles", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_lzcnt)] = .{ + .llvm_name = "fast-lzcnt", + .description = "LZCNT instructions are as fast as most simple integer ops", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_movbe)] = .{ + .llvm_name = "fast-movbe", + .description = "Prefer a movbe over a single-use load + bswap / single-use bswap + store", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_scalar_fsqrt)] = .{ + .llvm_name = "fast-scalar-fsqrt", + .description = "Scalar SQRT is fast (disable Newton-Raphson)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_scalar_shift_masks)] = .{ + .llvm_name = "fast-scalar-shift-masks", + .description = "Prefer a left/right scalar logical shift pair over a shift+and pair", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_shld_rotate)] = .{ + .llvm_name = "fast-shld-rotate", + .description = "SHLD can be used as a faster rotate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_variable_crosslane_shuffle)] = .{ + .llvm_name = "fast-variable-crosslane-shuffle", + .description = "Cross-lane shuffles with variable masks are fast", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_variable_perlane_shuffle)] = .{ + .llvm_name = "fast-variable-perlane-shuffle", + .description = "Per-lane shuffles with variable masks are fast", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_vector_fsqrt)] = .{ + .llvm_name = "fast-vector-fsqrt", + .description = "Vector SQRT is fast (disable Newton-Raphson)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fast_vector_shift_masks)] = .{ + .llvm_name = "fast-vector-shift-masks", + .description = "Prefer a left/right vector logical shift pair over a shift+and pair", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.faster_shift_than_shuffle)] = .{ + .llvm_name = "faster-shift-than-shuffle", + .description = "Shifts are faster (or as fast) as shuffle", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fma)] = .{ + .llvm_name = "fma", + .description = "Enable three-operand fused multiple-add", + .dependencies = featureSet(&[_]Feature{ + .avx, + }), + }; + result[@intFromEnum(Feature.fma4)] = .{ + .llvm_name = "fma4", + .description = "Enable four-operand fused multiple-add", + .dependencies = featureSet(&[_]Feature{ + .avx, + .sse4a, + }), + }; + result[@intFromEnum(Feature.fsgsbase)] = .{ + .llvm_name = "fsgsbase", + .description = "Support FS/GS Base instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fsrm)] = .{ + .llvm_name = "fsrm", + .description = "REP MOVSB of short lengths is faster", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.fxsr)] = .{ + .llvm_name = "fxsr", + .description = "Support fxsave/fxrestore instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.gfni)] = .{ + .llvm_name = "gfni", + .description = "Enable Galois Field Arithmetic Instructions", + .dependencies = featureSet(&[_]Feature{ + .sse2, + }), + }; + result[@intFromEnum(Feature.harden_sls_ijmp)] = .{ + .llvm_name = "harden-sls-ijmp", + .description = "Harden against straight line speculation across indirect JMP instructions.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.harden_sls_ret)] = .{ + .llvm_name = "harden-sls-ret", + .description = "Harden against straight line speculation across RET instructions.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.hreset)] = .{ + .llvm_name = "hreset", + .description = "Has hreset instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.idivl_to_divb)] = .{ + .llvm_name = "idivl-to-divb", + .description = "Use 8-bit divide for positive values less than 256", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.idivq_to_divl)] = .{ + .llvm_name = "idivq-to-divl", + .description = "Use 32-bit divide for positive values less than 2^32", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.invpcid)] = .{ + .llvm_name = "invpcid", + .description = "Invalidate Process-Context Identifier", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.kl)] = .{ + .llvm_name = "kl", + .description = "Support Key Locker kl Instructions", + .dependencies = featureSet(&[_]Feature{ + .sse2, + }), + }; + result[@intFromEnum(Feature.lea_sp)] = .{ + .llvm_name = "lea-sp", + .description = "Use LEA for adjusting the stack pointer (this is an optimization for Intel Atom processors)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lea_uses_ag)] = .{ + .llvm_name = "lea-uses-ag", + .description = "LEA instruction needs inputs at AG stage", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lvi_cfi)] = .{ + .llvm_name = "lvi-cfi", + .description = "Prevent indirect calls/branches from using a memory operand, and precede all indirect calls/branches from a register with an LFENCE instruction to serialize control flow. Also decompose RET instructions into a POP+LFENCE+JMP sequence.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lvi_load_hardening)] = .{ + .llvm_name = "lvi-load-hardening", + .description = "Insert LFENCE instructions to prevent data speculatively injected into loads from being used maliciously.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lwp)] = .{ + .llvm_name = "lwp", + .description = "Enable LWP instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.lzcnt)] = .{ + .llvm_name = "lzcnt", + .description = "Support LZCNT instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.macrofusion)] = .{ + .llvm_name = "macrofusion", + .description = "Various instructions can be fused with conditional branches", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mmx)] = .{ + .llvm_name = "mmx", + .description = "Enable MMX instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.movbe)] = .{ + .llvm_name = "movbe", + .description = "Support MOVBE instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.movdir64b)] = .{ + .llvm_name = "movdir64b", + .description = "Support movdir64b instruction (direct store 64 bytes)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.movdiri)] = .{ + .llvm_name = "movdiri", + .description = "Support movdiri instruction (direct store integer)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.mwaitx)] = .{ + .llvm_name = "mwaitx", + .description = "Enable MONITORX/MWAITX timer functionality", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_bypass_delay)] = .{ + .llvm_name = "no-bypass-delay", + .description = "Has no bypass delay when using the 'wrong' domain", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_bypass_delay_blend)] = .{ + .llvm_name = "no-bypass-delay-blend", + .description = "Has no bypass delay when using the 'wrong' blend type", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_bypass_delay_mov)] = .{ + .llvm_name = "no-bypass-delay-mov", + .description = "Has no bypass delay when using the 'wrong' mov type", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.no_bypass_delay_shuffle)] = .{ + .llvm_name = "no-bypass-delay-shuffle", + .description = "Has no bypass delay when using the 'wrong' shuffle type", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.nopl)] = .{ + .llvm_name = "nopl", + .description = "Enable NOPL instruction (generally pentium pro+)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pad_short_functions)] = .{ + .llvm_name = "pad-short-functions", + .description = "Pad short functions (to prevent a stall when returning too early)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pclmul)] = .{ + .llvm_name = "pclmul", + .description = "Enable packed carry-less multiplication instructions", + .dependencies = featureSet(&[_]Feature{ + .sse2, + }), + }; + result[@intFromEnum(Feature.pconfig)] = .{ + .llvm_name = "pconfig", + .description = "platform configuration instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.pku)] = .{ + .llvm_name = "pku", + .description = "Enable protection keys", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.popcnt)] = .{ + .llvm_name = "popcnt", + .description = "Support POPCNT instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefer_128_bit)] = .{ + .llvm_name = "prefer-128-bit", + .description = "Prefer 128-bit AVX instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefer_256_bit)] = .{ + .llvm_name = "prefer-256-bit", + .description = "Prefer 256-bit AVX instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefer_mask_registers)] = .{ + .llvm_name = "prefer-mask-registers", + .description = "Prefer AVX512 mask registers over PTEST/MOVMSK", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefer_movmsk_over_vtest)] = .{ + .llvm_name = "prefer-movmsk-over-vtest", + .description = "Prefer movmsk over vtest instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefetchi)] = .{ + .llvm_name = "prefetchi", + .description = "Prefetch instruction with T0 or T1 Hint", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prefetchwt1)] = .{ + .llvm_name = "prefetchwt1", + .description = "Prefetch with Intent to Write and T1 Hint", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.prfchw)] = .{ + .llvm_name = "prfchw", + .description = "Support PRFCHW instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ptwrite)] = .{ + .llvm_name = "ptwrite", + .description = "Support ptwrite instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.raoint)] = .{ + .llvm_name = "raoint", + .description = "Support RAO-INT instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rdpid)] = .{ + .llvm_name = "rdpid", + .description = "Support RDPID instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rdpru)] = .{ + .llvm_name = "rdpru", + .description = "Support RDPRU instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rdrnd)] = .{ + .llvm_name = "rdrnd", + .description = "Support RDRAND instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rdseed)] = .{ + .llvm_name = "rdseed", + .description = "Support RDSEED instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.retpoline)] = .{ + .llvm_name = "retpoline", + .description = "Remove speculation of indirect branches from the generated code, either by avoiding them entirely or lowering them with a speculation blocking construct", + .dependencies = featureSet(&[_]Feature{ + .retpoline_indirect_branches, + .retpoline_indirect_calls, + }), + }; + result[@intFromEnum(Feature.retpoline_external_thunk)] = .{ + .llvm_name = "retpoline-external-thunk", + .description = "When lowering an indirect call or branch using a `retpoline`, rely on the specified user provided thunk rather than emitting one ourselves. Only has effect when combined with some other retpoline feature", + .dependencies = featureSet(&[_]Feature{ + .retpoline_indirect_calls, + }), + }; + result[@intFromEnum(Feature.retpoline_indirect_branches)] = .{ + .llvm_name = "retpoline-indirect-branches", + .description = "Remove speculation of indirect branches from the generated code", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.retpoline_indirect_calls)] = .{ + .llvm_name = "retpoline-indirect-calls", + .description = "Remove speculation of indirect calls from the generated code", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.rtm)] = .{ + .llvm_name = "rtm", + .description = "Support RTM instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sahf)] = .{ + .llvm_name = "sahf", + .description = "Support LAHF and SAHF instructions in 64-bit mode", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sbb_dep_breaking)] = .{ + .llvm_name = "sbb-dep-breaking", + .description = "SBB with same register has no source dependency", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.serialize)] = .{ + .llvm_name = "serialize", + .description = "Has serialize instruction", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.seses)] = .{ + .llvm_name = "seses", + .description = "Prevent speculative execution side channel timing attacks by inserting a speculation barrier before memory reads, memory writes, and conditional branches. Implies LVI Control Flow integrity.", + .dependencies = featureSet(&[_]Feature{ + .lvi_cfi, + }), + }; + result[@intFromEnum(Feature.sgx)] = .{ + .llvm_name = "sgx", + .description = "Enable Software Guard Extensions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sha)] = .{ + .llvm_name = "sha", + .description = "Enable SHA instructions", + .dependencies = featureSet(&[_]Feature{ + .sse2, + }), + }; + result[@intFromEnum(Feature.sha512)] = .{ + .llvm_name = "sha512", + .description = "Support SHA512 instructions", + .dependencies = featureSet(&[_]Feature{ + .avx, + }), + }; + result[@intFromEnum(Feature.shstk)] = .{ + .llvm_name = "shstk", + .description = "Support CET Shadow-Stack instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_3ops_lea)] = .{ + .llvm_name = "slow-3ops-lea", + .description = "LEA instruction with 3 ops or certain registers is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_incdec)] = .{ + .llvm_name = "slow-incdec", + .description = "INC and DEC instructions are slower than ADD and SUB", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_lea)] = .{ + .llvm_name = "slow-lea", + .description = "LEA instruction with certain arguments is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_pmaddwd)] = .{ + .llvm_name = "slow-pmaddwd", + .description = "PMADDWD is slower than PMULLD", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_pmulld)] = .{ + .llvm_name = "slow-pmulld", + .description = "PMULLD instruction is slow (compared to PMULLW/PMULHW and PMULUDQ)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_shld)] = .{ + .llvm_name = "slow-shld", + .description = "SHLD instruction is slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_two_mem_ops)] = .{ + .llvm_name = "slow-two-mem-ops", + .description = "Two memory operand instructions are slow", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_unaligned_mem_16)] = .{ + .llvm_name = "slow-unaligned-mem-16", + .description = "Slow unaligned 16-byte memory access", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.slow_unaligned_mem_32)] = .{ + .llvm_name = "slow-unaligned-mem-32", + .description = "Slow unaligned 32-byte memory access", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sm3)] = .{ + .llvm_name = "sm3", + .description = "Support SM3 instructions", + .dependencies = featureSet(&[_]Feature{ + .avx, + }), + }; + result[@intFromEnum(Feature.sm4)] = .{ + .llvm_name = "sm4", + .description = "Support SM4 instructions", + .dependencies = featureSet(&[_]Feature{ + .avx, + }), + }; + result[@intFromEnum(Feature.soft_float)] = .{ + .llvm_name = "soft-float", + .description = "Use software floating point features", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sse)] = .{ + .llvm_name = "sse", + .description = "Enable SSE instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.sse2)] = .{ + .llvm_name = "sse2", + .description = "Enable SSE2 instructions", + .dependencies = featureSet(&[_]Feature{ + .sse, + }), + }; + result[@intFromEnum(Feature.sse3)] = .{ + .llvm_name = "sse3", + .description = "Enable SSE3 instructions", + .dependencies = featureSet(&[_]Feature{ + .sse2, + }), + }; + result[@intFromEnum(Feature.sse4_1)] = .{ + .llvm_name = "sse4.1", + .description = "Enable SSE 4.1 instructions", + .dependencies = featureSet(&[_]Feature{ + .ssse3, + }), + }; + result[@intFromEnum(Feature.sse4_2)] = .{ + .llvm_name = "sse4.2", + .description = "Enable SSE 4.2 instructions", + .dependencies = featureSet(&[_]Feature{ + .sse4_1, + }), + }; + result[@intFromEnum(Feature.sse4a)] = .{ + .llvm_name = "sse4a", + .description = "Support SSE 4a instructions", + .dependencies = featureSet(&[_]Feature{ + .sse3, + }), + }; + result[@intFromEnum(Feature.sse_unaligned_mem)] = .{ + .llvm_name = "sse-unaligned-mem", + .description = "Allow unaligned memory operands with SSE instructions (this may require setting a configuration bit in the processor)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.ssse3)] = .{ + .llvm_name = "ssse3", + .description = "Enable SSSE3 instructions", + .dependencies = featureSet(&[_]Feature{ + .sse3, + }), + }; + result[@intFromEnum(Feature.tagged_globals)] = .{ + .llvm_name = "tagged-globals", + .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits.", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tbm)] = .{ + .llvm_name = "tbm", + .description = "Enable TBM instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tsxldtrk)] = .{ + .llvm_name = "tsxldtrk", + .description = "Support TSXLDTRK instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.tuning_fast_imm_vector_shift)] = .{ + .llvm_name = "tuning-fast-imm-vector-shift", + .description = "Vector shifts are fast (2/cycle) as opposed to slow (1/cycle)", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.uintr)] = .{ + .llvm_name = "uintr", + .description = "Has UINTR Instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_glm_div_sqrt_costs)] = .{ + .llvm_name = "use-glm-div-sqrt-costs", + .description = "Use Goldmont specific floating point div/sqrt costs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.use_slm_arith_costs)] = .{ + .llvm_name = "use-slm-arith-costs", + .description = "Use Silvermont specific arithmetic costs", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.vaes)] = .{ + .llvm_name = "vaes", + .description = "Promote selected AES instructions to AVX512/AVX registers", + .dependencies = featureSet(&[_]Feature{ + .aes, + .avx, + }), + }; + result[@intFromEnum(Feature.vpclmulqdq)] = .{ + .llvm_name = "vpclmulqdq", + .description = "Enable vpclmulqdq instructions", + .dependencies = featureSet(&[_]Feature{ + .avx, + .pclmul, + }), + }; + result[@intFromEnum(Feature.vzeroupper)] = .{ + .llvm_name = "vzeroupper", + .description = "Should insert vzeroupper instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.waitpkg)] = .{ + .llvm_name = "waitpkg", + .description = "Wait and pause enhancements", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.wbnoinvd)] = .{ + .llvm_name = "wbnoinvd", + .description = "Write Back No Invalidate", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.widekl)] = .{ + .llvm_name = "widekl", + .description = "Support Key Locker wide Instructions", + .dependencies = featureSet(&[_]Feature{ + .kl, + }), + }; + result[@intFromEnum(Feature.x87)] = .{ + .llvm_name = "x87", + .description = "Enable X87 float instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xop)] = .{ + .llvm_name = "xop", + .description = "Enable XOP instructions", + .dependencies = featureSet(&[_]Feature{ + .fma4, + }), + }; + result[@intFromEnum(Feature.xsave)] = .{ + .llvm_name = "xsave", + .description = "Support xsave instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + result[@intFromEnum(Feature.xsavec)] = .{ + .llvm_name = "xsavec", + .description = "Support xsavec instructions", + .dependencies = featureSet(&[_]Feature{ + .xsave, + }), + }; + result[@intFromEnum(Feature.xsaveopt)] = .{ + .llvm_name = "xsaveopt", + .description = "Support xsaveopt instructions", + .dependencies = featureSet(&[_]Feature{ + .xsave, + }), + }; + result[@intFromEnum(Feature.xsaves)] = .{ + .llvm_name = "xsaves", + .description = "Support xsaves instructions", + .dependencies = featureSet(&[_]Feature{ + .xsave, + }), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const alderlake = CpuModel{ + .name = "alderlake", + .llvm_name = "alderlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .f16c, + .false_deps_perm, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fxsr, + .gfni, + .hreset, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_movmsk_over_vtest, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .widekl, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const amdfam10 = CpuModel{ + .name = "amdfam10", + .llvm_name = "amdfam10", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx16, + .fast_scalar_shift_masks, + .fxsr, + .lzcnt, + .nopl, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .sse4a, + .vzeroupper, + .x87, + }), + }; + pub const athlon = CpuModel{ + .name = "athlon", + .llvm_name = "athlon", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .cmov, + .cx8, + .nopl, + .slow_shld, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const athlon64 = CpuModel{ + .name = "athlon64", + .llvm_name = "athlon64", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx8, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const athlon64_sse3 = CpuModel{ + .name = "athlon64_sse3", + .llvm_name = "athlon64-sse3", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx16, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse3, + .vzeroupper, + .x87, + }), + }; + pub const athlon_4 = CpuModel{ + .name = "athlon_4", + .llvm_name = "athlon-4", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .cmov, + .cx8, + .fxsr, + .nopl, + .slow_shld, + .slow_unaligned_mem_16, + .sse, + .vzeroupper, + .x87, + }), + }; + pub const athlon_fx = CpuModel{ + .name = "athlon_fx", + .llvm_name = "athlon-fx", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx8, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const athlon_mp = CpuModel{ + .name = "athlon_mp", + .llvm_name = "athlon-mp", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .cmov, + .cx8, + .fxsr, + .nopl, + .slow_shld, + .slow_unaligned_mem_16, + .sse, + .vzeroupper, + .x87, + }), + }; + pub const athlon_tbird = CpuModel{ + .name = "athlon_tbird", + .llvm_name = "athlon-tbird", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .cmov, + .cx8, + .nopl, + .slow_shld, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const athlon_xp = CpuModel{ + .name = "athlon_xp", + .llvm_name = "athlon-xp", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .cmov, + .cx8, + .fxsr, + .nopl, + .slow_shld, + .slow_unaligned_mem_16, + .sse, + .vzeroupper, + .x87, + }), + }; + pub const atom = CpuModel{ + .name = "atom", + .llvm_name = "atom", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx16, + .fxsr, + .idivl_to_divb, + .idivq_to_divl, + .lea_sp, + .lea_uses_ag, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pad_short_functions, + .sahf, + .slow_two_mem_ops, + .slow_unaligned_mem_16, + .ssse3, + .vzeroupper, + .x87, + }), + }; + pub const atom_sse4_2_movbe = CpuModel{ + .name = "atom_sse4_2_movbe", + .llvm_name = "atom_sse4_2_movbe", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .clflushopt, + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_7bytenop, + .fast_movbe, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .sha, + .slow_incdec, + .slow_lea, + .slow_pmulld, + .slow_two_mem_ops, + .sse4_2, + .use_slm_arith_costs, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const barcelona = CpuModel{ + .name = "barcelona", + .llvm_name = "barcelona", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx16, + .fast_scalar_shift_masks, + .fxsr, + .lzcnt, + .nopl, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .sse4a, + .vzeroupper, + .x87, + }), + }; + pub const bdver1 = CpuModel{ + .name = "bdver1", + .llvm_name = "bdver1", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .branchfusion, + .cmov, + .crc32, + .cx16, + .fast_11bytenop, + .fast_scalar_shift_masks, + .fxsr, + .lwp, + .lzcnt, + .mmx, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .vzeroupper, + .x87, + .xop, + .xsave, + }), + }; + pub const bdver2 = CpuModel{ + .name = "bdver2", + .llvm_name = "bdver2", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .bmi, + .branchfusion, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_11bytenop, + .fast_bextr, + .fast_movbe, + .fast_scalar_shift_masks, + .fma, + .fxsr, + .lwp, + .lzcnt, + .mmx, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .tbm, + .vzeroupper, + .x87, + .xop, + .xsave, + }), + }; + pub const bdver3 = CpuModel{ + .name = "bdver3", + .llvm_name = "bdver3", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .bmi, + .branchfusion, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_11bytenop, + .fast_bextr, + .fast_movbe, + .fast_scalar_shift_masks, + .fma, + .fsgsbase, + .fxsr, + .lwp, + .lzcnt, + .mmx, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .tbm, + .vzeroupper, + .x87, + .xop, + .xsaveopt, + }), + }; + pub const bdver4 = CpuModel{ + .name = "bdver4", + .llvm_name = "bdver4", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .avx2, + .bmi, + .bmi2, + .branchfusion, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_11bytenop, + .fast_bextr, + .fast_movbe, + .fast_scalar_shift_masks, + .fma, + .fsgsbase, + .fxsr, + .lwp, + .lzcnt, + .mmx, + .movbe, + .mwaitx, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .tbm, + .vzeroupper, + .x87, + .xop, + .xsaveopt, + }), + }; + pub const bonnell = CpuModel{ + .name = "bonnell", + .llvm_name = "bonnell", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx16, + .fxsr, + .idivl_to_divb, + .idivq_to_divl, + .lea_sp, + .lea_uses_ag, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pad_short_functions, + .sahf, + .slow_two_mem_ops, + .slow_unaligned_mem_16, + .ssse3, + .vzeroupper, + .x87, + }), + }; + pub const broadwell = CpuModel{ + .name = "broadwell", + .llvm_name = "broadwell", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .cmov, + .crc32, + .cx16, + .ermsb, + .f16c, + .false_deps_lzcnt_tzcnt, + .false_deps_popcnt, + .fast_15bytenop, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fma, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .vzeroupper, + .x87, + .xsaveopt, + }), + }; + pub const btver1 = CpuModel{ + .name = "btver1", + .llvm_name = "btver1", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx16, + .fast_15bytenop, + .fast_scalar_shift_masks, + .fast_vector_shift_masks, + .fxsr, + .lzcnt, + .mmx, + .nopl, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .sse4a, + .ssse3, + .vzeroupper, + .x87, + }), + }; + pub const btver2 = CpuModel{ + .name = "btver2", + .llvm_name = "btver2", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .bmi, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_15bytenop, + .fast_bextr, + .fast_hops, + .fast_lzcnt, + .fast_movbe, + .fast_scalar_shift_masks, + .fast_vector_shift_masks, + .fxsr, + .lzcnt, + .mmx, + .movbe, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .sahf, + .sbb_dep_breaking, + .slow_shld, + .sse4a, + .x87, + .xsaveopt, + }), + }; + pub const c3 = CpuModel{ + .name = "c3", + .llvm_name = "c3", + .features = featureSet(&[_]Feature{ + .@"3dnow", + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const c3_2 = CpuModel{ + .name = "c3_2", + .llvm_name = "c3-2", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .slow_unaligned_mem_16, + .sse, + .vzeroupper, + .x87, + }), + }; + pub const cannonlake = CpuModel{ + .name = "cannonlake", + .llvm_name = "cannonlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx512cd, + .avx512dq, + .avx512ifma, + .avx512vbmi, + .avx512vl, + .bmi, + .bmi2, + .clflushopt, + .cmov, + .crc32, + .cx16, + .ermsb, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .sha, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const cascadelake = CpuModel{ + .name = "cascadelake", + .llvm_name = "cascadelake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx512bw, + .avx512cd, + .avx512dq, + .avx512vl, + .avx512vnni, + .bmi, + .bmi2, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .ermsb, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .faster_shift_than_shuffle, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const cooperlake = CpuModel{ + .name = "cooperlake", + .llvm_name = "cooperlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx512bf16, + .avx512cd, + .avx512dq, + .avx512vl, + .avx512vnni, + .bmi, + .bmi2, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .ermsb, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .faster_shift_than_shuffle, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const core2 = CpuModel{ + .name = "core2", + .llvm_name = "core2", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx16, + .fxsr, + .macrofusion, + .mmx, + .nopl, + .sahf, + .slow_unaligned_mem_16, + .ssse3, + .vzeroupper, + .x87, + }), + }; + pub const corei7 = CpuModel{ + .name = "corei7", + .llvm_name = "corei7", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .fxsr, + .macrofusion, + .mmx, + .no_bypass_delay_mov, + .nopl, + .popcnt, + .sahf, + .sse4_2, + .vzeroupper, + .x87, + }), + }; + pub const emeraldrapids = CpuModel{ + .name = "emeraldrapids", + .llvm_name = "emeraldrapids", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .amx_bf16, + .amx_int8, + .avx512bf16, + .avx512bitalg, + .avx512cd, + .avx512fp16, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vnni, + .avx512vpopcntdq, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .enqcmd, + .ermsb, + .false_deps_getmant, + .false_deps_mulc, + .false_deps_mullq, + .false_deps_perm, + .false_deps_range, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .tsxldtrk, + .tuning_fast_imm_vector_shift, + .uintr, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cx8, + .fast_15bytenop, + .fast_scalar_fsqrt, + .idivq_to_divl, + .macrofusion, + .slow_3ops_lea, + .vzeroupper, + .x87, + }), + }; + pub const geode = CpuModel{ + .name = "geode", + .llvm_name = "geode", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .cx8, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const goldmont = CpuModel{ + .name = "goldmont", + .llvm_name = "goldmont", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .clflushopt, + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_movbe, + .fsgsbase, + .fxsr, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .sha, + .slow_incdec, + .slow_lea, + .slow_two_mem_ops, + .sse4_2, + .use_glm_div_sqrt_costs, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const goldmont_plus = CpuModel{ + .name = "goldmont_plus", + .llvm_name = "goldmont-plus", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .clflushopt, + .cmov, + .crc32, + .cx16, + .fast_movbe, + .fsgsbase, + .fxsr, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .sha, + .slow_incdec, + .slow_lea, + .slow_two_mem_ops, + .sse4_2, + .use_glm_div_sqrt_costs, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const grandridge = CpuModel{ + .name = "grandridge", + .llvm_name = "grandridge", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .avxifma, + .avxneconvert, + .avxvnni, + .avxvnniint8, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .cmpccxadd, + .crc32, + .cx16, + .enqcmd, + .f16c, + .fast_movbe, + .fma, + .fsgsbase, + .fxsr, + .gfni, + .hreset, + .invpcid, + .lzcnt, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay, + .nopl, + .pconfig, + .pku, + .popcnt, + .prfchw, + .ptwrite, + .raoint, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .slow_incdec, + .slow_lea, + .slow_two_mem_ops, + .uintr, + .use_glm_div_sqrt_costs, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .widekl, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const graniterapids = CpuModel{ + .name = "graniterapids", + .llvm_name = "graniterapids", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .amx_bf16, + .amx_fp16, + .amx_int8, + .avx512bf16, + .avx512bitalg, + .avx512cd, + .avx512fp16, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vnni, + .avx512vpopcntdq, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .enqcmd, + .ermsb, + .false_deps_getmant, + .false_deps_mulc, + .false_deps_mullq, + .false_deps_perm, + .false_deps_range, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_256_bit, + .prefetchi, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .tsxldtrk, + .tuning_fast_imm_vector_shift, + .uintr, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const graniterapids_d = CpuModel{ + .name = "graniterapids_d", + .llvm_name = "graniterapids-d", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .amx_bf16, + .amx_complex, + .amx_fp16, + .amx_int8, + .avx512bf16, + .avx512bitalg, + .avx512cd, + .avx512fp16, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vnni, + .avx512vpopcntdq, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .enqcmd, + .ermsb, + .false_deps_getmant, + .false_deps_mulc, + .false_deps_mullq, + .false_deps_perm, + .false_deps_range, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_256_bit, + .prefetchi, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .tsxldtrk, + .tuning_fast_imm_vector_shift, + .uintr, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const haswell = CpuModel{ + .name = "haswell", + .llvm_name = "haswell", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .cmov, + .crc32, + .cx16, + .ermsb, + .f16c, + .false_deps_lzcnt_tzcnt, + .false_deps_popcnt, + .fast_15bytenop, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fma, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .popcnt, + .rdrnd, + .sahf, + .slow_3ops_lea, + .vzeroupper, + .x87, + .xsaveopt, + }), + }; + pub const @"i386" = CpuModel{ + .name = "i386", + .llvm_name = "i386", + .features = featureSet(&[_]Feature{ + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const @"i486" = CpuModel{ + .name = "i486", + .llvm_name = "i486", + .features = featureSet(&[_]Feature{ + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const @"i586" = CpuModel{ + .name = "i586", + .llvm_name = "i586", + .features = featureSet(&[_]Feature{ + .cx8, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const @"i686" = CpuModel{ + .name = "i686", + .llvm_name = "i686", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const icelake_client = CpuModel{ + .name = "icelake_client", + .llvm_name = "icelake-client", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx512bitalg, + .avx512cd, + .avx512dq, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vl, + .avx512vnni, + .avx512vpopcntdq, + .bmi, + .bmi2, + .clflushopt, + .cmov, + .crc32, + .cx16, + .ermsb, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .sha, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const icelake_server = CpuModel{ + .name = "icelake_server", + .llvm_name = "icelake-server", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx512bitalg, + .avx512cd, + .avx512dq, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vl, + .avx512vnni, + .avx512vpopcntdq, + .bmi, + .bmi2, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .ermsb, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .sha, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const ivybridge = CpuModel{ + .name = "ivybridge", + .llvm_name = "ivybridge", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .f16c, + .false_deps_popcnt, + .fast_15bytenop, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .macrofusion, + .mmx, + .no_bypass_delay_mov, + .nopl, + .pclmul, + .popcnt, + .rdrnd, + .sahf, + .slow_3ops_lea, + .slow_unaligned_mem_32, + .vzeroupper, + .x87, + .xsaveopt, + }), + }; + pub const k6 = CpuModel{ + .name = "k6", + .llvm_name = "k6", + .features = featureSet(&[_]Feature{ + .cx8, + .mmx, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const k6_2 = CpuModel{ + .name = "k6_2", + .llvm_name = "k6-2", + .features = featureSet(&[_]Feature{ + .@"3dnow", + .cx8, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const k6_3 = CpuModel{ + .name = "k6_3", + .llvm_name = "k6-3", + .features = featureSet(&[_]Feature{ + .@"3dnow", + .cx8, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const k8 = CpuModel{ + .name = "k8", + .llvm_name = "k8", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx8, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const k8_sse3 = CpuModel{ + .name = "k8_sse3", + .llvm_name = "k8-sse3", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx16, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse3, + .vzeroupper, + .x87, + }), + }; + pub const knl = CpuModel{ + .name = "knl", + .llvm_name = "knl", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .avx512cd, + .avx512er, + .avx512pf, + .bmi, + .bmi2, + .cmov, + .crc32, + .cx16, + .fast_gather, + .fast_movbe, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .lzcnt, + .mmx, + .movbe, + .nopl, + .pclmul, + .popcnt, + .prefer_mask_registers, + .prefetchwt1, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .slow_incdec, + .slow_pmaddwd, + .slow_two_mem_ops, + .x87, + .xsaveopt, + }), + }; + pub const knm = CpuModel{ + .name = "knm", + .llvm_name = "knm", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .avx512cd, + .avx512er, + .avx512pf, + .avx512vpopcntdq, + .bmi, + .bmi2, + .cmov, + .crc32, + .cx16, + .fast_gather, + .fast_movbe, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .lzcnt, + .mmx, + .movbe, + .nopl, + .pclmul, + .popcnt, + .prefer_mask_registers, + .prefetchwt1, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .slow_incdec, + .slow_pmaddwd, + .slow_two_mem_ops, + .x87, + .xsaveopt, + }), + }; + pub const lakemont = CpuModel{ + .name = "lakemont", + .llvm_name = "lakemont", + .features = featureSet(&[_]Feature{ + .cx8, + .slow_unaligned_mem_16, + .soft_float, + .vzeroupper, + }), + }; + pub const meteorlake = CpuModel{ + .name = "meteorlake", + .llvm_name = "meteorlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .f16c, + .false_deps_perm, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fxsr, + .gfni, + .hreset, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_movmsk_over_vtest, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .widekl, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const nehalem = CpuModel{ + .name = "nehalem", + .llvm_name = "nehalem", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .fxsr, + .macrofusion, + .mmx, + .no_bypass_delay_mov, + .nopl, + .popcnt, + .sahf, + .sse4_2, + .vzeroupper, + .x87, + }), + }; + pub const nocona = CpuModel{ + .name = "nocona", + .llvm_name = "nocona", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx16, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse3, + .vzeroupper, + .x87, + }), + }; + pub const opteron = CpuModel{ + .name = "opteron", + .llvm_name = "opteron", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx8, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const opteron_sse3 = CpuModel{ + .name = "opteron_sse3", + .llvm_name = "opteron-sse3", + .features = featureSet(&[_]Feature{ + .@"3dnowa", + .@"64bit", + .cmov, + .cx16, + .fast_scalar_shift_masks, + .fxsr, + .nopl, + .sbb_dep_breaking, + .slow_shld, + .slow_unaligned_mem_16, + .sse3, + .vzeroupper, + .x87, + }), + }; + pub const penryn = CpuModel{ + .name = "penryn", + .llvm_name = "penryn", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx16, + .fxsr, + .macrofusion, + .mmx, + .nopl, + .sahf, + .slow_unaligned_mem_16, + .sse4_1, + .vzeroupper, + .x87, + }), + }; + pub const pentium = CpuModel{ + .name = "pentium", + .llvm_name = "pentium", + .features = featureSet(&[_]Feature{ + .cx8, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const pentium2 = CpuModel{ + .name = "pentium2", + .llvm_name = "pentium2", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const pentium3 = CpuModel{ + .name = "pentium3", + .llvm_name = "pentium3", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse, + .vzeroupper, + .x87, + }), + }; + pub const pentium3m = CpuModel{ + .name = "pentium3m", + .llvm_name = "pentium3m", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse, + .vzeroupper, + .x87, + }), + }; + pub const pentium4 = CpuModel{ + .name = "pentium4", + .llvm_name = "pentium4", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const pentium_m = CpuModel{ + .name = "pentium_m", + .llvm_name = "pentium-m", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const pentium_mmx = CpuModel{ + .name = "pentium_mmx", + .llvm_name = "pentium-mmx", + .features = featureSet(&[_]Feature{ + .cx8, + .mmx, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const pentiumpro = CpuModel{ + .name = "pentiumpro", + .llvm_name = "pentiumpro", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .nopl, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const prescott = CpuModel{ + .name = "prescott", + .llvm_name = "prescott", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse3, + .vzeroupper, + .x87, + }), + }; + pub const raptorlake = CpuModel{ + .name = "raptorlake", + .llvm_name = "raptorlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .f16c, + .false_deps_perm, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fxsr, + .gfni, + .hreset, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_movmsk_over_vtest, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .widekl, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const rocketlake = CpuModel{ + .name = "rocketlake", + .llvm_name = "rocketlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx512bitalg, + .avx512cd, + .avx512dq, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vl, + .avx512vnni, + .avx512vpopcntdq, + .bmi, + .bmi2, + .clflushopt, + .cmov, + .crc32, + .cx16, + .ermsb, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .sha, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const sandybridge = CpuModel{ + .name = "sandybridge", + .llvm_name = "sandybridge", + .features = featureSet(&[_]Feature{ + .@"64bit", + .avx, + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_15bytenop, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fxsr, + .idivq_to_divl, + .macrofusion, + .mmx, + .no_bypass_delay_mov, + .nopl, + .pclmul, + .popcnt, + .sahf, + .slow_3ops_lea, + .slow_unaligned_mem_32, + .vzeroupper, + .x87, + .xsaveopt, + }), + }; + pub const sapphirerapids = CpuModel{ + .name = "sapphirerapids", + .llvm_name = "sapphirerapids", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .amx_bf16, + .amx_int8, + .avx512bf16, + .avx512bitalg, + .avx512cd, + .avx512fp16, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vnni, + .avx512vpopcntdq, + .avxvnni, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .enqcmd, + .ermsb, + .false_deps_getmant, + .false_deps_mulc, + .false_deps_mullq, + .false_deps_perm, + .false_deps_range, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pconfig, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .tsxldtrk, + .tuning_fast_imm_vector_shift, + .uintr, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const sierraforest = CpuModel{ + .name = "sierraforest", + .llvm_name = "sierraforest", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .avxifma, + .avxneconvert, + .avxvnni, + .avxvnniint8, + .bmi, + .bmi2, + .cldemote, + .clflushopt, + .clwb, + .cmov, + .cmpccxadd, + .crc32, + .cx16, + .enqcmd, + .f16c, + .fast_movbe, + .fma, + .fsgsbase, + .fxsr, + .gfni, + .hreset, + .invpcid, + .lzcnt, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay, + .nopl, + .pconfig, + .pku, + .popcnt, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .serialize, + .sha, + .shstk, + .slow_incdec, + .slow_lea, + .slow_two_mem_ops, + .uintr, + .use_glm_div_sqrt_costs, + .vaes, + .vpclmulqdq, + .vzeroupper, + .waitpkg, + .widekl, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const silvermont = CpuModel{ + .name = "silvermont", + .llvm_name = "silvermont", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_7bytenop, + .fast_movbe, + .fxsr, + .idivq_to_divl, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .sahf, + .slow_incdec, + .slow_lea, + .slow_pmulld, + .slow_two_mem_ops, + .sse4_2, + .use_slm_arith_costs, + .vzeroupper, + .x87, + }), + }; + pub const skx = CpuModel{ + .name = "skx", + .llvm_name = "skx", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx512bw, + .avx512cd, + .avx512dq, + .avx512vl, + .bmi, + .bmi2, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .ermsb, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .faster_shift_than_shuffle, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const skylake = CpuModel{ + .name = "skylake", + .llvm_name = "skylake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .clflushopt, + .cmov, + .crc32, + .cx16, + .ermsb, + .f16c, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const skylake_avx512 = CpuModel{ + .name = "skylake_avx512", + .llvm_name = "skylake-avx512", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx512bw, + .avx512cd, + .avx512dq, + .avx512vl, + .bmi, + .bmi2, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .ermsb, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .faster_shift_than_shuffle, + .fsgsbase, + .fxsr, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pclmul, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .slow_3ops_lea, + .tuning_fast_imm_vector_shift, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const slm = CpuModel{ + .name = "slm", + .llvm_name = "slm", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_7bytenop, + .fast_movbe, + .fxsr, + .idivq_to_divl, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .sahf, + .slow_incdec, + .slow_lea, + .slow_pmulld, + .slow_two_mem_ops, + .sse4_2, + .use_slm_arith_costs, + .vzeroupper, + .x87, + }), + }; + pub const tigerlake = CpuModel{ + .name = "tigerlake", + .llvm_name = "tigerlake", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx512bitalg, + .avx512cd, + .avx512dq, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vl, + .avx512vnni, + .avx512vp2intersect, + .avx512vpopcntdq, + .bmi, + .bmi2, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .ermsb, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .idivq_to_divl, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .movdir64b, + .movdiri, + .no_bypass_delay_blend, + .no_bypass_delay_mov, + .no_bypass_delay_shuffle, + .nopl, + .pku, + .popcnt, + .prefer_256_bit, + .prfchw, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .sha, + .shstk, + .tuning_fast_imm_vector_shift, + .vaes, + .vpclmulqdq, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const tremont = CpuModel{ + .name = "tremont", + .llvm_name = "tremont", + .features = featureSet(&[_]Feature{ + .@"64bit", + .aes, + .clflushopt, + .clwb, + .cmov, + .crc32, + .cx16, + .fast_movbe, + .fsgsbase, + .fxsr, + .gfni, + .mmx, + .movbe, + .no_bypass_delay, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .ptwrite, + .rdpid, + .rdrnd, + .rdseed, + .sahf, + .sha, + .slow_incdec, + .slow_lea, + .slow_two_mem_ops, + .sse4_2, + .use_glm_div_sqrt_costs, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const westmere = CpuModel{ + .name = "westmere", + .llvm_name = "westmere", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .fxsr, + .macrofusion, + .mmx, + .no_bypass_delay_mov, + .nopl, + .pclmul, + .popcnt, + .sahf, + .sse4_2, + .vzeroupper, + .x87, + }), + }; + pub const winchip2 = CpuModel{ + .name = "winchip2", + .llvm_name = "winchip2", + .features = featureSet(&[_]Feature{ + .@"3dnow", + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const winchip_c6 = CpuModel{ + .name = "winchip_c6", + .llvm_name = "winchip-c6", + .features = featureSet(&[_]Feature{ + .mmx, + .slow_unaligned_mem_16, + .vzeroupper, + .x87, + }), + }; + pub const x86_64 = CpuModel{ + .name = "x86_64", + .llvm_name = "x86-64", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .cx8, + .fxsr, + .idivq_to_divl, + .macrofusion, + .mmx, + .nopl, + .slow_3ops_lea, + .slow_incdec, + .sse2, + .vzeroupper, + .x87, + }), + }; + pub const x86_64_v2 = CpuModel{ + .name = "x86_64_v2", + .llvm_name = "x86-64-v2", + .features = featureSet(&[_]Feature{ + .@"64bit", + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_15bytenop, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fxsr, + .idivq_to_divl, + .macrofusion, + .mmx, + .nopl, + .popcnt, + .sahf, + .slow_3ops_lea, + .slow_unaligned_mem_32, + .sse4_2, + .vzeroupper, + .x87, + }), + }; + pub const x86_64_v3 = CpuModel{ + .name = "x86_64_v3", + .llvm_name = "x86-64-v3", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .cmov, + .crc32, + .cx16, + .f16c, + .false_deps_lzcnt_tzcnt, + .false_deps_popcnt, + .fast_15bytenop, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fma, + .fxsr, + .idivq_to_divl, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .nopl, + .popcnt, + .sahf, + .slow_3ops_lea, + .vzeroupper, + .x87, + .xsave, + }), + }; + pub const x86_64_v4 = CpuModel{ + .name = "x86_64_v4", + .llvm_name = "x86-64-v4", + .features = featureSet(&[_]Feature{ + .@"64bit", + .allow_light_256_bit, + .avx512bw, + .avx512cd, + .avx512dq, + .avx512vl, + .bmi, + .bmi2, + .cmov, + .crc32, + .cx16, + .false_deps_popcnt, + .fast_15bytenop, + .fast_gather, + .fast_scalar_fsqrt, + .fast_shld_rotate, + .fast_variable_crosslane_shuffle, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fxsr, + .idivq_to_divl, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .nopl, + .popcnt, + .prefer_256_bit, + .sahf, + .slow_3ops_lea, + .vzeroupper, + .x87, + .xsave, + }), + }; + pub const yonah = CpuModel{ + .name = "yonah", + .llvm_name = "yonah", + .features = featureSet(&[_]Feature{ + .cmov, + .cx8, + .fxsr, + .mmx, + .nopl, + .slow_unaligned_mem_16, + .sse3, + .vzeroupper, + .x87, + }), + }; + pub const znver1 = CpuModel{ + .name = "znver1", + .llvm_name = "znver1", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .branchfusion, + .clflushopt, + .clzero, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_15bytenop, + .fast_bextr, + .fast_lzcnt, + .fast_movbe, + .fast_scalar_fsqrt, + .fast_scalar_shift_masks, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fxsr, + .lzcnt, + .mmx, + .movbe, + .mwaitx, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdrnd, + .rdseed, + .sahf, + .sbb_dep_breaking, + .sha, + .slow_shld, + .sse4a, + .vzeroupper, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const znver2 = CpuModel{ + .name = "znver2", + .llvm_name = "znver2", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .aes, + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .branchfusion, + .clflushopt, + .clwb, + .clzero, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_15bytenop, + .fast_bextr, + .fast_lzcnt, + .fast_movbe, + .fast_scalar_fsqrt, + .fast_scalar_shift_masks, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fxsr, + .lzcnt, + .mmx, + .movbe, + .mwaitx, + .nopl, + .pclmul, + .popcnt, + .prfchw, + .rdpid, + .rdpru, + .rdrnd, + .rdseed, + .sahf, + .sbb_dep_breaking, + .sha, + .slow_shld, + .sse4a, + .vzeroupper, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const znver3 = CpuModel{ + .name = "znver3", + .llvm_name = "znver3", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx2, + .bmi, + .bmi2, + .branchfusion, + .clflushopt, + .clwb, + .clzero, + .cmov, + .crc32, + .cx16, + .f16c, + .fast_15bytenop, + .fast_bextr, + .fast_lzcnt, + .fast_movbe, + .fast_scalar_fsqrt, + .fast_scalar_shift_masks, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fma, + .fsgsbase, + .fsrm, + .fxsr, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .mwaitx, + .nopl, + .pku, + .popcnt, + .prfchw, + .rdpid, + .rdpru, + .rdrnd, + .rdseed, + .sahf, + .sbb_dep_breaking, + .sha, + .slow_shld, + .sse4a, + .vaes, + .vpclmulqdq, + .vzeroupper, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; + pub const znver4 = CpuModel{ + .name = "znver4", + .llvm_name = "znver4", + .features = featureSet(&[_]Feature{ + .@"64bit", + .adx, + .allow_light_256_bit, + .avx512bf16, + .avx512bitalg, + .avx512cd, + .avx512dq, + .avx512ifma, + .avx512vbmi, + .avx512vbmi2, + .avx512vl, + .avx512vnni, + .avx512vpopcntdq, + .bmi, + .bmi2, + .branchfusion, + .clflushopt, + .clwb, + .clzero, + .cmov, + .crc32, + .cx16, + .fast_15bytenop, + .fast_bextr, + .fast_lzcnt, + .fast_movbe, + .fast_scalar_fsqrt, + .fast_scalar_shift_masks, + .fast_variable_perlane_shuffle, + .fast_vector_fsqrt, + .fsgsbase, + .fsrm, + .fxsr, + .gfni, + .invpcid, + .lzcnt, + .macrofusion, + .mmx, + .movbe, + .mwaitx, + .nopl, + .pku, + .popcnt, + .prfchw, + .rdpid, + .rdpru, + .rdrnd, + .rdseed, + .sahf, + .sbb_dep_breaking, + .sha, + .shstk, + .slow_shld, + .sse4a, + .vaes, + .vpclmulqdq, + .vzeroupper, + .wbnoinvd, + .x87, + .xsavec, + .xsaveopt, + .xsaves, + }), + }; +}; diff --git a/lib/std/Target/xtensa.zig b/lib/std/Target/xtensa.zig new file mode 100644 index 0000000000..22851c4554 --- /dev/null +++ b/lib/std/Target/xtensa.zig @@ -0,0 +1,39 @@ +//! This file is auto-generated by tools/update_cpu_features.zig. + +const std = @import("../std.zig"); +const CpuFeature = std.Target.Cpu.Feature; +const CpuModel = std.Target.Cpu.Model; + +pub const Feature = enum { + density, +}; + +pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet; +pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas; +pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny; +pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll; + +pub const all_features = blk: { + const len = @typeInfo(Feature).Enum.fields.len; + std.debug.assert(len <= CpuFeature.Set.needed_bit_count); + var result: [len]CpuFeature = undefined; + result[@intFromEnum(Feature.density)] = .{ + .llvm_name = "density", + .description = "Enable Density instructions", + .dependencies = featureSet(&[_]Feature{}), + }; + const ti = @typeInfo(Feature); + for (&result, 0..) |*elem, i| { + elem.index = i; + elem.name = ti.Enum.fields[i].name; + } + break :blk result; +}; + +pub const cpu = struct { + pub const generic = CpuModel{ + .name = "generic", + .llvm_name = "generic", + .features = featureSet(&[_]Feature{}), + }; +}; -- cgit v1.2.3 From 3179f58c414b5e4845b9bf3acdf276fe8e2b88a0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 4 Dec 2023 12:35:04 -0700 Subject: rename std.zig.CrossTarget to std.Target.Query --- CMakeLists.txt | 2 +- lib/std/Build.zig | 38 +- lib/std/Build/Step/Compile.zig | 1 - lib/std/Target.zig | 4 +- lib/std/Target/Query.zig | 855 ++++++++++++++++++++++++++++ lib/std/zig.zig | 3 +- lib/std/zig/CrossTarget.zig | 854 --------------------------- lib/std/zig/system/NativeTargetInfo.zig | 106 ++-- lib/std/zig/system/darwin/macos.zig | 2 +- lib/std/zig/system/linux.zig | 3 - lib/std/zig/system/x86.zig | 5 +- src/libc_installation.zig | 2 +- src/main.zig | 74 +-- test/cbe.zig | 2 +- test/link/elf.zig | 1 - test/link/glibc_compat/build.zig | 2 +- test/link/link.zig | 1 - test/link/macho.zig | 2 - test/llvm_targets.zig | 2 +- test/src/Cases.zig | 12 +- test/src/translate_c.zig | 5 +- test/standalone.zig | 2 +- test/standalone/windows_resources/build.zig | 6 +- test/tests.zig | 12 +- test/translate_c.zig | 5 +- 25 files changed, 997 insertions(+), 1004 deletions(-) create mode 100644 lib/std/Target/Query.zig delete mode 100644 lib/std/zig/CrossTarget.zig (limited to 'lib/std/Target') diff --git a/CMakeLists.txt b/CMakeLists.txt index 831243557f..fa3a10dc4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,6 +481,7 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/start.zig" "${CMAKE_SOURCE_DIR}/lib/std/std.zig" "${CMAKE_SOURCE_DIR}/lib/std/Target.zig" + "${CMAKE_SOURCE_DIR}/lib/std/Target/Query.zig" "${CMAKE_SOURCE_DIR}/lib/std/Target/aarch64.zig" "${CMAKE_SOURCE_DIR}/lib/std/Target/amdgpu.zig" "${CMAKE_SOURCE_DIR}/lib/std/Target/arm.zig" @@ -508,7 +509,6 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/zig.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig" - "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig" diff --git a/lib/std/Build.zig b/lib/std/Build.zig index 24e245b028..db7e3493da 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -10,11 +10,11 @@ const log = std.log; const ArrayList = std.ArrayList; const StringHashMap = std.StringHashMap; const Allocator = mem.Allocator; +const Target = std.Target; const process = std.process; const EnvMap = std.process.EnvMap; const fmt_lib = std.fmt; const File = std.fs.File; -const TargetQuery = std.zig.CrossTarget; const Sha256 = std.crypto.hash.sha2.Sha256; const Build = @This(); @@ -375,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption const v = @field(args, field.name); const T = @TypeOf(v); switch (T) { - TargetQuery => { + Target.Query => { user_input_options.put(field.name, .{ .name = field.name, .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") }, @@ -1195,9 +1195,9 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio } pub const StandardTargetOptionsArgs = struct { - whitelist: ?[]const TargetQuery = null, + whitelist: ?[]const Target.Query = null, - default_target: TargetQuery = .{}, + default_target: Target.Query = .{}, }; /// Exposes standard `zig build` options for choosing a target and additionally @@ -1208,7 +1208,7 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve } /// Exposes standard `zig build` options for choosing a target. -pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) TargetQuery { +pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) Target.Query { const maybe_triple = self.option( []const u8, "target", @@ -1222,8 +1222,8 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA const triple = maybe_triple orelse "native"; - var diags: TargetQuery.ParseOptions.Diagnostics = .{}; - const selected_target = TargetQuery.parse(.{ + var diags: Target.Query.ParseOptions.Diagnostics = .{}; + const selected_target = Target.Query.parse(.{ .arch_os_abi = triple, .cpu_features = mcpu, .diagnostics = &diags, @@ -1260,7 +1260,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA \\Available operating systems: \\ , .{diags.os_name.?}); - inline for (std.meta.fields(std.Target.Os.Tag)) |field| { + inline for (std.meta.fields(Target.Os.Tag)) |field| { log.err(" {s}", .{field.name}); } self.markInvalidUserInput(); @@ -1279,7 +1279,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA // Make sure it's a match of one of the list. var mismatch_triple = true; var mismatch_cpu_features = true; - var whitelist_item: TargetQuery = .{}; + var whitelist_item: Target.Query = .{}; for (list) |t| { mismatch_cpu_features = true; mismatch_triple = true; @@ -1316,7 +1316,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA var populated_cpu_features = whitelist_cpu.model.features; populated_cpu_features.populateDependencies(all_features); for (all_features, 0..) |feature, i_usize| { - const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize)); + const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); const in_cpu_set = populated_cpu_features.isEnabled(i); if (in_cpu_set) { log.err("{s} ", .{feature.name}); @@ -1324,7 +1324,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA } log.err(" Remove: ", .{}); for (all_features, 0..) |feature, i_usize| { - const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize)); + const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); const in_cpu_set = populated_cpu_features.isEnabled(i); const in_actual_set = selected_cpu.features.isEnabled(i); if (in_actual_set and !in_cpu_set) { @@ -1587,7 +1587,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 { pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 { // TODO report error for ambiguous situations - const exe_extension = @as(TargetQuery, .{}).exeFileExt(); + const exe_extension = @as(Target.Query, .{}).exeFileExt(); for (self.search_prefixes.items) |search_prefix| { for (names) |name| { if (fs.path.isAbsolute(name)) { @@ -2064,7 +2064,7 @@ pub const InstalledFile = struct { } }; -pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 { +pub fn serializeCpu(allocator: Allocator, cpu: Target.Cpu) ![]const u8 { // TODO this logic can disappear if cpu model + features becomes part of the target triple const all_features = cpu.arch.allFeaturesList(); var populated_cpu_features = cpu.model.features; @@ -2078,7 +2078,7 @@ pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 { try mcpu_buffer.appendSlice(cpu.model.name); for (all_features, 0..) |feature, i_usize| { - const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize)); + const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); const in_cpu_set = populated_cpu_features.isEnabled(i); const in_actual_set = cpu.features.isEnabled(i); if (in_cpu_set and !in_actual_set) { @@ -2127,9 +2127,9 @@ pub fn hex64(x: u64) [16]u8 { /// target. The query is kept because the Zig toolchain needs to know which parts /// of the target are "native". This can apply to the CPU, the OS, or even the ABI. pub const ResolvedTarget = struct { - query: TargetQuery, - target: std.Target, - dynamic_linker: std.Target.DynamicLinker, + query: Target.Query, + target: Target, + dynamic_linker: Target.DynamicLinker, pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo { return .{ @@ -2141,7 +2141,7 @@ pub const ResolvedTarget = struct { /// Converts a target query into a fully resolved target that can be passed to /// various parts of the API. -pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget { +pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget { // This context will likely be required in the future when the target is // resolved via a WASI API or via the build protocol. _ = b; @@ -2156,7 +2156,7 @@ pub fn resolveTargetQuery(b: *Build, query: TargetQuery) ResolvedTarget { }; } -pub fn wantSharedLibSymLinks(target: std.Target) bool { +pub fn wantSharedLibSymLinks(target: Target) bool { return target.os.tag != .windows; } diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 93027003f3..cd59866176 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -9,7 +9,6 @@ const StringHashMap = std.StringHashMap; const Sha256 = std.crypto.hash.sha2.Sha256; const Allocator = mem.Allocator; const Step = std.Build.Step; -const CrossTarget = std.zig.CrossTarget; const NativeTargetInfo = std.zig.system.NativeTargetInfo; const LazyPath = std.Build.LazyPath; const PkgConfigPkg = std.Build.PkgConfigPkg; diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 9e7414365c..f5a2074264 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -3,6 +3,8 @@ os: Os, abi: Abi, ofmt: ObjectFormat, +pub const Query = @import("Target/Query.zig"); + pub const Os = struct { tag: Tag, version_range: VersionRange, @@ -1387,7 +1389,7 @@ pub const Cpu = struct { }; pub fn zigTriple(self: Target, allocator: Allocator) ![]u8 { - return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator); + return Query.fromTarget(self).zigTriple(allocator); } pub fn linuxTripleSimple(allocator: Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 { diff --git a/lib/std/Target/Query.zig b/lib/std/Target/Query.zig new file mode 100644 index 0000000000..617d141d39 --- /dev/null +++ b/lib/std/Target/Query.zig @@ -0,0 +1,855 @@ +//! Contains all the same data as `Target`, additionally introducing the +//! concept of "the native target". The purpose of this abstraction is to +//! provide meaningful and unsurprising defaults. This struct does reference +//! any resources and it is copyable. + +/// `null` means native. +cpu_arch: ?Target.Cpu.Arch = null, + +cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, + +/// Sparse set of CPU features to add to the set from `cpu_model`. +cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, + +/// Sparse set of CPU features to remove from the set from `cpu_model`. +cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, + +/// `null` means native. +os_tag: ?Target.Os.Tag = null, + +/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native) +/// then `null` for this field means native. +os_version_min: ?OsVersion = null, + +/// When cross compiling, `null` means default (latest known OS version). +/// When `os_tag` is native, `null` means equal to the native OS version. +os_version_max: ?OsVersion = null, + +/// `null` means default when cross compiling, or native when os_tag is native. +/// If `isGnuLibC()` is `false`, this must be `null` and is ignored. +glibc_version: ?SemanticVersion = null, + +/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. +abi: ?Target.Abi = null, + +/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path +/// based on the `os_tag`. +dynamic_linker: DynamicLinker = DynamicLinker{}, + +/// `null` means default for the cpu/arch/os combo. +ofmt: ?Target.ObjectFormat = null, + +pub const CpuModel = union(enum) { + /// Always native + native, + + /// Always baseline + baseline, + + /// If CPU Architecture is native, then the CPU model will be native. Otherwise, + /// it will be baseline. + determined_by_cpu_arch, + + explicit: *const Target.Cpu.Model, +}; + +pub const OsVersion = union(enum) { + none: void, + semver: SemanticVersion, + windows: Target.Os.WindowsVersion, +}; + +pub const SemanticVersion = std.SemanticVersion; + +pub const DynamicLinker = Target.DynamicLinker; + +pub fn fromTarget(target: Target) Query { + var result: Query = .{ + .cpu_arch = target.cpu.arch, + .cpu_model = .{ .explicit = target.cpu.model }, + .os_tag = target.os.tag, + .os_version_min = undefined, + .os_version_max = undefined, + .abi = target.abi, + .glibc_version = if (target.isGnuLibC()) + target.os.version_range.linux.glibc + else + null, + }; + result.updateOsVersionRange(target.os); + + const all_features = target.cpu.arch.allFeaturesList(); + var cpu_model_set = target.cpu.model.features; + cpu_model_set.populateDependencies(all_features); + { + // The "add" set is the full set with the CPU Model set removed. + const add_set = &result.cpu_features_add; + add_set.* = target.cpu.features; + add_set.removeFeatureSet(cpu_model_set); + } + { + // The "sub" set is the features that are on in CPU Model set and off in the full set. + const sub_set = &result.cpu_features_sub; + sub_set.* = cpu_model_set; + sub_set.removeFeatureSet(target.cpu.features); + } + return result; +} + +fn updateOsVersionRange(self: *Query, os: Target.Os) void { + switch (os.tag) { + .freestanding, + .ananas, + .cloudabi, + .fuchsia, + .kfreebsd, + .lv2, + .solaris, + .illumos, + .zos, + .haiku, + .minix, + .rtems, + .nacl, + .aix, + .cuda, + .nvcl, + .amdhsa, + .ps4, + .ps5, + .elfiamcu, + .mesa3d, + .contiki, + .amdpal, + .hermit, + .hurd, + .wasi, + .emscripten, + .driverkit, + .shadermodel, + .liteos, + .uefi, + .opencl, + .glsl450, + .vulkan, + .plan9, + .other, + => { + self.os_version_min = .{ .none = {} }; + self.os_version_max = .{ .none = {} }; + }, + + .freebsd, + .macos, + .ios, + .tvos, + .watchos, + .netbsd, + .openbsd, + .dragonfly, + => { + self.os_version_min = .{ .semver = os.version_range.semver.min }; + self.os_version_max = .{ .semver = os.version_range.semver.max }; + }, + + .linux => { + self.os_version_min = .{ .semver = os.version_range.linux.range.min }; + self.os_version_max = .{ .semver = os.version_range.linux.range.max }; + }, + + .windows => { + self.os_version_min = .{ .windows = os.version_range.windows.min }; + self.os_version_max = .{ .windows = os.version_range.windows.max }; + }, + } +} + +/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +pub fn toTarget(self: Query) Target { + return .{ + .cpu = self.getCpu(), + .os = self.getOs(), + .abi = self.getAbi(), + .ofmt = self.getObjectFormat(), + }; +} + +pub const ParseOptions = struct { + /// This is sometimes called a "triple". It looks roughly like this: + /// riscv64-linux-musl + /// The fields are, respectively: + /// * CPU Architecture + /// * Operating System (and optional version range) + /// * C ABI (optional, with optional glibc version) + /// The string "native" can be used for CPU architecture as well as Operating System. + /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. + arch_os_abi: []const u8 = "native", + + /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e" + /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features + /// to remove from the set. + /// The following special strings are recognized for CPU Model name: + /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set + /// of features that is expected to be supported on most available hardware. + /// * "native" - The native CPU model is to be detected when compiling. + /// If this field is not provided (`null`), then the value will depend on the + /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". + cpu_features: ?[]const u8 = null, + + /// Absolute path to dynamic linker, to override the default, which is either a natively + /// detected path, or a standard path. + dynamic_linker: ?[]const u8 = null, + + object_format: ?[]const u8 = null, + + /// If this is provided, the function will populate some information about parsing failures, + /// so that user-friendly error messages can be delivered. + diagnostics: ?*Diagnostics = null, + + pub const Diagnostics = struct { + /// If the architecture was determined, this will be populated. + arch: ?Target.Cpu.Arch = null, + + /// If the OS name was determined, this will be populated. + os_name: ?[]const u8 = null, + + /// If the OS tag was determined, this will be populated. + os_tag: ?Target.Os.Tag = null, + + /// If the ABI was determined, this will be populated. + abi: ?Target.Abi = null, + + /// If the CPU name was determined, this will be populated. + cpu_name: ?[]const u8 = null, + + /// If error.UnknownCpuFeature is returned, this will be populated. + unknown_feature_name: ?[]const u8 = null, + }; +}; + +pub fn parse(args: ParseOptions) !Query { + var dummy_diags: ParseOptions.Diagnostics = undefined; + const diags = args.diagnostics orelse &dummy_diags; + + var result: Query = .{ + .dynamic_linker = DynamicLinker.init(args.dynamic_linker), + }; + + var it = mem.splitScalar(u8, args.arch_os_abi, '-'); + const arch_name = it.first(); + const arch_is_native = mem.eql(u8, arch_name, "native"); + if (!arch_is_native) { + result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse + return error.UnknownArchitecture; + } + const arch = result.getCpuArch(); + diags.arch = arch; + + if (it.next()) |os_text| { + try parseOs(&result, diags, os_text); + } else if (!arch_is_native) { + return error.MissingOperatingSystem; + } + + const opt_abi_text = it.next(); + if (opt_abi_text) |abi_text| { + var abi_it = mem.splitScalar(u8, abi_text, '.'); + const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse + return error.UnknownApplicationBinaryInterface; + result.abi = abi; + diags.abi = abi; + + const abi_ver_text = abi_it.rest(); + if (abi_it.next() != null) { + if (result.isGnuLibC()) { + result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) { + error.Overflow => return error.InvalidAbiVersion, + error.InvalidVersion => return error.InvalidAbiVersion, + }; + } else { + return error.InvalidAbiVersion; + } + } + } + + if (it.next() != null) return error.UnexpectedExtraField; + + if (args.cpu_features) |cpu_features| { + const all_features = arch.allFeaturesList(); + var index: usize = 0; + while (index < cpu_features.len and + cpu_features[index] != '+' and + cpu_features[index] != '-') + { + index += 1; + } + const cpu_name = cpu_features[0..index]; + diags.cpu_name = cpu_name; + + const add_set = &result.cpu_features_add; + const sub_set = &result.cpu_features_sub; + if (mem.eql(u8, cpu_name, "native")) { + result.cpu_model = .native; + } else if (mem.eql(u8, cpu_name, "baseline")) { + result.cpu_model = .baseline; + } else { + result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) }; + } + + while (index < cpu_features.len) { + const op = cpu_features[index]; + const set = switch (op) { + '+' => add_set, + '-' => sub_set, + else => unreachable, + }; + index += 1; + const start = index; + while (index < cpu_features.len and + cpu_features[index] != '+' and + cpu_features[index] != '-') + { + index += 1; + } + const feature_name = cpu_features[start..index]; + for (all_features, 0..) |feature, feat_index_usize| { + const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize)); + if (mem.eql(u8, feature_name, feature.name)) { + set.addFeature(feat_index); + break; + } + } else { + diags.unknown_feature_name = feature_name; + return error.UnknownCpuFeature; + } + } + } + + if (args.object_format) |ofmt_name| { + result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse + return error.UnknownObjectFormat; + } + + return result; +} + +/// Similar to `parse` except instead of fully parsing, it only determines the CPU +/// architecture and returns it if it can be determined, and returns `null` otherwise. +/// This is intended to be used if the API user of Query needs to learn the +/// target CPU architecture in order to fully populate `ParseOptions`. +pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch { + var it = mem.splitScalar(u8, args.arch_os_abi, '-'); + const arch_name = it.first(); + const arch_is_native = mem.eql(u8, arch_name, "native"); + if (arch_is_native) { + return builtin.cpu.arch; + } else { + return std.meta.stringToEnum(Target.Cpu.Arch, arch_name); + } +} + +/// Similar to `SemanticVersion.parse`, but with following changes: +/// * Leading zeroes are allowed. +/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0. +pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion { + const parseVersionComponentFn = (struct { + fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize { + return std.fmt.parseUnsigned(usize, component, 10) catch |err| switch (err) { + error.InvalidCharacter => return error.InvalidVersion, + error.Overflow => return error.Overflow, + }; + } + }).parseVersionComponentInner; + var version_components = mem.splitScalar(u8, ver, '.'); + const major = version_components.first(); + const minor = version_components.next() orelse return error.InvalidVersion; + const patch = version_components.next() orelse "0"; + if (version_components.next() != null) return error.InvalidVersion; + return .{ + .major = try parseVersionComponentFn(major), + .minor = try parseVersionComponentFn(minor), + .patch = try parseVersionComponentFn(patch), + }; +} + +test parseVersion { + try std.testing.expectError(error.InvalidVersion, parseVersion("1")); + try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2")); + try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3")); + try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4")); +} + +/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +pub fn getCpu(self: Query) Target.Cpu { + switch (self.cpu_model) { + .native => { + // This works when doing `zig build` because Zig generates a build executable using + // native CPU model & features. However this will not be accurate otherwise, and + // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + return builtin.cpu; + }, + .baseline => { + var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); + self.updateCpuFeatures(&adjusted_baseline.features); + return adjusted_baseline; + }, + .determined_by_cpu_arch => if (self.cpu_arch == null) { + // This works when doing `zig build` because Zig generates a build executable using + // native CPU model & features. However this will not be accurate otherwise, and + // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + return builtin.cpu; + } else { + var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); + self.updateCpuFeatures(&adjusted_baseline.features); + return adjusted_baseline; + }, + .explicit => |model| { + var adjusted_model = model.toCpu(self.getCpuArch()); + self.updateCpuFeatures(&adjusted_model.features); + return adjusted_model; + }, + } +} + +pub fn getCpuArch(self: Query) Target.Cpu.Arch { + return self.cpu_arch orelse builtin.cpu.arch; +} + +pub fn getCpuModel(self: Query) *const Target.Cpu.Model { + return switch (self.cpu_model) { + .explicit => |cpu_model| cpu_model, + else => self.getCpu().model, + }; +} + +pub fn getCpuFeatures(self: Query) Target.Cpu.Feature.Set { + return self.getCpu().features; +} + +/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +pub fn getOs(self: Query) Target.Os { + // `builtin.os` works when doing `zig build` because Zig generates a build executable using + // native OS version range. However this will not be accurate otherwise, and + // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os; + + if (self.os_version_min) |min| switch (min) { + .none => {}, + .semver => |semver| switch (self.getOsTag()) { + .linux => adjusted_os.version_range.linux.range.min = semver, + else => adjusted_os.version_range.semver.min = semver, + }, + .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver, + }; + + if (self.os_version_max) |max| switch (max) { + .none => {}, + .semver => |semver| switch (self.getOsTag()) { + .linux => adjusted_os.version_range.linux.range.max = semver, + else => adjusted_os.version_range.semver.max = semver, + }, + .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver, + }; + + if (self.glibc_version) |glibc| { + assert(self.isGnuLibC()); + adjusted_os.version_range.linux.glibc = glibc; + } + + return adjusted_os; +} + +pub fn getOsTag(self: Query) Target.Os.Tag { + return self.os_tag orelse builtin.os.tag; +} + +/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +pub fn getOsVersionMin(self: Query) OsVersion { + if (self.os_version_min) |version_min| return version_min; + var tmp: Query = undefined; + tmp.updateOsVersionRange(self.getOs()); + return tmp.os_version_min.?; +} + +/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +pub fn getOsVersionMax(self: Query) OsVersion { + if (self.os_version_max) |version_max| return version_max; + var tmp: Query = undefined; + tmp.updateOsVersionRange(self.getOs()); + return tmp.os_version_max.?; +} + +/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +pub fn getAbi(self: Query) Target.Abi { + if (self.abi) |abi| return abi; + + if (self.os_tag == null) { + // This works when doing `zig build` because Zig generates a build executable using + // native CPU model & features. However this will not be accurate otherwise, and + // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + return builtin.abi; + } + + return Target.Abi.default(self.getCpuArch(), self.getOs()); +} + +pub fn isFreeBSD(self: Query) bool { + return self.getOsTag() == .freebsd; +} + +pub fn isDarwin(self: Query) bool { + return self.getOsTag().isDarwin(); +} + +pub fn isNetBSD(self: Query) bool { + return self.getOsTag() == .netbsd; +} + +pub fn isOpenBSD(self: Query) bool { + return self.getOsTag() == .openbsd; +} + +pub fn isUefi(self: Query) bool { + return self.getOsTag() == .uefi; +} + +pub fn isDragonFlyBSD(self: Query) bool { + return self.getOsTag() == .dragonfly; +} + +pub fn isLinux(self: Query) bool { + return self.getOsTag() == .linux; +} + +pub fn isWindows(self: Query) bool { + return self.getOsTag() == .windows; +} + +pub fn exeFileExt(self: Query) [:0]const u8 { + return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); +} + +pub fn staticLibSuffix(self: Query) [:0]const u8 { + return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); +} + +pub fn dynamicLibSuffix(self: Query) [:0]const u8 { + return self.getOsTag().dynamicLibSuffix(); +} + +pub fn libPrefix(self: Query) [:0]const u8 { + return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); +} + +pub fn isNativeCpu(self: Query) bool { + return self.cpu_arch == null and + (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and + self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty(); +} + +pub fn isNativeOs(self: Query) bool { + return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and + self.dynamic_linker.get() == null and self.glibc_version == null; +} + +pub fn isNativeAbi(self: Query) bool { + return self.os_tag == null and self.abi == null; +} + +pub fn isNative(self: Query) bool { + return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi(); +} + +/// Formats a version with the patch component omitted if it is zero, +/// unlike SemanticVersion.format which formats all its version components regardless. +fn formatVersion(version: SemanticVersion, writer: anytype) !void { + if (version.patch == 0) { + try writer.print("{d}.{d}", .{ version.major, version.minor }); + } else { + try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch }); + } +} + +pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 { + if (self.isNative()) { + return allocator.dupe(u8, "native"); + } + + const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native"; + const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native"; + + var result = std.ArrayList(u8).init(allocator); + defer result.deinit(); + + try result.writer().print("{s}-{s}", .{ arch_name, os_name }); + + // The zig target syntax does not allow specifying a max os version with no min, so + // if either are present, we need the min. + if (self.os_version_min != null or self.os_version_max != null) { + switch (self.getOsVersionMin()) { + .none => {}, + .semver => |v| { + try result.writer().writeAll("."); + try formatVersion(v, result.writer()); + }, + .windows => |v| try result.writer().print("{s}", .{v}), + } + } + if (self.os_version_max) |max| { + switch (max) { + .none => {}, + .semver => |v| { + try result.writer().writeAll("..."); + try formatVersion(v, result.writer()); + }, + .windows => |v| try result.writer().print("..{s}", .{v}), + } + } + + if (self.glibc_version) |v| { + try result.writer().print("-{s}.", .{@tagName(self.getAbi())}); + try formatVersion(v, result.writer()); + } else if (self.abi) |abi| { + try result.writer().print("-{s}", .{@tagName(abi)}); + } + + return result.toOwnedSlice(); +} + +pub fn allocDescription(self: Query, allocator: mem.Allocator) ![]u8 { + // TODO is there anything else worthy of the description that is not + // already captured in the triple? + return self.zigTriple(allocator); +} + +pub fn linuxTriple(self: Query, allocator: mem.Allocator) ![]u8 { + return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); +} + +pub fn isGnuLibC(self: Query) bool { + return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); +} + +pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void { + assert(self.isGnuLibC()); + self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; +} + +pub fn getObjectFormat(self: Query) Target.ObjectFormat { + return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); +} + +pub fn updateCpuFeatures(self: Query, set: *Target.Cpu.Feature.Set) void { + set.removeFeatureSet(self.cpu_features_sub); + set.addFeatureSet(self.cpu_features_add); + set.populateDependencies(self.getCpuArch().allFeaturesList()); + set.removeFeatureSet(self.cpu_features_sub); +} + +fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !void { + var it = mem.splitScalar(u8, text, '.'); + const os_name = it.first(); + diags.os_name = os_name; + const os_is_native = mem.eql(u8, os_name, "native"); + if (!os_is_native) { + result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse + return error.UnknownOperatingSystem; + } + const tag = result.getOsTag(); + diags.os_tag = tag; + + const version_text = it.rest(); + if (it.next() == null) return; + + switch (tag) { + .freestanding, + .ananas, + .cloudabi, + .fuchsia, + .kfreebsd, + .lv2, + .solaris, + .illumos, + .zos, + .haiku, + .minix, + .rtems, + .nacl, + .aix, + .cuda, + .nvcl, + .amdhsa, + .ps4, + .ps5, + .elfiamcu, + .mesa3d, + .contiki, + .amdpal, + .hermit, + .hurd, + .wasi, + .emscripten, + .uefi, + .opencl, + .glsl450, + .vulkan, + .plan9, + .driverkit, + .shadermodel, + .liteos, + .other, + => return error.InvalidOperatingSystemVersion, + + .freebsd, + .macos, + .ios, + .tvos, + .watchos, + .netbsd, + .openbsd, + .linux, + .dragonfly, + => { + var range_it = mem.splitSequence(u8, version_text, "..."); + + const min_text = range_it.next().?; + const min_ver = parseVersion(min_text) catch |err| switch (err) { + error.Overflow => return error.InvalidOperatingSystemVersion, + error.InvalidVersion => return error.InvalidOperatingSystemVersion, + }; + result.os_version_min = .{ .semver = min_ver }; + + const max_text = range_it.next() orelse return; + const max_ver = parseVersion(max_text) catch |err| switch (err) { + error.Overflow => return error.InvalidOperatingSystemVersion, + error.InvalidVersion => return error.InvalidOperatingSystemVersion, + }; + result.os_version_max = .{ .semver = max_ver }; + }, + + .windows => { + var range_it = mem.splitSequence(u8, version_text, "..."); + + const min_text = range_it.first(); + const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse + return error.InvalidOperatingSystemVersion; + result.os_version_min = .{ .windows = min_ver }; + + const max_text = range_it.next() orelse return; + const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse + return error.InvalidOperatingSystemVersion; + result.os_version_max = .{ .windows = max_ver }; + }, + } +} + +const Query = @This(); +const std = @import("../std.zig"); +const builtin = @import("builtin"); +const assert = std.debug.assert; +const Target = std.Target; +const mem = std.mem; + +test parse { + if (builtin.target.isGnuLibC()) { + var query = try Query.parse(.{}); + query.setGnuLibCVersion(2, 1, 1); + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + + var buf: [256]u8 = undefined; + const triple = std.fmt.bufPrint( + buf[0..], + "native-native-{s}.2.1.1", + .{@tagName(builtin.abi)}, + ) catch unreachable; + + try std.testing.expectEqualSlices(u8, triple, text); + } + { + const query = try Query.parse(.{ + .arch_os_abi = "aarch64-linux", + .cpu_features = "native", + }); + + try std.testing.expect(query.cpu_arch.? == .aarch64); + try std.testing.expect(query.cpu_model == .native); + } + { + const query = try Query.parse(.{ .arch_os_abi = "native" }); + + try std.testing.expect(query.cpu_arch == null); + try std.testing.expect(query.isNative()); + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + try std.testing.expectEqualSlices(u8, "native", text); + } + { + const query = try Query.parse(.{ + .arch_os_abi = "x86_64-linux-gnu", + .cpu_features = "x86_64-sse-sse2-avx-cx8", + }); + const target = query.toTarget(); + + try std.testing.expect(target.os.tag == .linux); + try std.testing.expect(target.abi == .gnu); + try std.testing.expect(target.cpu.arch == .x86_64); + try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse)); + try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx)); + try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8)); + try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov)); + try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr)); + + try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov })); + try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx })); + try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 })); + try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse })); + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text); + } + { + const query = try Query.parse(.{ + .arch_os_abi = "arm-linux-musleabihf", + .cpu_features = "generic+v8a", + }); + const target = query.toTarget(); + + try std.testing.expect(target.os.tag == .linux); + try std.testing.expect(target.abi == .musleabihf); + try std.testing.expect(target.cpu.arch == .arm); + try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic); + try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a)); + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text); + } + { + const query = try Query.parse(.{ + .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27", + .cpu_features = "generic+v8a", + }); + const target = query.toTarget(); + + try std.testing.expect(target.cpu.arch == .aarch64); + try std.testing.expect(target.os.tag == .linux); + try std.testing.expect(target.os.version_range.linux.range.min.major == 3); + try std.testing.expect(target.os.version_range.linux.range.min.minor == 10); + try std.testing.expect(target.os.version_range.linux.range.min.patch == 0); + try std.testing.expect(target.os.version_range.linux.range.max.major == 4); + try std.testing.expect(target.os.version_range.linux.range.max.minor == 4); + try std.testing.expect(target.os.version_range.linux.range.max.patch == 1); + try std.testing.expect(target.os.version_range.linux.glibc.major == 2); + try std.testing.expect(target.os.version_range.linux.glibc.minor == 27); + try std.testing.expect(target.os.version_range.linux.glibc.patch == 0); + try std.testing.expect(target.abi == .gnu); + + const text = try query.zigTriple(std.testing.allocator); + defer std.testing.allocator.free(text); + try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text); + } +} diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 9af804fa0a..481768bfb2 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -16,7 +16,8 @@ pub const number_literal = @import("zig/number_literal.zig"); pub const primitives = @import("zig/primitives.zig"); pub const Ast = @import("zig/Ast.zig"); pub const system = @import("zig/system.zig"); -pub const CrossTarget = @import("zig/CrossTarget.zig"); +/// Deprecated: use `std.Target.Query`. +pub const CrossTarget = std.Target.Query; pub const BuiltinFn = @import("zig/BuiltinFn.zig"); pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig"); diff --git a/lib/std/zig/CrossTarget.zig b/lib/std/zig/CrossTarget.zig deleted file mode 100644 index dc6de46af5..0000000000 --- a/lib/std/zig/CrossTarget.zig +++ /dev/null @@ -1,854 +0,0 @@ -//! Contains all the same data as `Target`, additionally introducing the concept of "the native target". -//! The purpose of this abstraction is to provide meaningful and unsurprising defaults. -//! This struct does reference any resources and it is copyable. - -const CrossTarget = @This(); -const std = @import("../std.zig"); -const builtin = @import("builtin"); -const assert = std.debug.assert; -const Target = std.Target; -const mem = std.mem; - -/// `null` means native. -cpu_arch: ?Target.Cpu.Arch = null, - -cpu_model: CpuModel = CpuModel.determined_by_cpu_arch, - -/// Sparse set of CPU features to add to the set from `cpu_model`. -cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, - -/// Sparse set of CPU features to remove from the set from `cpu_model`. -cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty, - -/// `null` means native. -os_tag: ?Target.Os.Tag = null, - -/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native) -/// then `null` for this field means native. -os_version_min: ?OsVersion = null, - -/// When cross compiling, `null` means default (latest known OS version). -/// When `os_tag` is native, `null` means equal to the native OS version. -os_version_max: ?OsVersion = null, - -/// `null` means default when cross compiling, or native when os_tag is native. -/// If `isGnuLibC()` is `false`, this must be `null` and is ignored. -glibc_version: ?SemanticVersion = null, - -/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI. -abi: ?Target.Abi = null, - -/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path -/// based on the `os_tag`. -dynamic_linker: DynamicLinker = DynamicLinker{}, - -/// `null` means default for the cpu/arch/os combo. -ofmt: ?Target.ObjectFormat = null, - -pub const CpuModel = union(enum) { - /// Always native - native, - - /// Always baseline - baseline, - - /// If CPU Architecture is native, then the CPU model will be native. Otherwise, - /// it will be baseline. - determined_by_cpu_arch, - - explicit: *const Target.Cpu.Model, -}; - -pub const OsVersion = union(enum) { - none: void, - semver: SemanticVersion, - windows: Target.Os.WindowsVersion, -}; - -pub const SemanticVersion = std.SemanticVersion; - -pub const DynamicLinker = Target.DynamicLinker; - -pub fn fromTarget(target: Target) CrossTarget { - var result: CrossTarget = .{ - .cpu_arch = target.cpu.arch, - .cpu_model = .{ .explicit = target.cpu.model }, - .os_tag = target.os.tag, - .os_version_min = undefined, - .os_version_max = undefined, - .abi = target.abi, - .glibc_version = if (target.isGnuLibC()) - target.os.version_range.linux.glibc - else - null, - }; - result.updateOsVersionRange(target.os); - - const all_features = target.cpu.arch.allFeaturesList(); - var cpu_model_set = target.cpu.model.features; - cpu_model_set.populateDependencies(all_features); - { - // The "add" set is the full set with the CPU Model set removed. - const add_set = &result.cpu_features_add; - add_set.* = target.cpu.features; - add_set.removeFeatureSet(cpu_model_set); - } - { - // The "sub" set is the features that are on in CPU Model set and off in the full set. - const sub_set = &result.cpu_features_sub; - sub_set.* = cpu_model_set; - sub_set.removeFeatureSet(target.cpu.features); - } - return result; -} - -fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void { - switch (os.tag) { - .freestanding, - .ananas, - .cloudabi, - .fuchsia, - .kfreebsd, - .lv2, - .solaris, - .illumos, - .zos, - .haiku, - .minix, - .rtems, - .nacl, - .aix, - .cuda, - .nvcl, - .amdhsa, - .ps4, - .ps5, - .elfiamcu, - .mesa3d, - .contiki, - .amdpal, - .hermit, - .hurd, - .wasi, - .emscripten, - .driverkit, - .shadermodel, - .liteos, - .uefi, - .opencl, - .glsl450, - .vulkan, - .plan9, - .other, - => { - self.os_version_min = .{ .none = {} }; - self.os_version_max = .{ .none = {} }; - }, - - .freebsd, - .macos, - .ios, - .tvos, - .watchos, - .netbsd, - .openbsd, - .dragonfly, - => { - self.os_version_min = .{ .semver = os.version_range.semver.min }; - self.os_version_max = .{ .semver = os.version_range.semver.max }; - }, - - .linux => { - self.os_version_min = .{ .semver = os.version_range.linux.range.min }; - self.os_version_max = .{ .semver = os.version_range.linux.range.max }; - }, - - .windows => { - self.os_version_min = .{ .windows = os.version_range.windows.min }; - self.os_version_max = .{ .windows = os.version_range.windows.max }; - }, - } -} - -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. -pub fn toTarget(self: CrossTarget) Target { - return .{ - .cpu = self.getCpu(), - .os = self.getOs(), - .abi = self.getAbi(), - .ofmt = self.getObjectFormat(), - }; -} - -pub const ParseOptions = struct { - /// This is sometimes called a "triple". It looks roughly like this: - /// riscv64-linux-musl - /// The fields are, respectively: - /// * CPU Architecture - /// * Operating System (and optional version range) - /// * C ABI (optional, with optional glibc version) - /// The string "native" can be used for CPU architecture as well as Operating System. - /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted. - arch_os_abi: []const u8 = "native", - - /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e" - /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features - /// to remove from the set. - /// The following special strings are recognized for CPU Model name: - /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set - /// of features that is expected to be supported on most available hardware. - /// * "native" - The native CPU model is to be detected when compiling. - /// If this field is not provided (`null`), then the value will depend on the - /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline". - cpu_features: ?[]const u8 = null, - - /// Absolute path to dynamic linker, to override the default, which is either a natively - /// detected path, or a standard path. - dynamic_linker: ?[]const u8 = null, - - object_format: ?[]const u8 = null, - - /// If this is provided, the function will populate some information about parsing failures, - /// so that user-friendly error messages can be delivered. - diagnostics: ?*Diagnostics = null, - - pub const Diagnostics = struct { - /// If the architecture was determined, this will be populated. - arch: ?Target.Cpu.Arch = null, - - /// If the OS name was determined, this will be populated. - os_name: ?[]const u8 = null, - - /// If the OS tag was determined, this will be populated. - os_tag: ?Target.Os.Tag = null, - - /// If the ABI was determined, this will be populated. - abi: ?Target.Abi = null, - - /// If the CPU name was determined, this will be populated. - cpu_name: ?[]const u8 = null, - - /// If error.UnknownCpuFeature is returned, this will be populated. - unknown_feature_name: ?[]const u8 = null, - }; -}; - -pub fn parse(args: ParseOptions) !CrossTarget { - var dummy_diags: ParseOptions.Diagnostics = undefined; - const diags = args.diagnostics orelse &dummy_diags; - - var result: CrossTarget = .{ - .dynamic_linker = DynamicLinker.init(args.dynamic_linker), - }; - - var it = mem.splitScalar(u8, args.arch_os_abi, '-'); - const arch_name = it.first(); - const arch_is_native = mem.eql(u8, arch_name, "native"); - if (!arch_is_native) { - result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse - return error.UnknownArchitecture; - } - const arch = result.getCpuArch(); - diags.arch = arch; - - if (it.next()) |os_text| { - try parseOs(&result, diags, os_text); - } else if (!arch_is_native) { - return error.MissingOperatingSystem; - } - - const opt_abi_text = it.next(); - if (opt_abi_text) |abi_text| { - var abi_it = mem.splitScalar(u8, abi_text, '.'); - const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse - return error.UnknownApplicationBinaryInterface; - result.abi = abi; - diags.abi = abi; - - const abi_ver_text = abi_it.rest(); - if (abi_it.next() != null) { - if (result.isGnuLibC()) { - result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) { - error.Overflow => return error.InvalidAbiVersion, - error.InvalidVersion => return error.InvalidAbiVersion, - }; - } else { - return error.InvalidAbiVersion; - } - } - } - - if (it.next() != null) return error.UnexpectedExtraField; - - if (args.cpu_features) |cpu_features| { - const all_features = arch.allFeaturesList(); - var index: usize = 0; - while (index < cpu_features.len and - cpu_features[index] != '+' and - cpu_features[index] != '-') - { - index += 1; - } - const cpu_name = cpu_features[0..index]; - diags.cpu_name = cpu_name; - - const add_set = &result.cpu_features_add; - const sub_set = &result.cpu_features_sub; - if (mem.eql(u8, cpu_name, "native")) { - result.cpu_model = .native; - } else if (mem.eql(u8, cpu_name, "baseline")) { - result.cpu_model = .baseline; - } else { - result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) }; - } - - while (index < cpu_features.len) { - const op = cpu_features[index]; - const set = switch (op) { - '+' => add_set, - '-' => sub_set, - else => unreachable, - }; - index += 1; - const start = index; - while (index < cpu_features.len and - cpu_features[index] != '+' and - cpu_features[index] != '-') - { - index += 1; - } - const feature_name = cpu_features[start..index]; - for (all_features, 0..) |feature, feat_index_usize| { - const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize)); - if (mem.eql(u8, feature_name, feature.name)) { - set.addFeature(feat_index); - break; - } - } else { - diags.unknown_feature_name = feature_name; - return error.UnknownCpuFeature; - } - } - } - - if (args.object_format) |ofmt_name| { - result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse - return error.UnknownObjectFormat; - } - - return result; -} - -/// Similar to `parse` except instead of fully parsing, it only determines the CPU -/// architecture and returns it if it can be determined, and returns `null` otherwise. -/// This is intended to be used if the API user of CrossTarget needs to learn the -/// target CPU architecture in order to fully populate `ParseOptions`. -pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch { - var it = mem.splitScalar(u8, args.arch_os_abi, '-'); - const arch_name = it.first(); - const arch_is_native = mem.eql(u8, arch_name, "native"); - if (arch_is_native) { - return builtin.cpu.arch; - } else { - return std.meta.stringToEnum(Target.Cpu.Arch, arch_name); - } -} - -/// Similar to `SemanticVersion.parse`, but with following changes: -/// * Leading zeroes are allowed. -/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0. -pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion { - const parseVersionComponentFn = (struct { - fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize { - return std.fmt.parseUnsigned(usize, component, 10) catch |err| switch (err) { - error.InvalidCharacter => return error.InvalidVersion, - error.Overflow => return error.Overflow, - }; - } - }).parseVersionComponentInner; - var version_components = mem.splitScalar(u8, ver, '.'); - const major = version_components.first(); - const minor = version_components.next() orelse return error.InvalidVersion; - const patch = version_components.next() orelse "0"; - if (version_components.next() != null) return error.InvalidVersion; - return .{ - .major = try parseVersionComponentFn(major), - .minor = try parseVersionComponentFn(minor), - .patch = try parseVersionComponentFn(patch), - }; -} - -test parseVersion { - try std.testing.expectError(error.InvalidVersion, parseVersion("1")); - try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2")); - try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3")); - try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4")); -} - -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. -pub fn getCpu(self: CrossTarget) Target.Cpu { - switch (self.cpu_model) { - .native => { - // This works when doing `zig build` because Zig generates a build executable using - // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. - return builtin.cpu; - }, - .baseline => { - var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); - self.updateCpuFeatures(&adjusted_baseline.features); - return adjusted_baseline; - }, - .determined_by_cpu_arch => if (self.cpu_arch == null) { - // This works when doing `zig build` because Zig generates a build executable using - // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. - return builtin.cpu; - } else { - var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); - self.updateCpuFeatures(&adjusted_baseline.features); - return adjusted_baseline; - }, - .explicit => |model| { - var adjusted_model = model.toCpu(self.getCpuArch()); - self.updateCpuFeatures(&adjusted_model.features); - return adjusted_model; - }, - } -} - -pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch { - return self.cpu_arch orelse builtin.cpu.arch; -} - -pub fn getCpuModel(self: CrossTarget) *const Target.Cpu.Model { - return switch (self.cpu_model) { - .explicit => |cpu_model| cpu_model, - else => self.getCpu().model, - }; -} - -pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set { - return self.getCpu().features; -} - -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. -pub fn getOs(self: CrossTarget) Target.Os { - // `builtin.os` works when doing `zig build` because Zig generates a build executable using - // native OS version range. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. - var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os; - - if (self.os_version_min) |min| switch (min) { - .none => {}, - .semver => |semver| switch (self.getOsTag()) { - .linux => adjusted_os.version_range.linux.range.min = semver, - else => adjusted_os.version_range.semver.min = semver, - }, - .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver, - }; - - if (self.os_version_max) |max| switch (max) { - .none => {}, - .semver => |semver| switch (self.getOsTag()) { - .linux => adjusted_os.version_range.linux.range.max = semver, - else => adjusted_os.version_range.semver.max = semver, - }, - .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver, - }; - - if (self.glibc_version) |glibc| { - assert(self.isGnuLibC()); - adjusted_os.version_range.linux.glibc = glibc; - } - - return adjusted_os; -} - -pub fn getOsTag(self: CrossTarget) Target.Os.Tag { - return self.os_tag orelse builtin.os.tag; -} - -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. -pub fn getOsVersionMin(self: CrossTarget) OsVersion { - if (self.os_version_min) |version_min| return version_min; - var tmp: CrossTarget = undefined; - tmp.updateOsVersionRange(self.getOs()); - return tmp.os_version_min.?; -} - -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. -pub fn getOsVersionMax(self: CrossTarget) OsVersion { - if (self.os_version_max) |version_max| return version_max; - var tmp: CrossTarget = undefined; - tmp.updateOsVersionRange(self.getOs()); - return tmp.os_version_max.?; -} - -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. -pub fn getAbi(self: CrossTarget) Target.Abi { - if (self.abi) |abi| return abi; - - if (self.os_tag == null) { - // This works when doing `zig build` because Zig generates a build executable using - // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. - return builtin.abi; - } - - return Target.Abi.default(self.getCpuArch(), self.getOs()); -} - -pub fn isFreeBSD(self: CrossTarget) bool { - return self.getOsTag() == .freebsd; -} - -pub fn isDarwin(self: CrossTarget) bool { - return self.getOsTag().isDarwin(); -} - -pub fn isNetBSD(self: CrossTarget) bool { - return self.getOsTag() == .netbsd; -} - -pub fn isOpenBSD(self: CrossTarget) bool { - return self.getOsTag() == .openbsd; -} - -pub fn isUefi(self: CrossTarget) bool { - return self.getOsTag() == .uefi; -} - -pub fn isDragonFlyBSD(self: CrossTarget) bool { - return self.getOsTag() == .dragonfly; -} - -pub fn isLinux(self: CrossTarget) bool { - return self.getOsTag() == .linux; -} - -pub fn isWindows(self: CrossTarget) bool { - return self.getOsTag() == .windows; -} - -pub fn exeFileExt(self: CrossTarget) [:0]const u8 { - return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); -} - -pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 { - return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); -} - -pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 { - return self.getOsTag().dynamicLibSuffix(); -} - -pub fn libPrefix(self: CrossTarget) [:0]const u8 { - return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); -} - -pub fn isNativeCpu(self: CrossTarget) bool { - return self.cpu_arch == null and - (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and - self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty(); -} - -pub fn isNativeOs(self: CrossTarget) bool { - return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and - self.dynamic_linker.get() == null and self.glibc_version == null; -} - -pub fn isNativeAbi(self: CrossTarget) bool { - return self.os_tag == null and self.abi == null; -} - -pub fn isNative(self: CrossTarget) bool { - return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi(); -} - -/// Formats a version with the patch component omitted if it is zero, -/// unlike SemanticVersion.format which formats all its version components regardless. -fn formatVersion(version: SemanticVersion, writer: anytype) !void { - if (version.patch == 0) { - try writer.print("{d}.{d}", .{ version.major, version.minor }); - } else { - try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch }); - } -} - -pub fn zigTriple(self: CrossTarget, allocator: mem.Allocator) error{OutOfMemory}![]u8 { - if (self.isNative()) { - return allocator.dupe(u8, "native"); - } - - const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native"; - const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native"; - - var result = std.ArrayList(u8).init(allocator); - defer result.deinit(); - - try result.writer().print("{s}-{s}", .{ arch_name, os_name }); - - // The zig target syntax does not allow specifying a max os version with no min, so - // if either are present, we need the min. - if (self.os_version_min != null or self.os_version_max != null) { - switch (self.getOsVersionMin()) { - .none => {}, - .semver => |v| { - try result.writer().writeAll("."); - try formatVersion(v, result.writer()); - }, - .windows => |v| try result.writer().print("{s}", .{v}), - } - } - if (self.os_version_max) |max| { - switch (max) { - .none => {}, - .semver => |v| { - try result.writer().writeAll("..."); - try formatVersion(v, result.writer()); - }, - .windows => |v| try result.writer().print("..{s}", .{v}), - } - } - - if (self.glibc_version) |v| { - try result.writer().print("-{s}.", .{@tagName(self.getAbi())}); - try formatVersion(v, result.writer()); - } else if (self.abi) |abi| { - try result.writer().print("-{s}", .{@tagName(abi)}); - } - - return result.toOwnedSlice(); -} - -pub fn allocDescription(self: CrossTarget, allocator: mem.Allocator) ![]u8 { - // TODO is there anything else worthy of the description that is not - // already captured in the triple? - return self.zigTriple(allocator); -} - -pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 { - return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); -} - -pub fn isGnuLibC(self: CrossTarget) bool { - return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); -} - -pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) void { - assert(self.isGnuLibC()); - self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; -} - -pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat { - return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); -} - -pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void { - set.removeFeatureSet(self.cpu_features_sub); - set.addFeatureSet(self.cpu_features_add); - set.populateDependencies(self.getCpuArch().allFeaturesList()); - set.removeFeatureSet(self.cpu_features_sub); -} - -fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const u8) !void { - var it = mem.splitScalar(u8, text, '.'); - const os_name = it.first(); - diags.os_name = os_name; - const os_is_native = mem.eql(u8, os_name, "native"); - if (!os_is_native) { - result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse - return error.UnknownOperatingSystem; - } - const tag = result.getOsTag(); - diags.os_tag = tag; - - const version_text = it.rest(); - if (it.next() == null) return; - - switch (tag) { - .freestanding, - .ananas, - .cloudabi, - .fuchsia, - .kfreebsd, - .lv2, - .solaris, - .illumos, - .zos, - .haiku, - .minix, - .rtems, - .nacl, - .aix, - .cuda, - .nvcl, - .amdhsa, - .ps4, - .ps5, - .elfiamcu, - .mesa3d, - .contiki, - .amdpal, - .hermit, - .hurd, - .wasi, - .emscripten, - .uefi, - .opencl, - .glsl450, - .vulkan, - .plan9, - .driverkit, - .shadermodel, - .liteos, - .other, - => return error.InvalidOperatingSystemVersion, - - .freebsd, - .macos, - .ios, - .tvos, - .watchos, - .netbsd, - .openbsd, - .linux, - .dragonfly, - => { - var range_it = mem.splitSequence(u8, version_text, "..."); - - const min_text = range_it.next().?; - const min_ver = parseVersion(min_text) catch |err| switch (err) { - error.Overflow => return error.InvalidOperatingSystemVersion, - error.InvalidVersion => return error.InvalidOperatingSystemVersion, - }; - result.os_version_min = .{ .semver = min_ver }; - - const max_text = range_it.next() orelse return; - const max_ver = parseVersion(max_text) catch |err| switch (err) { - error.Overflow => return error.InvalidOperatingSystemVersion, - error.InvalidVersion => return error.InvalidOperatingSystemVersion, - }; - result.os_version_max = .{ .semver = max_ver }; - }, - - .windows => { - var range_it = mem.splitSequence(u8, version_text, "..."); - - const min_text = range_it.first(); - const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse - return error.InvalidOperatingSystemVersion; - result.os_version_min = .{ .windows = min_ver }; - - const max_text = range_it.next() orelse return; - const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse - return error.InvalidOperatingSystemVersion; - result.os_version_max = .{ .windows = max_ver }; - }, - } -} - -test "CrossTarget.parse" { - if (builtin.target.isGnuLibC()) { - var cross_target = try CrossTarget.parse(.{}); - cross_target.setGnuLibCVersion(2, 1, 1); - - const text = try cross_target.zigTriple(std.testing.allocator); - defer std.testing.allocator.free(text); - - var buf: [256]u8 = undefined; - const triple = std.fmt.bufPrint( - buf[0..], - "native-native-{s}.2.1.1", - .{@tagName(builtin.abi)}, - ) catch unreachable; - - try std.testing.expectEqualSlices(u8, triple, text); - } - { - const cross_target = try CrossTarget.parse(.{ - .arch_os_abi = "aarch64-linux", - .cpu_features = "native", - }); - - try std.testing.expect(cross_target.cpu_arch.? == .aarch64); - try std.testing.expect(cross_target.cpu_model == .native); - } - { - const cross_target = try CrossTarget.parse(.{ .arch_os_abi = "native" }); - - try std.testing.expect(cross_target.cpu_arch == null); - try std.testing.expect(cross_target.isNative()); - - const text = try cross_target.zigTriple(std.testing.allocator); - defer std.testing.allocator.free(text); - try std.testing.expectEqualSlices(u8, "native", text); - } - { - const cross_target = try CrossTarget.parse(.{ - .arch_os_abi = "x86_64-linux-gnu", - .cpu_features = "x86_64-sse-sse2-avx-cx8", - }); - const target = cross_target.toTarget(); - - try std.testing.expect(target.os.tag == .linux); - try std.testing.expect(target.abi == .gnu); - try std.testing.expect(target.cpu.arch == .x86_64); - try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse)); - try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx)); - try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8)); - try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov)); - try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr)); - - try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov })); - try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx })); - try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 })); - try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse })); - - const text = try cross_target.zigTriple(std.testing.allocator); - defer std.testing.allocator.free(text); - try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text); - } - { - const cross_target = try CrossTarget.parse(.{ - .arch_os_abi = "arm-linux-musleabihf", - .cpu_features = "generic+v8a", - }); - const target = cross_target.toTarget(); - - try std.testing.expect(target.os.tag == .linux); - try std.testing.expect(target.abi == .musleabihf); - try std.testing.expect(target.cpu.arch == .arm); - try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic); - try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a)); - - const text = try cross_target.zigTriple(std.testing.allocator); - defer std.testing.allocator.free(text); - try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text); - } - { - const cross_target = try CrossTarget.parse(.{ - .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27", - .cpu_features = "generic+v8a", - }); - const target = cross_target.toTarget(); - - try std.testing.expect(target.cpu.arch == .aarch64); - try std.testing.expect(target.os.tag == .linux); - try std.testing.expect(target.os.version_range.linux.range.min.major == 3); - try std.testing.expect(target.os.version_range.linux.range.min.minor == 10); - try std.testing.expect(target.os.version_range.linux.range.min.patch == 0); - try std.testing.expect(target.os.version_range.linux.range.max.major == 4); - try std.testing.expect(target.os.version_range.linux.range.max.minor == 4); - try std.testing.expect(target.os.version_range.linux.range.max.patch == 1); - try std.testing.expect(target.os.version_range.linux.glibc.major == 2); - try std.testing.expect(target.os.version_range.linux.glibc.minor == 27); - try std.testing.expect(target.os.version_range.linux.glibc.patch == 0); - try std.testing.expect(target.abi == .gnu); - - const text = try cross_target.zigTriple(std.testing.allocator); - defer std.testing.allocator.free(text); - try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text); - } -} diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig index d44e396fb5..c4562cf7d5 100644 --- a/lib/std/zig/system/NativeTargetInfo.zig +++ b/lib/std/zig/system/NativeTargetInfo.zig @@ -9,7 +9,6 @@ const native_endian = builtin.cpu.arch.endian(); const NativeTargetInfo = @This(); const Target = std.Target; const Allocator = std.mem.Allocator; -const CrossTarget = std.zig.CrossTarget; const windows = std.zig.system.windows; const darwin = std.zig.system.darwin; const linux = std.zig.system.linux; @@ -30,13 +29,14 @@ pub const DetectError = error{ Unexpected, }; -/// Given a `CrossTarget`, which specifies in detail which parts of the target should be detected -/// natively, which should be standard or default, and which are provided explicitly, this function -/// resolves the native components by detecting the native system, and then resolves standard/default parts -/// relative to that. -pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { - var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch()); - if (cross_target.os_tag == null) { +/// Given a `Target.Query`, which specifies in detail which parts of the +/// target should be detected natively, which should be standard or default, +/// and which are provided explicitly, this function resolves the native +/// components by detecting the native system, and then resolves +/// standard/default parts relative to that. +pub fn detect(query: Target.Query) DetectError!NativeTargetInfo { + var os = query.getOsTag().defaultVersionRange(query.getCpuArch()); + if (query.os_tag == null) { switch (builtin.target.os.tag) { .linux => { const uts = std.os.uname(); @@ -162,45 +162,45 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { } } - if (cross_target.os_version_min) |min| switch (min) { + if (query.os_version_min) |min| switch (min) { .none => {}, - .semver => |semver| switch (cross_target.getOsTag()) { + .semver => |semver| switch (query.getOsTag()) { .linux => os.version_range.linux.range.min = semver, else => os.version_range.semver.min = semver, }, .windows => |win_ver| os.version_range.windows.min = win_ver, }; - if (cross_target.os_version_max) |max| switch (max) { + if (query.os_version_max) |max| switch (max) { .none => {}, - .semver => |semver| switch (cross_target.getOsTag()) { + .semver => |semver| switch (query.getOsTag()) { .linux => os.version_range.linux.range.max = semver, else => os.version_range.semver.max = semver, }, .windows => |win_ver| os.version_range.windows.max = win_ver, }; - if (cross_target.glibc_version) |glibc| { - assert(cross_target.isGnuLibC()); + if (query.glibc_version) |glibc| { + assert(query.isGnuLibC()); os.version_range.linux.glibc = glibc; } // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the // native CPU architecture as being different than the current target), we use this: - const cpu_arch = cross_target.getCpuArch(); + const cpu_arch = query.getCpuArch(); - const cpu = switch (cross_target.cpu_model) { - .native => detectNativeCpuAndFeatures(cpu_arch, os, cross_target), + const cpu = switch (query.cpu_model) { + .native => detectNativeCpuAndFeatures(cpu_arch, os, query), .baseline => Target.Cpu.baseline(cpu_arch), - .determined_by_cpu_arch => if (cross_target.cpu_arch == null) - detectNativeCpuAndFeatures(cpu_arch, os, cross_target) + .determined_by_cpu_arch => if (query.cpu_arch == null) + detectNativeCpuAndFeatures(cpu_arch, os, query) else Target.Cpu.baseline(cpu_arch), .explicit => |model| model.toCpu(cpu_arch), } orelse backup_cpu_detection: { break :backup_cpu_detection Target.Cpu.baseline(cpu_arch); }; - var result = try detectAbiAndDynamicLinker(cpu, os, cross_target); + var result = try detectAbiAndDynamicLinker(cpu, os, query); // For x86, we need to populate some CPU feature flags depending on architecture // and mode: // * 16bit_mode => if the abi is code16 @@ -209,15 +209,15 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { // sets one of them, that takes precedence. switch (cpu_arch) { .x86 => { - if (!std.Target.x86.featureSetHasAny(cross_target.cpu_features_add, .{ + if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{ .@"16bit_mode", .@"32bit_mode", })) { switch (result.target.abi) { .code16 => result.target.cpu.features.addFeature( - @intFromEnum(std.Target.x86.Feature.@"16bit_mode"), + @intFromEnum(Target.x86.Feature.@"16bit_mode"), ), else => result.target.cpu.features.addFeature( - @intFromEnum(std.Target.x86.Feature.@"32bit_mode"), + @intFromEnum(Target.x86.Feature.@"32bit_mode"), ), } } @@ -228,12 +228,12 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { }, .thumb, .thumbeb => { result.target.cpu.features.addFeature( - @intFromEnum(std.Target.arm.Feature.thumb_mode), + @intFromEnum(Target.arm.Feature.thumb_mode), ); }, else => {}, } - cross_target.updateCpuFeatures(&result.target.cpu.features); + query.updateCpuFeatures(&result.target.cpu.features); return result; } @@ -253,22 +253,22 @@ pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo { fn detectAbiAndDynamicLinker( cpu: Target.Cpu, os: Target.Os, - cross_target: CrossTarget, + query: Target.Query, ) DetectError!NativeTargetInfo { const native_target_has_ld = comptime builtin.target.hasDynamicLinker(); const is_linux = builtin.target.os.tag == .linux; const is_solarish = builtin.target.os.tag.isSolarish(); - const have_all_info = cross_target.dynamic_linker.get() != null and - cross_target.abi != null and (!is_linux or cross_target.abi.?.isGnu()); - const os_is_non_native = cross_target.os_tag != null; + const have_all_info = query.dynamic_linker.get() != null and + query.abi != null and (!is_linux or query.abi.?.isGnu()); + const os_is_non_native = query.os_tag != null; // The Solaris/illumos environment is always the same. if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) { - return defaultAbiAndDynamicLinker(cpu, os, cross_target); + return defaultAbiAndDynamicLinker(cpu, os, query); } - if (cross_target.abi) |abi| { + if (query.abi) |abi| { if (abi.isMusl()) { // musl implies static linking. - return defaultAbiAndDynamicLinker(cpu, os, cross_target); + return defaultAbiAndDynamicLinker(cpu, os, query); } } // The current target's ABI cannot be relied on for this. For example, we may build the zig @@ -287,7 +287,7 @@ fn detectAbiAndDynamicLinker( }; var ld_info_list_buffer: [all_abis.len]LdInfo = undefined; var ld_info_list_len: usize = 0; - const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch); + const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch); for (all_abis) |abi| { // This may be a nonsensical parameter. We detect this with @@ -345,7 +345,7 @@ fn detectAbiAndDynamicLinker( error.Unexpected, => |e| { std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)}); - return defaultAbiAndDynamicLinker(cpu, os, cross_target); + return defaultAbiAndDynamicLinker(cpu, os, query); }, else => |e| return e, @@ -363,7 +363,7 @@ fn detectAbiAndDynamicLinker( const line = buffer[0..newline]; if (!mem.startsWith(u8, line, "#!")) break :blk file; var it = mem.tokenizeScalar(u8, line[2..], ' '); - file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, cross_target); + file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, query); file.close(); } }; @@ -373,7 +373,7 @@ fn detectAbiAndDynamicLinker( // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file. // TODO: inline this function and combine the buffer we already read above to find // the possible shebang line with the buffer we use for the ELF header. - return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, cross_target) catch |err| switch (err) { + return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, query) catch |err| switch (err) { error.FileSystem, error.SystemResources, error.SymLinkLoop, @@ -393,7 +393,7 @@ fn detectAbiAndDynamicLinker( // Finally, we fall back on the standard path. => |e| { std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)}); - return defaultAbiAndDynamicLinker(cpu, os, cross_target); + return defaultAbiAndDynamicLinker(cpu, os, query); }, }; } @@ -565,7 +565,7 @@ fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion { while (it.next()) |s| { if (mem.startsWith(u8, s, "GLIBC_2.")) { const chopped = s["GLIBC_".len..]; - const ver = CrossTarget.parseVersion(chopped) catch |err| switch (err) { + const ver = Target.Query.parseVersion(chopped) catch |err| switch (err) { error.Overflow => return error.InvalidGnuLibCVersion, error.InvalidVersion => return error.InvalidGnuLibCVersion, }; @@ -588,7 +588,7 @@ fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ Unreco } // chop off "libc-" and ".so" const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len]; - return CrossTarget.parseVersion(link_name_chopped) catch |err| switch (err) { + return Target.Query.parseVersion(link_name_chopped) catch |err| switch (err) { error.Overflow => return error.InvalidGnuLibCVersion, error.InvalidVersion => return error.InvalidGnuLibCVersion, }; @@ -627,7 +627,7 @@ pub fn abiAndDynamicLinkerFromFile( cpu: Target.Cpu, os: Target.Os, ld_info_list: []const LdInfo, - cross_target: CrossTarget, + query: Target.Query, ) AbiAndDynamicLinkerFromFileError!NativeTargetInfo { var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len); @@ -655,13 +655,13 @@ pub fn abiAndDynamicLinkerFromFile( .target = .{ .cpu = cpu, .os = os, - .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), - .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), + .abi = query.abi orelse Target.Abi.default(cpu.arch, os), + .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), }, - .dynamic_linker = cross_target.dynamic_linker, + .dynamic_linker = query.dynamic_linker, }; var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC - const look_for_ld = cross_target.dynamic_linker.get() == null; + const look_for_ld = query.dynamic_linker.get() == null; var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined; if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile; @@ -706,7 +706,7 @@ pub fn abiAndDynamicLinkerFromFile( }, // We only need this for detecting glibc version. elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and - cross_target.glibc_version == null) + query.glibc_version == null) { var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); @@ -747,7 +747,7 @@ pub fn abiAndDynamicLinkerFromFile( } if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and - cross_target.glibc_version == null) + query.glibc_version == null) { const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); @@ -927,19 +927,19 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize { return i; } -fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: CrossTarget) !NativeTargetInfo { +fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) !NativeTargetInfo { const target: Target = .{ .cpu = cpu, .os = os, - .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os), - .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), + .abi = query.abi orelse Target.Abi.default(cpu.arch, os), + .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), }; return NativeTargetInfo{ .target = target, - .dynamic_linker = if (cross_target.dynamic_linker.get() == null) + .dynamic_linker = if (query.dynamic_linker.get() == null) target.standardDynamicLinkerPath() else - cross_target.dynamic_linker, + query.dynamic_linker, }; } @@ -964,13 +964,13 @@ pub fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @ } } -fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) ?Target.Cpu { +fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu { // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`, // although it is a runtime value, is guaranteed to be one of the architectures in the set // of the respective switch prong. switch (builtin.cpu.arch) { .x86_64, .x86 => { - return @import("x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, cross_target); + return @import("x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query); }, else => {}, } diff --git a/lib/std/zig/system/darwin/macos.zig b/lib/std/zig/system/darwin/macos.zig index 2c0b22e96c..c4feb7a35b 100644 --- a/lib/std/zig/system/darwin/macos.zig +++ b/lib/std/zig/system/darwin/macos.zig @@ -87,7 +87,7 @@ fn parseSystemVersion(buf: []const u8) !std.SemanticVersion { const ver = try svt.expectContent(); try svt.skipUntilTag(.end, "string"); - return try std.zig.CrossTarget.parseVersion(ver); + return try std.Target.Query.parseVersion(ver); } const SystemVersionTokenizer = struct { diff --git a/lib/std/zig/system/linux.zig b/lib/std/zig/system/linux.zig index f2f89f8317..d2d31b4079 100644 --- a/lib/std/zig/system/linux.zig +++ b/lib/std/zig/system/linux.zig @@ -5,10 +5,7 @@ const io = std.io; const fs = std.fs; const fmt = std.fmt; const testing = std.testing; - const Target = std.Target; -const CrossTarget = std.zig.CrossTarget; - const assert = std.debug.assert; const SparcCpuinfoImpl = struct { diff --git a/lib/std/zig/system/x86.zig b/lib/std/zig/system/x86.zig index b99f5cf65f..edcfcebf29 100644 --- a/lib/std/zig/system/x86.zig +++ b/lib/std/zig/system/x86.zig @@ -1,7 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); const Target = std.Target; -const CrossTarget = std.zig.CrossTarget; const XCR0_XMM = 0x02; const XCR0_YMM = 0x04; @@ -23,8 +22,8 @@ inline fn hasMask(input: u32, mask: u32) bool { return (input & mask) == mask; } -pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) Target.Cpu { - _ = cross_target; +pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) Target.Cpu { + _ = query; var cpu = Target.Cpu{ .arch = arch, .model = Target.Cpu.Model.generic(arch), diff --git a/src/libc_installation.zig b/src/libc_installation.zig index 48b505d935..facb16257e 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -41,7 +41,7 @@ pub const LibCInstallation = struct { pub fn parse( allocator: Allocator, libc_file: []const u8, - target: std.zig.CrossTarget, + target: std.Target.Query, ) !LibCInstallation { var self: LibCInstallation = .{}; diff --git a/src/main.zig b/src/main.zig index 0e6ce947aa..17603acf2c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2551,7 +2551,7 @@ fn buildOutputType( } }; - var target_parse_options: std.zig.CrossTarget.ParseOptions = .{ + var target_parse_options: std.Target.Query.ParseOptions = .{ .arch_os_abi = target_arch_os_abi, .cpu_features = target_mcpu, .dynamic_linker = target_dynamic_linker, @@ -2563,7 +2563,7 @@ fn buildOutputType( if (llvm_m_args.items.len != 0) { // If this returns null, we let it fall through to the case below which will // run the full parse function and do proper error handling. - if (std.zig.CrossTarget.parseCpuArch(target_parse_options)) |cpu_arch| { + if (std.Target.Query.parseCpuArch(target_parse_options)) |cpu_arch| { var llvm_to_zig_name = std.StringHashMap([]const u8).init(gpa); defer llvm_to_zig_name.deinit(); @@ -2607,8 +2607,8 @@ fn buildOutputType( } } - const cross_target = try parseCrossTargetOrReportFatalError(arena, target_parse_options); - const target_info = try detectNativeTargetInfo(cross_target); + const target_query = try parseTargetQueryOrReportFatalError(arena, target_parse_options); + const target_info = try detectNativeTargetInfo(target_query); if (target_info.target.os.tag != .freestanding) { if (ensure_libc_on_non_freestanding) @@ -2695,13 +2695,13 @@ fn buildOutputType( } if (use_lld) |opt| { - if (opt and cross_target.isDarwin()) { + if (opt and target_query.isDarwin()) { fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{}); } } if (want_lto) |opt| { - if (opt and cross_target.isDarwin()) { + if (opt and target_query.isDarwin()) { fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{}); } } @@ -2771,7 +2771,7 @@ fn buildOutputType( var libc_installation: ?LibCInstallation = null; if (libc_paths_file) |paths_file| { - libc_installation = LibCInstallation.parse(arena, paths_file, cross_target) catch |err| { + libc_installation = LibCInstallation.parse(arena, paths_file, target_query) catch |err| { fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) }); }; } @@ -2835,7 +2835,7 @@ fn buildOutputType( // After this point, external_system_libs is used instead of system_libs. // Trigger native system library path detection if necessary. - if (sysroot == null and cross_target.isNativeOs() and cross_target.isNativeAbi() and + if (sysroot == null and target_query.isNativeOs() and target_query.isNativeAbi() and (external_system_libs.len != 0 or want_native_include_dirs)) { const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| { @@ -2864,7 +2864,7 @@ fn buildOutputType( libc_installation = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true, - .target = cross_target.toTarget(), + .target = target_query.toTarget(), }); try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? }); @@ -3455,8 +3455,8 @@ fn buildOutputType( .global_cache_directory = global_cache_directory, .root_name = root_name, .target = target_info.target, - .is_native_os = cross_target.isNativeOs(), - .is_native_abi = cross_target.isNativeAbi(), + .is_native_os = target_query.isNativeOs(), + .is_native_abi = target_query.isNativeAbi(), .dynamic_linker = target_info.dynamic_linker.get(), .sysroot = sysroot, .output_mode = output_mode, @@ -4013,16 +4013,16 @@ const ModuleDepIterator = struct { } }; -fn parseCrossTargetOrReportFatalError( +fn parseTargetQueryOrReportFatalError( allocator: Allocator, - opts: std.zig.CrossTarget.ParseOptions, -) !std.zig.CrossTarget { + opts: std.Target.Query.ParseOptions, +) !std.Target.Query { var opts_with_diags = opts; - var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{}; + var diags: std.Target.Query.ParseOptions.Diagnostics = .{}; if (opts_with_diags.diagnostics == null) { opts_with_diags.diagnostics = &diags; } - return std.zig.CrossTarget.parse(opts_with_diags) catch |err| switch (err) { + return std.Target.Query.parse(opts_with_diags) catch |err| switch (err) { error.UnknownCpuModel => { help: { var help_text = std.ArrayList(u8).init(allocator); @@ -4666,9 +4666,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes: while (true) { switch (cur_includes) { .any, .msvc => { - const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable; - const target = cross_target.toTarget(); - const is_native_abi = cross_target.isNativeAbi(); + const target_query = std.Target.Query.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable; + const target = target_query.toTarget(); + const is_native_abi = target_query.isNativeAbi(); const detected_libc = Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null) catch |err| { if (cur_includes == .any) { // fall back to mingw @@ -4691,9 +4691,9 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes: }; }, .gnu => { - const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable; - const target = cross_target.toTarget(); - const is_native_abi = cross_target.isNativeAbi(); + const target_query = std.Target.Query.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable; + const target = target_query.toTarget(); + const is_native_abi = target_query.isNativeAbi(); const detected_libc = try Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null); return .{ .include_paths = detected_libc.libc_include_dir_list, @@ -4754,7 +4754,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { } } - const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{ + const target_query = try parseTargetQueryOrReportFatalError(gpa, .{ .arch_os_abi = target_arch_os_abi, }); @@ -4766,7 +4766,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { const libc_installation: ?*LibCInstallation = libc: { if (input_file) |libc_file| { const libc = try arena.create(LibCInstallation); - libc.* = LibCInstallation.parse(arena, libc_file, cross_target) catch |err| { + libc.* = LibCInstallation.parse(arena, libc_file, target_query) catch |err| { fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); }; break :libc libc; @@ -4781,8 +4781,8 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { }; defer zig_lib_directory.handle.close(); - const target = cross_target.toTarget(); - const is_native_abi = cross_target.isNativeAbi(); + const target = target_query.toTarget(); + const is_native_abi = target_query.isNativeAbi(); const libc_dirs = Compilation.detectLibCIncludeDirs( arena, @@ -4812,15 +4812,15 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { } if (input_file) |libc_file| { - var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| { + var libc = LibCInstallation.parse(gpa, libc_file, target_query) catch |err| { fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); }; defer libc.deinit(gpa); } else { - if (!cross_target.isNative()) { + if (!target_query.isNative()) { fatal("unable to detect libc for non-native target", .{}); } - const target_info = try detectNativeTargetInfo(cross_target); + const target_info = try detectNativeTargetInfo(target_query); var libc = LibCInstallation.findNative(.{ .allocator = gpa, @@ -5113,8 +5113,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi gimmeMoreOfThoseSweetSweetFileDescriptors(); - const cross_target: std.zig.CrossTarget = .{}; - const target_info = try detectNativeTargetInfo(cross_target); + const target_query: std.Target.Query = .{}; + const target_info = try detectNativeTargetInfo(target_query); const exe_basename = try std.zig.binNameAlloc(arena, .{ .root_name = "build", @@ -5283,8 +5283,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi .global_cache_directory = global_cache_directory, .root_name = "build", .target = target_info.target, - .is_native_os = cross_target.isNativeOs(), - .is_native_abi = cross_target.isNativeAbi(), + .is_native_os = target_query.isNativeOs(), + .is_native_abi = target_query.isNativeAbi(), .dynamic_linker = target_info.dynamic_linker.get(), .output_mode = .Exe, .main_mod = &main_mod, @@ -6269,8 +6269,8 @@ test "fds" { gimmeMoreOfThoseSweetSweetFileDescriptors(); } -fn detectNativeTargetInfo(cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo { - return std.zig.system.NativeTargetInfo.detect(cross_target); +fn detectNativeTargetInfo(target_query: std.Target.Query) !std.zig.system.NativeTargetInfo { + return std.zig.system.NativeTargetInfo.detect(target_query); } const usage_ast_check = @@ -6672,8 +6672,8 @@ fn warnAboutForeignBinaries( target_info: *const std.zig.system.NativeTargetInfo, link_libc: bool, ) !void { - const host_cross_target: std.zig.CrossTarget = .{}; - const host_target_info = try detectNativeTargetInfo(host_cross_target); + const host_query: std.Target.Query = .{}; + const host_target_info = try detectNativeTargetInfo(host_query); switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) { .native => return, diff --git a/test/cbe.zig b/test/cbe.zig index b45a4e5f72..26724a1df0 100644 --- a/test/cbe.zig +++ b/test/cbe.zig @@ -5,7 +5,7 @@ const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; pub fn addCases(ctx: *Cases, b: *std.Build) !void { // These tests should work with all platforms, but we're using linux_x64 for // now for consistency. Will be expanded eventually. - const linux_x64: std.zig.CrossTarget = .{ + const linux_x64: std.Target.Query = .{ .cpu_arch = .x86_64, .os_tag = .linux, }; diff --git a/test/link/elf.zig b/test/link/elf.zig index 95bb929dc0..459244db29 100644 --- a/test/link/elf.zig +++ b/test/link/elf.zig @@ -3833,7 +3833,6 @@ const link = @import("link.zig"); const std = @import("std"); const Build = std.Build; -const CrossTarget = std.zig.CrossTarget; const Options = link.Options; const Step = Build.Step; const WriteFile = Step.WriteFile; diff --git a/test/link/glibc_compat/build.zig b/test/link/glibc_compat/build.zig index 85cbc48e54..6bafb07152 100644 --- a/test/link/glibc_compat/build.zig +++ b/test/link/glibc_compat/build.zig @@ -8,7 +8,7 @@ pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = t, .root_source_file = .{ .path = "main.c" }, - .target = b.resolveTargetQuery(std.zig.CrossTarget.parse( + .target = b.resolveTargetQuery(std.Target.Query.parse( .{ .arch_os_abi = t }, ) catch unreachable), }); diff --git a/test/link/link.zig b/test/link/link.zig index d5bbbe9f4b..4d31d2d49a 100644 --- a/test/link/link.zig +++ b/test/link/link.zig @@ -199,7 +199,6 @@ const std = @import("std"); const Build = std.Build; const Compile = Step.Compile; -const CrossTarget = std.zig.CrossTarget; const Run = Step.Run; const Step = Build.Step; const WriteFile = Step.WriteFile; diff --git a/test/link/macho.zig b/test/link/macho.zig index 230107c9b2..8a5016f9b7 100644 --- a/test/link/macho.zig +++ b/test/link/macho.zig @@ -95,7 +95,5 @@ const addExecutable = link.addExecutable; const expectLinkErrors = link.expectLinkErrors; const link = @import("link.zig"); const std = @import("std"); - -const CrossTarget = std.zig.CrossTarget; const Options = link.Options; const Step = std.Build.Step; diff --git a/test/llvm_targets.zig b/test/llvm_targets.zig index 6a3139dd9f..99eb161a58 100644 --- a/test/llvm_targets.zig +++ b/test/llvm_targets.zig @@ -1,7 +1,7 @@ const std = @import("std"); const Cases = @import("src/Cases.zig"); -const targets = [_]std.zig.CrossTarget{ +const targets = [_]std.Target.Query{ .{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none }, .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .none }, .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .simulator }, diff --git a/test/src/Cases.zig b/test/src/Cases.zig index 2aa92fc908..de7378d10a 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -188,7 +188,7 @@ pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Cas return ctx.addExe(name, target); } -pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.zig.CrossTarget, b: *std.Build) *Case { +pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.Target.Query, b: *std.Build) *Case { var adjusted_query = target_query; adjusted_query.ofmt = .c; ctx.cases.append(Case{ @@ -423,7 +423,7 @@ fn addFromDirInner( var manifest = try TestManifest.parse(ctx.arena, src); const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend); - const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.zig.CrossTarget); + const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.Target.Query); const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); @@ -1160,9 +1160,9 @@ const TestManifest = struct { } fn getDefaultParser(comptime T: type) ParseFn(T) { - if (T == std.zig.CrossTarget) return struct { + if (T == std.Target.Query) return struct { fn parse(str: []const u8) anyerror!T { - return std.zig.CrossTarget.parse(.{ .arch_os_abi = str }); + return std.Target.Query.parse(.{ .arch_os_abi = str }); } }.parse; @@ -1287,7 +1287,7 @@ pub fn main() !void { if (cases.items.len == 0) { const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend); - const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.zig.CrossTarget); + const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.Target.Query); const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend); const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool); const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool); @@ -1385,7 +1385,7 @@ pub fn main() !void { return runCases(&ctx, zig_exe_path); } -fn resolveTargetQuery(query: std.zig.CrossTarget) std.Build.ResolvedTarget { +fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget { const result = std.zig.system.NativeTargetInfo.detect(query) catch @panic("unable to resolve target query"); diff --git a/test/src/translate_c.zig b/test/src/translate_c.zig index 71288c11da..528e370918 100644 --- a/test/src/translate_c.zig +++ b/test/src/translate_c.zig @@ -5,7 +5,6 @@ const ArrayList = std.ArrayList; const fmt = std.fmt; const mem = std.mem; const fs = std.fs; -const CrossTarget = std.zig.CrossTarget; pub const TranslateCContext = struct { b: *std.Build, @@ -18,7 +17,7 @@ pub const TranslateCContext = struct { sources: ArrayList(SourceFile), expected_lines: ArrayList([]const u8), allow_warnings: bool, - target: CrossTarget = .{}, + target: std.Target.Query = .{}, const SourceFile = struct { filename: []const u8, @@ -74,7 +73,7 @@ pub const TranslateCContext = struct { pub fn addWithTarget( self: *TranslateCContext, name: []const u8, - target: CrossTarget, + target: std.Target.Query, source: []const u8, expected_lines: []const []const u8, ) void { diff --git a/test/standalone.zig b/test/standalone.zig index fdd3185cdf..0303c49c13 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -2,7 +2,7 @@ pub const SimpleCase = struct { src_path: []const u8, link_libc: bool = false, all_modes: bool = false, - target: std.zig.CrossTarget = .{}, + target: std.Target.Query = .{}, is_test: bool = false, is_exe: bool = true, /// Run only on this OS. diff --git a/test/standalone/windows_resources/build.zig b/test/standalone/windows_resources/build.zig index e927a03fc4..5111751571 100644 --- a/test/standalone/windows_resources/build.zig +++ b/test/standalone/windows_resources/build.zig @@ -4,17 +4,17 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Test it"); b.default_step = test_step; - const cross_target = b.resolveTargetQuery(.{ + const target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .windows, .abi = .gnu, }); add(b, b.host, .any, test_step); - add(b, cross_target, .any, test_step); + add(b, target, .any, test_step); add(b, b.host, .gnu, test_step); - add(b, cross_target, .gnu, test_step); + add(b, target, .gnu, test_step); } fn add( diff --git a/test/tests.zig b/test/tests.zig index a8f9b62810..29d181c605 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -21,7 +21,7 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig"); pub const StackTracesContext = @import("src/StackTrace.zig"); const TestTarget = struct { - target: std.zig.CrossTarget = .{}, + target: std.Target.Query = .{}, optimize_mode: std.builtin.OptimizeMode = .Debug, link_libc: ?bool = null, single_threaded: ?bool = null, @@ -145,7 +145,7 @@ const test_targets = blk: { //}, // https://github.com/ziglang/zig/issues/13623 //.{ - // .target = std.zig.CrossTarget.parse(.{ + // .target = std.Target.Query.parse(.{ // .arch_os_abi = "arm-linux-none", // .cpu_features = "generic+v8a", // }) catch unreachable, @@ -286,13 +286,13 @@ const test_targets = blk: { }, .{ - .target = std.zig.CrossTarget.parse(.{ + .target = std.Target.Query.parse(.{ .arch_os_abi = "arm-linux-none", .cpu_features = "generic+v8a", }) catch unreachable, }, .{ - .target = std.zig.CrossTarget.parse(.{ + .target = std.Target.Query.parse(.{ .arch_os_abi = "arm-linux-musleabihf", .cpu_features = "generic+v8a", }) catch unreachable, @@ -300,7 +300,7 @@ const test_targets = blk: { }, // https://github.com/ziglang/zig/issues/3287 //.{ - // .target = std.zig.CrossTarget.parse(.{ + // .target = std.Target.Query.parse(.{ // .arch_os_abi = "arm-linux-gnueabihf", // .cpu_features = "generic+v8a", // }) catch unreachable, @@ -494,7 +494,7 @@ const test_targets = blk: { }; const CAbiTarget = struct { - target: std.zig.CrossTarget = .{}, + target: std.Target.Query = .{}, use_llvm: ?bool = null, use_lld: ?bool = null, pic: ?bool = null, diff --git a/test/translate_c.zig b/test/translate_c.zig index 2b87da4067..a390810830 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -1,7 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); const tests = @import("tests.zig"); -const CrossTarget = std.zig.CrossTarget; // ******************************************************** // * * @@ -1846,7 +1845,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void; }); - cases.addWithTarget("Calling convention", CrossTarget.parse(.{ + cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ .arch_os_abi = "arm-linux-none", .cpu_features = "generic+v8_5a", }) catch unreachable, @@ -1857,7 +1856,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void; }); - cases.addWithTarget("Calling convention", CrossTarget.parse(.{ + cases.addWithTarget("Calling convention", std.Target.Query.parse(.{ .arch_os_abi = "aarch64-linux-none", .cpu_features = "generic+v8_5a", }) catch unreachable, -- cgit v1.2.3 From dbdb87502d6936597424fe86842c15978ba86918 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 4 Dec 2023 15:26:57 -0700 Subject: std.Target: add DynamicLinker --- CMakeLists.txt | 1 - lib/build_runner.zig | 4 +- lib/std/Build.zig | 15 +- lib/std/Build/Module.zig | 1 - lib/std/Build/Step/Compile.zig | 1 - lib/std/Build/Step/Options.zig | 4 +- lib/std/Build/Step/Run.zig | 6 +- lib/std/Target.zig | 72 +- lib/std/Target/Query.zig | 26 +- lib/std/zig/system.zig | 1118 +++++++++++++++++++++++++++++- lib/std/zig/system/NativePaths.zig | 4 +- lib/std/zig/system/NativeTargetInfo.zig | 1130 ------------------------------- src/Compilation.zig | 27 +- src/main.zig | 132 ++-- src/print_env.zig | 4 +- test/src/Cases.zig | 30 +- 16 files changed, 1280 insertions(+), 1295 deletions(-) delete mode 100644 lib/std/zig/system/NativeTargetInfo.zig (limited to 'lib/std/Target') diff --git a/CMakeLists.txt b/CMakeLists.txt index fa3a10dc4c..b3004d3254 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -516,7 +516,6 @@ set(ZIG_STAGE2_SOURCES "${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/system.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativePaths.zig" - "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativeTargetInfo.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/system/x86.zig" "${CMAKE_SOURCE_DIR}/lib/std/zig/tokenizer.zig" "${CMAKE_SOURCE_DIR}/src/Air.zig" diff --git a/lib/build_runner.zig b/lib/build_runner.zig index 8be6b61425..b485469a38 100644 --- a/lib/build_runner.zig +++ b/lib/build_runner.zig @@ -46,11 +46,9 @@ pub fn main() !void { return error.InvalidArgs; }; - const detected = try std.zig.system.NativeTargetInfo.detect(.{}); const host: std.Build.ResolvedTarget = .{ .query = .{}, - .target = detected.target, - .dynamic_linker = detected.dynamic_linker, + .target = try std.zig.system.resolveTargetQuery(.{}), }; const build_root_directory: std.Build.Cache.Directory = .{ diff --git a/lib/std/Build.zig b/lib/std/Build.zig index db7e3493da..cb5a503593 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -2129,14 +2129,6 @@ pub fn hex64(x: u64) [16]u8 { pub const ResolvedTarget = struct { query: Target.Query, target: Target, - dynamic_linker: Target.DynamicLinker, - - pub fn toNativeTargetInfo(self: ResolvedTarget) std.zig.system.NativeTargetInfo { - return .{ - .target = self.target, - .dynamic_linker = self.dynamic_linker, - }; - } }; /// Converts a target query into a fully resolved target that can be passed to @@ -2146,13 +2138,10 @@ pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget { // resolved via a WASI API or via the build protocol. _ = b; - const result = std.zig.system.NativeTargetInfo.detect(query) catch - @panic("unable to resolve target query"); - return .{ .query = query, - .target = result.target, - .dynamic_linker = result.dynamic_linker, + .target = std.zig.system.resolveTargetQuery(query) catch + @panic("unable to resolve target query"), }; } diff --git a/lib/std/Build/Module.zig b/lib/std/Build/Module.zig index f17f296e64..5482ca25ec 100644 --- a/lib/std/Build/Module.zig +++ b/lib/std/Build/Module.zig @@ -746,5 +746,4 @@ const Module = @This(); const std = @import("std"); const assert = std.debug.assert; const LazyPath = std.Build.LazyPath; -const NativeTargetInfo = std.zig.system.NativeTargetInfo; const Step = std.Build.Step; diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index cd59866176..b51304c910 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -9,7 +9,6 @@ const StringHashMap = std.StringHashMap; const Sha256 = std.crypto.hash.sha2.Sha256; const Allocator = mem.Allocator; const Step = std.Build.Step; -const NativeTargetInfo = std.zig.system.NativeTargetInfo; const LazyPath = std.Build.LazyPath; const PkgConfigPkg = std.Build.PkgConfigPkg; const PkgConfigError = std.Build.PkgConfigError; diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index 9ed936fe7e..938649d83f 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -294,11 +294,9 @@ test Options { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena.deinit(); - const detected = try std.zig.system.NativeTargetInfo.detect(.{}); const host: std.Build.ResolvedTarget = .{ .query = .{}, - .target = detected.target, - .dynamic_linker = detected.dynamic_linker, + .target = try std.zig.system.resolveTargetQuery(.{}), }; var cache: std.Build.Cache = .{ diff --git a/lib/std/Build/Step/Run.zig b/lib/std/Build/Step/Run.zig index 36b2eb82eb..ad68dce648 100644 --- a/lib/std/Build/Step/Run.zig +++ b/lib/std/Build/Step/Run.zig @@ -678,8 +678,8 @@ fn runCommand( const need_cross_glibc = exe.rootModuleTarget().isGnuLibC() and exe.is_linking_libc; - const other_target_info = exe.root_module.target.?.toNativeTargetInfo(); - switch (b.host.toNativeTargetInfo().getExternalExecutor(&other_target_info, .{ + const other_target = exe.root_module.target.?.target; + switch (std.zig.system.getExternalExecutor(b.host.target, &other_target, .{ .qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null, .link_libc = exe.is_linking_libc, })) { @@ -752,7 +752,7 @@ fn runCommand( .bad_dl => |foreign_dl| { if (allow_skip) return error.MakeSkipped; - const host_dl = b.host.dynamic_linker.get() orelse "(none)"; + const host_dl = b.host.target.dynamic_linker.get() orelse "(none)"; return step.fail( \\the host system is unable to execute binaries from the target diff --git a/lib/std/Target.zig b/lib/std/Target.zig index f5a2074264..6f30aa75b1 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1,7 +1,13 @@ +//! All the details about the machine that will be executing code. +//! Unlike `Query` which might leave some things as "default" or "host", this +//! data is fully resolved into a concrete set of OS versions, CPU features, +//! etc. + cpu: Cpu, os: Os, abi: Abi, ofmt: ObjectFormat, +dynamic_linker: DynamicLinker = DynamicLinker.none, pub const Query = @import("Target/Query.zig"); @@ -1529,13 +1535,19 @@ pub inline fn hasDynamicLinker(self: Target) bool { } pub const DynamicLinker = struct { - /// Contains the memory used to store the dynamic linker path. This field should - /// not be used directly. See `get` and `set`. This field exists so that this API requires no allocator. - buffer: [255]u8 = undefined, + /// Contains the memory used to store the dynamic linker path. This field + /// should not be used directly. See `get` and `set`. This field exists so + /// that this API requires no allocator. + buffer: [255]u8, /// Used to construct the dynamic linker path. This field should not be used /// directly. See `get` and `set`. - max_byte: ?u8 = null, + max_byte: ?u8, + + pub const none: DynamicLinker = .{ + .buffer = undefined, + .max_byte = null, + }; /// Asserts that the length is less than or equal to 255 bytes. pub fn init(dl_or_null: ?[]const u8) DynamicLinker { @@ -1561,8 +1573,12 @@ pub const DynamicLinker = struct { } }; -pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { - var result: DynamicLinker = .{}; +pub fn standardDynamicLinkerPath(target: Target) DynamicLinker { + return standardDynamicLinkerPath_cpu_os_abi(target.cpu, target.os.tag, target.abi); +} + +pub fn standardDynamicLinkerPath_cpu_os_abi(cpu: Cpu, os_tag: Os.Tag, abi: Abi) DynamicLinker { + var result = DynamicLinker.none; const S = struct { fn print(r: *DynamicLinker, comptime fmt: []const u8, args: anytype) DynamicLinker { r.max_byte = @as(u8, @intCast((std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1)); @@ -1577,32 +1593,32 @@ pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { const print = S.print; const copy = S.copy; - if (self.abi == .android) { - const suffix = if (self.ptrBitWidth() == 64) "64" else ""; + if (abi == .android) { + const suffix = if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else ""; return print(&result, "/system/bin/linker{s}", .{suffix}); } - if (self.abi.isMusl()) { - const is_arm = switch (self.cpu.arch) { + if (abi.isMusl()) { + const is_arm = switch (cpu.arch) { .arm, .armeb, .thumb, .thumbeb => true, else => false, }; - const arch_part = switch (self.cpu.arch) { + const arch_part = switch (cpu.arch) { .arm, .thumb => "arm", .armeb, .thumbeb => "armeb", else => |arch| @tagName(arch), }; - const arch_suffix = if (is_arm and self.abi.floatAbi() == .hard) "hf" else ""; + const arch_suffix = if (is_arm and abi.floatAbi() == .hard) "hf" else ""; return print(&result, "/lib/ld-musl-{s}{s}.so.1", .{ arch_part, arch_suffix }); } - switch (self.os.tag) { + switch (os_tag) { .freebsd => return copy(&result, "/libexec/ld-elf.so.1"), .netbsd => return copy(&result, "/libexec/ld.elf_so"), .openbsd => return copy(&result, "/usr/libexec/ld.so"), .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"), .solaris, .illumos => return copy(&result, "/lib/64/ld.so.1"), - .linux => switch (self.cpu.arch) { + .linux => switch (cpu.arch) { .x86, .sparc, .sparcel, @@ -1616,7 +1632,7 @@ pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { .armeb, .thumb, .thumbeb, - => return copy(&result, switch (self.abi.floatAbi()) { + => return copy(&result, switch (abi.floatAbi()) { .hard => "/lib/ld-linux-armhf.so.3", else => "/lib/ld-linux.so.3", }), @@ -1626,12 +1642,12 @@ pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { .mips64, .mips64el, => { - const lib_suffix = switch (self.abi) { + const lib_suffix = switch (abi) { .gnuabin32, .gnux32 => "32", .gnuabi64 => "64", else => "", }; - const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); + const is_nan_2008 = mips.featureSetHas(cpu.features, .nan2008); const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1"; return print(&result, "/lib{s}/{s}", .{ lib_suffix, loader }); }, @@ -1640,7 +1656,7 @@ pub fn standardDynamicLinkerPath(self: Target) DynamicLinker { .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"), .s390x => return copy(&result, "/lib64/ld64.so.1"), .sparc64 => return copy(&result, "/lib64/ld-linux.so.2"), - .x86_64 => return copy(&result, switch (self.abi) { + .x86_64 => return copy(&result, switch (abi) { .gnux32 => "/libx32/ld-linux-x32.so.2", else => "/lib64/ld-linux-x86-64.so.2", }), @@ -1862,17 +1878,17 @@ pub fn maxIntAlignment(target: Target) u16 { }; } -pub fn ptrBitWidth(target: Target) u16 { - switch (target.abi) { +pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 { + switch (abi) { .gnux32, .muslx32, .gnuabin32, .gnuilp32 => return 32, .gnuabi64 => return 64, else => {}, } - switch (target.cpu.arch) { + return switch (cpu.arch) { .avr, .msp430, .spu_2, - => return 16, + => 16, .arc, .arm, @@ -1908,7 +1924,7 @@ pub fn ptrBitWidth(target: Target) u16 { .loongarch32, .dxil, .xtensa, - => return 32, + => 32, .aarch64, .aarch64_be, @@ -1933,10 +1949,14 @@ pub fn ptrBitWidth(target: Target) u16 { .ve, .spirv64, .loongarch64, - => return 64, + => 64, - .sparc => return if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) 64 else 32, - } + .sparc => if (std.Target.sparc.featureSetHas(cpu.features, .v9)) 64 else 32, + }; +} + +pub fn ptrBitWidth(target: Target) u16 { + return ptrBitWidth_cpu_abi(target.cpu, target.abi); } pub fn stackAlignment(target: Target) u16 { diff --git a/lib/std/Target/Query.zig b/lib/std/Target/Query.zig index 617d141d39..bb5949d597 100644 --- a/lib/std/Target/Query.zig +++ b/lib/std/Target/Query.zig @@ -34,7 +34,7 @@ abi: ?Target.Abi = null, /// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path /// based on the `os_tag`. -dynamic_linker: DynamicLinker = DynamicLinker{}, +dynamic_linker: Target.DynamicLinker = Target.DynamicLinker.none, /// `null` means default for the cpu/arch/os combo. ofmt: ?Target.ObjectFormat = null, @@ -61,8 +61,6 @@ pub const OsVersion = union(enum) { pub const SemanticVersion = std.SemanticVersion; -pub const DynamicLinker = Target.DynamicLinker; - pub fn fromTarget(target: Target) Query { var result: Query = .{ .cpu_arch = target.cpu.arch, @@ -164,7 +162,7 @@ fn updateOsVersionRange(self: *Query, os: Target.Os) void { } } -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. pub fn toTarget(self: Query) Target { return .{ .cpu = self.getCpu(), @@ -232,7 +230,7 @@ pub fn parse(args: ParseOptions) !Query { const diags = args.diagnostics orelse &dummy_diags; var result: Query = .{ - .dynamic_linker = DynamicLinker.init(args.dynamic_linker), + .dynamic_linker = Target.DynamicLinker.init(args.dynamic_linker), }; var it = mem.splitScalar(u8, args.arch_os_abi, '-'); @@ -379,13 +377,13 @@ test parseVersion { try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4")); } -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. pub fn getCpu(self: Query) Target.Cpu { switch (self.cpu_model) { .native => { // This works when doing `zig build` because Zig generates a build executable using // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + // will need to be integrated with `std.zig.system.resolveTargetQuery`. return builtin.cpu; }, .baseline => { @@ -396,7 +394,7 @@ pub fn getCpu(self: Query) Target.Cpu { .determined_by_cpu_arch => if (self.cpu_arch == null) { // This works when doing `zig build` because Zig generates a build executable using // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + // will need to be integrated with `std.zig.system.resolveTargetQuery`. return builtin.cpu; } else { var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); @@ -426,11 +424,11 @@ pub fn getCpuFeatures(self: Query) Target.Cpu.Feature.Set { return self.getCpu().features; } -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. pub fn getOs(self: Query) Target.Os { // `builtin.os` works when doing `zig build` because Zig generates a build executable using // native OS version range. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + // will need to be integrated with `std.zig.system.resolveTargetQuery`. var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os; if (self.os_version_min) |min| switch (min) { @@ -463,7 +461,7 @@ pub fn getOsTag(self: Query) Target.Os.Tag { return self.os_tag orelse builtin.os.tag; } -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. pub fn getOsVersionMin(self: Query) OsVersion { if (self.os_version_min) |version_min| return version_min; var tmp: Query = undefined; @@ -471,7 +469,7 @@ pub fn getOsVersionMin(self: Query) OsVersion { return tmp.os_version_min.?; } -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. pub fn getOsVersionMax(self: Query) OsVersion { if (self.os_version_max) |version_max| return version_max; var tmp: Query = undefined; @@ -479,14 +477,14 @@ pub fn getOsVersionMax(self: Query) OsVersion { return tmp.os_version_max.?; } -/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`. +/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. pub fn getAbi(self: Query) Target.Abi { if (self.abi) |abi| return abi; if (self.os_tag == null) { // This works when doing `zig build` because Zig generates a build executable using // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`. + // will need to be integrated with `std.zig.system.resolveTargetQuery`. return builtin.abi; } diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 3ec92c8274..6920999ef0 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -1,13 +1,1127 @@ pub const NativePaths = @import("system/NativePaths.zig"); -pub const NativeTargetInfo = @import("system/NativeTargetInfo.zig"); pub const windows = @import("system/windows.zig"); pub const darwin = @import("system/darwin.zig"); pub const linux = @import("system/linux.zig"); +pub const Executor = union(enum) { + native, + rosetta, + qemu: []const u8, + wine: []const u8, + wasmtime: []const u8, + darling: []const u8, + bad_dl: []const u8, + bad_os_or_cpu, +}; + +pub const GetExternalExecutorOptions = struct { + allow_darling: bool = true, + allow_qemu: bool = true, + allow_rosetta: bool = true, + allow_wasmtime: bool = true, + allow_wine: bool = true, + qemu_fixes_dl: bool = false, + link_libc: bool = false, +}; + +/// Return whether or not the given host is capable of running executables of +/// the other target. +pub fn getExternalExecutor( + host: std.Target, + candidate: *const std.Target, + options: GetExternalExecutorOptions, +) Executor { + const os_match = host.os.tag == candidate.os.tag; + const cpu_ok = cpu_ok: { + if (host.cpu.arch == candidate.cpu.arch) + break :cpu_ok true; + + if (host.cpu.arch == .x86_64 and candidate.cpu.arch == .x86) + break :cpu_ok true; + + if (host.cpu.arch == .aarch64 and candidate.cpu.arch == .arm) + break :cpu_ok true; + + if (host.cpu.arch == .aarch64_be and candidate.cpu.arch == .armeb) + break :cpu_ok true; + + // TODO additionally detect incompatible CPU features. + // Note that in some cases the OS kernel will emulate missing CPU features + // when an illegal instruction is encountered. + + break :cpu_ok false; + }; + + var bad_result: Executor = .bad_os_or_cpu; + + if (os_match and cpu_ok) native: { + if (options.link_libc) { + if (candidate.dynamic_linker.get()) |candidate_dl| { + fs.cwd().access(candidate_dl, .{}) catch { + bad_result = .{ .bad_dl = candidate_dl }; + break :native; + }; + } + } + return .native; + } + + // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2 + // to emulate the foreign architecture. + if (options.allow_rosetta and os_match and + host.os.tag == .macos and host.cpu.arch == .aarch64) + { + switch (candidate.cpu.arch) { + .x86_64 => return .rosetta, + else => return bad_result, + } + } + + // If the OS matches, we can use QEMU to emulate a foreign architecture. + if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) { + return switch (candidate.cpu.arch) { + .aarch64 => Executor{ .qemu = "qemu-aarch64" }, + .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, + .arm => Executor{ .qemu = "qemu-arm" }, + .armeb => Executor{ .qemu = "qemu-armeb" }, + .hexagon => Executor{ .qemu = "qemu-hexagon" }, + .x86 => Executor{ .qemu = "qemu-i386" }, + .m68k => Executor{ .qemu = "qemu-m68k" }, + .mips => Executor{ .qemu = "qemu-mips" }, + .mipsel => Executor{ .qemu = "qemu-mipsel" }, + .mips64 => Executor{ .qemu = "qemu-mips64" }, + .mips64el => Executor{ .qemu = "qemu-mips64el" }, + .powerpc => Executor{ .qemu = "qemu-ppc" }, + .powerpc64 => Executor{ .qemu = "qemu-ppc64" }, + .powerpc64le => Executor{ .qemu = "qemu-ppc64le" }, + .riscv32 => Executor{ .qemu = "qemu-riscv32" }, + .riscv64 => Executor{ .qemu = "qemu-riscv64" }, + .s390x => Executor{ .qemu = "qemu-s390x" }, + .sparc => Executor{ .qemu = "qemu-sparc" }, + .sparc64 => Executor{ .qemu = "qemu-sparc64" }, + .x86_64 => Executor{ .qemu = "qemu-x86_64" }, + else => return bad_result, + }; + } + + switch (candidate.os.tag) { + .windows => { + if (options.allow_wine) { + // x86_64 wine does not support emulating aarch64-windows and + // vice versa. + if (candidate.cpu.arch != builtin.cpu.arch) { + return bad_result; + } + switch (candidate.ptrBitWidth()) { + 32 => return Executor{ .wine = "wine" }, + 64 => return Executor{ .wine = "wine64" }, + else => return bad_result, + } + } + return bad_result; + }, + .wasi => { + if (options.allow_wasmtime) { + switch (candidate.ptrBitWidth()) { + 32 => return Executor{ .wasmtime = "wasmtime" }, + else => return bad_result, + } + } + return bad_result; + }, + .macos => { + if (options.allow_darling) { + // This check can be loosened once darling adds a QEMU-based emulation + // layer for non-host architectures: + // https://github.com/darlinghq/darling/issues/863 + if (candidate.cpu.arch != builtin.cpu.arch) { + return bad_result; + } + return Executor{ .darling = "darling" }; + } + return bad_result; + }, + else => return bad_result, + } +} + +pub const DetectError = error{ + FileSystem, + SystemResources, + SymLinkLoop, + ProcessFdQuotaExceeded, + SystemFdQuotaExceeded, + DeviceBusy, + OSVersionDetectionFail, + Unexpected, +}; + +/// Given a `Target.Query`, which specifies in detail which parts of the +/// target should be detected natively, which should be standard or default, +/// and which are provided explicitly, this function resolves the native +/// components by detecting the native system, and then resolves +/// standard/default parts relative to that. +pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { + var os = query.getOsTag().defaultVersionRange(query.getCpuArch()); + if (query.os_tag == null) { + switch (builtin.target.os.tag) { + .linux => { + const uts = std.os.uname(); + const release = mem.sliceTo(&uts.release, 0); + // The release field sometimes has a weird format, + // `Version.parse` will attempt to find some meaningful interpretation. + if (std.SemanticVersion.parse(release)) |ver| { + os.version_range.linux.range.min = ver; + os.version_range.linux.range.max = ver; + } else |err| switch (err) { + error.Overflow => {}, + error.InvalidVersion => {}, + } + }, + .solaris, .illumos => { + const uts = std.os.uname(); + const release = mem.sliceTo(&uts.release, 0); + if (std.SemanticVersion.parse(release)) |ver| { + os.version_range.semver.min = ver; + os.version_range.semver.max = ver; + } else |err| switch (err) { + error.Overflow => {}, + error.InvalidVersion => {}, + } + }, + .windows => { + const detected_version = windows.detectRuntimeVersion(); + os.version_range.windows.min = detected_version; + os.version_range.windows.max = detected_version; + }, + .macos => try darwin.macos.detect(&os), + .freebsd, .netbsd, .dragonfly => { + const key = switch (builtin.target.os.tag) { + .freebsd => "kern.osreldate", + .netbsd, .dragonfly => "kern.osrevision", + else => unreachable, + }; + var value: u32 = undefined; + var len: usize = @sizeOf(@TypeOf(value)); + + std.os.sysctlbynameZ(key, &value, &len, null, 0) catch |err| switch (err) { + error.NameTooLong => unreachable, // constant, known good value + error.PermissionDenied => unreachable, // only when setting values, + error.SystemResources => unreachable, // memory already on the stack + error.UnknownName => unreachable, // constant, known good value + error.Unexpected => return error.OSVersionDetectionFail, + }; + + switch (builtin.target.os.tag) { + .freebsd => { + // https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html + // Major * 100,000 has been convention since FreeBSD 2.2 (1997) + // Minor * 1(0),000 summed has been convention since FreeBSD 2.2 (1997) + // e.g. 492101 = 4.11-STABLE = 4.(9+2) + const major = value / 100_000; + const minor1 = value % 100_000 / 10_000; // usually 0 since 5.1 + const minor2 = value % 10_000 / 1_000; // 0 before 5.1, minor version since + const patch = value % 1_000; + os.version_range.semver.min = .{ .major = major, .minor = minor1 + minor2, .patch = patch }; + os.version_range.semver.max = os.version_range.semver.min; + }, + .netbsd => { + // #define __NetBSD_Version__ MMmmrrpp00 + // + // M = major version + // m = minor version; a minor number of 99 indicates current. + // r = 0 (*) + // p = patchlevel + const major = value / 100_000_000; + const minor = value % 100_000_000 / 1_000_000; + const patch = value % 10_000 / 100; + os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch }; + os.version_range.semver.max = os.version_range.semver.min; + }, + .dragonfly => { + // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/cb2cde83771754aeef9bb3251ee48959138dec87/Makefile.inc1#L15-L17 + // flat base10 format: Mmmmpp + // M = major + // m = minor; odd-numbers indicate current dev branch + // p = patch + const major = value / 100_000; + const minor = value % 100_000 / 100; + const patch = value % 100; + os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch }; + os.version_range.semver.max = os.version_range.semver.min; + }, + else => unreachable, + } + }, + .openbsd => { + const mib: [2]c_int = [_]c_int{ + std.os.CTL.KERN, + std.os.KERN.OSRELEASE, + }; + var buf: [64]u8 = undefined; + // consider that sysctl result includes null-termination + // reserve 1 byte to ensure we never overflow when appending ".0" + var len: usize = buf.len - 1; + + std.os.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) { + error.NameTooLong => unreachable, // constant, known good value + error.PermissionDenied => unreachable, // only when setting values, + error.SystemResources => unreachable, // memory already on the stack + error.UnknownName => unreachable, // constant, known good value + error.Unexpected => return error.OSVersionDetectionFail, + }; + + // append ".0" to satisfy semver + buf[len - 1] = '.'; + buf[len] = '0'; + len += 1; + + if (std.SemanticVersion.parse(buf[0..len])) |ver| { + os.version_range.semver.min = ver; + os.version_range.semver.max = ver; + } else |_| { + return error.OSVersionDetectionFail; + } + }, + else => { + // Unimplemented, fall back to default version range. + }, + } + } + + if (query.os_version_min) |min| switch (min) { + .none => {}, + .semver => |semver| switch (query.getOsTag()) { + .linux => os.version_range.linux.range.min = semver, + else => os.version_range.semver.min = semver, + }, + .windows => |win_ver| os.version_range.windows.min = win_ver, + }; + + if (query.os_version_max) |max| switch (max) { + .none => {}, + .semver => |semver| switch (query.getOsTag()) { + .linux => os.version_range.linux.range.max = semver, + else => os.version_range.semver.max = semver, + }, + .windows => |win_ver| os.version_range.windows.max = win_ver, + }; + + if (query.glibc_version) |glibc| { + assert(query.isGnuLibC()); + os.version_range.linux.glibc = glibc; + } + + // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the + // native CPU architecture as being different than the current target), we use this: + const cpu_arch = query.getCpuArch(); + + const cpu = switch (query.cpu_model) { + .native => detectNativeCpuAndFeatures(cpu_arch, os, query), + .baseline => Target.Cpu.baseline(cpu_arch), + .determined_by_cpu_arch => if (query.cpu_arch == null) + detectNativeCpuAndFeatures(cpu_arch, os, query) + else + Target.Cpu.baseline(cpu_arch), + .explicit => |model| model.toCpu(cpu_arch), + } orelse backup_cpu_detection: { + break :backup_cpu_detection Target.Cpu.baseline(cpu_arch); + }; + var result = try detectAbiAndDynamicLinker(cpu, os, query); + // For x86, we need to populate some CPU feature flags depending on architecture + // and mode: + // * 16bit_mode => if the abi is code16 + // * 32bit_mode => if the arch is x86 + // However, the "mode" flags can be used as overrides, so if the user explicitly + // sets one of them, that takes precedence. + switch (cpu_arch) { + .x86 => { + if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{ + .@"16bit_mode", .@"32bit_mode", + })) { + switch (result.abi) { + .code16 => result.cpu.features.addFeature( + @intFromEnum(Target.x86.Feature.@"16bit_mode"), + ), + else => result.cpu.features.addFeature( + @intFromEnum(Target.x86.Feature.@"32bit_mode"), + ), + } + } + }, + .arm, .armeb => { + // XXX What do we do if the target has the noarm feature? + // What do we do if the user specifies +thumb_mode? + }, + .thumb, .thumbeb => { + result.cpu.features.addFeature( + @intFromEnum(Target.arm.Feature.thumb_mode), + ); + }, + else => {}, + } + query.updateCpuFeatures(&result.cpu.features); + return result; +} + +fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu { + // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`, + // although it is a runtime value, is guaranteed to be one of the architectures in the set + // of the respective switch prong. + switch (builtin.cpu.arch) { + .x86_64, .x86 => { + return @import("system/x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query); + }, + else => {}, + } + + switch (builtin.os.tag) { + .linux => return linux.detectNativeCpuAndFeatures(), + .macos => return darwin.macos.detectNativeCpuAndFeatures(), + .windows => return windows.detectNativeCpuAndFeatures(), + else => {}, + } + + // This architecture does not have CPU model & feature detection yet. + // See https://github.com/ziglang/zig/issues/4591 + return null; +} + +pub const AbiAndDynamicLinkerFromFileError = error{ + FileSystem, + SystemResources, + SymLinkLoop, + ProcessFdQuotaExceeded, + SystemFdQuotaExceeded, + UnableToReadElfFile, + InvalidElfClass, + InvalidElfVersion, + InvalidElfEndian, + InvalidElfFile, + InvalidElfMagic, + Unexpected, + UnexpectedEndOfFile, + NameTooLong, +}; + +pub fn abiAndDynamicLinkerFromFile( + file: fs.File, + cpu: Target.Cpu, + os: Target.Os, + ld_info_list: []const LdInfo, + query: Target.Query, +) AbiAndDynamicLinkerFromFileError!Target { + var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; + _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len); + const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf)); + const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf)); + if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic; + const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) { + elf.ELFDATA2LSB => .little, + elf.ELFDATA2MSB => .big, + else => return error.InvalidElfEndian, + }; + const need_bswap = elf_endian != native_endian; + if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion; + + const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) { + elf.ELFCLASS32 => false, + elf.ELFCLASS64 => true, + else => return error.InvalidElfClass, + }; + var phoff = elfInt(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff); + const phentsize = elfInt(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize); + const phnum = elfInt(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum); + + var result: Target = .{ + .cpu = cpu, + .os = os, + .abi = query.abi orelse Target.Abi.default(cpu.arch, os), + .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), + .dynamic_linker = query.dynamic_linker, + }; + var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC + const look_for_ld = query.dynamic_linker.get() == null; + + var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined; + if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile; + + var ph_i: u16 = 0; + while (ph_i < phnum) { + // Reserve some bytes so that we can deref the 64-bit struct fields + // even when the ELF file is 32-bits. + const ph_reserve: usize = @sizeOf(elf.Elf64_Phdr) - @sizeOf(elf.Elf32_Phdr); + const ph_read_byte_len = try preadMin(file, ph_buf[0 .. ph_buf.len - ph_reserve], phoff, phentsize); + var ph_buf_i: usize = 0; + while (ph_buf_i < ph_read_byte_len and ph_i < phnum) : ({ + ph_i += 1; + phoff += phentsize; + ph_buf_i += phentsize; + }) { + const ph32: *elf.Elf32_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i])); + const ph64: *elf.Elf64_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i])); + const p_type = elfInt(is_64, need_bswap, ph32.p_type, ph64.p_type); + switch (p_type) { + elf.PT_INTERP => if (look_for_ld) { + const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); + const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); + if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; + const filesz = @as(usize, @intCast(p_filesz)); + _ = try preadMin(file, result.dynamic_linker.buffer[0..filesz], p_offset, filesz); + // PT_INTERP includes a null byte in filesz. + const len = filesz - 1; + // dynamic_linker.max_byte is "max", not "len". + // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. + result.dynamic_linker.max_byte = @as(u8, @intCast(len - 1)); + + // Use it to determine ABI. + const full_ld_path = result.dynamic_linker.buffer[0..len]; + for (ld_info_list) |ld_info| { + const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); + if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { + result.abi = ld_info.abi; + break; + } + } + }, + // We only need this for detecting glibc version. + elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.isGnuLibC() and + query.glibc_version == null) + { + var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); + const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); + const dyn_size: usize = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn); + const dyn_num = p_filesz / dyn_size; + var dyn_buf: [16 * @sizeOf(elf.Elf64_Dyn)]u8 align(@alignOf(elf.Elf64_Dyn)) = undefined; + var dyn_i: usize = 0; + dyn: while (dyn_i < dyn_num) { + // Reserve some bytes so that we can deref the 64-bit struct fields + // even when the ELF file is 32-bits. + const dyn_reserve: usize = @sizeOf(elf.Elf64_Dyn) - @sizeOf(elf.Elf32_Dyn); + const dyn_read_byte_len = try preadMin( + file, + dyn_buf[0 .. dyn_buf.len - dyn_reserve], + dyn_off, + dyn_size, + ); + var dyn_buf_i: usize = 0; + while (dyn_buf_i < dyn_read_byte_len and dyn_i < dyn_num) : ({ + dyn_i += 1; + dyn_off += dyn_size; + dyn_buf_i += dyn_size; + }) { + const dyn32: *elf.Elf32_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i])); + const dyn64: *elf.Elf64_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i])); + const tag = elfInt(is_64, need_bswap, dyn32.d_tag, dyn64.d_tag); + const val = elfInt(is_64, need_bswap, dyn32.d_val, dyn64.d_val); + if (tag == elf.DT_RUNPATH) { + rpath_offset = val; + break :dyn; + } + } + } + }, + else => continue, + } + } + } + + if (builtin.target.os.tag == .linux and result.isGnuLibC() and + query.glibc_version == null) + { + const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); + + var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff); + const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize); + const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx); + + var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined; + if (sh_buf.len < shentsize) return error.InvalidElfFile; + + _ = try preadMin(file, &sh_buf, str_section_off, shentsize); + const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf)); + const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf)); + const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset); + const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size); + var strtab_buf: [4096:0]u8 = undefined; + const shstrtab_len = @min(shstrtab_size, strtab_buf.len); + const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len); + const shstrtab = strtab_buf[0..shstrtab_read_len]; + + const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum); + var sh_i: u16 = 0; + const dynstr: ?struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) { + // Reserve some bytes so that we can deref the 64-bit struct fields + // even when the ELF file is 32-bits. + const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr); + const sh_read_byte_len = try preadMin( + file, + sh_buf[0 .. sh_buf.len - sh_reserve], + shoff, + shentsize, + ); + var sh_buf_i: usize = 0; + while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({ + sh_i += 1; + shoff += shentsize; + sh_buf_i += shentsize; + }) { + const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); + const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); + const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); + const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0); + if (mem.eql(u8, sh_name, ".dynstr")) { + break :find_dyn_str .{ + .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), + .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size), + }; + } + } + } else null; + + if (dynstr) |ds| { + if (rpath_offset) |rpoff| { + if (rpoff > ds.size) return error.InvalidElfFile; + const rpoff_file = ds.offset + rpoff; + const rp_max_size = ds.size - rpoff; + + const strtab_len = @min(rp_max_size, strtab_buf.len); + const strtab_read_len = try preadMin(file, &strtab_buf, rpoff_file, strtab_len); + const strtab = strtab_buf[0..strtab_read_len]; + + const rpath_list = mem.sliceTo(strtab, 0); + var it = mem.tokenizeScalar(u8, rpath_list, ':'); + while (it.next()) |rpath| { + if (glibcVerFromRPath(rpath)) |ver| { + result.os.version_range.linux.glibc = ver; + return result; + } else |err| switch (err) { + error.GLibCNotFound => continue, + else => |e| return e, + } + } + } + } + + if (result.dynamic_linker.get()) |dl_path| glibc_ver: { + // There is no DT_RUNPATH so we try to find libc.so.6 inside the same + // directory as the dynamic linker. + if (fs.path.dirname(dl_path)) |rpath| { + if (glibcVerFromRPath(rpath)) |ver| { + result.os.version_range.linux.glibc = ver; + return result; + } else |err| switch (err) { + error.GLibCNotFound => {}, + else => |e| return e, + } + } + + // So far, no luck. Next we try to see if the information is + // present in the symlink data for the dynamic linker path. + var link_buf: [std.os.PATH_MAX]u8 = undefined; + const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) { + error.NameTooLong => unreachable, + error.InvalidUtf8 => unreachable, // Windows only + error.BadPathName => unreachable, // Windows only + error.UnsupportedReparsePointType => unreachable, // Windows only + error.NetworkNotFound => unreachable, // Windows only + + error.AccessDenied, + error.FileNotFound, + error.NotLink, + error.NotDir, + => break :glibc_ver, + + error.SystemResources, + error.FileSystem, + error.SymLinkLoop, + error.Unexpected, + => |e| return e, + }; + result.os.version_range.linux.glibc = glibcVerFromLinkName( + fs.path.basename(link_name), + "ld-", + ) catch |err| switch (err) { + error.UnrecognizedGnuLibCFileName, + error.InvalidGnuLibCVersion, + => break :glibc_ver, + }; + return result; + } + + // Nothing worked so far. Finally we fall back to hard-coded search paths. + // Some distros such as Debian keep their libc.so.6 in `/lib/$triple/`. + var path_buf: [std.os.PATH_MAX]u8 = undefined; + var index: usize = 0; + const prefix = "/lib/"; + const cpu_arch = @tagName(result.cpu.arch); + const os_tag = @tagName(result.os.tag); + const abi = @tagName(result.abi); + @memcpy(path_buf[index..][0..prefix.len], prefix); + index += prefix.len; + @memcpy(path_buf[index..][0..cpu_arch.len], cpu_arch); + index += cpu_arch.len; + path_buf[index] = '-'; + index += 1; + @memcpy(path_buf[index..][0..os_tag.len], os_tag); + index += os_tag.len; + path_buf[index] = '-'; + index += 1; + @memcpy(path_buf[index..][0..abi.len], abi); + index += abi.len; + const rpath = path_buf[0..index]; + if (glibcVerFromRPath(rpath)) |ver| { + result.os.version_range.linux.glibc = ver; + return result; + } else |err| switch (err) { + error.GLibCNotFound => {}, + else => |e| return e, + } + } + + return result; +} + +fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ UnrecognizedGnuLibCFileName, InvalidGnuLibCVersion }!std.SemanticVersion { + // example: "libc-2.3.4.so" + // example: "libc-2.27.so" + // example: "ld-2.33.so" + const suffix = ".so"; + if (!mem.startsWith(u8, link_name, prefix) or !mem.endsWith(u8, link_name, suffix)) { + return error.UnrecognizedGnuLibCFileName; + } + // chop off "libc-" and ".so" + const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len]; + return Target.Query.parseVersion(link_name_chopped) catch |err| switch (err) { + error.Overflow => return error.InvalidGnuLibCVersion, + error.InvalidVersion => return error.InvalidGnuLibCVersion, + }; +} + +test glibcVerFromLinkName { + try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("ld-2.37.so", "this-prefix-does-not-exist")); + try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("libc-2.37.so-is-not-end", "libc-")); + + try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.so", "ld-")); + try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.so", "ld-")); + try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.0.so", "ld-")); + try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 1 }, try glibcVerFromLinkName("ld-2.37.1.so", "ld-")); + try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.37.4.5.so", "ld-")); +} + +fn glibcVerFromRPath(rpath: []const u8) !std.SemanticVersion { + var dir = fs.cwd().openDir(rpath, .{}) catch |err| switch (err) { + error.NameTooLong => unreachable, + error.InvalidUtf8 => unreachable, + error.BadPathName => unreachable, + error.DeviceBusy => unreachable, + error.NetworkNotFound => unreachable, // Windows-only + + error.FileNotFound, + error.NotDir, + error.InvalidHandle, + error.AccessDenied, + error.NoDevice, + => return error.GLibCNotFound, + + error.ProcessFdQuotaExceeded, + error.SystemFdQuotaExceeded, + error.SystemResources, + error.SymLinkLoop, + error.Unexpected, + => |e| return e, + }; + defer dir.close(); + + // Now we have a candidate for the path to libc shared object. In + // the past, we used readlink() here because the link name would + // reveal the glibc version. However, in more recent GNU/Linux + // installations, there is no symlink. Thus we instead use a more + // robust check of opening the libc shared object and looking at the + // .dynstr section, and finding the max version number of symbols + // that start with "GLIBC_2.". + const glibc_so_basename = "libc.so.6"; + var f = dir.openFile(glibc_so_basename, .{}) catch |err| switch (err) { + error.NameTooLong => unreachable, + error.InvalidUtf8 => unreachable, // Windows only + error.BadPathName => unreachable, // Windows only + error.PipeBusy => unreachable, // Windows-only + error.SharingViolation => unreachable, // Windows-only + error.NetworkNotFound => unreachable, // Windows-only + error.FileLocksNotSupported => unreachable, // No lock requested. + error.NoSpaceLeft => unreachable, // read-only + error.PathAlreadyExists => unreachable, // read-only + error.DeviceBusy => unreachable, // read-only + error.FileBusy => unreachable, // read-only + error.InvalidHandle => unreachable, // should not be in the error set + error.WouldBlock => unreachable, // not using O_NONBLOCK + error.NoDevice => unreachable, // not asking for a special device + + error.AccessDenied, + error.FileNotFound, + error.NotDir, + error.IsDir, + => return error.GLibCNotFound, + + error.FileTooBig => return error.Unexpected, + + error.ProcessFdQuotaExceeded, + error.SystemFdQuotaExceeded, + error.SystemResources, + error.SymLinkLoop, + error.Unexpected, + => |e| return e, + }; + defer f.close(); + + return glibcVerFromSoFile(f) catch |err| switch (err) { + error.InvalidElfMagic, + error.InvalidElfEndian, + error.InvalidElfClass, + error.InvalidElfFile, + error.InvalidElfVersion, + error.InvalidGnuLibCVersion, + error.UnexpectedEndOfFile, + => return error.GLibCNotFound, + + error.SystemResources, + error.UnableToReadElfFile, + error.Unexpected, + error.FileSystem, + => |e| return e, + }; +} + +fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion { + var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; + _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len); + const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf)); + const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf)); + if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic; + const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) { + elf.ELFDATA2LSB => .little, + elf.ELFDATA2MSB => .big, + else => return error.InvalidElfEndian, + }; + const need_bswap = elf_endian != native_endian; + if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion; + + const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) { + elf.ELFCLASS32 => false, + elf.ELFCLASS64 => true, + else => return error.InvalidElfClass, + }; + const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); + var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff); + const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize); + const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx); + var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined; + if (sh_buf.len < shentsize) return error.InvalidElfFile; + + _ = try preadMin(file, &sh_buf, str_section_off, shentsize); + const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf)); + const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf)); + const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset); + const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size); + var strtab_buf: [4096:0]u8 = undefined; + const shstrtab_len = @min(shstrtab_size, strtab_buf.len); + const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len); + const shstrtab = strtab_buf[0..shstrtab_read_len]; + const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum); + var sh_i: u16 = 0; + const dynstr: struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) { + // Reserve some bytes so that we can deref the 64-bit struct fields + // even when the ELF file is 32-bits. + const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr); + const sh_read_byte_len = try preadMin( + file, + sh_buf[0 .. sh_buf.len - sh_reserve], + shoff, + shentsize, + ); + var sh_buf_i: usize = 0; + while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({ + sh_i += 1; + shoff += shentsize; + sh_buf_i += shentsize; + }) { + const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); + const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); + const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); + const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0); + if (mem.eql(u8, sh_name, ".dynstr")) { + break :find_dyn_str .{ + .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), + .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size), + }; + } + } + } else return error.InvalidGnuLibCVersion; + + // Here we loop over all the strings in the dynstr string table, assuming that any + // strings that start with "GLIBC_2." indicate the existence of such a glibc version, + // and furthermore, that the system-installed glibc is at minimum that version. + + // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system. + // Here I use double this value plus some headroom. This makes it only need + // a single read syscall here. + var buf: [80000]u8 = undefined; + if (buf.len < dynstr.size) return error.InvalidGnuLibCVersion; + + const dynstr_size: usize = @intCast(dynstr.size); + const dynstr_bytes = buf[0..dynstr_size]; + _ = try preadMin(file, dynstr_bytes, dynstr.offset, dynstr_bytes.len); + var it = mem.splitScalar(u8, dynstr_bytes, 0); + var max_ver: std.SemanticVersion = .{ .major = 2, .minor = 2, .patch = 5 }; + while (it.next()) |s| { + if (mem.startsWith(u8, s, "GLIBC_2.")) { + const chopped = s["GLIBC_".len..]; + const ver = Target.Query.parseVersion(chopped) catch |err| switch (err) { + error.Overflow => return error.InvalidGnuLibCVersion, + error.InvalidVersion => return error.InvalidGnuLibCVersion, + }; + switch (ver.order(max_ver)) { + .gt => max_ver = ver, + .lt, .eq => continue, + } + } + } + return max_ver; +} + +/// In the past, this function attempted to use the executable's own binary if it was dynamically +/// linked to answer both the C ABI question and the dynamic linker question. However, this +/// could be problematic on a system that uses a RUNPATH for the compiler binary, locking +/// it to an older glibc version, while system binaries such as /usr/bin/env use a newer glibc +/// version. The problem is that libc.so.6 glibc version will match that of the system while +/// the dynamic linker will match that of the compiler binary. Executables with these versions +/// mismatching will fail to run. +/// +/// Therefore, this function works the same regardless of whether the compiler binary is +/// dynamically or statically linked. It inspects `/usr/bin/env` as an ELF file to find the +/// answer to these questions, or if there is a shebang line, then it chases the referenced +/// file recursively. If that does not provide the answer, then the function falls back to +/// defaults. +fn detectAbiAndDynamicLinker( + cpu: Target.Cpu, + os: Target.Os, + query: Target.Query, +) DetectError!Target { + const native_target_has_ld = comptime builtin.target.hasDynamicLinker(); + const is_linux = builtin.target.os.tag == .linux; + const is_solarish = builtin.target.os.tag.isSolarish(); + const have_all_info = query.dynamic_linker.get() != null and + query.abi != null and (!is_linux or query.abi.?.isGnu()); + const os_is_non_native = query.os_tag != null; + // The Solaris/illumos environment is always the same. + if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) { + return defaultAbiAndDynamicLinker(cpu, os, query); + } + if (query.abi) |abi| { + if (abi.isMusl()) { + // musl implies static linking. + return defaultAbiAndDynamicLinker(cpu, os, query); + } + } + // The current target's ABI cannot be relied on for this. For example, we may build the zig + // compiler for target riscv64-linux-musl and provide a tarball for users to download. + // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined + // and supported by Zig. But that means that we must detect the system ABI here rather than + // relying on `builtin.target`. + const all_abis = comptime blk: { + assert(@intFromEnum(Target.Abi.none) == 0); + const fields = std.meta.fields(Target.Abi)[1..]; + var array: [fields.len]Target.Abi = undefined; + for (fields, 0..) |field, i| { + array[i] = @field(Target.Abi, field.name); + } + break :blk array; + }; + var ld_info_list_buffer: [all_abis.len]LdInfo = undefined; + var ld_info_list_len: usize = 0; + const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch); + + for (all_abis) |abi| { + // This may be a nonsensical parameter. We detect this with + // error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`. + const target: Target = .{ + .cpu = cpu, + .os = os, + .abi = abi, + .ofmt = ofmt, + }; + const ld = target.standardDynamicLinkerPath(); + if (ld.get() == null) continue; + + ld_info_list_buffer[ld_info_list_len] = .{ + .ld = ld, + .abi = abi, + }; + ld_info_list_len += 1; + } + const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; + + // Best case scenario: the executable is dynamically linked, and we can iterate + // over our own shared objects and find a dynamic linker. + const elf_file = blk: { + // This block looks for a shebang line in /usr/bin/env, + // if it finds one, then instead of using /usr/bin/env as the ELF file to examine, it uses the file it references instead, + // doing the same logic recursively in case it finds another shebang line. + + // Since /usr/bin/env is hard-coded into the shebang line of many portable scripts, it's a + // reasonably reliable path to start with. + var file_name: []const u8 = "/usr/bin/env"; + // #! (2) + 255 (max length of shebang line since Linux 5.1) + \n (1) + var buffer: [258]u8 = undefined; + while (true) { + const file = fs.openFileAbsolute(file_name, .{}) catch |err| switch (err) { + error.NoSpaceLeft => unreachable, + error.NameTooLong => unreachable, + error.PathAlreadyExists => unreachable, + error.SharingViolation => unreachable, + error.InvalidUtf8 => unreachable, + error.BadPathName => unreachable, + error.PipeBusy => unreachable, + error.FileLocksNotSupported => unreachable, + error.WouldBlock => unreachable, + error.FileBusy => unreachable, // opened without write permissions + + error.IsDir, + error.NotDir, + error.InvalidHandle, + error.AccessDenied, + error.NoDevice, + error.FileNotFound, + error.NetworkNotFound, + error.FileTooBig, + error.Unexpected, + => |e| { + std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)}); + return defaultAbiAndDynamicLinker(cpu, os, query); + }, + + else => |e| return e, + }; + errdefer file.close(); + + const len = preadMin(file, &buffer, 0, buffer.len) catch |err| switch (err) { + error.UnexpectedEndOfFile, + error.UnableToReadElfFile, + => break :blk file, + + else => |e| return e, + }; + const newline = mem.indexOfScalar(u8, buffer[0..len], '\n') orelse break :blk file; + const line = buffer[0..newline]; + if (!mem.startsWith(u8, line, "#!")) break :blk file; + var it = mem.tokenizeScalar(u8, line[2..], ' '); + file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, query); + file.close(); + } + }; + defer elf_file.close(); + + // If Zig is statically linked, such as via distributed binary static builds, the above + // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file. + // TODO: inline this function and combine the buffer we already read above to find + // the possible shebang line with the buffer we use for the ELF header. + return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, query) catch |err| switch (err) { + error.FileSystem, + error.SystemResources, + error.SymLinkLoop, + error.ProcessFdQuotaExceeded, + error.SystemFdQuotaExceeded, + => |e| return e, + + error.UnableToReadElfFile, + error.InvalidElfClass, + error.InvalidElfVersion, + error.InvalidElfEndian, + error.InvalidElfFile, + error.InvalidElfMagic, + error.Unexpected, + error.UnexpectedEndOfFile, + error.NameTooLong, + // Finally, we fall back on the standard path. + => |e| { + std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)}); + return defaultAbiAndDynamicLinker(cpu, os, query); + }, + }; +} + +fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) !Target { + const abi = query.abi orelse Target.Abi.default(cpu.arch, os); + return .{ + .cpu = cpu, + .os = os, + .abi = abi, + .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), + .dynamic_linker = if (query.dynamic_linker.get() == null) + Target.standardDynamicLinkerPath_cpu_os_abi(cpu, os.tag, abi) + else + query.dynamic_linker, + }; +} + +const LdInfo = struct { + ld: Target.DynamicLinker, + abi: Target.Abi, +}; + +fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize { + var i: usize = 0; + while (i < min_read_len) { + const len = file.pread(buf[i..], offset + i) catch |err| switch (err) { + error.OperationAborted => unreachable, // Windows-only + error.WouldBlock => unreachable, // Did not request blocking mode + error.NotOpenForReading => unreachable, + error.SystemResources => return error.SystemResources, + error.IsDir => return error.UnableToReadElfFile, + error.BrokenPipe => return error.UnableToReadElfFile, + error.Unseekable => return error.UnableToReadElfFile, + error.ConnectionResetByPeer => return error.UnableToReadElfFile, + error.ConnectionTimedOut => return error.UnableToReadElfFile, + error.SocketNotConnected => return error.UnableToReadElfFile, + error.NetNameDeleted => return error.UnableToReadElfFile, + error.Unexpected => return error.Unexpected, + error.InputOutput => return error.FileSystem, + error.AccessDenied => return error.Unexpected, + }; + if (len == 0) return error.UnexpectedEndOfFile; + i += len; + } + return i; +} + +fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) { + if (is_64) { + if (need_bswap) { + return @byteSwap(int_64); + } else { + return int_64; + } + } else { + if (need_bswap) { + return @byteSwap(int_32); + } else { + return int_32; + } + } +} + +const builtin = @import("builtin"); +const std = @import("../std.zig"); +const mem = std.mem; +const elf = std.elf; +const fs = std.fs; +const assert = std.debug.assert; +const Target = std.Target; +const native_endian = builtin.cpu.arch.endian(); + test { _ = NativePaths; - _ = NativeTargetInfo; _ = darwin; _ = linux; diff --git a/lib/std/zig/system/NativePaths.zig b/lib/std/zig/system/NativePaths.zig index 833d698d42..715c172c39 100644 --- a/lib/std/zig/system/NativePaths.zig +++ b/lib/std/zig/system/NativePaths.zig @@ -5,7 +5,6 @@ const process = std.process; const mem = std.mem; const NativePaths = @This(); -const NativeTargetInfo = std.zig.system.NativeTargetInfo; arena: Allocator, include_dirs: std.ArrayListUnmanaged([]const u8) = .{}, @@ -14,8 +13,7 @@ framework_dirs: std.ArrayListUnmanaged([]const u8) = .{}, rpaths: std.ArrayListUnmanaged([]const u8) = .{}, warnings: std.ArrayListUnmanaged([]const u8) = .{}, -pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths { - const native_target = native_info.target; +pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths { var self: NativePaths = .{ .arena = arena }; var is_nix = false; if (process.getEnvVarOwned(arena, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| { diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig deleted file mode 100644 index c4562cf7d5..0000000000 --- a/lib/std/zig/system/NativeTargetInfo.zig +++ /dev/null @@ -1,1130 +0,0 @@ -const std = @import("../../std.zig"); -const builtin = @import("builtin"); -const mem = std.mem; -const assert = std.debug.assert; -const fs = std.fs; -const elf = std.elf; -const native_endian = builtin.cpu.arch.endian(); - -const NativeTargetInfo = @This(); -const Target = std.Target; -const Allocator = std.mem.Allocator; -const windows = std.zig.system.windows; -const darwin = std.zig.system.darwin; -const linux = std.zig.system.linux; - -target: Target, -dynamic_linker: DynamicLinker = DynamicLinker{}, - -pub const DynamicLinker = Target.DynamicLinker; - -pub const DetectError = error{ - FileSystem, - SystemResources, - SymLinkLoop, - ProcessFdQuotaExceeded, - SystemFdQuotaExceeded, - DeviceBusy, - OSVersionDetectionFail, - Unexpected, -}; - -/// Given a `Target.Query`, which specifies in detail which parts of the -/// target should be detected natively, which should be standard or default, -/// and which are provided explicitly, this function resolves the native -/// components by detecting the native system, and then resolves -/// standard/default parts relative to that. -pub fn detect(query: Target.Query) DetectError!NativeTargetInfo { - var os = query.getOsTag().defaultVersionRange(query.getCpuArch()); - if (query.os_tag == null) { - switch (builtin.target.os.tag) { - .linux => { - const uts = std.os.uname(); - const release = mem.sliceTo(&uts.release, 0); - // The release field sometimes has a weird format, - // `Version.parse` will attempt to find some meaningful interpretation. - if (std.SemanticVersion.parse(release)) |ver| { - os.version_range.linux.range.min = ver; - os.version_range.linux.range.max = ver; - } else |err| switch (err) { - error.Overflow => {}, - error.InvalidVersion => {}, - } - }, - .solaris, .illumos => { - const uts = std.os.uname(); - const release = mem.sliceTo(&uts.release, 0); - if (std.SemanticVersion.parse(release)) |ver| { - os.version_range.semver.min = ver; - os.version_range.semver.max = ver; - } else |err| switch (err) { - error.Overflow => {}, - error.InvalidVersion => {}, - } - }, - .windows => { - const detected_version = windows.detectRuntimeVersion(); - os.version_range.windows.min = detected_version; - os.version_range.windows.max = detected_version; - }, - .macos => try darwin.macos.detect(&os), - .freebsd, .netbsd, .dragonfly => { - const key = switch (builtin.target.os.tag) { - .freebsd => "kern.osreldate", - .netbsd, .dragonfly => "kern.osrevision", - else => unreachable, - }; - var value: u32 = undefined; - var len: usize = @sizeOf(@TypeOf(value)); - - std.os.sysctlbynameZ(key, &value, &len, null, 0) catch |err| switch (err) { - error.NameTooLong => unreachable, // constant, known good value - error.PermissionDenied => unreachable, // only when setting values, - error.SystemResources => unreachable, // memory already on the stack - error.UnknownName => unreachable, // constant, known good value - error.Unexpected => return error.OSVersionDetectionFail, - }; - - switch (builtin.target.os.tag) { - .freebsd => { - // https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html - // Major * 100,000 has been convention since FreeBSD 2.2 (1997) - // Minor * 1(0),000 summed has been convention since FreeBSD 2.2 (1997) - // e.g. 492101 = 4.11-STABLE = 4.(9+2) - const major = value / 100_000; - const minor1 = value % 100_000 / 10_000; // usually 0 since 5.1 - const minor2 = value % 10_000 / 1_000; // 0 before 5.1, minor version since - const patch = value % 1_000; - os.version_range.semver.min = .{ .major = major, .minor = minor1 + minor2, .patch = patch }; - os.version_range.semver.max = os.version_range.semver.min; - }, - .netbsd => { - // #define __NetBSD_Version__ MMmmrrpp00 - // - // M = major version - // m = minor version; a minor number of 99 indicates current. - // r = 0 (*) - // p = patchlevel - const major = value / 100_000_000; - const minor = value % 100_000_000 / 1_000_000; - const patch = value % 10_000 / 100; - os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch }; - os.version_range.semver.max = os.version_range.semver.min; - }, - .dragonfly => { - // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/cb2cde83771754aeef9bb3251ee48959138dec87/Makefile.inc1#L15-L17 - // flat base10 format: Mmmmpp - // M = major - // m = minor; odd-numbers indicate current dev branch - // p = patch - const major = value / 100_000; - const minor = value % 100_000 / 100; - const patch = value % 100; - os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch }; - os.version_range.semver.max = os.version_range.semver.min; - }, - else => unreachable, - } - }, - .openbsd => { - const mib: [2]c_int = [_]c_int{ - std.os.CTL.KERN, - std.os.KERN.OSRELEASE, - }; - var buf: [64]u8 = undefined; - // consider that sysctl result includes null-termination - // reserve 1 byte to ensure we never overflow when appending ".0" - var len: usize = buf.len - 1; - - std.os.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) { - error.NameTooLong => unreachable, // constant, known good value - error.PermissionDenied => unreachable, // only when setting values, - error.SystemResources => unreachable, // memory already on the stack - error.UnknownName => unreachable, // constant, known good value - error.Unexpected => return error.OSVersionDetectionFail, - }; - - // append ".0" to satisfy semver - buf[len - 1] = '.'; - buf[len] = '0'; - len += 1; - - if (std.SemanticVersion.parse(buf[0..len])) |ver| { - os.version_range.semver.min = ver; - os.version_range.semver.max = ver; - } else |_| { - return error.OSVersionDetectionFail; - } - }, - else => { - // Unimplemented, fall back to default version range. - }, - } - } - - if (query.os_version_min) |min| switch (min) { - .none => {}, - .semver => |semver| switch (query.getOsTag()) { - .linux => os.version_range.linux.range.min = semver, - else => os.version_range.semver.min = semver, - }, - .windows => |win_ver| os.version_range.windows.min = win_ver, - }; - - if (query.os_version_max) |max| switch (max) { - .none => {}, - .semver => |semver| switch (query.getOsTag()) { - .linux => os.version_range.linux.range.max = semver, - else => os.version_range.semver.max = semver, - }, - .windows => |win_ver| os.version_range.windows.max = win_ver, - }; - - if (query.glibc_version) |glibc| { - assert(query.isGnuLibC()); - os.version_range.linux.glibc = glibc; - } - - // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the - // native CPU architecture as being different than the current target), we use this: - const cpu_arch = query.getCpuArch(); - - const cpu = switch (query.cpu_model) { - .native => detectNativeCpuAndFeatures(cpu_arch, os, query), - .baseline => Target.Cpu.baseline(cpu_arch), - .determined_by_cpu_arch => if (query.cpu_arch == null) - detectNativeCpuAndFeatures(cpu_arch, os, query) - else - Target.Cpu.baseline(cpu_arch), - .explicit => |model| model.toCpu(cpu_arch), - } orelse backup_cpu_detection: { - break :backup_cpu_detection Target.Cpu.baseline(cpu_arch); - }; - var result = try detectAbiAndDynamicLinker(cpu, os, query); - // For x86, we need to populate some CPU feature flags depending on architecture - // and mode: - // * 16bit_mode => if the abi is code16 - // * 32bit_mode => if the arch is x86 - // However, the "mode" flags can be used as overrides, so if the user explicitly - // sets one of them, that takes precedence. - switch (cpu_arch) { - .x86 => { - if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{ - .@"16bit_mode", .@"32bit_mode", - })) { - switch (result.target.abi) { - .code16 => result.target.cpu.features.addFeature( - @intFromEnum(Target.x86.Feature.@"16bit_mode"), - ), - else => result.target.cpu.features.addFeature( - @intFromEnum(Target.x86.Feature.@"32bit_mode"), - ), - } - } - }, - .arm, .armeb => { - // XXX What do we do if the target has the noarm feature? - // What do we do if the user specifies +thumb_mode? - }, - .thumb, .thumbeb => { - result.target.cpu.features.addFeature( - @intFromEnum(Target.arm.Feature.thumb_mode), - ); - }, - else => {}, - } - query.updateCpuFeatures(&result.target.cpu.features); - return result; -} - -/// In the past, this function attempted to use the executable's own binary if it was dynamically -/// linked to answer both the C ABI question and the dynamic linker question. However, this -/// could be problematic on a system that uses a RUNPATH for the compiler binary, locking -/// it to an older glibc version, while system binaries such as /usr/bin/env use a newer glibc -/// version. The problem is that libc.so.6 glibc version will match that of the system while -/// the dynamic linker will match that of the compiler binary. Executables with these versions -/// mismatching will fail to run. -/// -/// Therefore, this function works the same regardless of whether the compiler binary is -/// dynamically or statically linked. It inspects `/usr/bin/env` as an ELF file to find the -/// answer to these questions, or if there is a shebang line, then it chases the referenced -/// file recursively. If that does not provide the answer, then the function falls back to -/// defaults. -fn detectAbiAndDynamicLinker( - cpu: Target.Cpu, - os: Target.Os, - query: Target.Query, -) DetectError!NativeTargetInfo { - const native_target_has_ld = comptime builtin.target.hasDynamicLinker(); - const is_linux = builtin.target.os.tag == .linux; - const is_solarish = builtin.target.os.tag.isSolarish(); - const have_all_info = query.dynamic_linker.get() != null and - query.abi != null and (!is_linux or query.abi.?.isGnu()); - const os_is_non_native = query.os_tag != null; - // The Solaris/illumos environment is always the same. - if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) { - return defaultAbiAndDynamicLinker(cpu, os, query); - } - if (query.abi) |abi| { - if (abi.isMusl()) { - // musl implies static linking. - return defaultAbiAndDynamicLinker(cpu, os, query); - } - } - // The current target's ABI cannot be relied on for this. For example, we may build the zig - // compiler for target riscv64-linux-musl and provide a tarball for users to download. - // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined - // and supported by Zig. But that means that we must detect the system ABI here rather than - // relying on `builtin.target`. - const all_abis = comptime blk: { - assert(@intFromEnum(Target.Abi.none) == 0); - const fields = std.meta.fields(Target.Abi)[1..]; - var array: [fields.len]Target.Abi = undefined; - for (fields, 0..) |field, i| { - array[i] = @field(Target.Abi, field.name); - } - break :blk array; - }; - var ld_info_list_buffer: [all_abis.len]LdInfo = undefined; - var ld_info_list_len: usize = 0; - const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch); - - for (all_abis) |abi| { - // This may be a nonsensical parameter. We detect this with - // error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`. - const target: Target = .{ - .cpu = cpu, - .os = os, - .abi = abi, - .ofmt = ofmt, - }; - const ld = target.standardDynamicLinkerPath(); - if (ld.get() == null) continue; - - ld_info_list_buffer[ld_info_list_len] = .{ - .ld = ld, - .abi = abi, - }; - ld_info_list_len += 1; - } - const ld_info_list = ld_info_list_buffer[0..ld_info_list_len]; - - // Best case scenario: the executable is dynamically linked, and we can iterate - // over our own shared objects and find a dynamic linker. - const elf_file = blk: { - // This block looks for a shebang line in /usr/bin/env, - // if it finds one, then instead of using /usr/bin/env as the ELF file to examine, it uses the file it references instead, - // doing the same logic recursively in case it finds another shebang line. - - // Since /usr/bin/env is hard-coded into the shebang line of many portable scripts, it's a - // reasonably reliable path to start with. - var file_name: []const u8 = "/usr/bin/env"; - // #! (2) + 255 (max length of shebang line since Linux 5.1) + \n (1) - var buffer: [258]u8 = undefined; - while (true) { - const file = fs.openFileAbsolute(file_name, .{}) catch |err| switch (err) { - error.NoSpaceLeft => unreachable, - error.NameTooLong => unreachable, - error.PathAlreadyExists => unreachable, - error.SharingViolation => unreachable, - error.InvalidUtf8 => unreachable, - error.BadPathName => unreachable, - error.PipeBusy => unreachable, - error.FileLocksNotSupported => unreachable, - error.WouldBlock => unreachable, - error.FileBusy => unreachable, // opened without write permissions - - error.IsDir, - error.NotDir, - error.InvalidHandle, - error.AccessDenied, - error.NoDevice, - error.FileNotFound, - error.NetworkNotFound, - error.FileTooBig, - error.Unexpected, - => |e| { - std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)}); - return defaultAbiAndDynamicLinker(cpu, os, query); - }, - - else => |e| return e, - }; - errdefer file.close(); - - const len = preadMin(file, &buffer, 0, buffer.len) catch |err| switch (err) { - error.UnexpectedEndOfFile, - error.UnableToReadElfFile, - => break :blk file, - - else => |e| return e, - }; - const newline = mem.indexOfScalar(u8, buffer[0..len], '\n') orelse break :blk file; - const line = buffer[0..newline]; - if (!mem.startsWith(u8, line, "#!")) break :blk file; - var it = mem.tokenizeScalar(u8, line[2..], ' '); - file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, query); - file.close(); - } - }; - defer elf_file.close(); - - // If Zig is statically linked, such as via distributed binary static builds, the above - // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file. - // TODO: inline this function and combine the buffer we already read above to find - // the possible shebang line with the buffer we use for the ELF header. - return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, query) catch |err| switch (err) { - error.FileSystem, - error.SystemResources, - error.SymLinkLoop, - error.ProcessFdQuotaExceeded, - error.SystemFdQuotaExceeded, - => |e| return e, - - error.UnableToReadElfFile, - error.InvalidElfClass, - error.InvalidElfVersion, - error.InvalidElfEndian, - error.InvalidElfFile, - error.InvalidElfMagic, - error.Unexpected, - error.UnexpectedEndOfFile, - error.NameTooLong, - // Finally, we fall back on the standard path. - => |e| { - std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)}); - return defaultAbiAndDynamicLinker(cpu, os, query); - }, - }; -} - -fn glibcVerFromRPath(rpath: []const u8) !std.SemanticVersion { - var dir = fs.cwd().openDir(rpath, .{}) catch |err| switch (err) { - error.NameTooLong => unreachable, - error.InvalidUtf8 => unreachable, - error.BadPathName => unreachable, - error.DeviceBusy => unreachable, - error.NetworkNotFound => unreachable, // Windows-only - - error.FileNotFound, - error.NotDir, - error.InvalidHandle, - error.AccessDenied, - error.NoDevice, - => return error.GLibCNotFound, - - error.ProcessFdQuotaExceeded, - error.SystemFdQuotaExceeded, - error.SystemResources, - error.SymLinkLoop, - error.Unexpected, - => |e| return e, - }; - defer dir.close(); - - // Now we have a candidate for the path to libc shared object. In - // the past, we used readlink() here because the link name would - // reveal the glibc version. However, in more recent GNU/Linux - // installations, there is no symlink. Thus we instead use a more - // robust check of opening the libc shared object and looking at the - // .dynstr section, and finding the max version number of symbols - // that start with "GLIBC_2.". - const glibc_so_basename = "libc.so.6"; - var f = dir.openFile(glibc_so_basename, .{}) catch |err| switch (err) { - error.NameTooLong => unreachable, - error.InvalidUtf8 => unreachable, // Windows only - error.BadPathName => unreachable, // Windows only - error.PipeBusy => unreachable, // Windows-only - error.SharingViolation => unreachable, // Windows-only - error.NetworkNotFound => unreachable, // Windows-only - error.FileLocksNotSupported => unreachable, // No lock requested. - error.NoSpaceLeft => unreachable, // read-only - error.PathAlreadyExists => unreachable, // read-only - error.DeviceBusy => unreachable, // read-only - error.FileBusy => unreachable, // read-only - error.InvalidHandle => unreachable, // should not be in the error set - error.WouldBlock => unreachable, // not using O_NONBLOCK - error.NoDevice => unreachable, // not asking for a special device - - error.AccessDenied, - error.FileNotFound, - error.NotDir, - error.IsDir, - => return error.GLibCNotFound, - - error.FileTooBig => return error.Unexpected, - - error.ProcessFdQuotaExceeded, - error.SystemFdQuotaExceeded, - error.SystemResources, - error.SymLinkLoop, - error.Unexpected, - => |e| return e, - }; - defer f.close(); - - return glibcVerFromSoFile(f) catch |err| switch (err) { - error.InvalidElfMagic, - error.InvalidElfEndian, - error.InvalidElfClass, - error.InvalidElfFile, - error.InvalidElfVersion, - error.InvalidGnuLibCVersion, - error.UnexpectedEndOfFile, - => return error.GLibCNotFound, - - error.SystemResources, - error.UnableToReadElfFile, - error.Unexpected, - error.FileSystem, - => |e| return e, - }; -} - -fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion { - var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; - _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len); - const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf)); - const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf)); - if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic; - const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) { - elf.ELFDATA2LSB => .little, - elf.ELFDATA2MSB => .big, - else => return error.InvalidElfEndian, - }; - const need_bswap = elf_endian != native_endian; - if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion; - - const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) { - elf.ELFCLASS32 => false, - elf.ELFCLASS64 => true, - else => return error.InvalidElfClass, - }; - const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); - var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff); - const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize); - const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx); - var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined; - if (sh_buf.len < shentsize) return error.InvalidElfFile; - - _ = try preadMin(file, &sh_buf, str_section_off, shentsize); - const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf)); - const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf)); - const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset); - const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size); - var strtab_buf: [4096:0]u8 = undefined; - const shstrtab_len = @min(shstrtab_size, strtab_buf.len); - const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len); - const shstrtab = strtab_buf[0..shstrtab_read_len]; - const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum); - var sh_i: u16 = 0; - const dynstr: struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) { - // Reserve some bytes so that we can deref the 64-bit struct fields - // even when the ELF file is 32-bits. - const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr); - const sh_read_byte_len = try preadMin( - file, - sh_buf[0 .. sh_buf.len - sh_reserve], - shoff, - shentsize, - ); - var sh_buf_i: usize = 0; - while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({ - sh_i += 1; - shoff += shentsize; - sh_buf_i += shentsize; - }) { - const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); - const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); - const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); - const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0); - if (mem.eql(u8, sh_name, ".dynstr")) { - break :find_dyn_str .{ - .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), - .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size), - }; - } - } - } else return error.InvalidGnuLibCVersion; - - // Here we loop over all the strings in the dynstr string table, assuming that any - // strings that start with "GLIBC_2." indicate the existence of such a glibc version, - // and furthermore, that the system-installed glibc is at minimum that version. - - // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system. - // Here I use double this value plus some headroom. This makes it only need - // a single read syscall here. - var buf: [80000]u8 = undefined; - if (buf.len < dynstr.size) return error.InvalidGnuLibCVersion; - - const dynstr_size: usize = @intCast(dynstr.size); - const dynstr_bytes = buf[0..dynstr_size]; - _ = try preadMin(file, dynstr_bytes, dynstr.offset, dynstr_bytes.len); - var it = mem.splitScalar(u8, dynstr_bytes, 0); - var max_ver: std.SemanticVersion = .{ .major = 2, .minor = 2, .patch = 5 }; - while (it.next()) |s| { - if (mem.startsWith(u8, s, "GLIBC_2.")) { - const chopped = s["GLIBC_".len..]; - const ver = Target.Query.parseVersion(chopped) catch |err| switch (err) { - error.Overflow => return error.InvalidGnuLibCVersion, - error.InvalidVersion => return error.InvalidGnuLibCVersion, - }; - switch (ver.order(max_ver)) { - .gt => max_ver = ver, - .lt, .eq => continue, - } - } - } - return max_ver; -} - -fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ UnrecognizedGnuLibCFileName, InvalidGnuLibCVersion }!std.SemanticVersion { - // example: "libc-2.3.4.so" - // example: "libc-2.27.so" - // example: "ld-2.33.so" - const suffix = ".so"; - if (!mem.startsWith(u8, link_name, prefix) or !mem.endsWith(u8, link_name, suffix)) { - return error.UnrecognizedGnuLibCFileName; - } - // chop off "libc-" and ".so" - const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len]; - return Target.Query.parseVersion(link_name_chopped) catch |err| switch (err) { - error.Overflow => return error.InvalidGnuLibCVersion, - error.InvalidVersion => return error.InvalidGnuLibCVersion, - }; -} - -test glibcVerFromLinkName { - try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("ld-2.37.so", "this-prefix-does-not-exist")); - try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("libc-2.37.so-is-not-end", "libc-")); - - try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.so", "ld-")); - try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.so", "ld-")); - try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.0.so", "ld-")); - try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 1 }, try glibcVerFromLinkName("ld-2.37.1.so", "ld-")); - try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.37.4.5.so", "ld-")); -} - -pub const AbiAndDynamicLinkerFromFileError = error{ - FileSystem, - SystemResources, - SymLinkLoop, - ProcessFdQuotaExceeded, - SystemFdQuotaExceeded, - UnableToReadElfFile, - InvalidElfClass, - InvalidElfVersion, - InvalidElfEndian, - InvalidElfFile, - InvalidElfMagic, - Unexpected, - UnexpectedEndOfFile, - NameTooLong, -}; - -pub fn abiAndDynamicLinkerFromFile( - file: fs.File, - cpu: Target.Cpu, - os: Target.Os, - ld_info_list: []const LdInfo, - query: Target.Query, -) AbiAndDynamicLinkerFromFileError!NativeTargetInfo { - var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined; - _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len); - const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf)); - const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf)); - if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic; - const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) { - elf.ELFDATA2LSB => .little, - elf.ELFDATA2MSB => .big, - else => return error.InvalidElfEndian, - }; - const need_bswap = elf_endian != native_endian; - if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion; - - const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) { - elf.ELFCLASS32 => false, - elf.ELFCLASS64 => true, - else => return error.InvalidElfClass, - }; - var phoff = elfInt(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff); - const phentsize = elfInt(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize); - const phnum = elfInt(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum); - - var result: NativeTargetInfo = .{ - .target = .{ - .cpu = cpu, - .os = os, - .abi = query.abi orelse Target.Abi.default(cpu.arch, os), - .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), - }, - .dynamic_linker = query.dynamic_linker, - }; - var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC - const look_for_ld = query.dynamic_linker.get() == null; - - var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined; - if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile; - - var ph_i: u16 = 0; - while (ph_i < phnum) { - // Reserve some bytes so that we can deref the 64-bit struct fields - // even when the ELF file is 32-bits. - const ph_reserve: usize = @sizeOf(elf.Elf64_Phdr) - @sizeOf(elf.Elf32_Phdr); - const ph_read_byte_len = try preadMin(file, ph_buf[0 .. ph_buf.len - ph_reserve], phoff, phentsize); - var ph_buf_i: usize = 0; - while (ph_buf_i < ph_read_byte_len and ph_i < phnum) : ({ - ph_i += 1; - phoff += phentsize; - ph_buf_i += phentsize; - }) { - const ph32: *elf.Elf32_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i])); - const ph64: *elf.Elf64_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i])); - const p_type = elfInt(is_64, need_bswap, ph32.p_type, ph64.p_type); - switch (p_type) { - elf.PT_INTERP => if (look_for_ld) { - const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); - const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); - if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong; - const filesz = @as(usize, @intCast(p_filesz)); - _ = try preadMin(file, result.dynamic_linker.buffer[0..filesz], p_offset, filesz); - // PT_INTERP includes a null byte in filesz. - const len = filesz - 1; - // dynamic_linker.max_byte is "max", not "len". - // We know it will fit in u8 because we check against dynamic_linker.buffer.len above. - result.dynamic_linker.max_byte = @as(u8, @intCast(len - 1)); - - // Use it to determine ABI. - const full_ld_path = result.dynamic_linker.buffer[0..len]; - for (ld_info_list) |ld_info| { - const standard_ld_basename = fs.path.basename(ld_info.ld.get().?); - if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) { - result.target.abi = ld_info.abi; - break; - } - } - }, - // We only need this for detecting glibc version. - elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and - query.glibc_version == null) - { - var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset); - const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz); - const dyn_size: usize = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn); - const dyn_num = p_filesz / dyn_size; - var dyn_buf: [16 * @sizeOf(elf.Elf64_Dyn)]u8 align(@alignOf(elf.Elf64_Dyn)) = undefined; - var dyn_i: usize = 0; - dyn: while (dyn_i < dyn_num) { - // Reserve some bytes so that we can deref the 64-bit struct fields - // even when the ELF file is 32-bits. - const dyn_reserve: usize = @sizeOf(elf.Elf64_Dyn) - @sizeOf(elf.Elf32_Dyn); - const dyn_read_byte_len = try preadMin( - file, - dyn_buf[0 .. dyn_buf.len - dyn_reserve], - dyn_off, - dyn_size, - ); - var dyn_buf_i: usize = 0; - while (dyn_buf_i < dyn_read_byte_len and dyn_i < dyn_num) : ({ - dyn_i += 1; - dyn_off += dyn_size; - dyn_buf_i += dyn_size; - }) { - const dyn32: *elf.Elf32_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i])); - const dyn64: *elf.Elf64_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i])); - const tag = elfInt(is_64, need_bswap, dyn32.d_tag, dyn64.d_tag); - const val = elfInt(is_64, need_bswap, dyn32.d_val, dyn64.d_val); - if (tag == elf.DT_RUNPATH) { - rpath_offset = val; - break :dyn; - } - } - } - }, - else => continue, - } - } - } - - if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and - query.glibc_version == null) - { - const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx); - - var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff); - const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize); - const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx); - - var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined; - if (sh_buf.len < shentsize) return error.InvalidElfFile; - - _ = try preadMin(file, &sh_buf, str_section_off, shentsize); - const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf)); - const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf)); - const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset); - const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size); - var strtab_buf: [4096:0]u8 = undefined; - const shstrtab_len = @min(shstrtab_size, strtab_buf.len); - const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len); - const shstrtab = strtab_buf[0..shstrtab_read_len]; - - const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum); - var sh_i: u16 = 0; - const dynstr: ?struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) { - // Reserve some bytes so that we can deref the 64-bit struct fields - // even when the ELF file is 32-bits. - const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr); - const sh_read_byte_len = try preadMin( - file, - sh_buf[0 .. sh_buf.len - sh_reserve], - shoff, - shentsize, - ); - var sh_buf_i: usize = 0; - while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({ - sh_i += 1; - shoff += shentsize; - sh_buf_i += shentsize; - }) { - const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); - const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i])); - const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name); - const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0); - if (mem.eql(u8, sh_name, ".dynstr")) { - break :find_dyn_str .{ - .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset), - .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size), - }; - } - } - } else null; - - if (dynstr) |ds| { - if (rpath_offset) |rpoff| { - if (rpoff > ds.size) return error.InvalidElfFile; - const rpoff_file = ds.offset + rpoff; - const rp_max_size = ds.size - rpoff; - - const strtab_len = @min(rp_max_size, strtab_buf.len); - const strtab_read_len = try preadMin(file, &strtab_buf, rpoff_file, strtab_len); - const strtab = strtab_buf[0..strtab_read_len]; - - const rpath_list = mem.sliceTo(strtab, 0); - var it = mem.tokenizeScalar(u8, rpath_list, ':'); - while (it.next()) |rpath| { - if (glibcVerFromRPath(rpath)) |ver| { - result.target.os.version_range.linux.glibc = ver; - return result; - } else |err| switch (err) { - error.GLibCNotFound => continue, - else => |e| return e, - } - } - } - } - - if (result.dynamic_linker.get()) |dl_path| glibc_ver: { - // There is no DT_RUNPATH so we try to find libc.so.6 inside the same - // directory as the dynamic linker. - if (fs.path.dirname(dl_path)) |rpath| { - if (glibcVerFromRPath(rpath)) |ver| { - result.target.os.version_range.linux.glibc = ver; - return result; - } else |err| switch (err) { - error.GLibCNotFound => {}, - else => |e| return e, - } - } - - // So far, no luck. Next we try to see if the information is - // present in the symlink data for the dynamic linker path. - var link_buf: [std.os.PATH_MAX]u8 = undefined; - const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) { - error.NameTooLong => unreachable, - error.InvalidUtf8 => unreachable, // Windows only - error.BadPathName => unreachable, // Windows only - error.UnsupportedReparsePointType => unreachable, // Windows only - error.NetworkNotFound => unreachable, // Windows only - - error.AccessDenied, - error.FileNotFound, - error.NotLink, - error.NotDir, - => break :glibc_ver, - - error.SystemResources, - error.FileSystem, - error.SymLinkLoop, - error.Unexpected, - => |e| return e, - }; - result.target.os.version_range.linux.glibc = glibcVerFromLinkName( - fs.path.basename(link_name), - "ld-", - ) catch |err| switch (err) { - error.UnrecognizedGnuLibCFileName, - error.InvalidGnuLibCVersion, - => break :glibc_ver, - }; - return result; - } - - // Nothing worked so far. Finally we fall back to hard-coded search paths. - // Some distros such as Debian keep their libc.so.6 in `/lib/$triple/`. - var path_buf: [std.os.PATH_MAX]u8 = undefined; - var index: usize = 0; - const prefix = "/lib/"; - const cpu_arch = @tagName(result.target.cpu.arch); - const os_tag = @tagName(result.target.os.tag); - const abi = @tagName(result.target.abi); - @memcpy(path_buf[index..][0..prefix.len], prefix); - index += prefix.len; - @memcpy(path_buf[index..][0..cpu_arch.len], cpu_arch); - index += cpu_arch.len; - path_buf[index] = '-'; - index += 1; - @memcpy(path_buf[index..][0..os_tag.len], os_tag); - index += os_tag.len; - path_buf[index] = '-'; - index += 1; - @memcpy(path_buf[index..][0..abi.len], abi); - index += abi.len; - const rpath = path_buf[0..index]; - if (glibcVerFromRPath(rpath)) |ver| { - result.target.os.version_range.linux.glibc = ver; - return result; - } else |err| switch (err) { - error.GLibCNotFound => {}, - else => |e| return e, - } - } - - return result; -} - -fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize { - var i: usize = 0; - while (i < min_read_len) { - const len = file.pread(buf[i..], offset + i) catch |err| switch (err) { - error.OperationAborted => unreachable, // Windows-only - error.WouldBlock => unreachable, // Did not request blocking mode - error.NotOpenForReading => unreachable, - error.SystemResources => return error.SystemResources, - error.IsDir => return error.UnableToReadElfFile, - error.BrokenPipe => return error.UnableToReadElfFile, - error.Unseekable => return error.UnableToReadElfFile, - error.ConnectionResetByPeer => return error.UnableToReadElfFile, - error.ConnectionTimedOut => return error.UnableToReadElfFile, - error.SocketNotConnected => return error.UnableToReadElfFile, - error.NetNameDeleted => return error.UnableToReadElfFile, - error.Unexpected => return error.Unexpected, - error.InputOutput => return error.FileSystem, - error.AccessDenied => return error.Unexpected, - }; - if (len == 0) return error.UnexpectedEndOfFile; - i += len; - } - return i; -} - -fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) !NativeTargetInfo { - const target: Target = .{ - .cpu = cpu, - .os = os, - .abi = query.abi orelse Target.Abi.default(cpu.arch, os), - .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch), - }; - return NativeTargetInfo{ - .target = target, - .dynamic_linker = if (query.dynamic_linker.get() == null) - target.standardDynamicLinkerPath() - else - query.dynamic_linker, - }; -} - -pub const LdInfo = struct { - ld: DynamicLinker, - abi: Target.Abi, -}; - -pub fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) { - if (is_64) { - if (need_bswap) { - return @byteSwap(int_64); - } else { - return int_64; - } - } else { - if (need_bswap) { - return @byteSwap(int_32); - } else { - return int_32; - } - } -} - -fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu { - // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`, - // although it is a runtime value, is guaranteed to be one of the architectures in the set - // of the respective switch prong. - switch (builtin.cpu.arch) { - .x86_64, .x86 => { - return @import("x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query); - }, - else => {}, - } - - switch (builtin.os.tag) { - .linux => return linux.detectNativeCpuAndFeatures(), - .macos => return darwin.macos.detectNativeCpuAndFeatures(), - .windows => return windows.detectNativeCpuAndFeatures(), - else => {}, - } - - // This architecture does not have CPU model & feature detection yet. - // See https://github.com/ziglang/zig/issues/4591 - return null; -} - -pub const Executor = union(enum) { - native, - rosetta, - qemu: []const u8, - wine: []const u8, - wasmtime: []const u8, - darling: []const u8, - bad_dl: []const u8, - bad_os_or_cpu, -}; - -pub const GetExternalExecutorOptions = struct { - allow_darling: bool = true, - allow_qemu: bool = true, - allow_rosetta: bool = true, - allow_wasmtime: bool = true, - allow_wine: bool = true, - qemu_fixes_dl: bool = false, - link_libc: bool = false, -}; - -/// Return whether or not the given host is capable of running executables of -/// the other target. -pub fn getExternalExecutor( - host: NativeTargetInfo, - candidate: *const NativeTargetInfo, - options: GetExternalExecutorOptions, -) Executor { - const os_match = host.target.os.tag == candidate.target.os.tag; - const cpu_ok = cpu_ok: { - if (host.target.cpu.arch == candidate.target.cpu.arch) - break :cpu_ok true; - - if (host.target.cpu.arch == .x86_64 and candidate.target.cpu.arch == .x86) - break :cpu_ok true; - - if (host.target.cpu.arch == .aarch64 and candidate.target.cpu.arch == .arm) - break :cpu_ok true; - - if (host.target.cpu.arch == .aarch64_be and candidate.target.cpu.arch == .armeb) - break :cpu_ok true; - - // TODO additionally detect incompatible CPU features. - // Note that in some cases the OS kernel will emulate missing CPU features - // when an illegal instruction is encountered. - - break :cpu_ok false; - }; - - var bad_result: Executor = .bad_os_or_cpu; - - if (os_match and cpu_ok) native: { - if (options.link_libc) { - if (candidate.dynamic_linker.get()) |candidate_dl| { - fs.cwd().access(candidate_dl, .{}) catch { - bad_result = .{ .bad_dl = candidate_dl }; - break :native; - }; - } - } - return .native; - } - - // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2 - // to emulate the foreign architecture. - if (options.allow_rosetta and os_match and - host.target.os.tag == .macos and host.target.cpu.arch == .aarch64) - { - switch (candidate.target.cpu.arch) { - .x86_64 => return .rosetta, - else => return bad_result, - } - } - - // If the OS matches, we can use QEMU to emulate a foreign architecture. - if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) { - return switch (candidate.target.cpu.arch) { - .aarch64 => Executor{ .qemu = "qemu-aarch64" }, - .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" }, - .arm => Executor{ .qemu = "qemu-arm" }, - .armeb => Executor{ .qemu = "qemu-armeb" }, - .hexagon => Executor{ .qemu = "qemu-hexagon" }, - .x86 => Executor{ .qemu = "qemu-i386" }, - .m68k => Executor{ .qemu = "qemu-m68k" }, - .mips => Executor{ .qemu = "qemu-mips" }, - .mipsel => Executor{ .qemu = "qemu-mipsel" }, - .mips64 => Executor{ .qemu = "qemu-mips64" }, - .mips64el => Executor{ .qemu = "qemu-mips64el" }, - .powerpc => Executor{ .qemu = "qemu-ppc" }, - .powerpc64 => Executor{ .qemu = "qemu-ppc64" }, - .powerpc64le => Executor{ .qemu = "qemu-ppc64le" }, - .riscv32 => Executor{ .qemu = "qemu-riscv32" }, - .riscv64 => Executor{ .qemu = "qemu-riscv64" }, - .s390x => Executor{ .qemu = "qemu-s390x" }, - .sparc => Executor{ .qemu = "qemu-sparc" }, - .sparc64 => Executor{ .qemu = "qemu-sparc64" }, - .x86_64 => Executor{ .qemu = "qemu-x86_64" }, - else => return bad_result, - }; - } - - switch (candidate.target.os.tag) { - .windows => { - if (options.allow_wine) { - // x86_64 wine does not support emulating aarch64-windows and - // vice versa. - if (candidate.target.cpu.arch != builtin.cpu.arch) { - return bad_result; - } - switch (candidate.target.ptrBitWidth()) { - 32 => return Executor{ .wine = "wine" }, - 64 => return Executor{ .wine = "wine64" }, - else => return bad_result, - } - } - return bad_result; - }, - .wasi => { - if (options.allow_wasmtime) { - switch (candidate.target.ptrBitWidth()) { - 32 => return Executor{ .wasmtime = "wasmtime" }, - else => return bad_result, - } - } - return bad_result; - }, - .macos => { - if (options.allow_darling) { - // This check can be loosened once darling adds a QEMU-based emulation - // layer for non-host architectures: - // https://github.com/darlinghq/darling/issues/863 - if (candidate.target.cpu.arch != builtin.cpu.arch) { - return bad_result; - } - return Executor{ .darling = "darling" }; - } - return bad_result; - }, - else => return bad_result, - } -} diff --git a/src/Compilation.zig b/src/Compilation.zig index 7831a58840..0b275f97c1 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -6527,7 +6527,6 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca try buffer.writer().print(" .{},\n", .{std.zig.fmtId(feature.name)}); } } - try buffer.writer().print( \\ }}), \\}}; @@ -6607,15 +6606,31 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Alloca .{ windows.min, windows.max }, ), } - try buffer.appendSlice("};\n"); - - try buffer.writer().print( - \\pub const target = std.Target{{ + try buffer.appendSlice( + \\}; + \\pub const target: std.Target = .{ \\ .cpu = cpu, \\ .os = os, \\ .abi = abi, \\ .ofmt = object_format, - \\}}; + \\ + ); + + if (target.dynamic_linker.get()) |dl| { + try buffer.writer().print( + \\ .dynamic_linker = std.Target.DynamicLinker.init("{s}"), + \\}}; + \\ + , .{dl}); + } else { + try buffer.appendSlice( + \\ .dynamic_linker = std.Target.DynamicLinker.none, + \\}; + \\ + ); + } + + try buffer.writer().print( \\pub const object_format = std.Target.ObjectFormat.{}; \\pub const mode = std.builtin.OptimizeMode.{}; \\pub const link_libc = {}; diff --git a/src/main.zig b/src/main.zig index 17603acf2c..716be60763 100644 --- a/src/main.zig +++ b/src/main.zig @@ -321,13 +321,14 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi } else if (mem.eql(u8, cmd, "init")) { return cmdInit(gpa, arena, cmd_args); } else if (mem.eql(u8, cmd, "targets")) { - const info = try detectNativeTargetInfo(.{}); + const host = try std.zig.system.resolveTargetQuery(.{}); const stdout = io.getStdOut().writer(); - return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target); + return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, host); } else if (mem.eql(u8, cmd, "version")) { try std.io.getStdOut().writeAll(build_options.version ++ "\n"); - // Check libc++ linkage to make sure Zig was built correctly, but only for "env" and "version" - // to avoid affecting the startup time for build-critical commands (check takes about ~10 μs) + // Check libc++ linkage to make sure Zig was built correctly, but only + // for "env" and "version" to avoid affecting the startup time for + // build-critical commands (check takes about ~10 μs) return verifyLibcxxCorrectlyLinked(); } else if (mem.eql(u8, cmd, "env")) { verifyLibcxxCorrectlyLinked(); @@ -2608,9 +2609,9 @@ fn buildOutputType( } const target_query = try parseTargetQueryOrReportFatalError(arena, target_parse_options); - const target_info = try detectNativeTargetInfo(target_query); + const target = try std.zig.system.resolveTargetQuery(target_query); - if (target_info.target.os.tag != .freestanding) { + if (target.os.tag != .freestanding) { if (ensure_libc_on_non_freestanding) link_libc = true; if (ensure_libcpp_on_non_freestanding) @@ -2621,7 +2622,7 @@ fn buildOutputType( if (!force) { entry = null; } else if (entry == null and output_mode == .Exe) { - entry = switch (target_info.target.ofmt) { + entry = switch (target.ofmt) { .coff => "wWinMainCRTStartup", .macho => "_main", .elf, .plan9 => "_start", @@ -2629,12 +2630,12 @@ fn buildOutputType( else => |tag| fatal("No default entry point available for output format {s}", .{@tagName(tag)}), }; } - } else if (entry == null and target_info.target.isWasm() and output_mode == .Exe) { + } else if (entry == null and target.isWasm() and output_mode == .Exe) { // For WebAssembly the compiler defaults to setting the entry name when no flags are set. entry = defaultWasmEntryName(wasi_exec_model); } - if (target_info.target.ofmt == .coff) { + if (target.ofmt == .coff) { // Now that we know the target supports resources, // we can add the res files as link objects. for (res_files.items) |res_file| { @@ -2652,7 +2653,7 @@ fn buildOutputType( } } - if (target_info.target.cpu.arch.isWasm()) blk: { + if (target.cpu.arch.isWasm()) blk: { if (single_threaded == null) { single_threaded = true; } @@ -2678,8 +2679,8 @@ fn buildOutputType( fatal("shared memory is not allowed in object files", .{}); } - if (!target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or - !target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory))) + if (!target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or + !target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory))) { fatal("'atomics' and 'bulk-memory' features must be enabled to use shared memory", .{}); } @@ -2777,15 +2778,15 @@ fn buildOutputType( } for (system_libs.keys(), system_libs.values()) |lib_name, info| { - if (target_info.target.is_libc_lib_name(lib_name)) { + if (target.is_libc_lib_name(lib_name)) { link_libc = true; continue; } - if (target_info.target.is_libcpp_lib_name(lib_name)) { + if (target.is_libcpp_lib_name(lib_name)) { link_libcpp = true; continue; } - switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) { + switch (target_util.classifyCompilerRtLibName(target, lib_name)) { .none => {}, .only_libunwind, .both => { link_libunwind = true; @@ -2797,8 +2798,8 @@ fn buildOutputType( }, } - if (target_info.target.isMinGW()) { - const exists = mingw.libExists(arena, target_info.target, zig_lib_directory, lib_name) catch |err| { + if (target.isMinGW()) { + const exists = mingw.libExists(arena, target, zig_lib_directory, lib_name) catch |err| { fatal("failed to check zig installation for DLL import libs: {s}", .{ @errorName(err), }); @@ -2820,7 +2821,7 @@ fn buildOutputType( fatal("cannot use absolute path as a system library: {s}", .{lib_name}); } - if (target_info.target.os.tag == .wasi) { + if (target.os.tag == .wasi) { if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| { try wasi_emulated_libs.append(crt_file); continue; @@ -2838,7 +2839,7 @@ fn buildOutputType( if (sysroot == null and target_query.isNativeOs() and target_query.isNativeAbi() and (external_system_libs.len != 0 or want_native_include_dirs)) { - const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| { + const paths = std.zig.system.NativePaths.detect(arena, target) catch |err| { fatal("unable to detect native system paths: {s}", .{@errorName(err)}); }; for (paths.warnings.items) |warning| { @@ -2857,7 +2858,7 @@ fn buildOutputType( } if (builtin.target.os.tag == .windows and - target_info.target.abi == .msvc and + target.abi == .msvc and external_system_libs.len != 0) { if (libc_installation == null) { @@ -2902,7 +2903,7 @@ fn buildOutputType( &checked_paths, lib_dir_path, lib_name, - target_info.target, + target, info.preferred_mode, )) { const path = try arena.dupe(u8, test_path.items); @@ -2936,7 +2937,7 @@ fn buildOutputType( &checked_paths, lib_dir_path, lib_name, - target_info.target, + target, info.fallbackMode(), )) { const path = try arena.dupe(u8, test_path.items); @@ -2970,7 +2971,7 @@ fn buildOutputType( &checked_paths, lib_dir_path, lib_name, - target_info.target, + target, info.preferred_mode, )) { const path = try arena.dupe(u8, test_path.items); @@ -2994,7 +2995,7 @@ fn buildOutputType( &checked_paths, lib_dir_path, lib_name, - target_info.target, + target, info.fallbackMode(), )) { const path = try arena.dupe(u8, test_path.items); @@ -3089,15 +3090,13 @@ fn buildOutputType( } // After this point, resolved_frameworks is used instead of frameworks. - const object_format = target_info.target.ofmt; - - if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) { + if (output_mode == .Obj and (target.ofmt == .coff or target.ofmt == .macho)) { const total_obj_count = c_source_files.items.len + @intFromBool(root_src_file != null) + rc_source_files.items.len + link_objects.items.len; if (total_obj_count > 1) { - fatal("{s} does not support linking multiple objects into one", .{@tagName(object_format)}); + fatal("{s} does not support linking multiple objects into one", .{@tagName(target.ofmt)}); } } @@ -3110,7 +3109,7 @@ fn buildOutputType( const resolved_soname: ?[]const u8 = switch (soname) { .yes => |explicit| explicit, .no => null, - .yes_default_value => switch (object_format) { + .yes_default_value => switch (target.ofmt) { .elf => if (have_version) try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major }) else @@ -3119,7 +3118,7 @@ fn buildOutputType( }, }; - const a_out_basename = switch (object_format) { + const a_out_basename = switch (target.ofmt) { .coff => "a.exe", else => "a.out", }; @@ -3141,7 +3140,7 @@ fn buildOutputType( }, .basename = try std.zig.binNameAlloc(arena, .{ .root_name = root_name, - .target = target_info.target, + .target = target, .output_mode = output_mode, .link_mode = link_mode, .version = optional_version, @@ -3269,7 +3268,7 @@ fn buildOutputType( // Note that cmake when targeting Windows will try to execute // zig cc to make an executable and output an implib too. const implib_eligible = is_exe_or_dyn_lib and - emit_bin_loc != null and target_info.target.os.tag == .windows; + emit_bin_loc != null and target.os.tag == .windows; if (!implib_eligible) { if (!emit_implib_arg_provided) { emit_implib = .no; @@ -3419,7 +3418,7 @@ fn buildOutputType( // "-" is stdin. Dump it to a real file. const sep = fs.path.sep_str; const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{ - std.crypto.random.int(u64), ext.canonicalName(target_info.target), + std.crypto.random.int(u64), ext.canonicalName(target), }); try local_cache_directory.handle.makePath("tmp"); // Note that in one of the happy paths, execve() is used to switch @@ -3454,10 +3453,10 @@ fn buildOutputType( .local_cache_directory = local_cache_directory, .global_cache_directory = global_cache_directory, .root_name = root_name, - .target = target_info.target, + .target = target, .is_native_os = target_query.isNativeOs(), .is_native_abi = target_query.isNativeAbi(), - .dynamic_linker = target_info.dynamic_linker.get(), + .dynamic_linker = target.dynamic_linker.get(), .sysroot = sysroot, .output_mode = output_mode, .main_mod = main_mod, @@ -3603,7 +3602,6 @@ fn buildOutputType( .want_structured_cfg = want_structured_cfg, }) catch |err| switch (err) { error.LibCUnavailable => { - const target = target_info.target; const triple_name = try target.zigTriple(arena); std.log.err("unable to find or provide libc for target '{s}'", .{triple_name}); @@ -3692,7 +3690,7 @@ fn buildOutputType( try comp.makeBinFileExecutable(); saveState(comp, debug_incremental); - if (test_exec_args.items.len == 0 and object_format == .c) default_exec_args: { + if (test_exec_args.items.len == 0 and target.ofmt == .c) default_exec_args: { // Default to using `zig run` to execute the produced .c code from `zig test`. const c_code_loc = emit_bin_loc orelse break :default_exec_args; const c_code_directory = c_code_loc.directory orelse comp.bin_file.options.emit.?.directory; @@ -3707,7 +3705,7 @@ fn buildOutputType( if (link_libc) { try test_exec_args.append("-lc"); - } else if (target_info.target.os.tag == .windows) { + } else if (target.os.tag == .windows) { try test_exec_args.appendSlice(&.{ "--subsystem", "console", "-lkernel32", "-lntdll", @@ -3741,7 +3739,7 @@ fn buildOutputType( test_exec_args.items, self_exe_path.?, arg_mode, - &target_info, + &target, &comp_destroyed, all_args, runtime_args_start, @@ -3861,7 +3859,7 @@ fn serve( // test_exec_args, // self_exe_path.?, // arg_mode, - // target_info, + // target, // true, // &comp_destroyed, // all_args, @@ -4071,7 +4069,7 @@ fn runOrTest( test_exec_args: []const ?[]const u8, self_exe_path: []const u8, arg_mode: ArgMode, - target_info: *const std.zig.system.NativeTargetInfo, + target: *const std.Target, comp_destroyed: *bool, all_args: []const []const u8, runtime_args_start: ?usize, @@ -4105,7 +4103,7 @@ fn runOrTest( if (process.can_execv and arg_mode == .run) { // execv releases the locks; no need to destroy the Compilation here. const err = process.execve(gpa, argv.items, &env_map); - try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc); + try warnAboutForeignBinaries(arena, arg_mode, target, link_libc); const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd }); } else if (process.can_spawn) { @@ -4121,7 +4119,7 @@ fn runOrTest( comp_destroyed.* = true; const term = child.spawnAndWait() catch |err| { - try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc); + try warnAboutForeignBinaries(arena, arg_mode, target, link_libc); const cmd = try std.mem.join(arena, " ", argv.items); fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd }); }; @@ -4820,12 +4818,10 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { if (!target_query.isNative()) { fatal("unable to detect libc for non-native target", .{}); } - const target_info = try detectNativeTargetInfo(target_query); - var libc = LibCInstallation.findNative(.{ .allocator = gpa, .verbose = true, - .target = target_info.target, + .target = try std.zig.system.resolveTargetQuery(target_query), }) catch |err| { fatal("unable to detect native libc: {s}", .{@errorName(err)}); }; @@ -5114,11 +5110,11 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi gimmeMoreOfThoseSweetSweetFileDescriptors(); const target_query: std.Target.Query = .{}; - const target_info = try detectNativeTargetInfo(target_query); + const target = try std.zig.system.resolveTargetQuery(target_query); const exe_basename = try std.zig.binNameAlloc(arena, .{ .root_name = "build", - .target = target_info.target, + .target = target, .output_mode = .Exe, }); const emit_bin: Compilation.EmitLoc = .{ @@ -5282,10 +5278,10 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi .local_cache_directory = local_cache_directory, .global_cache_directory = global_cache_directory, .root_name = "build", - .target = target_info.target, + .target = target, .is_native_os = target_query.isNativeOs(), .is_native_abi = target_query.isNativeAbi(), - .dynamic_linker = target_info.dynamic_linker.get(), + .dynamic_linker = target.dynamic_linker.get(), .output_mode = .Exe, .main_mod = &main_mod, .emit_bin = emit_bin, @@ -6269,10 +6265,6 @@ test "fds" { gimmeMoreOfThoseSweetSweetFileDescriptors(); } -fn detectNativeTargetInfo(target_query: std.Target.Query) !std.zig.system.NativeTargetInfo { - return std.zig.system.NativeTargetInfo.detect(target_query); -} - const usage_ast_check = \\Usage: zig ast-check [file] \\ @@ -6669,24 +6661,24 @@ fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 { fn warnAboutForeignBinaries( arena: Allocator, arg_mode: ArgMode, - target_info: *const std.zig.system.NativeTargetInfo, + target: *const std.Target, link_libc: bool, ) !void { const host_query: std.Target.Query = .{}; - const host_target_info = try detectNativeTargetInfo(host_query); + const host_target = try std.zig.system.resolveTargetQuery(host_query); - switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) { + switch (std.zig.system.getExternalExecutor(host_target, target, .{ .link_libc = link_libc })) { .native => return, .rosetta => { - const host_name = try host_target_info.target.zigTriple(arena); - const foreign_name = try target_info.target.zigTriple(arena); + const host_name = try host_target.zigTriple(arena); + const foreign_name = try target.zigTriple(arena); warn("the host system ({s}) does not appear to be capable of executing binaries from the target ({s}). Consider installing Rosetta.", .{ host_name, foreign_name, }); }, .qemu => |qemu| { - const host_name = try host_target_info.target.zigTriple(arena); - const foreign_name = try target_info.target.zigTriple(arena); + const host_name = try host_target.zigTriple(arena); + const foreign_name = try target.zigTriple(arena); switch (arg_mode) { .zig_test => warn( "the host system ({s}) does not appear to be capable of executing binaries " ++ @@ -6702,8 +6694,8 @@ fn warnAboutForeignBinaries( } }, .wine => |wine| { - const host_name = try host_target_info.target.zigTriple(arena); - const foreign_name = try target_info.target.zigTriple(arena); + const host_name = try host_target.zigTriple(arena); + const foreign_name = try target.zigTriple(arena); switch (arg_mode) { .zig_test => warn( "the host system ({s}) does not appear to be capable of executing binaries " ++ @@ -6719,8 +6711,8 @@ fn warnAboutForeignBinaries( } }, .wasmtime => |wasmtime| { - const host_name = try host_target_info.target.zigTriple(arena); - const foreign_name = try target_info.target.zigTriple(arena); + const host_name = try host_target.zigTriple(arena); + const foreign_name = try target.zigTriple(arena); switch (arg_mode) { .zig_test => warn( "the host system ({s}) does not appear to be capable of executing binaries " ++ @@ -6736,8 +6728,8 @@ fn warnAboutForeignBinaries( } }, .darling => |darling| { - const host_name = try host_target_info.target.zigTriple(arena); - const foreign_name = try target_info.target.zigTriple(arena); + const host_name = try host_target.zigTriple(arena); + const foreign_name = try target.zigTriple(arena); switch (arg_mode) { .zig_test => warn( "the host system ({s}) does not appear to be capable of executing binaries " ++ @@ -6753,7 +6745,7 @@ fn warnAboutForeignBinaries( } }, .bad_dl => |foreign_dl| { - const host_dl = host_target_info.dynamic_linker.get() orelse "(none)"; + const host_dl = host_target.dynamic_linker.get() orelse "(none)"; const tip_suffix = switch (arg_mode) { .zig_test => ", '--test-no-exec', or '--test-cmd'", else => "", @@ -6763,8 +6755,8 @@ fn warnAboutForeignBinaries( }); }, .bad_os_or_cpu => { - const host_name = try host_target_info.target.zigTriple(arena); - const foreign_name = try target_info.target.zigTriple(arena); + const host_name = try host_target.zigTriple(arena); + const foreign_name = try target.zigTriple(arena); const tip_suffix = switch (arg_mode) { .zig_test => ". Consider using '--test-no-exec' or '--test-cmd'", else => "", diff --git a/src/print_env.zig b/src/print_env.zig index 89c6ffe754..46ca10d149 100644 --- a/src/print_env.zig +++ b/src/print_env.zig @@ -17,8 +17,8 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr const global_cache_dir = try introspect.resolveGlobalCacheDir(arena); - const info = try std.zig.system.NativeTargetInfo.detect(.{}); - const triple = try info.target.zigTriple(arena); + const host = try std.zig.system.resolveTargetQuery(.{}); + const triple = try host.zigTriple(arena); var bw = std.io.bufferedWriter(stdout); const w = bw.writer(); diff --git a/test/src/Cases.zig b/test/src/Cases.zig index de7378d10a..0f2645f0e0 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -541,7 +541,7 @@ pub fn lowerToBuildSteps( cases_dir_path: []const u8, incremental_exe: *std.Build.Step.Compile, ) void { - const host = std.zig.system.NativeTargetInfo.detect(.{}) catch |err| + const host = std.zig.system.resolveTargetQuery(.{}) catch |err| std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)}); for (self.incremental_cases.items) |incr_case| { @@ -648,8 +648,7 @@ pub fn lowerToBuildSteps( }, .Execution => |expected_stdout| no_exec: { const run = if (case.target.target.ofmt == .c) run_step: { - const target_info = case.target.toNativeTargetInfo(); - if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) { + if (getExternalExecutor(host, &case.target.target, .{ .link_libc = true }) != .native) { // We wouldn't be able to run the compiled C code. break :no_exec; } @@ -694,8 +693,7 @@ pub fn lowerToBuildSteps( continue; // Pass test. } - const target_info = case.target.toNativeTargetInfo(); - if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) { + if (getExternalExecutor(host, &case.target.target, .{ .link_libc = true }) != .native) { // We wouldn't be able to run the compiled C code. continue; // Pass test. } @@ -1199,6 +1197,8 @@ const builtin = @import("builtin"); const std = @import("std"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; +const getExternalExecutor = std.zig.system.getExternalExecutor; + const Compilation = @import("../../src/Compilation.zig"); const zig_h = @import("../../src/link.zig").File.C.zig_h; const introspect = @import("../../src/introspect.zig"); @@ -1386,18 +1386,15 @@ pub fn main() !void { } fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget { - const result = std.zig.system.NativeTargetInfo.detect(query) catch - @panic("unable to resolve target query"); - return .{ .query = query, - .target = result.target, - .dynamic_linker = result.dynamic_linker, + .target = std.zig.system.resolveTargetQuery(query) catch + @panic("unable to resolve target query"), }; } fn runCases(self: *Cases, zig_exe_path: []const u8) !void { - const host = try std.zig.system.NativeTargetInfo.detect(.{}); + const host = try std.zig.system.resolveTargetQuery(.{}); var progress = std.Progress{}; const root_node = progress.start("compiler", self.cases.items.len); @@ -1478,7 +1475,7 @@ fn runOneCase( zig_exe_path: []const u8, thread_pool: *ThreadPool, global_cache_directory: Compilation.Directory, - host: std.zig.system.NativeTargetInfo, + host: std.Target, ) !void { const tmp_src_path = "tmp.zig"; const enable_rosetta = build_options.enable_rosetta; @@ -1488,8 +1485,7 @@ fn runOneCase( const enable_darling = build_options.enable_darling; const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir; - const target_info = try std.zig.system.NativeTargetInfo.detect(case.target); - const target = target_info.target; + const target = try std.zig.system.resolveTargetQuery(case.target); var arena_allocator = std.heap.ArenaAllocator.init(allocator); defer arena_allocator.deinit(); @@ -1579,7 +1575,7 @@ fn runOneCase( .keep_source_files_loaded = true, .is_native_os = case.target.isNativeOs(), .is_native_abi = case.target.isNativeAbi(), - .dynamic_linker = target_info.dynamic_linker.get(), + .dynamic_linker = target.dynamic_linker.get(), .link_libc = case.link_libc, .use_llvm = use_llvm, .self_exe_path = zig_exe_path, @@ -1715,7 +1711,7 @@ fn runOneCase( .{ &tmp.sub_path, bin_name }, ); if (case.target.ofmt != null and case.target.ofmt.? == .c) { - if (host.getExternalExecutor(target_info, .{ .link_libc = true }) != .native) { + if (getExternalExecutor(host, &target, .{ .link_libc = true }) != .native) { // We wouldn't be able to run the compiled C code. continue :update; // Pass test. } @@ -1734,7 +1730,7 @@ fn runOneCase( if (zig_lib_directory.path) |p| { try argv.appendSlice(&.{ "-I", p }); } - } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) { + } else switch (getExternalExecutor(host, &target, .{ .link_libc = case.link_libc })) { .native => { if (case.backend == .stage2 and case.target.getCpuArch().isArmOrThumb()) { // https://github.com/ziglang/zig/issues/13623 -- cgit v1.2.3 From 8c44954bc6a91ae66f5aea92ea8380c28b50b3f0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 4 Dec 2023 20:30:32 -0700 Subject: std.Target.Query: remove deprecated API These functions have been doomed for a long time. Finally I figured out what the proper relationship between this API and std.Target is. --- deps/aro/aro/Driver.zig | 9 +- lib/std/Build.zig | 136 ++++--------------- lib/std/Build/Module.zig | 4 +- lib/std/Target.zig | 13 +- lib/std/Target/Query.zig | 334 ++++++++++++++++++---------------------------- lib/std/zig.zig | 46 ++++++- lib/std/zig/system.zig | 29 +++- src/libc_installation.zig | 13 +- src/main.zig | 16 +-- test/tests.zig | 48 ++++--- 10 files changed, 275 insertions(+), 373 deletions(-) (limited to 'lib/std/Target') diff --git a/deps/aro/aro/Driver.zig b/deps/aro/aro/Driver.zig index 18a24b86a7..1738b14093 100644 --- a/deps/aro/aro/Driver.zig +++ b/deps/aro/aro/Driver.zig @@ -366,12 +366,15 @@ pub fn parseArgs( } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) { d.only_preprocess_and_compile = true; } else if (option(arg, "--target=")) |triple| { - const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = triple }) catch { + const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch { try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{}); continue; }; - d.comp.target = cross.toTarget(); // TODO deprecated - d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(d.comp.target)); + const target = std.zig.system.resolveTargetQuery(query) catch |e| { + return d.fatal("unable to resolve target: {s}", .{errorDescription(e)}); + }; + d.comp.target = target; + d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target)); d.raw_target_triple = triple; } else if (mem.eql(u8, arg, "--verbose-ast")) { d.verbose_ast = true; diff --git a/lib/std/Build.zig b/lib/std/Build.zig index cb5a503593..96b98b8583 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -383,12 +383,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption }) catch @panic("OOM"); user_input_options.put("cpu", .{ .name = "cpu", - .value = .{ - .scalar = if (v.isNativeCpu()) - "native" - else - serializeCpu(allocator, v.getCpu()) catch unreachable, - }, + .value = .{ .scalar = v.serializeCpuAlloc(allocator) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); }, @@ -400,12 +395,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption }) catch @panic("OOM"); user_input_options.put("cpu", .{ .name = "cpu", - .value = .{ - .scalar = if (v.query.isNativeCpu()) - "native" - else - serializeCpu(allocator, v.target.cpu) catch unreachable, - }, + .value = .{ .scalar = v.query.serializeCpuAlloc(allocator) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); }, @@ -1196,7 +1186,6 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio pub const StandardTargetOptionsArgs = struct { whitelist: ?[]const Target.Query = null, - default_target: Target.Query = .{}, }; @@ -1208,13 +1197,13 @@ pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) Resolve } /// Exposes standard `zig build` options for choosing a target. -pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsArgs) Target.Query { - const maybe_triple = self.option( +pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query { + const maybe_triple = b.option( []const u8, "target", "The CPU architecture, OS, and ABI to build for", ); - const mcpu = self.option([]const u8, "cpu", "Target CPU features to add or subtract"); + const mcpu = b.option([]const u8, "cpu", "Target CPU features to add or subtract"); if (maybe_triple == null and mcpu == null) { return args.default_target; @@ -1236,7 +1225,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA for (diags.arch.?.allCpuModels()) |cpu| { log.err(" {s}", .{cpu.name}); } - self.markInvalidUserInput(); + b.markInvalidUserInput(); return args.default_target; }, error.UnknownCpuFeature => { @@ -1251,7 +1240,7 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA for (diags.arch.?.allFeaturesList()) |feature| { log.err(" {s}: {s}", .{ feature.name, feature.description }); } - self.markInvalidUserInput(); + b.markInvalidUserInput(); return args.default_target; }, error.UnknownOperatingSystem => { @@ -1263,80 +1252,35 @@ pub fn standardTargetOptionsQueryOnly(self: *Build, args: StandardTargetOptionsA inline for (std.meta.fields(Target.Os.Tag)) |field| { log.err(" {s}", .{field.name}); } - self.markInvalidUserInput(); + b.markInvalidUserInput(); return args.default_target; }, else => |e| { log.err("Unable to parse target '{s}': {s}\n", .{ triple, @errorName(e) }); - self.markInvalidUserInput(); + b.markInvalidUserInput(); return args.default_target; }, }; - const selected_canonicalized_triple = selected_target.zigTriple(self.allocator) catch @panic("OOM"); - - if (args.whitelist) |list| whitelist_check: { - // Make sure it's a match of one of the list. - var mismatch_triple = true; - var mismatch_cpu_features = true; - var whitelist_item: Target.Query = .{}; - for (list) |t| { - mismatch_cpu_features = true; - mismatch_triple = true; - - const t_triple = t.zigTriple(self.allocator) catch @panic("OOM"); - if (mem.eql(u8, t_triple, selected_canonicalized_triple)) { - mismatch_triple = false; - whitelist_item = t; - if (t.getCpuFeatures().isSuperSetOf(selected_target.getCpuFeatures())) { - mismatch_cpu_features = false; - break :whitelist_check; - } else { - break; - } - } - } - if (mismatch_triple) { - log.err("Chosen target '{s}' does not match one of the supported targets:", .{ - selected_canonicalized_triple, - }); - for (list) |t| { - const t_triple = t.zigTriple(self.allocator) catch @panic("OOM"); - log.err(" {s}", .{t_triple}); - } - } else { - assert(mismatch_cpu_features); - const whitelist_cpu = whitelist_item.getCpu(); - const selected_cpu = selected_target.getCpu(); - log.err("Chosen CPU model '{s}' does not match one of the supported targets:", .{ - selected_cpu.model.name, - }); - log.err(" Supported feature Set: ", .{}); - const all_features = whitelist_cpu.arch.allFeaturesList(); - var populated_cpu_features = whitelist_cpu.model.features; - populated_cpu_features.populateDependencies(all_features); - for (all_features, 0..) |feature, i_usize| { - const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); - const in_cpu_set = populated_cpu_features.isEnabled(i); - if (in_cpu_set) { - log.err("{s} ", .{feature.name}); - } - } - log.err(" Remove: ", .{}); - for (all_features, 0..) |feature, i_usize| { - const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); - const in_cpu_set = populated_cpu_features.isEnabled(i); - const in_actual_set = selected_cpu.features.isEnabled(i); - if (in_actual_set and !in_cpu_set) { - log.err("{s} ", .{feature.name}); - } - } - } - self.markInvalidUserInput(); - return args.default_target; + const whitelist = args.whitelist orelse return selected_target; + + // Make sure it's a match of one of the list. + for (whitelist) |q| { + if (q.eql(selected_target)) + return selected_target; } - return selected_target; + for (whitelist) |q| { + log.info("allowed target: -Dtarget={s} -Dcpu={s}", .{ + q.zigTriple(b.allocator) catch @panic("OOM"), + q.serializeCpuAlloc(b.allocator) catch @panic("OOM"), + }); + } + log.err("chosen target '{s}' does not match one of the allowed targets", .{ + selected_target.zigTriple(b.allocator) catch @panic("OOM"), + }); + b.markInvalidUserInput(); + return args.default_target; } pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const u8) !bool { @@ -2064,34 +2008,6 @@ pub const InstalledFile = struct { } }; -pub fn serializeCpu(allocator: Allocator, cpu: Target.Cpu) ![]const u8 { - // TODO this logic can disappear if cpu model + features becomes part of the target triple - const all_features = cpu.arch.allFeaturesList(); - var populated_cpu_features = cpu.model.features; - populated_cpu_features.populateDependencies(all_features); - - if (populated_cpu_features.eql(cpu.features)) { - // The CPU name alone is sufficient. - return cpu.model.name; - } else { - var mcpu_buffer = ArrayList(u8).init(allocator); - try mcpu_buffer.appendSlice(cpu.model.name); - - for (all_features, 0..) |feature, i_usize| { - const i = @as(Target.Cpu.Feature.Set.Index, @intCast(i_usize)); - const in_cpu_set = populated_cpu_features.isEnabled(i); - const in_actual_set = cpu.features.isEnabled(i); - if (in_cpu_set and !in_actual_set) { - try mcpu_buffer.writer().print("-{s}", .{feature.name}); - } else if (!in_cpu_set and in_actual_set) { - try mcpu_buffer.writer().print("+{s}", .{feature.name}); - } - } - - return try mcpu_buffer.toOwnedSlice(); - } -} - /// This function is intended to be called in the `configure` phase only. /// It returns an absolute directory path, which is potentially going to be a /// source of API breakage in the future, so keep that in mind when using this diff --git a/lib/std/Build/Module.zig b/lib/std/Build/Module.zig index 5482ca25ec..9c98dd0a46 100644 --- a/lib/std/Build/Module.zig +++ b/lib/std/Build/Module.zig @@ -627,12 +627,12 @@ pub fn appendZigProcessFlags( try zig_args.append(@tagName(m.code_model)); } - if (m.target) |target| { + if (m.target) |*target| { // Communicate the query via CLI since it's more compact. if (!target.query.isNative()) { try zig_args.appendSlice(&.{ "-target", try target.query.zigTriple(b.allocator), - "-mcpu", try std.Build.serializeCpu(b.allocator, target.query.getCpu()), + "-mcpu", try target.query.serializeCpuAlloc(b.allocator), }); if (target.query.dynamic_linker.get()) |dynamic_linker| { diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 6f30aa75b1..f8ce63b37f 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1394,7 +1394,7 @@ pub const Cpu = struct { } }; -pub fn zigTriple(self: Target, allocator: Allocator) ![]u8 { +pub fn zigTriple(self: Target, allocator: Allocator) Allocator.Error![]u8 { return Query.fromTarget(self).zigTriple(allocator); } @@ -1566,11 +1566,20 @@ pub const DynamicLinker = struct { pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void { if (dl_or_null) |dl| { @memcpy(self.buffer[0..dl.len], dl); - self.max_byte = @as(u8, @intCast(dl.len - 1)); + self.max_byte = @intCast(dl.len - 1); } else { self.max_byte = null; } } + + pub fn eql(a: DynamicLinker, b: DynamicLinker) bool { + const a_m = a.max_byte orelse return b.max_byte == null; + const b_m = b.max_byte orelse return false; + if (a_m != b_m) return false; + const a_s = a.buffer[0 .. a_m + 1]; + const b_s = b.buffer[0 .. a_m + 1]; + return std.mem.eql(u8, a_s, b_s); + } }; pub fn standardDynamicLinkerPath(target: Target) DynamicLinker { diff --git a/lib/std/Target/Query.zig b/lib/std/Target/Query.zig index bb5949d597..1deff022cc 100644 --- a/lib/std/Target/Query.zig +++ b/lib/std/Target/Query.zig @@ -51,12 +51,41 @@ pub const CpuModel = union(enum) { determined_by_cpu_arch, explicit: *const Target.Cpu.Model, + + pub fn eql(a: CpuModel, b: CpuModel) bool { + const Tag = @typeInfo(CpuModel).Union.tag_type.?; + const a_tag: Tag = a; + const b_tag: Tag = b; + if (a_tag != b_tag) return false; + return switch (a) { + .native, .baseline, .determined_by_cpu_arch => true, + .explicit => |a_model| a_model == b.explicit, + }; + } }; pub const OsVersion = union(enum) { none: void, semver: SemanticVersion, windows: Target.Os.WindowsVersion, + + pub fn eql(a: OsVersion, b: OsVersion) bool { + const Tag = @typeInfo(OsVersion).Union.tag_type.?; + const a_tag: Tag = a; + const b_tag: Tag = b; + if (a_tag != b_tag) return false; + return switch (a) { + .none => true, + .semver => |a_semver| a_semver.order(b.semver) == .eq, + .windows => |a_windows| a_windows == b.windows, + }; + } + + pub fn eqlOpt(a: ?OsVersion, b: ?OsVersion) bool { + if (a == null and b == null) return true; + if (a == null or b == null) return false; + return OsVersion.eql(a.?, b.?); + } }; pub const SemanticVersion = std.SemanticVersion; @@ -162,16 +191,6 @@ fn updateOsVersionRange(self: *Query, os: Target.Os) void { } } -/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. -pub fn toTarget(self: Query) Target { - return .{ - .cpu = self.getCpu(), - .os = self.getOs(), - .abi = self.getAbi(), - .ofmt = self.getObjectFormat(), - }; -} - pub const ParseOptions = struct { /// This is sometimes called a "triple". It looks roughly like this: /// riscv64-linux-musl @@ -240,7 +259,7 @@ pub fn parse(args: ParseOptions) !Query { result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse return error.UnknownArchitecture; } - const arch = result.getCpuArch(); + const arch = result.cpu_arch orelse builtin.cpu.arch; diags.arch = arch; if (it.next()) |os_text| { @@ -259,7 +278,7 @@ pub fn parse(args: ParseOptions) !Query { const abi_ver_text = abi_it.rest(); if (abi_it.next() != null) { - if (result.isGnuLibC()) { + if (Target.isGnuLibC_os_tag_abi(result.os_tag orelse builtin.os.tag, abi)) { result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) { error.Overflow => return error.InvalidAbiVersion, error.InvalidVersion => return error.InvalidAbiVersion, @@ -377,168 +396,6 @@ test parseVersion { try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4")); } -/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. -pub fn getCpu(self: Query) Target.Cpu { - switch (self.cpu_model) { - .native => { - // This works when doing `zig build` because Zig generates a build executable using - // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.resolveTargetQuery`. - return builtin.cpu; - }, - .baseline => { - var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); - self.updateCpuFeatures(&adjusted_baseline.features); - return adjusted_baseline; - }, - .determined_by_cpu_arch => if (self.cpu_arch == null) { - // This works when doing `zig build` because Zig generates a build executable using - // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.resolveTargetQuery`. - return builtin.cpu; - } else { - var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch()); - self.updateCpuFeatures(&adjusted_baseline.features); - return adjusted_baseline; - }, - .explicit => |model| { - var adjusted_model = model.toCpu(self.getCpuArch()); - self.updateCpuFeatures(&adjusted_model.features); - return adjusted_model; - }, - } -} - -pub fn getCpuArch(self: Query) Target.Cpu.Arch { - return self.cpu_arch orelse builtin.cpu.arch; -} - -pub fn getCpuModel(self: Query) *const Target.Cpu.Model { - return switch (self.cpu_model) { - .explicit => |cpu_model| cpu_model, - else => self.getCpu().model, - }; -} - -pub fn getCpuFeatures(self: Query) Target.Cpu.Feature.Set { - return self.getCpu().features; -} - -/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. -pub fn getOs(self: Query) Target.Os { - // `builtin.os` works when doing `zig build` because Zig generates a build executable using - // native OS version range. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.resolveTargetQuery`. - var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os; - - if (self.os_version_min) |min| switch (min) { - .none => {}, - .semver => |semver| switch (self.getOsTag()) { - .linux => adjusted_os.version_range.linux.range.min = semver, - else => adjusted_os.version_range.semver.min = semver, - }, - .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver, - }; - - if (self.os_version_max) |max| switch (max) { - .none => {}, - .semver => |semver| switch (self.getOsTag()) { - .linux => adjusted_os.version_range.linux.range.max = semver, - else => adjusted_os.version_range.semver.max = semver, - }, - .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver, - }; - - if (self.glibc_version) |glibc| { - assert(self.isGnuLibC()); - adjusted_os.version_range.linux.glibc = glibc; - } - - return adjusted_os; -} - -pub fn getOsTag(self: Query) Target.Os.Tag { - return self.os_tag orelse builtin.os.tag; -} - -/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. -pub fn getOsVersionMin(self: Query) OsVersion { - if (self.os_version_min) |version_min| return version_min; - var tmp: Query = undefined; - tmp.updateOsVersionRange(self.getOs()); - return tmp.os_version_min.?; -} - -/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. -pub fn getOsVersionMax(self: Query) OsVersion { - if (self.os_version_max) |version_max| return version_max; - var tmp: Query = undefined; - tmp.updateOsVersionRange(self.getOs()); - return tmp.os_version_max.?; -} - -/// TODO deprecated, use `std.zig.system.resolveTargetQuery`. -pub fn getAbi(self: Query) Target.Abi { - if (self.abi) |abi| return abi; - - if (self.os_tag == null) { - // This works when doing `zig build` because Zig generates a build executable using - // native CPU model & features. However this will not be accurate otherwise, and - // will need to be integrated with `std.zig.system.resolveTargetQuery`. - return builtin.abi; - } - - return Target.Abi.default(self.getCpuArch(), self.getOs()); -} - -pub fn isFreeBSD(self: Query) bool { - return self.getOsTag() == .freebsd; -} - -pub fn isDarwin(self: Query) bool { - return self.getOsTag().isDarwin(); -} - -pub fn isNetBSD(self: Query) bool { - return self.getOsTag() == .netbsd; -} - -pub fn isOpenBSD(self: Query) bool { - return self.getOsTag() == .openbsd; -} - -pub fn isUefi(self: Query) bool { - return self.getOsTag() == .uefi; -} - -pub fn isDragonFlyBSD(self: Query) bool { - return self.getOsTag() == .dragonfly; -} - -pub fn isLinux(self: Query) bool { - return self.getOsTag() == .linux; -} - -pub fn isWindows(self: Query) bool { - return self.getOsTag() == .windows; -} - -pub fn exeFileExt(self: Query) [:0]const u8 { - return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag()); -} - -pub fn staticLibSuffix(self: Query) [:0]const u8 { - return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi()); -} - -pub fn dynamicLibSuffix(self: Query) [:0]const u8 { - return self.getOsTag().dynamicLibSuffix(); -} - -pub fn libPrefix(self: Query) [:0]const u8 { - return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi()); -} - pub fn isNativeCpu(self: Query) bool { return self.cpu_arch == null and (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and @@ -568,7 +425,7 @@ fn formatVersion(version: SemanticVersion, writer: anytype) !void { } } -pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 { +pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { if (self.isNative()) { return allocator.dupe(u8, "native"); } @@ -583,14 +440,16 @@ pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 // The zig target syntax does not allow specifying a max os version with no min, so // if either are present, we need the min. - if (self.os_version_min != null or self.os_version_max != null) { - switch (self.getOsVersionMin()) { + if (self.os_version_min) |min| { + switch (min) { .none => {}, .semver => |v| { try result.writer().writeAll("."); try formatVersion(v, result.writer()); }, - .windows => |v| try result.writer().print("{s}", .{v}), + .windows => |v| { + try result.writer().print("{s}", .{v}); + }, } } if (self.os_version_max) |max| { @@ -600,48 +459,88 @@ pub fn zigTriple(self: Query, allocator: mem.Allocator) error{OutOfMemory}![]u8 try result.writer().writeAll("..."); try formatVersion(v, result.writer()); }, - .windows => |v| try result.writer().print("..{s}", .{v}), + .windows => |v| { + try result.writer().print("...{s}", .{v}); + }, } } if (self.glibc_version) |v| { - try result.writer().print("-{s}.", .{@tagName(self.getAbi())}); + const name = @tagName(self.abi orelse builtin.target.abi); + try result.ensureUnusedCapacity(name.len + 2); + result.appendAssumeCapacity('-'); + result.appendSliceAssumeCapacity(name); + result.appendAssumeCapacity('.'); try formatVersion(v, result.writer()); } else if (self.abi) |abi| { - try result.writer().print("-{s}", .{@tagName(abi)}); + const name = @tagName(abi); + try result.ensureUnusedCapacity(name.len + 1); + result.appendAssumeCapacity('-'); + result.appendSliceAssumeCapacity(name); } return result.toOwnedSlice(); } -pub fn allocDescription(self: Query, allocator: mem.Allocator) ![]u8 { - // TODO is there anything else worthy of the description that is not - // already captured in the triple? - return self.zigTriple(allocator); -} +/// Renders the query into a textual representation that can be parsed via the +/// `-mcpu` flag passed to the Zig compiler. +/// Appends the result to `buffer`. +pub fn serializeCpu(q: Query, buffer: *std.ArrayList(u8)) Allocator.Error!void { + try buffer.ensureUnusedCapacity(8); + switch (q.cpu_model) { + .native => { + buffer.appendSliceAssumeCapacity("native"); + }, + .baseline => { + buffer.appendSliceAssumeCapacity("baseline"); + }, + .determined_by_cpu_arch => { + if (q.cpu_arch == null) { + buffer.appendSliceAssumeCapacity("native"); + } else { + buffer.appendSliceAssumeCapacity("baseline"); + } + }, + .explicit => |model| { + try buffer.appendSlice(model.name); + }, + } -pub fn linuxTriple(self: Query, allocator: mem.Allocator) ![]u8 { - return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi()); -} + if (q.cpu_features_add.isEmpty() and q.cpu_features_sub.isEmpty()) { + // The CPU name alone is sufficient. + return; + } -pub fn isGnuLibC(self: Query) bool { - return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi()); + const cpu_arch = q.cpu_arch orelse builtin.cpu.arch; + const all_features = cpu_arch.allFeaturesList(); + + for (all_features, 0..) |feature, i_usize| { + const i: Target.Cpu.Feature.Set.Index = @intCast(i_usize); + try buffer.ensureUnusedCapacity(feature.name.len + 1); + if (q.cpu_features_sub.isEnabled(i)) { + buffer.appendAssumeCapacity('-'); + buffer.appendSliceAssumeCapacity(feature.name); + } else if (q.cpu_features_add.isEnabled(i)) { + buffer.appendAssumeCapacity('+'); + buffer.appendSliceAssumeCapacity(feature.name); + } + } } -pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void { - assert(self.isGnuLibC()); - self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; +pub fn serializeCpuAlloc(q: Query, ally: Allocator) Allocator.Error![]u8 { + var buffer = std.ArrayList(u8).init(ally); + try serializeCpu(q, &buffer); + return buffer.toOwnedSlice(); } -pub fn getObjectFormat(self: Query) Target.ObjectFormat { - return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch()); +pub fn allocDescription(self: Query, allocator: Allocator) ![]u8 { + // TODO is there anything else worthy of the description that is not + // already captured in the triple? + return self.zigTriple(allocator); } -pub fn updateCpuFeatures(self: Query, set: *Target.Cpu.Feature.Set) void { - set.removeFeatureSet(self.cpu_features_sub); - set.addFeatureSet(self.cpu_features_add); - set.populateDependencies(self.getCpuArch().allFeaturesList()); - set.removeFeatureSet(self.cpu_features_sub); +pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void { + self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch }; } fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !void { @@ -653,7 +552,7 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) ! result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse return error.UnknownOperatingSystem; } - const tag = result.getOsTag(); + const tag = result.os_tag orelse builtin.os.tag; diags.os_tag = tag; const version_text = it.rest(); @@ -741,12 +640,35 @@ fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) ! } } +pub fn eql(a: Query, b: Query) bool { + if (a.cpu_arch != b.cpu_arch) return false; + if (!a.cpu_model.eql(b.cpu_model)) return false; + if (!a.cpu_features_add.eql(b.cpu_features_add)) return false; + if (!a.cpu_features_sub.eql(b.cpu_features_sub)) return false; + if (a.os_tag != b.os_tag) return false; + if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false; + if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false; + if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false; + if (a.abi != b.abi) return false; + if (!a.dynamic_linker.eql(b.dynamic_linker)) return false; + if (a.ofmt != b.ofmt) return false; + + return true; +} + +fn versionEqualOpt(a: ?SemanticVersion, b: ?SemanticVersion) bool { + if (a == null and b == null) return true; + if (a == null or b == null) return false; + return SemanticVersion.order(a.?, b.?) == .eq; +} + const Query = @This(); const std = @import("../std.zig"); const builtin = @import("builtin"); const assert = std.debug.assert; const Target = std.Target; const mem = std.mem; +const Allocator = std.mem.Allocator; test parse { if (builtin.target.isGnuLibC()) { @@ -760,7 +682,7 @@ test parse { const triple = std.fmt.bufPrint( buf[0..], "native-native-{s}.2.1.1", - .{@tagName(builtin.abi)}, + .{@tagName(builtin.target.abi)}, ) catch unreachable; try std.testing.expectEqualSlices(u8, triple, text); @@ -789,7 +711,7 @@ test parse { .arch_os_abi = "x86_64-linux-gnu", .cpu_features = "x86_64-sse-sse2-avx-cx8", }); - const target = query.toTarget(); + const target = try std.zig.system.resolveTargetQuery(query); try std.testing.expect(target.os.tag == .linux); try std.testing.expect(target.abi == .gnu); @@ -814,7 +736,7 @@ test parse { .arch_os_abi = "arm-linux-musleabihf", .cpu_features = "generic+v8a", }); - const target = query.toTarget(); + const target = try std.zig.system.resolveTargetQuery(query); try std.testing.expect(target.os.tag == .linux); try std.testing.expect(target.abi == .musleabihf); @@ -831,7 +753,7 @@ test parse { .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27", .cpu_features = "generic+v8a", }); - const target = query.toTarget(); + const target = try std.zig.system.resolveTargetQuery(query); try std.testing.expect(target.cpu.arch == .aarch64); try std.testing.expect(target.os.tag == .linux); diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 481768bfb2..84feb2cf0a 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -1,7 +1,4 @@ -const std = @import("std.zig"); -const tokenizer = @import("zig/tokenizer.zig"); pub const fmt = @import("zig/fmt.zig"); -const assert = std.debug.assert; pub const ErrorBundle = @import("zig/ErrorBundle.zig"); pub const Server = @import("zig/Server.zig"); @@ -115,7 +112,7 @@ pub const BinNameOptions = struct { }; /// Returns the standard file system basename of a binary generated by the Zig compiler. -pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { +pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 { const root_name = options.root_name; const target = options.target; switch (target.ofmt) { @@ -281,6 +278,47 @@ pub const BuildId = union(enum) { } }; +/// Renders a `std.Target.Cpu` value into a textual representation that can be parsed +/// via the `-mcpu` flag passed to the Zig compiler. +/// Appends the result to `buffer`. +pub fn serializeCpu(buffer: *std.ArrayList(u8), cpu: std.Target.Cpu) Allocator.Error!void { + const all_features = cpu.arch.allFeaturesList(); + var populated_cpu_features = cpu.model.features; + populated_cpu_features.populateDependencies(all_features); + + try buffer.appendSlice(cpu.model.name); + + if (populated_cpu_features.eql(cpu.features)) { + // The CPU name alone is sufficient. + return; + } + + for (all_features, 0..) |feature, i_usize| { + const i: std.Target.Cpu.Feature.Set.Index = @intCast(i_usize); + const in_cpu_set = populated_cpu_features.isEnabled(i); + const in_actual_set = cpu.features.isEnabled(i); + try buffer.ensureUnusedCapacity(feature.name.len + 1); + if (in_cpu_set and !in_actual_set) { + buffer.appendAssumeCapacity('-'); + buffer.appendSliceAssumeCapacity(feature.name); + } else if (!in_cpu_set and in_actual_set) { + buffer.appendAssumeCapacity('+'); + buffer.appendSliceAssumeCapacity(feature.name); + } + } +} + +pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![]u8 { + var buffer = std.ArrayList(u8).init(ally); + try serializeCpu(&buffer, cpu); + return buffer.toOwnedSlice(); +} + +const std = @import("std.zig"); +const tokenizer = @import("zig/tokenizer.zig"); +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; + test { @import("std").testing.refAllDecls(@This()); } diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 6920999ef0..c2a9fa4f9f 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -163,7 +163,8 @@ pub const DetectError = error{ /// components by detecting the native system, and then resolves /// standard/default parts relative to that. pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { - var os = query.getOsTag().defaultVersionRange(query.getCpuArch()); + const query_os_tag = query.os_tag orelse builtin.os.tag; + var os = query_os_tag.defaultVersionRange(query.cpu_arch orelse builtin.cpu.arch); if (query.os_tag == null) { switch (builtin.target.os.tag) { .linux => { @@ -292,7 +293,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { if (query.os_version_min) |min| switch (min) { .none => {}, - .semver => |semver| switch (query.getOsTag()) { + .semver => |semver| switch (os.tag) { .linux => os.version_range.linux.range.min = semver, else => os.version_range.semver.min = semver, }, @@ -301,7 +302,7 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { if (query.os_version_max) |max| switch (max) { .none => {}, - .semver => |semver| switch (query.getOsTag()) { + .semver => |semver| switch (os.tag) { .linux => os.version_range.linux.range.max = semver, else => os.version_range.semver.max = semver, }, @@ -309,13 +310,12 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { }; if (query.glibc_version) |glibc| { - assert(query.isGnuLibC()); os.version_range.linux.glibc = glibc; } // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the // native CPU architecture as being different than the current target), we use this: - const cpu_arch = query.getCpuArch(); + const cpu_arch = query.cpu_arch orelse builtin.cpu.arch; const cpu = switch (query.cpu_model) { .native => detectNativeCpuAndFeatures(cpu_arch, os, query), @@ -361,10 +361,27 @@ pub fn resolveTargetQuery(query: Target.Query) DetectError!Target { }, else => {}, } - query.updateCpuFeatures(&result.cpu.features); + updateCpuFeatures( + &result.cpu.features, + cpu_arch.allFeaturesList(), + query.cpu_features_add, + query.cpu_features_sub, + ); return result; } +fn updateCpuFeatures( + set: *Target.Cpu.Feature.Set, + all_features_list: []const Target.Cpu.Feature, + add_set: Target.Cpu.Feature.Set, + sub_set: Target.Cpu.Feature.Set, +) void { + set.removeFeatureSet(sub_set); + set.addFeatureSet(add_set); + set.populateDependencies(all_features_list); + set.removeFeatureSet(sub_set); +} + fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu { // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`, // although it is a runtime value, is guaranteed to be one of the architectures in the set diff --git a/src/libc_installation.zig b/src/libc_installation.zig index facb16257e..0901194dd8 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -41,7 +41,7 @@ pub const LibCInstallation = struct { pub fn parse( allocator: Allocator, libc_file: []const u8, - target: std.Target.Query, + target: std.Target, ) !LibCInstallation { var self: LibCInstallation = .{}; @@ -95,24 +95,23 @@ pub const LibCInstallation = struct { return error.ParseError; } - const os_tag = target.getOsTag(); + const os_tag = target.os.tag; if (self.crt_dir == null and !target.isDarwin()) { log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)}); return error.ParseError; } - const abi = target.getAbi(); - if (self.msvc_lib_dir == null and target.isWindows() and abi == .msvc) { + if (self.msvc_lib_dir == null and os_tag == .windows and target.abi == .msvc) { log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{ @tagName(os_tag), - @tagName(abi), + @tagName(target.abi), }); return error.ParseError; } - if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) { + if (self.kernel32_lib_dir == null and os_tag == .windows and target.abi == .msvc) { log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{ @tagName(os_tag), - @tagName(abi), + @tagName(target.abi), }); return error.ParseError; } diff --git a/src/main.zig b/src/main.zig index 716be60763..3abe6ed3e4 100644 --- a/src/main.zig +++ b/src/main.zig @@ -2696,13 +2696,13 @@ fn buildOutputType( } if (use_lld) |opt| { - if (opt and target_query.isDarwin()) { + if (opt and target.isDarwin()) { fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{}); } } if (want_lto) |opt| { - if (opt and target_query.isDarwin()) { + if (opt and target.isDarwin()) { fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{}); } } @@ -2772,7 +2772,7 @@ fn buildOutputType( var libc_installation: ?LibCInstallation = null; if (libc_paths_file) |paths_file| { - libc_installation = LibCInstallation.parse(arena, paths_file, target_query) catch |err| { + libc_installation = LibCInstallation.parse(arena, paths_file, target) catch |err| { fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) }); }; } @@ -2865,7 +2865,7 @@ fn buildOutputType( libc_installation = try LibCInstallation.findNative(.{ .allocator = arena, .verbose = true, - .target = target_query.toTarget(), + .target = target, }); try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? }); @@ -4755,6 +4755,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { const target_query = try parseTargetQueryOrReportFatalError(gpa, .{ .arch_os_abi = target_arch_os_abi, }); + const target = try std.zig.system.resolveTargetQuery(target_query); if (print_includes) { var arena_state = std.heap.ArenaAllocator.init(gpa); @@ -4764,7 +4765,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { const libc_installation: ?*LibCInstallation = libc: { if (input_file) |libc_file| { const libc = try arena.create(LibCInstallation); - libc.* = LibCInstallation.parse(arena, libc_file, target_query) catch |err| { + libc.* = LibCInstallation.parse(arena, libc_file, target) catch |err| { fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); }; break :libc libc; @@ -4779,7 +4780,6 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { }; defer zig_lib_directory.handle.close(); - const target = target_query.toTarget(); const is_native_abi = target_query.isNativeAbi(); const libc_dirs = Compilation.detectLibCIncludeDirs( @@ -4810,7 +4810,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { } if (input_file) |libc_file| { - var libc = LibCInstallation.parse(gpa, libc_file, target_query) catch |err| { + var libc = LibCInstallation.parse(gpa, libc_file, target) catch |err| { fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) }); }; defer libc.deinit(gpa); @@ -4821,7 +4821,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void { var libc = LibCInstallation.findNative(.{ .allocator = gpa, .verbose = true, - .target = try std.zig.system.resolveTargetQuery(target_query), + .target = target, }) catch |err| { fatal("unable to detect native libc: {s}", .{@errorName(err)}); }; diff --git a/test/tests.zig b/test/tests.zig index 29d181c605..64c0f3a42e 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -1036,14 +1036,17 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { for (test_targets) |test_target| { const is_native = test_target.target.isNative() or - (test_target.target.getOsTag() == builtin.os.tag and - test_target.target.getCpuArch() == builtin.cpu.arch); + (test_target.target.os_tag == builtin.os.tag and + test_target.target.cpu_arch == builtin.cpu.arch); if (options.skip_non_native and !is_native) continue; + const resolved_target = b.resolveTargetQuery(test_target.target); + const target = resolved_target.target; + if (options.skip_cross_glibc and !test_target.target.isNative() and - test_target.target.isGnuLibC() and test_target.link_libc == true) + target.isGnuLibC() and test_target.link_libc == true) continue; if (options.skip_libc and test_target.link_libc == true) @@ -1053,35 +1056,30 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { continue; // TODO get compiler-rt tests passing for self-hosted backends. - if ((test_target.target.getCpuArch() != .x86_64 or - test_target.target.getObjectFormat() != .elf) and + if ((target.cpu.arch != .x86_64 or target.ofmt != .elf) and test_target.use_llvm == false and mem.eql(u8, options.name, "compiler-rt")) continue; // TODO get compiler-rt tests passing for wasm32-wasi // currently causes "LLVM ERROR: Unable to expand fixed point multiplication." - if (test_target.target.getCpuArch() == .wasm32 and - test_target.target.getOsTag() == .wasi and + if (target.cpu.arch == .wasm32 and target.os.tag == .wasi and mem.eql(u8, options.name, "compiler-rt")) { continue; } // TODO get universal-libc tests passing for other self-hosted backends. - if (test_target.target.getCpuArch() != .x86_64 and + if (target.cpu.arch != .x86_64 and test_target.use_llvm == false and mem.eql(u8, options.name, "universal-libc")) continue; // TODO get std lib tests passing for other self-hosted backends. - if ((test_target.target.getCpuArch() != .x86_64 or - test_target.target.getOsTag() != .linux) and + if ((target.cpu.arch != .x86_64 or target.os.tag != .linux) and test_target.use_llvm == false and mem.eql(u8, options.name, "std")) continue; - if (test_target.target.getCpuArch() == .x86_64 and - test_target.target.getOsTag() == .windows and - test_target.target.cpu_arch == null and - test_target.optimize_mode != .Debug and + if (target.cpu.arch == .x86_64 and target.os.tag == .windows and + test_target.target.cpu_arch == null and test_target.optimize_mode != .Debug and mem.eql(u8, options.name, "std")) { // https://github.com/ziglang/zig/issues/17902 @@ -1094,11 +1092,11 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { if (!want_this_mode) continue; const libc_suffix = if (test_target.link_libc == true) "-libc" else ""; - const triple_txt = test_target.target.zigTriple(b.allocator) catch @panic("OOM"); - const model_txt = test_target.target.getCpuModel().name; + const triple_txt = target.zigTriple(b.allocator) catch @panic("OOM"); + const model_txt = target.cpu.model.name; // wasm32-wasi builds need more RAM, idk why - const max_rss = if (test_target.target.getOs().tag == .wasi) + const max_rss = if (target.os.tag == .wasi) options.max_rss * 2 else options.max_rss; @@ -1106,7 +1104,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { const these_tests = b.addTest(.{ .root_source_file = .{ .path = options.root_src }, .optimize = test_target.optimize_mode, - .target = b.resolveTargetQuery(test_target.target), + .target = resolved_target, .max_rss = max_rss, .filter = options.test_filter, .link_libc = test_target.link_libc, @@ -1120,7 +1118,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else ""; const backend_suffix = if (test_target.use_llvm == true) "-llvm" - else if (test_target.target.ofmt == std.Target.ObjectFormat.c) + else if (target.ofmt == std.Target.ObjectFormat.c) "-cbe" else if (test_target.use_llvm == false) "-selfhosted" @@ -1131,7 +1129,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { these_tests.addIncludePath(.{ .path = "test" }); - if (test_target.target.getOs().tag == .wasi) { + if (target.os.tag == .wasi) { // WASI's default stack size can be too small for some big tests. these_tests.stack_size = 2 * 1024 * 1024; } @@ -1148,14 +1146,14 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { use_pic, }); - if (test_target.target.ofmt == std.Target.ObjectFormat.c) { - var altered_target = test_target.target; - altered_target.ofmt = null; + if (target.ofmt == std.Target.ObjectFormat.c) { + var altered_query = test_target.target; + altered_query.ofmt = null; const compile_c = b.addExecutable(.{ .name = qualified_name, .link_libc = test_target.link_libc, - .target = b.resolveTargetQuery(altered_target), + .target = b.resolveTargetQuery(altered_query), .zig_lib_dir = .{ .path = "lib" }, }); compile_c.addCSourceFile(.{ @@ -1179,7 +1177,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step { }, }); compile_c.addIncludePath(.{ .path = "lib" }); // for zig.h - if (test_target.target.getOsTag() == .windows) { + if (target.os.tag == .windows) { if (true) { // Unfortunately this requires about 8G of RAM for clang to compile // and our Windows CI runners do not have this much. -- cgit v1.2.3 From 8d5da5558827d9152dc8453c87c41ac6519f8a05 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 4 Dec 2023 23:15:53 -0700 Subject: std.Target.Query: fix regression with windows os version range somebody left a landmine here without even a comment to warn about it --- lib/std/Target/Query.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/std/Target') diff --git a/lib/std/Target/Query.zig b/lib/std/Target/Query.zig index 1deff022cc..10130e03bb 100644 --- a/lib/std/Target/Query.zig +++ b/lib/std/Target/Query.zig @@ -460,7 +460,9 @@ pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 { try formatVersion(v, result.writer()); }, .windows => |v| { - try result.writer().print("...{s}", .{v}); + // This is counting on a custom format() function defined on `WindowsVersion` + // to add a prefix '.' and make there be a total of three dots. + try result.writer().print("..{s}", .{v}); }, } } -- cgit v1.2.3