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