authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-02 14:11:27-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-02 14:11:27-08:00
log289ae45c1b58e952867c4fa1e246d0ef7bc2ff64
tree5dd034143a2354b7b44496e684f1c764e2f9664c
parentc89bb3e141ee215add0b52930d48bffd8dae8342
parentc546ddb3edc557fae4b932e5239b9dcb66117832
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #18160 from ziglang/std-build-module

Move many settings from being per-Compilation to being per-Module

258 files changed, 43139 insertions(+), 40739 deletions(-)

CMakeLists.txt+43-34
......@@ -480,22 +480,23 @@ set(ZIG_STAGE2_SOURCES
480480 "${CMAKE_SOURCE_DIR}/lib/compiler_rt/unordtf2.zig"
481481 "${CMAKE_SOURCE_DIR}/lib/std/start.zig"
482482 "${CMAKE_SOURCE_DIR}/lib/std/std.zig"
483 "${CMAKE_SOURCE_DIR}/lib/std/target.zig"
484 "${CMAKE_SOURCE_DIR}/lib/std/target/aarch64.zig"
485 "${CMAKE_SOURCE_DIR}/lib/std/target/amdgpu.zig"
486 "${CMAKE_SOURCE_DIR}/lib/std/target/arm.zig"
487 "${CMAKE_SOURCE_DIR}/lib/std/target/avr.zig"
488 "${CMAKE_SOURCE_DIR}/lib/std/target/bpf.zig"
489 "${CMAKE_SOURCE_DIR}/lib/std/target/hexagon.zig"
490 "${CMAKE_SOURCE_DIR}/lib/std/target/mips.zig"
491 "${CMAKE_SOURCE_DIR}/lib/std/target/msp430.zig"
492 "${CMAKE_SOURCE_DIR}/lib/std/target/nvptx.zig"
493 "${CMAKE_SOURCE_DIR}/lib/std/target/powerpc.zig"
494 "${CMAKE_SOURCE_DIR}/lib/std/target/riscv.zig"
495 "${CMAKE_SOURCE_DIR}/lib/std/target/sparc.zig"
496 "${CMAKE_SOURCE_DIR}/lib/std/target/s390x.zig"
497 "${CMAKE_SOURCE_DIR}/lib/std/target/wasm.zig"
498 "${CMAKE_SOURCE_DIR}/lib/std/target/x86.zig"
483 "${CMAKE_SOURCE_DIR}/lib/std/Target.zig"
484 "${CMAKE_SOURCE_DIR}/lib/std/Target/Query.zig"
485 "${CMAKE_SOURCE_DIR}/lib/std/Target/aarch64.zig"
486 "${CMAKE_SOURCE_DIR}/lib/std/Target/amdgpu.zig"
487 "${CMAKE_SOURCE_DIR}/lib/std/Target/arm.zig"
488 "${CMAKE_SOURCE_DIR}/lib/std/Target/avr.zig"
489 "${CMAKE_SOURCE_DIR}/lib/std/Target/bpf.zig"
490 "${CMAKE_SOURCE_DIR}/lib/std/Target/hexagon.zig"
491 "${CMAKE_SOURCE_DIR}/lib/std/Target/mips.zig"
492 "${CMAKE_SOURCE_DIR}/lib/std/Target/msp430.zig"
493 "${CMAKE_SOURCE_DIR}/lib/std/Target/nvptx.zig"
494 "${CMAKE_SOURCE_DIR}/lib/std/Target/powerpc.zig"
495 "${CMAKE_SOURCE_DIR}/lib/std/Target/riscv.zig"
496 "${CMAKE_SOURCE_DIR}/lib/std/Target/sparc.zig"
497 "${CMAKE_SOURCE_DIR}/lib/std/Target/s390x.zig"
498 "${CMAKE_SOURCE_DIR}/lib/std/Target/wasm.zig"
499 "${CMAKE_SOURCE_DIR}/lib/std/Target/x86.zig"
499500 "${CMAKE_SOURCE_DIR}/lib/std/Thread.zig"
500501 "${CMAKE_SOURCE_DIR}/lib/std/Thread/Futex.zig"
501502 "${CMAKE_SOURCE_DIR}/lib/std/Thread/Mutex.zig"
......@@ -508,7 +509,6 @@ set(ZIG_STAGE2_SOURCES
508509 "${CMAKE_SOURCE_DIR}/lib/std/zig.zig"
509510 "${CMAKE_SOURCE_DIR}/lib/std/zig/Ast.zig"
510511 "${CMAKE_SOURCE_DIR}/lib/std/zig/AstRlAnnotate.zig"
511 "${CMAKE_SOURCE_DIR}/lib/std/zig/CrossTarget.zig"
512512 "${CMAKE_SOURCE_DIR}/lib/std/zig/c_builtins.zig"
513513 "${CMAKE_SOURCE_DIR}/lib/std/zig/Parse.zig"
514514 "${CMAKE_SOURCE_DIR}/lib/std/zig/render.zig"
......@@ -516,12 +516,12 @@ set(ZIG_STAGE2_SOURCES
516516 "${CMAKE_SOURCE_DIR}/lib/std/zig/string_literal.zig"
517517 "${CMAKE_SOURCE_DIR}/lib/std/zig/system.zig"
518518 "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativePaths.zig"
519 "${CMAKE_SOURCE_DIR}/lib/std/zig/system/NativeTargetInfo.zig"
520519 "${CMAKE_SOURCE_DIR}/lib/std/zig/system/x86.zig"
521520 "${CMAKE_SOURCE_DIR}/lib/std/zig/tokenizer.zig"
522521 "${CMAKE_SOURCE_DIR}/src/Air.zig"
523522 "${CMAKE_SOURCE_DIR}/src/AstGen.zig"
524523 "${CMAKE_SOURCE_DIR}/src/Compilation.zig"
524 "${CMAKE_SOURCE_DIR}/src/Compilation/Config.zig"
525525 "${CMAKE_SOURCE_DIR}/src/Liveness.zig"
526526 "${CMAKE_SOURCE_DIR}/src/Module.zig"
527527 "${CMAKE_SOURCE_DIR}/src/Package.zig"
......@@ -810,18 +810,26 @@ endif()
810810
811811set(BUILD_ZIG2_ARGS
812812 "${CMAKE_SOURCE_DIR}/lib"
813 build-exe src/main.zig -ofmt=c -lc
814 -OReleaseSmall
815 --name zig2 -femit-bin="${ZIG2_C_SOURCE}"
816 --mod "build_options::${ZIG_CONFIG_ZIG_OUT}"
817 --mod "aro_options::src/stubs/aro_options.zig"
818 --mod "Builtins/Builtin.def::src/stubs/aro_builtins.zig"
819 --mod "Attribute/names.def::src/stubs/aro_names.zig"
820 --mod "Diagnostics/messages.def::src/stubs/aro_messages.zig"
821 --mod "aro_backend:build_options=aro_options:deps/aro/backend.zig"
822 --mod "aro:Builtins/Builtin.def,Attribute/names.def,Diagnostics/messages.def,build_options=aro_options,backend=aro_backend:deps/aro/aro.zig"
823 --deps build_options,aro
813 build-exe -ofmt=c -lc -OReleaseSmall
814 --name zig2
815 -femit-bin="${ZIG2_C_SOURCE}"
824816 -target "${ZIG_HOST_TARGET_TRIPLE}"
817 --dep "build_options"
818 --dep "aro"
819 --mod "root" "src/main.zig"
820 --mod "build_options" "${ZIG_CONFIG_ZIG_OUT}"
821 --mod "aro_options" "src/stubs/aro_options.zig"
822 --mod "Builtins/Builtin.def" "src/stubs/aro_builtins.zig"
823 --mod "Attribute/names.def" "src/stubs/aro_names.zig"
824 --mod "Diagnostics/messages.def" "src/stubs/aro_messages.zig"
825 --dep "build_options=aro_options"
826 --mod "aro_backend" "deps/aro/backend.zig"
827 --dep "Builtins/Builtin.def"
828 --dep "Attribute/names.def"
829 --dep "Diagnostics/messages.def"
830 --dep "build_options=aro_options"
831 --dep "backend=aro_backend"
832 --mod "aro" "deps/aro/aro.zig"
825833)
826834
827835add_custom_command(
......@@ -834,12 +842,13 @@ add_custom_command(
834842
835843set(BUILD_COMPILER_RT_ARGS
836844 "${CMAKE_SOURCE_DIR}/lib"
837 build-obj lib/compiler_rt.zig -ofmt=c
838 -OReleaseSmall
839 --name compiler_rt -femit-bin="${ZIG_COMPILER_RT_C_SOURCE}"
840 --mod "build_options::${ZIG_CONFIG_ZIG_OUT}"
841 --deps build_options
845 build-obj -ofmt=c -OReleaseSmall
846 --name compiler_rt
847 -femit-bin="${ZIG_COMPILER_RT_C_SOURCE}"
842848 -target "${ZIG_HOST_TARGET_TRIPLE}"
849 --dep "build_options"
850 --mod "root" "lib/compiler_rt.zig"
851 --mod "build_options" "${ZIG_CONFIG_ZIG_OUT}"
843852)
844853
845854add_custom_command(
bootstrap.c+24-12
......@@ -138,18 +138,29 @@ int main(int argc, char **argv) {
138138
139139 {
140140 const char *child_argv[] = {
141 "./zig1", "lib", "build-exe", "src/main.zig",
141 "./zig1", "lib", "build-exe",
142142 "-ofmt=c", "-lc", "-OReleaseSmall",
143143 "--name", "zig2", "-femit-bin=zig2.c",
144 "--mod", "build_options::config.zig",
145 "--mod", "aro_options::src/stubs/aro_options.zig",
146 "--mod", "Builtins/Builtin.def::src/stubs/aro_builtins.zig",
147 "--mod", "Attribute/names.def::src/stubs/aro_names.zig",
148 "--mod", "Diagnostics/messages.def::src/stubs/aro_messages.zig",
149 "--mod", "aro_backend:build_options=aro_options:deps/aro/backend.zig",
150 "--mod", "aro:Builtins/Builtin.def,Attribute/names.def,Diagnostics/messages.def,build_options=aro_options,backend=aro_backend:deps/aro/aro.zig",
151 "--deps", "build_options,aro",
152144 "-target", host_triple,
145 "--dep", "build_options",
146 "--dep", "aro",
147 "--mod", "root", "src/main.zig",
148
149 "--mod", "build_options", "config.zig",
150 "--mod", "aro_options", "src/stubs/aro_options.zig",
151 "--mod", "Builtins/Builtin.def", "src/stubs/aro_builtins.zig",
152 "--mod", "Attribute/names.def", "src/stubs/aro_names.zig",
153 "--mod", "Diagnostics/messages.def", "src/stubs/aro_messages.zig",
154
155 "--dep", "build_options=aro_options",
156 "--mod", "aro_backend", "deps/aro/backend.zig",
157
158 "--dep", "Builtins/Builtin.def",
159 "--dep", "Attribute/names.def",
160 "--dep", "Diagnostics/messages.def",
161 "--dep", "build_options=aro_options",
162 "--dep", "backend=aro_backend",
163 "--mod", "aro", "deps/aro/aro.zig",
153164 NULL,
154165 };
155166 print_and_run(child_argv);
......@@ -157,12 +168,13 @@ int main(int argc, char **argv) {
157168
158169 {
159170 const char *child_argv[] = {
160 "./zig1", "lib", "build-obj", "lib/compiler_rt.zig",
171 "./zig1", "lib", "build-obj",
161172 "-ofmt=c", "-OReleaseSmall",
162173 "--name", "compiler_rt", "-femit-bin=compiler_rt.c",
163 "--mod", "build_options::config.zig",
164 "--deps", "build_options",
165174 "-target", host_triple,
175 "--dep", "build_options",
176 "--mod", "root", "lib/compiler_rt.zig",
177 "--mod", "build_options", "config.zig",
166178 NULL,
167179 };
168180 print_and_run(child_argv);
build.zig+53-39
......@@ -39,10 +39,10 @@ pub fn build(b: *std.Build) !void {
3939 const docgen_exe = b.addExecutable(.{
4040 .name = "docgen",
4141 .root_source_file = .{ .path = "tools/docgen.zig" },
42 .target = .{},
42 .target = b.host,
4343 .optimize = .Debug,
44 .single_threaded = single_threaded,
4445 });
45 docgen_exe.single_threaded = single_threaded;
4646
4747 const docgen_cmd = b.addRunArtifact(docgen_exe);
4848 docgen_cmd.addArgs(&.{ "--zig", b.zig_exe });
......@@ -89,11 +89,11 @@ pub fn build(b: *std.Build) !void {
8989 const check_case_exe = b.addExecutable(.{
9090 .name = "check-case",
9191 .root_source_file = .{ .path = "test/src/Cases.zig" },
92 .target = b.host,
9293 .optimize = optimize,
93 .main_mod_path = .{ .path = "." },
94 .single_threaded = single_threaded,
9495 });
9596 check_case_exe.stack_size = stack_size;
96 check_case_exe.single_threaded = single_threaded;
9797
9898 const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false;
9999 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
......@@ -194,14 +194,18 @@ pub fn build(b: *std.Build) !void {
194194 break :blk 4;
195195 };
196196
197 const exe = addCompilerStep(b, optimize, target);
198 exe.strip = strip;
197 const exe = addCompilerStep(b, .{
198 .optimize = optimize,
199 .target = target,
200 .strip = strip,
201 .sanitize_thread = sanitize_thread,
202 .single_threaded = single_threaded,
203 });
199204 exe.pie = pie;
200 exe.sanitize_thread = sanitize_thread;
201205 exe.entitlements = entitlements;
202206
203207 exe.build_id = b.option(
204 std.Build.Step.Compile.BuildId,
208 std.zig.BuildId,
205209 "build-id",
206210 "Request creation of '.note.gnu.build-id' section",
207211 );
......@@ -217,9 +221,7 @@ pub fn build(b: *std.Build) !void {
217221
218222 test_step.dependOn(&exe.step);
219223
220 exe.single_threaded = single_threaded;
221
222 if (target.isWindows() and target.getAbi() == .gnu) {
224 if (target.result.os.tag == .windows and target.result.abi == .gnu) {
223225 // LTO is currently broken on mingw, this can be removed when it's fixed.
224226 exe.want_lto = false;
225227 check_case_exe.want_lto = false;
......@@ -230,7 +232,7 @@ pub fn build(b: *std.Build) !void {
230232 exe.use_lld = use_llvm;
231233
232234 const exe_options = b.addOptions();
233 exe.addOptions("build_options", exe_options);
235 exe.root_module.addOptions("build_options", exe_options);
234236
235237 exe_options.addOption(u32, "mem_leak_frames", mem_leak_frames);
236238 exe_options.addOption(bool, "skip_non_native", skip_non_native);
......@@ -345,7 +347,7 @@ pub fn build(b: *std.Build) !void {
345347 try addStaticLlvmOptionsToExe(exe);
346348 try addStaticLlvmOptionsToExe(check_case_exe);
347349 }
348 if (target.isWindows()) {
350 if (target.result.os.tag == .windows) {
349351 inline for (.{ exe, check_case_exe }) |artifact| {
350352 artifact.linkSystemLibrary("version");
351353 artifact.linkSystemLibrary("uuid");
......@@ -369,7 +371,7 @@ pub fn build(b: *std.Build) !void {
369371 );
370372
371373 // On mingw, we need to opt into windows 7+ to get some features required by tracy.
372 const tracy_c_flags: []const []const u8 = if (target.isWindows() and target.getAbi() == .gnu)
374 const tracy_c_flags: []const []const u8 = if (target.result.os.tag == .windows and target.result.abi == .gnu)
373375 &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined", "-D_WIN32_WINNT=0x601" }
374376 else
375377 &[_][]const u8{ "-DTRACY_ENABLE=1", "-fno-sanitize=undefined" };
......@@ -377,11 +379,11 @@ pub fn build(b: *std.Build) !void {
377379 exe.addIncludePath(.{ .cwd_relative = tracy_path });
378380 exe.addCSourceFile(.{ .file = .{ .cwd_relative = client_cpp }, .flags = tracy_c_flags });
379381 if (!enable_llvm) {
380 exe.linkSystemLibraryName("c++");
382 exe.root_module.linkSystemLibrary("c++", .{ .use_pkg_config = .no });
381383 }
382384 exe.linkLibC();
383385
384 if (target.isWindows()) {
386 if (target.result.os.tag == .windows) {
385387 exe.linkSystemLibrary("dbghelp");
386388 exe.linkSystemLibrary("ws2_32");
387389 }
......@@ -390,7 +392,7 @@ pub fn build(b: *std.Build) !void {
390392 const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
391393
392394 const test_cases_options = b.addOptions();
393 check_case_exe.addOptions("build_options", test_cases_options);
395 check_case_exe.root_module.addOptions("build_options", test_cases_options);
394396
395397 test_cases_options.addOption(bool, "enable_tracy", false);
396398 test_cases_options.addOption(bool, "enable_logging", enable_logging);
......@@ -540,16 +542,19 @@ pub fn build(b: *std.Build) !void {
540542fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
541543 const semver = try std.SemanticVersion.parse(version);
542544
543 var target: std.zig.CrossTarget = .{
545 var target_query: std.zig.CrossTarget = .{
544546 .cpu_arch = .wasm32,
545547 .os_tag = .wasi,
546548 };
547 target.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory));
549 target_query.cpu_features_add.addFeature(@intFromEnum(std.Target.wasm.Feature.bulk_memory));
548550
549 const exe = addCompilerStep(b, .ReleaseSmall, target);
551 const exe = addCompilerStep(b, .{
552 .optimize = .ReleaseSmall,
553 .target = b.resolveTargetQuery(target_query),
554 });
550555
551556 const exe_options = b.addOptions();
552 exe.addOptions("build_options", exe_options);
557 exe.root_module.addOptions("build_options", exe_options);
553558
554559 exe_options.addOption(u32, "mem_leak_frames", 0);
555560 exe_options.addOption(bool, "have_llvm", false);
......@@ -584,17 +589,24 @@ fn addWasiUpdateStep(b: *std.Build, version: [:0]const u8) !void {
584589 update_zig1_step.dependOn(&copy_zig_h.step);
585590}
586591
587fn addCompilerStep(
588 b: *std.Build,
592const AddCompilerStepOptions = struct {
589593 optimize: std.builtin.OptimizeMode,
590 target: std.zig.CrossTarget,
591) *std.Build.Step.Compile {
594 target: std.Build.ResolvedTarget,
595 strip: ?bool = null,
596 sanitize_thread: ?bool = null,
597 single_threaded: ?bool = null,
598};
599
600fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.Step.Compile {
592601 const exe = b.addExecutable(.{
593602 .name = "zig",
594603 .root_source_file = .{ .path = "src/main.zig" },
595 .target = target,
596 .optimize = optimize,
604 .target = options.target,
605 .optimize = options.optimize,
597606 .max_rss = 7_000_000_000,
607 .strip = options.strip,
608 .sanitize_thread = options.sanitize_thread,
609 .single_threaded = options.single_threaded,
598610 });
599611 exe.stack_size = stack_size;
600612
......@@ -602,15 +614,15 @@ fn addCompilerStep(
602614 aro_options.addOption([]const u8, "version_str", "aro-zig");
603615 const aro_options_module = aro_options.createModule();
604616 const aro_backend = b.createModule(.{
605 .source_file = .{ .path = "deps/aro/backend.zig" },
606 .dependencies = &.{.{
617 .root_source_file = .{ .path = "deps/aro/backend.zig" },
618 .imports = &.{.{
607619 .name = "build_options",
608620 .module = aro_options_module,
609621 }},
610622 });
611623 const aro_module = b.createModule(.{
612 .source_file = .{ .path = "deps/aro/aro.zig" },
613 .dependencies = &.{
624 .root_source_file = .{ .path = "deps/aro/aro.zig" },
625 .imports = &.{
614626 .{
615627 .name = "build_options",
616628 .module = aro_options_module,
......@@ -625,7 +637,7 @@ fn addCompilerStep(
625637 },
626638 });
627639
628 exe.addModule("aro", aro_module);
640 exe.root_module.addImport("aro", aro_module);
629641 return exe;
630642}
631643
......@@ -649,7 +661,7 @@ fn addCmakeCfgOptionsToExe(
649661 exe: *std.Build.Step.Compile,
650662 use_zig_libcxx: bool,
651663) !void {
652 if (exe.target.isDarwin()) {
664 if (exe.rootModuleTarget().isDarwin()) {
653665 // useful for package maintainers
654666 exe.headerpad_max_install_names = true;
655667 }
......@@ -677,8 +689,8 @@ fn addCmakeCfgOptionsToExe(
677689 // against system-provided LLVM, Clang, LLD.
678690 const need_cpp_includes = true;
679691 const static = cfg.llvm_linkage == .static;
680 const lib_suffix = if (static) exe.target.staticLibSuffix()[1..] else exe.target.dynamicLibSuffix()[1..];
681 switch (exe.target.getOsTag()) {
692 const lib_suffix = if (static) exe.rootModuleTarget().staticLibSuffix()[1..] else exe.rootModuleTarget().dynamicLibSuffix()[1..];
693 switch (exe.rootModuleTarget().os.tag) {
682694 .linux => {
683695 // First we try to link against the detected libcxx name. If that doesn't work, we fall
684696 // back to -lc++ and cross our fingers.
......@@ -694,7 +706,7 @@ fn addCmakeCfgOptionsToExe(
694706 exe.linkLibCpp();
695707 },
696708 .windows => {
697 if (exe.target.getAbi() != .msvc) exe.linkLibCpp();
709 if (exe.rootModuleTarget().abi != .msvc) exe.linkLibCpp();
698710 },
699711 .freebsd => {
700712 if (static) {
......@@ -756,12 +768,12 @@ fn addStaticLlvmOptionsToExe(exe: *std.Build.Step.Compile) !void {
756768 exe.linkSystemLibrary("z");
757769 exe.linkSystemLibrary("zstd");
758770
759 if (exe.target.getOs().tag != .windows or exe.target.getAbi() != .msvc) {
771 if (exe.rootModuleTarget().os.tag != .windows or exe.rootModuleTarget().abi != .msvc) {
760772 // This means we rely on clang-or-zig-built LLVM, Clang, LLD libraries.
761773 exe.linkSystemLibrary("c++");
762774 }
763775
764 if (exe.target.getOs().tag == .windows) {
776 if (exe.rootModuleTarget().os.tag == .windows) {
765777 exe.linkSystemLibrary("version");
766778 exe.linkSystemLibrary("uuid");
767779 exe.linkSystemLibrary("ole32");
......@@ -810,7 +822,9 @@ fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void {
810822 while (it.next()) |lib| {
811823 if (mem.startsWith(u8, lib, "-l")) {
812824 exe.linkSystemLibrary(lib["-l".len..]);
813 } else if (exe.target.isWindows() and mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib)) {
825 } else if (exe.rootModuleTarget().os.tag == .windows and
826 mem.endsWith(u8, lib, ".lib") and !fs.path.isAbsolute(lib))
827 {
814828 exe.linkSystemLibrary(lib[0 .. lib.len - ".lib".len]);
815829 } else {
816830 exe.addObjectFile(.{ .cwd_relative = lib });
ci/x86_64-windows-debug.ps1+4-4
......@@ -76,15 +76,15 @@ Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
7676CheckLastExitCode
7777
7878& "stage3-debug\bin\zig.exe" build-obj `
79 ..\lib\compiler_rt.zig `
8079 --zig-lib-dir "$ZIG_LIB_DIR" `
8180 -ofmt=c `
8281 -OReleaseSmall `
8382 --name compiler_rt `
8483 -femit-bin="compiler_rt-x86_64-windows-msvc.c" `
85 --mod build_options::config.zig `
86 --deps build_options `
87 -target x86_64-windows-msvc
84 --dep build_options `
85 -target x86_64-windows-msvc `
86 --mod root ..\lib\compiler_rt.zig `
87 --mod build_options config.zig
8888CheckLastExitCode
8989
9090Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
ci/x86_64-windows-release.ps1+4-4
......@@ -75,15 +75,15 @@ Write-Output "Build x86_64-windows-msvc behavior tests using the C backend..."
7575CheckLastExitCode
7676
7777& "stage3-release\bin\zig.exe" build-obj `
78 ..\lib\compiler_rt.zig `
7978 --zig-lib-dir "$ZIG_LIB_DIR" `
8079 -ofmt=c `
8180 -OReleaseSmall `
8281 --name compiler_rt `
8382 -femit-bin="compiler_rt-x86_64-windows-msvc.c" `
84 --mod build_options::config.zig `
85 --deps build_options `
86 -target x86_64-windows-msvc
83 --dep build_options `
84 -target x86_64-windows-msvc `
85 --mod root ..\lib\compiler_rt.zig `
86 --mod build_options config.zig
8787CheckLastExitCode
8888
8989Import-Module "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
deps/aro/aro/Driver.zig+6-3
......@@ -366,12 +366,15 @@ pub fn parseArgs(
366366 } else if (mem.eql(u8, arg, "-S") or mem.eql(u8, arg, "--assemble")) {
367367 d.only_preprocess_and_compile = true;
368368 } else if (option(arg, "--target=")) |triple| {
369 const cross = std.zig.CrossTarget.parse(.{ .arch_os_abi = triple }) catch {
369 const query = std.Target.Query.parse(.{ .arch_os_abi = triple }) catch {
370370 try d.comp.addDiagnostic(.{ .tag = .cli_invalid_target, .extra = .{ .str = arg } }, &.{});
371371 continue;
372372 };
373 d.comp.target = cross.toTarget(); // TODO deprecated
374 d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(d.comp.target));
373 const target = std.zig.system.resolveTargetQuery(query) catch |e| {
374 return d.fatal("unable to resolve target: {s}", .{errorDescription(e)});
375 };
376 d.comp.target = target;
377 d.comp.langopts.setEmulatedCompiler(target_util.systemCompiler(target));
375378 d.raw_target_triple = triple;
376379 } else if (mem.eql(u8, arg, "--verbose-ast")) {
377380 d.verbose_ast = true;
deps/aro/build/GenerateDef.zig+2-2
......@@ -21,7 +21,7 @@ pub const Options = struct {
2121 pub const Kind = enum { dafsa, named };
2222};
2323
24pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency {
24pub fn create(owner: *std.Build, options: Options) std.Build.Module.Import {
2525 const self = owner.allocator.create(GenerateDef) catch @panic("OOM");
2626 const path = owner.pathJoin(&.{ options.src_prefix, options.name });
2727
......@@ -39,7 +39,7 @@ pub fn create(owner: *std.Build, options: Options) std.Build.ModuleDependency {
3939 .generated_file = .{ .step = &self.step },
4040 };
4141 const module = self.step.owner.createModule(.{
42 .source_file = .{ .generated = &self.generated_file },
42 .root_source_file = .{ .generated = &self.generated_file },
4343 });
4444 return .{
4545 .module = module,
lib/build_runner.zig+205-140
......@@ -46,7 +46,10 @@ pub fn main() !void {
4646 return error.InvalidArgs;
4747 };
4848
49 const host = try std.zig.system.NativeTargetInfo.detect(.{});
49 const host: std.Build.ResolvedTarget = .{
50 .query = .{},
51 .result = try std.zig.system.resolveTargetQuery(.{}),
52 };
5053
5154 const build_root_directory: std.Build.Cache.Directory = .{
5255 .path = build_root,
......@@ -96,6 +99,7 @@ pub fn main() !void {
9699 var skip_oom_steps: bool = false;
97100 var color: Color = .auto;
98101 var seed: u32 = 0;
102 var prominent_compile_errors: bool = false;
99103
100104 const stderr_stream = io.getStdErr().writer();
101105 const stdout_stream = io.getStdOut().writer();
......@@ -239,6 +243,8 @@ pub fn main() !void {
239243 builder.verbose_cc = true;
240244 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
241245 builder.verbose_llvm_cpu_features = true;
246 } else if (mem.eql(u8, arg, "--prominent-compile-errors")) {
247 prominent_compile_errors = true;
242248 } else if (mem.eql(u8, arg, "-fwine")) {
243249 builder.enable_wine = true;
244250 } else if (mem.eql(u8, arg, "-fno-wine")) {
......@@ -322,6 +328,7 @@ pub fn main() !void {
322328 .max_rss_mutex = .{},
323329 .skip_oom_steps = skip_oom_steps,
324330 .memory_blocked_steps = std.ArrayList(*Step).init(arena),
331 .prominent_compile_errors = prominent_compile_errors,
325332
326333 .claimed_rss = 0,
327334 .summary = summary,
......@@ -354,11 +361,12 @@ const Run = struct {
354361 max_rss_mutex: std.Thread.Mutex,
355362 skip_oom_steps: bool,
356363 memory_blocked_steps: std.ArrayList(*Step),
364 prominent_compile_errors: bool,
357365
358366 claimed_rss: usize,
359367 summary: ?Summary,
360368 ttyconf: std.io.tty.Config,
361 stderr: std.fs.File,
369 stderr: File,
362370};
363371
364372fn runStepNames(
......@@ -558,7 +566,7 @@ fn runStepNames(
558566 // Finally, render compile errors at the bottom of the terminal.
559567 // We use a separate compile_error_steps array list because step_stack is destructively
560568 // mutated in printTreeStep above.
561 if (total_compile_errors > 0) {
569 if (run.prominent_compile_errors and total_compile_errors > 0) {
562570 for (compile_error_steps.items) |s| {
563571 if (s.result_error_bundle.errorMessageCount() > 0) {
564572 s.result_error_bundle.renderToStdErr(renderOptions(ttyconf));
......@@ -579,7 +587,7 @@ const PrintNode = struct {
579587 last: bool = false,
580588};
581589
582fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.io.tty.Config) !void {
590fn printPrefix(node: *PrintNode, stderr: File, ttyconf: std.io.tty.Config) !void {
583591 const parent = node.parent orelse return;
584592 if (parent.parent == null) return;
585593 try printPrefix(parent, stderr, ttyconf);
......@@ -593,11 +601,145 @@ fn printPrefix(node: *PrintNode, stderr: std.fs.File, ttyconf: std.io.tty.Config
593601 }
594602}
595603
604fn printChildNodePrefix(stderr: File, ttyconf: std.io.tty.Config) !void {
605 try stderr.writeAll(switch (ttyconf) {
606 .no_color, .windows_api => "+- ",
607 .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─
608 });
609}
610
611fn printStepStatus(
612 s: *Step,
613 stderr: File,
614 ttyconf: std.io.tty.Config,
615 run: *const Run,
616) !void {
617 switch (s.state) {
618 .precheck_unstarted => unreachable,
619 .precheck_started => unreachable,
620 .precheck_done => unreachable,
621 .running => unreachable,
622
623 .dependency_failure => {
624 try ttyconf.setColor(stderr, .dim);
625 try stderr.writeAll(" transitive failure\n");
626 try ttyconf.setColor(stderr, .reset);
627 },
628
629 .success => {
630 try ttyconf.setColor(stderr, .green);
631 if (s.result_cached) {
632 try stderr.writeAll(" cached");
633 } else if (s.test_results.test_count > 0) {
634 const pass_count = s.test_results.passCount();
635 try stderr.writer().print(" {d} passed", .{pass_count});
636 if (s.test_results.skip_count > 0) {
637 try ttyconf.setColor(stderr, .yellow);
638 try stderr.writer().print(" {d} skipped", .{s.test_results.skip_count});
639 }
640 } else {
641 try stderr.writeAll(" success");
642 }
643 try ttyconf.setColor(stderr, .reset);
644 if (s.result_duration_ns) |ns| {
645 try ttyconf.setColor(stderr, .dim);
646 if (ns >= std.time.ns_per_min) {
647 try stderr.writer().print(" {d}m", .{ns / std.time.ns_per_min});
648 } else if (ns >= std.time.ns_per_s) {
649 try stderr.writer().print(" {d}s", .{ns / std.time.ns_per_s});
650 } else if (ns >= std.time.ns_per_ms) {
651 try stderr.writer().print(" {d}ms", .{ns / std.time.ns_per_ms});
652 } else if (ns >= std.time.ns_per_us) {
653 try stderr.writer().print(" {d}us", .{ns / std.time.ns_per_us});
654 } else {
655 try stderr.writer().print(" {d}ns", .{ns});
656 }
657 try ttyconf.setColor(stderr, .reset);
658 }
659 if (s.result_peak_rss != 0) {
660 const rss = s.result_peak_rss;
661 try ttyconf.setColor(stderr, .dim);
662 if (rss >= 1000_000_000) {
663 try stderr.writer().print(" MaxRSS:{d}G", .{rss / 1000_000_000});
664 } else if (rss >= 1000_000) {
665 try stderr.writer().print(" MaxRSS:{d}M", .{rss / 1000_000});
666 } else if (rss >= 1000) {
667 try stderr.writer().print(" MaxRSS:{d}K", .{rss / 1000});
668 } else {
669 try stderr.writer().print(" MaxRSS:{d}B", .{rss});
670 }
671 try ttyconf.setColor(stderr, .reset);
672 }
673 try stderr.writeAll("\n");
674 },
675 .skipped, .skipped_oom => |skip| {
676 try ttyconf.setColor(stderr, .yellow);
677 try stderr.writeAll(" skipped");
678 if (skip == .skipped_oom) {
679 try stderr.writeAll(" (not enough memory)");
680 try ttyconf.setColor(stderr, .dim);
681 try stderr.writer().print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss });
682 try ttyconf.setColor(stderr, .yellow);
683 }
684 try stderr.writeAll("\n");
685 try ttyconf.setColor(stderr, .reset);
686 },
687 .failure => try printStepFailure(s, stderr, ttyconf),
688 }
689}
690
691fn printStepFailure(
692 s: *Step,
693 stderr: File,
694 ttyconf: std.io.tty.Config,
695) !void {
696 if (s.result_error_bundle.errorMessageCount() > 0) {
697 try ttyconf.setColor(stderr, .red);
698 try stderr.writer().print(" {d} errors\n", .{
699 s.result_error_bundle.errorMessageCount(),
700 });
701 try ttyconf.setColor(stderr, .reset);
702 } else if (!s.test_results.isSuccess()) {
703 try stderr.writer().print(" {d}/{d} passed", .{
704 s.test_results.passCount(), s.test_results.test_count,
705 });
706 if (s.test_results.fail_count > 0) {
707 try stderr.writeAll(", ");
708 try ttyconf.setColor(stderr, .red);
709 try stderr.writer().print("{d} failed", .{
710 s.test_results.fail_count,
711 });
712 try ttyconf.setColor(stderr, .reset);
713 }
714 if (s.test_results.skip_count > 0) {
715 try stderr.writeAll(", ");
716 try ttyconf.setColor(stderr, .yellow);
717 try stderr.writer().print("{d} skipped", .{
718 s.test_results.skip_count,
719 });
720 try ttyconf.setColor(stderr, .reset);
721 }
722 if (s.test_results.leak_count > 0) {
723 try stderr.writeAll(", ");
724 try ttyconf.setColor(stderr, .red);
725 try stderr.writer().print("{d} leaked", .{
726 s.test_results.leak_count,
727 });
728 try ttyconf.setColor(stderr, .reset);
729 }
730 try stderr.writeAll("\n");
731 } else {
732 try ttyconf.setColor(stderr, .red);
733 try stderr.writeAll(" failure\n");
734 try ttyconf.setColor(stderr, .reset);
735 }
736}
737
596738fn printTreeStep(
597739 b: *std.Build,
598740 s: *Step,
599741 run: *const Run,
600 stderr: std.fs.File,
742 stderr: File,
601743 ttyconf: std.io.tty.Config,
602744 parent_node: *PrintNode,
603745 step_stack: *std.AutoArrayHashMapUnmanaged(*Step, void),
......@@ -610,10 +752,7 @@ fn printTreeStep(
610752 if (!first) try ttyconf.setColor(stderr, .dim);
611753 if (parent_node.parent != null) {
612754 if (parent_node.last) {
613 try stderr.writeAll(switch (ttyconf) {
614 .no_color, .windows_api => "+- ",
615 .escape_codes => "\x1B\x28\x30\x6d\x71\x1B\x28\x42 ", // └─
616 });
755 try printChildNodePrefix(stderr, ttyconf);
617756 } else {
618757 try stderr.writeAll(switch (ttyconf) {
619758 .no_color, .windows_api => "+- ",
......@@ -626,119 +765,7 @@ fn printTreeStep(
626765 try stderr.writeAll(s.name);
627766
628767 if (first) {
629 switch (s.state) {
630 .precheck_unstarted => unreachable,
631 .precheck_started => unreachable,
632 .precheck_done => unreachable,
633 .running => unreachable,
634
635 .dependency_failure => {
636 try ttyconf.setColor(stderr, .dim);
637 try stderr.writeAll(" transitive failure\n");
638 try ttyconf.setColor(stderr, .reset);
639 },
640
641 .success => {
642 try ttyconf.setColor(stderr, .green);
643 if (s.result_cached) {
644 try stderr.writeAll(" cached");
645 } else if (s.test_results.test_count > 0) {
646 const pass_count = s.test_results.passCount();
647 try stderr.writer().print(" {d} passed", .{pass_count});
648 if (s.test_results.skip_count > 0) {
649 try ttyconf.setColor(stderr, .yellow);
650 try stderr.writer().print(" {d} skipped", .{s.test_results.skip_count});
651 }
652 } else {
653 try stderr.writeAll(" success");
654 }
655 try ttyconf.setColor(stderr, .reset);
656 if (s.result_duration_ns) |ns| {
657 try ttyconf.setColor(stderr, .dim);
658 if (ns >= std.time.ns_per_min) {
659 try stderr.writer().print(" {d}m", .{ns / std.time.ns_per_min});
660 } else if (ns >= std.time.ns_per_s) {
661 try stderr.writer().print(" {d}s", .{ns / std.time.ns_per_s});
662 } else if (ns >= std.time.ns_per_ms) {
663 try stderr.writer().print(" {d}ms", .{ns / std.time.ns_per_ms});
664 } else if (ns >= std.time.ns_per_us) {
665 try stderr.writer().print(" {d}us", .{ns / std.time.ns_per_us});
666 } else {
667 try stderr.writer().print(" {d}ns", .{ns});
668 }
669 try ttyconf.setColor(stderr, .reset);
670 }
671 if (s.result_peak_rss != 0) {
672 const rss = s.result_peak_rss;
673 try ttyconf.setColor(stderr, .dim);
674 if (rss >= 1000_000_000) {
675 try stderr.writer().print(" MaxRSS:{d}G", .{rss / 1000_000_000});
676 } else if (rss >= 1000_000) {
677 try stderr.writer().print(" MaxRSS:{d}M", .{rss / 1000_000});
678 } else if (rss >= 1000) {
679 try stderr.writer().print(" MaxRSS:{d}K", .{rss / 1000});
680 } else {
681 try stderr.writer().print(" MaxRSS:{d}B", .{rss});
682 }
683 try ttyconf.setColor(stderr, .reset);
684 }
685 try stderr.writeAll("\n");
686 },
687 .skipped, .skipped_oom => |skip| {
688 try ttyconf.setColor(stderr, .yellow);
689 try stderr.writeAll(" skipped");
690 if (skip == .skipped_oom) {
691 try stderr.writeAll(" (not enough memory)");
692 try ttyconf.setColor(stderr, .dim);
693 try stderr.writer().print(" upper bound of {d} exceeded runner limit ({d})", .{ s.max_rss, run.max_rss });
694 try ttyconf.setColor(stderr, .yellow);
695 }
696 try stderr.writeAll("\n");
697 try ttyconf.setColor(stderr, .reset);
698 },
699 .failure => {
700 if (s.result_error_bundle.errorMessageCount() > 0) {
701 try ttyconf.setColor(stderr, .red);
702 try stderr.writer().print(" {d} errors\n", .{
703 s.result_error_bundle.errorMessageCount(),
704 });
705 try ttyconf.setColor(stderr, .reset);
706 } else if (!s.test_results.isSuccess()) {
707 try stderr.writer().print(" {d}/{d} passed", .{
708 s.test_results.passCount(), s.test_results.test_count,
709 });
710 if (s.test_results.fail_count > 0) {
711 try stderr.writeAll(", ");
712 try ttyconf.setColor(stderr, .red);
713 try stderr.writer().print("{d} failed", .{
714 s.test_results.fail_count,
715 });
716 try ttyconf.setColor(stderr, .reset);
717 }
718 if (s.test_results.skip_count > 0) {
719 try stderr.writeAll(", ");
720 try ttyconf.setColor(stderr, .yellow);
721 try stderr.writer().print("{d} skipped", .{
722 s.test_results.skip_count,
723 });
724 try ttyconf.setColor(stderr, .reset);
725 }
726 if (s.test_results.leak_count > 0) {
727 try stderr.writeAll(", ");
728 try ttyconf.setColor(stderr, .red);
729 try stderr.writer().print("{d} leaked", .{
730 s.test_results.leak_count,
731 });
732 try ttyconf.setColor(stderr, .reset);
733 }
734 try stderr.writeAll("\n");
735 } else {
736 try ttyconf.setColor(stderr, .red);
737 try stderr.writeAll(" failure\n");
738 try ttyconf.setColor(stderr, .reset);
739 }
740 },
741 }
768 try printStepStatus(s, stderr, ttyconf, run);
742769
743770 const last_index = if (!failures_only) s.dependencies.items.len -| 1 else blk: {
744771 var i: usize = s.dependencies.items.len;
......@@ -888,26 +915,15 @@ fn workerMakeOneStep(
888915 const make_result = s.make(&sub_prog_node);
889916
890917 // No matter the result, we want to display error/warning messages.
891 if (s.result_error_msgs.items.len > 0) {
918 const show_compile_errors = !run.prominent_compile_errors and
919 s.result_error_bundle.errorMessageCount() > 0;
920 const show_error_msgs = s.result_error_msgs.items.len > 0;
921
922 if (show_error_msgs or show_compile_errors) {
892923 sub_prog_node.context.lock_stderr();
893924 defer sub_prog_node.context.unlock_stderr();
894925
895 const stderr = run.stderr;
896 const ttyconf = run.ttyconf;
897
898 for (s.result_error_msgs.items) |msg| {
899 // Sometimes it feels like you just can't catch a break. Finally,
900 // with Zig, you can.
901 ttyconf.setColor(stderr, .bold) catch break;
902 stderr.writeAll(s.owner.dep_prefix) catch break;
903 stderr.writeAll(s.name) catch break;
904 stderr.writeAll(": ") catch break;
905 ttyconf.setColor(stderr, .red) catch break;
906 stderr.writeAll("error: ") catch break;
907 ttyconf.setColor(stderr, .reset) catch break;
908 stderr.writeAll(msg) catch break;
909 stderr.writeAll("\n") catch break;
910 }
926 printErrorMessages(b, s, run) catch {};
911927 }
912928
913929 handle_result: {
......@@ -962,6 +978,54 @@ fn workerMakeOneStep(
962978 }
963979}
964980
981fn printErrorMessages(b: *std.Build, failing_step: *Step, run: *const Run) !void {
982 const gpa = b.allocator;
983 const stderr = run.stderr;
984 const ttyconf = run.ttyconf;
985
986 // Provide context for where these error messages are coming from by
987 // printing the corresponding Step subtree.
988
989 var step_stack: std.ArrayListUnmanaged(*Step) = .{};
990 defer step_stack.deinit(gpa);
991 try step_stack.append(gpa, failing_step);
992 while (step_stack.items[step_stack.items.len - 1].dependants.items.len != 0) {
993 try step_stack.append(gpa, step_stack.items[step_stack.items.len - 1].dependants.items[0]);
994 }
995
996 // Now, `step_stack` has the subtree that we want to print, in reverse order.
997 try ttyconf.setColor(stderr, .dim);
998 var indent: usize = 0;
999 while (step_stack.popOrNull()) |s| : (indent += 1) {
1000 if (indent > 0) {
1001 try stderr.writer().writeByteNTimes(' ', (indent - 1) * 3);
1002 try printChildNodePrefix(stderr, ttyconf);
1003 }
1004
1005 try stderr.writeAll(s.name);
1006
1007 if (s == failing_step) {
1008 try printStepFailure(s, stderr, ttyconf);
1009 } else {
1010 try stderr.writeAll("\n");
1011 }
1012 }
1013 try ttyconf.setColor(stderr, .reset);
1014
1015 // Penultimately, the compilation errors.
1016 if (!run.prominent_compile_errors and failing_step.result_error_bundle.errorMessageCount() > 0)
1017 try failing_step.result_error_bundle.renderToWriter(renderOptions(ttyconf), stderr.writer());
1018
1019 // Finally, generic error messages.
1020 for (failing_step.result_error_msgs.items) |msg| {
1021 try ttyconf.setColor(stderr, .red);
1022 try stderr.writeAll("error: ");
1023 try ttyconf.setColor(stderr, .reset);
1024 try stderr.writeAll(msg);
1025 try stderr.writeAll("\n");
1026 }
1027}
1028
9651029fn steps(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !void {
9661030 // run the build script to collect the options
9671031 if (!already_ran_build) {
......@@ -1027,6 +1091,7 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi
10271091 \\ -l, --list-steps Print available steps
10281092 \\ --verbose Print commands before executing them
10291093 \\ --color [auto|off|on] Enable or disable colored error messages
1094 \\ --prominent-compile-errors Buffer compile errors and display at end
10301095 \\ --summary [mode] Control the printing of the build summary
10311096 \\ all Print the build summary in its entirety
10321097 \\ failures (Default) Only print failed steps
......@@ -1111,7 +1176,7 @@ fn cleanExit() void {
11111176const Color = enum { auto, off, on };
11121177const Summary = enum { all, failures, none };
11131178
1114fn get_tty_conf(color: Color, stderr: std.fs.File) std.io.tty.Config {
1179fn get_tty_conf(color: Color, stderr: File) std.io.tty.Config {
11151180 return switch (color) {
11161181 .auto => std.io.tty.detectConfig(stderr),
11171182 .on => .escape_codes,
lib/std/Build.zig+207-287
......@@ -10,55 +10,17 @@ const log = std.log;
1010const ArrayList = std.ArrayList;
1111const StringHashMap = std.StringHashMap;
1212const Allocator = mem.Allocator;
13const Target = std.Target;
1314const process = std.process;
1415const EnvMap = std.process.EnvMap;
1516const fmt_lib = std.fmt;
1617const File = std.fs.File;
17const CrossTarget = std.zig.CrossTarget;
18const NativeTargetInfo = std.zig.system.NativeTargetInfo;
1918const Sha256 = std.crypto.hash.sha2.Sha256;
2019const Build = @This();
2120
2221pub const Cache = @import("Build/Cache.zig");
23
24/// deprecated: use `Step.Compile`.
25pub const LibExeObjStep = Step.Compile;
26/// deprecated: use `Build`.
27pub const Builder = Build;
28/// deprecated: use `Step.InstallDir.Options`
29pub const InstallDirectoryOptions = Step.InstallDir.Options;
30
3122pub const Step = @import("Build/Step.zig");
32/// deprecated: use `Step.CheckFile`.
33pub const CheckFileStep = @import("Build/Step/CheckFile.zig");
34/// deprecated: use `Step.CheckObject`.
35pub const CheckObjectStep = @import("Build/Step/CheckObject.zig");
36/// deprecated: use `Step.ConfigHeader`.
37pub const ConfigHeaderStep = @import("Build/Step/ConfigHeader.zig");
38/// deprecated: use `Step.Fmt`.
39pub const FmtStep = @import("Build/Step/Fmt.zig");
40/// deprecated: use `Step.InstallArtifact`.
41pub const InstallArtifactStep = @import("Build/Step/InstallArtifact.zig");
42/// deprecated: use `Step.InstallDir`.
43pub const InstallDirStep = @import("Build/Step/InstallDir.zig");
44/// deprecated: use `Step.InstallFile`.
45pub const InstallFileStep = @import("Build/Step/InstallFile.zig");
46/// deprecated: use `Step.ObjCopy`.
47pub const ObjCopyStep = @import("Build/Step/ObjCopy.zig");
48/// deprecated: use `Step.Compile`.
49pub const CompileStep = @import("Build/Step/Compile.zig");
50/// deprecated: use `Step.Options`.
51pub const OptionsStep = @import("Build/Step/Options.zig");
52/// deprecated: use `Step.RemoveDir`.
53pub const RemoveDirStep = @import("Build/Step/RemoveDir.zig");
54/// deprecated: use `Step.Run`.
55pub const RunStep = @import("Build/Step/Run.zig");
56/// deprecated: use `Step.TranslateC`.
57pub const TranslateCStep = @import("Build/Step/TranslateC.zig");
58/// deprecated: use `Step.WriteFile`.
59pub const WriteFileStep = @import("Build/Step/WriteFile.zig");
60/// deprecated: use `LazyPath`.
61pub const FileSource = LazyPath;
23pub const Module = @import("Build/Module.zig");
6224
6325install_tls: TopLevelStep,
6426uninstall_tls: TopLevelStep,
......@@ -96,7 +58,6 @@ cache_root: Cache.Directory,
9658global_cache_root: Cache.Directory,
9759cache: *Cache,
9860zig_lib_dir: ?LazyPath,
99vcpkg_root: VcpkgRoot = .unattempted,
10061pkg_config_pkg_list: ?(PkgConfigError![]const PkgConfigPkg) = null,
10162args: ?[][]const u8 = null,
10263debug_log_scopes: []const []const u8 = &.{},
......@@ -124,7 +85,7 @@ enable_wine: bool = false,
12485glibc_runtimes_dir: ?[]const u8 = null,
12586
12687/// Information about the native target. Computed before build() is invoked.
127host: NativeTargetInfo,
88host: ResolvedTarget,
12889
12990dep_prefix: []const u8 = "",
13091
......@@ -250,7 +211,7 @@ pub fn create(
250211 build_root: Cache.Directory,
251212 cache_root: Cache.Directory,
252213 global_cache_root: Cache.Directory,
253 host: NativeTargetInfo,
214 host: ResolvedTarget,
254215 cache: *Cache,
255216 available_deps: AvailableDeps,
256217) !*Build {
......@@ -414,7 +375,7 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption
414375 const v = @field(args, field.name);
415376 const T = @TypeOf(v);
416377 switch (T) {
417 CrossTarget => {
378 Target.Query => {
418379 user_input_options.put(field.name, .{
419380 .name = field.name,
420381 .value = .{ .scalar = v.zigTriple(allocator) catch @panic("OOM") },
......@@ -422,12 +383,19 @@ fn userInputOptionsFromArgs(allocator: Allocator, args: anytype) UserInputOption
422383 }) catch @panic("OOM");
423384 user_input_options.put("cpu", .{
424385 .name = "cpu",
425 .value = .{
426 .scalar = if (v.isNativeCpu())
427 "native"
428 else
429 serializeCpu(allocator, v.getCpu()) catch unreachable,
430 },
386 .value = .{ .scalar = v.serializeCpuAlloc(allocator) catch @panic("OOM") },
387 .used = false,
388 }) catch @panic("OOM");
389 },
390 ResolvedTarget => {
391 user_input_options.put(field.name, .{
392 .name = field.name,
393 .value = .{ .scalar = v.query.zigTriple(allocator) catch @panic("OOM") },
394 .used = false,
395 }) catch @panic("OOM");
396 user_input_options.put("cpu", .{
397 .name = "cpu",
398 .value = .{ .scalar = v.query.serializeCpuAlloc(allocator) catch @panic("OOM") },
431399 .used = false,
432400 }) catch @panic("OOM");
433401 },
......@@ -633,45 +601,57 @@ pub fn addOptions(self: *Build) *Step.Options {
633601
634602pub const ExecutableOptions = struct {
635603 name: []const u8,
604 /// If you want the executable to run on the same computer as the one
605 /// building the package, pass the `host` field of the package's `Build`
606 /// instance.
607 target: ResolvedTarget,
636608 root_source_file: ?LazyPath = null,
637609 version: ?std.SemanticVersion = null,
638 target: CrossTarget = .{},
639610 optimize: std.builtin.OptimizeMode = .Debug,
640611 linkage: ?Step.Compile.Linkage = null,
641612 max_rss: usize = 0,
642613 link_libc: ?bool = null,
643614 single_threaded: ?bool = null,
615 pic: ?bool = null,
616 strip: ?bool = null,
617 unwind_tables: ?bool = null,
618 omit_frame_pointer: ?bool = null,
619 sanitize_thread: ?bool = null,
620 error_tracing: ?bool = null,
644621 use_llvm: ?bool = null,
645622 use_lld: ?bool = null,
646623 zig_lib_dir: ?LazyPath = null,
647 main_mod_path: ?LazyPath = null,
648624 /// Embed a `.manifest` file in the compilation if the object format supports it.
649625 /// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference
650626 /// Manifest files must have the extension `.manifest`.
651627 /// Can be set regardless of target. The `.manifest` file will be ignored
652628 /// if the target object format does not support embedded manifests.
653629 win32_manifest: ?LazyPath = null,
654
655 /// Deprecated; use `main_mod_path`.
656 main_pkg_path: ?LazyPath = null,
657630};
658631
659632pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
660633 return Step.Compile.create(b, .{
661634 .name = options.name,
662 .root_source_file = options.root_source_file,
635 .root_module = .{
636 .root_source_file = options.root_source_file,
637 .target = options.target,
638 .optimize = options.optimize,
639 .link_libc = options.link_libc,
640 .single_threaded = options.single_threaded,
641 .pic = options.pic,
642 .strip = options.strip,
643 .unwind_tables = options.unwind_tables,
644 .omit_frame_pointer = options.omit_frame_pointer,
645 .sanitize_thread = options.sanitize_thread,
646 .error_tracing = options.error_tracing,
647 },
663648 .version = options.version,
664 .target = options.target,
665 .optimize = options.optimize,
666649 .kind = .exe,
667650 .linkage = options.linkage,
668651 .max_rss = options.max_rss,
669 .link_libc = options.link_libc,
670 .single_threaded = options.single_threaded,
671652 .use_llvm = options.use_llvm,
672653 .use_lld = options.use_lld,
673654 .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
674 .main_mod_path = options.main_mod_path orelse options.main_pkg_path,
675655 .win32_manifest = options.win32_manifest,
676656 });
677657}
......@@ -679,77 +659,99 @@ pub fn addExecutable(b: *Build, options: ExecutableOptions) *Step.Compile {
679659pub const ObjectOptions = struct {
680660 name: []const u8,
681661 root_source_file: ?LazyPath = null,
682 target: CrossTarget,
662 /// To choose the same computer as the one building the package, pass the
663 /// `host` field of the package's `Build` instance.
664 target: ResolvedTarget,
683665 optimize: std.builtin.OptimizeMode,
684666 max_rss: usize = 0,
685667 link_libc: ?bool = null,
686668 single_threaded: ?bool = null,
669 pic: ?bool = null,
670 strip: ?bool = null,
671 unwind_tables: ?bool = null,
672 omit_frame_pointer: ?bool = null,
673 sanitize_thread: ?bool = null,
674 error_tracing: ?bool = null,
687675 use_llvm: ?bool = null,
688676 use_lld: ?bool = null,
689677 zig_lib_dir: ?LazyPath = null,
690 main_mod_path: ?LazyPath = null,
691
692 /// Deprecated; use `main_mod_path`.
693 main_pkg_path: ?LazyPath = null,
694678};
695679
696680pub fn addObject(b: *Build, options: ObjectOptions) *Step.Compile {
697681 return Step.Compile.create(b, .{
698682 .name = options.name,
699 .root_source_file = options.root_source_file,
700 .target = options.target,
701 .optimize = options.optimize,
683 .root_module = .{
684 .root_source_file = options.root_source_file,
685 .target = options.target,
686 .optimize = options.optimize,
687 .link_libc = options.link_libc,
688 .single_threaded = options.single_threaded,
689 .pic = options.pic,
690 .strip = options.strip,
691 .unwind_tables = options.unwind_tables,
692 .omit_frame_pointer = options.omit_frame_pointer,
693 .sanitize_thread = options.sanitize_thread,
694 .error_tracing = options.error_tracing,
695 },
702696 .kind = .obj,
703697 .max_rss = options.max_rss,
704 .link_libc = options.link_libc,
705 .single_threaded = options.single_threaded,
706698 .use_llvm = options.use_llvm,
707699 .use_lld = options.use_lld,
708700 .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
709 .main_mod_path = options.main_mod_path orelse options.main_pkg_path,
710701 });
711702}
712703
713704pub const SharedLibraryOptions = struct {
714705 name: []const u8,
706 /// To choose the same computer as the one building the package, pass the
707 /// `host` field of the package's `Build` instance.
708 target: ResolvedTarget,
709 optimize: std.builtin.OptimizeMode,
715710 root_source_file: ?LazyPath = null,
716711 version: ?std.SemanticVersion = null,
717 target: CrossTarget,
718 optimize: std.builtin.OptimizeMode,
719712 max_rss: usize = 0,
720713 link_libc: ?bool = null,
721714 single_threaded: ?bool = null,
715 pic: ?bool = null,
716 strip: ?bool = null,
717 unwind_tables: ?bool = null,
718 omit_frame_pointer: ?bool = null,
719 sanitize_thread: ?bool = null,
720 error_tracing: ?bool = null,
722721 use_llvm: ?bool = null,
723722 use_lld: ?bool = null,
724723 zig_lib_dir: ?LazyPath = null,
725 main_mod_path: ?LazyPath = null,
726724 /// Embed a `.manifest` file in the compilation if the object format supports it.
727725 /// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference
728726 /// Manifest files must have the extension `.manifest`.
729727 /// Can be set regardless of target. The `.manifest` file will be ignored
730728 /// if the target object format does not support embedded manifests.
731729 win32_manifest: ?LazyPath = null,
732
733 /// Deprecated; use `main_mod_path`.
734 main_pkg_path: ?LazyPath = null,
735730};
736731
737732pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile {
738733 return Step.Compile.create(b, .{
739734 .name = options.name,
740 .root_source_file = options.root_source_file,
735 .root_module = .{
736 .target = options.target,
737 .optimize = options.optimize,
738 .root_source_file = options.root_source_file,
739 .link_libc = options.link_libc,
740 .single_threaded = options.single_threaded,
741 .pic = options.pic,
742 .strip = options.strip,
743 .unwind_tables = options.unwind_tables,
744 .omit_frame_pointer = options.omit_frame_pointer,
745 .sanitize_thread = options.sanitize_thread,
746 .error_tracing = options.error_tracing,
747 },
741748 .kind = .lib,
742749 .linkage = .dynamic,
743750 .version = options.version,
744 .target = options.target,
745 .optimize = options.optimize,
746751 .max_rss = options.max_rss,
747 .link_libc = options.link_libc,
748 .single_threaded = options.single_threaded,
749752 .use_llvm = options.use_llvm,
750753 .use_lld = options.use_lld,
751754 .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
752 .main_mod_path = options.main_mod_path orelse options.main_pkg_path,
753755 .win32_manifest = options.win32_manifest,
754756 });
755757}
......@@ -757,44 +759,55 @@ pub fn addSharedLibrary(b: *Build, options: SharedLibraryOptions) *Step.Compile
757759pub const StaticLibraryOptions = struct {
758760 name: []const u8,
759761 root_source_file: ?LazyPath = null,
760 target: CrossTarget,
762 /// To choose the same computer as the one building the package, pass the
763 /// `host` field of the package's `Build` instance.
764 target: ResolvedTarget,
761765 optimize: std.builtin.OptimizeMode,
762766 version: ?std.SemanticVersion = null,
763767 max_rss: usize = 0,
764768 link_libc: ?bool = null,
765769 single_threaded: ?bool = null,
770 pic: ?bool = null,
771 strip: ?bool = null,
772 unwind_tables: ?bool = null,
773 omit_frame_pointer: ?bool = null,
774 sanitize_thread: ?bool = null,
775 error_tracing: ?bool = null,
766776 use_llvm: ?bool = null,
767777 use_lld: ?bool = null,
768778 zig_lib_dir: ?LazyPath = null,
769 main_mod_path: ?LazyPath = null,
770
771 /// Deprecated; use `main_mod_path`.
772 main_pkg_path: ?LazyPath = null,
773779};
774780
775781pub fn addStaticLibrary(b: *Build, options: StaticLibraryOptions) *Step.Compile {
776782 return Step.Compile.create(b, .{
777783 .name = options.name,
778 .root_source_file = options.root_source_file,
784 .root_module = .{
785 .target = options.target,
786 .optimize = options.optimize,
787 .root_source_file = options.root_source_file,
788 .link_libc = options.link_libc,
789 .single_threaded = options.single_threaded,
790 .pic = options.pic,
791 .strip = options.strip,
792 .unwind_tables = options.unwind_tables,
793 .omit_frame_pointer = options.omit_frame_pointer,
794 .sanitize_thread = options.sanitize_thread,
795 .error_tracing = options.error_tracing,
796 },
779797 .kind = .lib,
780798 .linkage = .static,
781799 .version = options.version,
782 .target = options.target,
783 .optimize = options.optimize,
784800 .max_rss = options.max_rss,
785 .link_libc = options.link_libc,
786 .single_threaded = options.single_threaded,
787801 .use_llvm = options.use_llvm,
788802 .use_lld = options.use_lld,
789803 .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
790 .main_mod_path = options.main_mod_path orelse options.main_pkg_path,
791804 });
792805}
793806
794807pub const TestOptions = struct {
795808 name: []const u8 = "test",
796809 root_source_file: LazyPath,
797 target: CrossTarget = .{},
810 target: ?ResolvedTarget = null,
798811 optimize: std.builtin.OptimizeMode = .Debug,
799812 version: ?std.SemanticVersion = null,
800813 max_rss: usize = 0,
......@@ -802,38 +815,49 @@ pub const TestOptions = struct {
802815 test_runner: ?[]const u8 = null,
803816 link_libc: ?bool = null,
804817 single_threaded: ?bool = null,
818 pic: ?bool = null,
819 strip: ?bool = null,
820 unwind_tables: ?bool = null,
821 omit_frame_pointer: ?bool = null,
822 sanitize_thread: ?bool = null,
823 error_tracing: ?bool = null,
805824 use_llvm: ?bool = null,
806825 use_lld: ?bool = null,
807826 zig_lib_dir: ?LazyPath = null,
808 main_mod_path: ?LazyPath = null,
809
810 /// Deprecated; use `main_mod_path`.
811 main_pkg_path: ?LazyPath = null,
812827};
813828
814829pub fn addTest(b: *Build, options: TestOptions) *Step.Compile {
815830 return Step.Compile.create(b, .{
816831 .name = options.name,
817832 .kind = .@"test",
818 .root_source_file = options.root_source_file,
819 .target = options.target,
820 .optimize = options.optimize,
833 .root_module = .{
834 .root_source_file = options.root_source_file,
835 .target = options.target orelse b.host,
836 .optimize = options.optimize,
837 .link_libc = options.link_libc,
838 .single_threaded = options.single_threaded,
839 .pic = options.pic,
840 .strip = options.strip,
841 .unwind_tables = options.unwind_tables,
842 .omit_frame_pointer = options.omit_frame_pointer,
843 .sanitize_thread = options.sanitize_thread,
844 .error_tracing = options.error_tracing,
845 },
821846 .max_rss = options.max_rss,
822847 .filter = options.filter,
823848 .test_runner = options.test_runner,
824 .link_libc = options.link_libc,
825 .single_threaded = options.single_threaded,
826849 .use_llvm = options.use_llvm,
827850 .use_lld = options.use_lld,
828851 .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
829 .main_mod_path = options.main_mod_path orelse options.main_pkg_path,
830852 });
831853}
832854
833855pub const AssemblyOptions = struct {
834856 name: []const u8,
835857 source_file: LazyPath,
836 target: CrossTarget,
858 /// To choose the same computer as the one building the package, pass the
859 /// `host` field of the package's `Build` instance.
860 target: ResolvedTarget,
837861 optimize: std.builtin.OptimizeMode,
838862 max_rss: usize = 0,
839863 zig_lib_dir: ?LazyPath = null,
......@@ -843,9 +867,10 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile {
843867 const obj_step = Step.Compile.create(b, .{
844868 .name = options.name,
845869 .kind = .obj,
846 .root_source_file = null,
847 .target = options.target,
848 .optimize = options.optimize,
870 .root_module = .{
871 .target = options.target,
872 .optimize = options.optimize,
873 },
849874 .max_rss = options.max_rss,
850875 .zig_lib_dir = options.zig_lib_dir orelse b.zig_lib_dir,
851876 });
......@@ -856,41 +881,17 @@ pub fn addAssembly(b: *Build, options: AssemblyOptions) *Step.Compile {
856881/// This function creates a module and adds it to the package's module set, making
857882/// it available to other packages which depend on this one.
858883/// `createModule` can be used instead to create a private module.
859pub fn addModule(b: *Build, name: []const u8, options: CreateModuleOptions) *Module {
860 const module = b.createModule(options);
884pub fn addModule(b: *Build, name: []const u8, options: Module.CreateOptions) *Module {
885 const module = Module.create(b, options);
861886 b.modules.put(b.dupe(name), module) catch @panic("OOM");
862887 return module;
863888}
864889
865pub const ModuleDependency = struct {
866 name: []const u8,
867 module: *Module,
868};
869
870pub const CreateModuleOptions = struct {
871 source_file: LazyPath,
872 dependencies: []const ModuleDependency = &.{},
873};
874
875890/// This function creates a private module, to be used by the current package,
876891/// but not exposed to other packages depending on this one.
877892/// `addModule` can be used instead to create a public module.
878pub fn createModule(b: *Build, options: CreateModuleOptions) *Module {
879 const module = b.allocator.create(Module) catch @panic("OOM");
880 module.* = .{
881 .builder = b,
882 .source_file = options.source_file.dupe(b),
883 .dependencies = moduleDependenciesToArrayHashMap(b.allocator, options.dependencies),
884 };
885 return module;
886}
887
888fn moduleDependenciesToArrayHashMap(arena: Allocator, deps: []const ModuleDependency) std.StringArrayHashMap(*Module) {
889 var result = std.StringArrayHashMap(*Module).init(arena);
890 for (deps) |dep| {
891 result.put(dep.name, dep.module) catch @panic("OOM");
892 }
893 return result;
893pub fn createModule(b: *Build, options: Module.CreateOptions) *Module {
894 return Module.create(b, options);
894895}
895896
896897/// Initializes a `Step.Run` with argv, which must at least have the path to the
......@@ -918,10 +919,6 @@ pub fn addRunArtifact(b: *Build, exe: *Step.Compile) *Step.Run {
918919 run_step.enableTestRunnerMode();
919920 }
920921
921 if (exe.vcpkg_bin_path) |path| {
922 run_step.addPathDir(path);
923 }
924
925922 return run_step;
926923}
927924
......@@ -1143,7 +1140,7 @@ pub fn option(self: *Build, comptime T: type, name_raw: []const u8, description_
11431140 return null;
11441141 },
11451142 .scalar => |s| {
1146 if (Step.Compile.BuildId.parse(s)) |build_id| {
1143 if (std.zig.BuildId.parse(s)) |build_id| {
11471144 return build_id;
11481145 } else |err| {
11491146 log.err("unable to parse option '-D{s}': {s}", .{ name, @errorName(err) });
......@@ -1208,19 +1205,25 @@ pub fn standardOptimizeOption(self: *Build, options: StandardOptimizeOptionOptio
12081205}
12091206
12101207pub const StandardTargetOptionsArgs = struct {
1211 whitelist: ?[]const CrossTarget = null,
1212
1213 default_target: CrossTarget = CrossTarget{},
1208 whitelist: ?[]const Target.Query = null,
1209 default_target: Target.Query = .{},
12141210};
12151211
1212/// Exposes standard `zig build` options for choosing a target and additionally
1213/// resolves the target query.
1214pub fn standardTargetOptions(b: *Build, args: StandardTargetOptionsArgs) ResolvedTarget {
1215 const query = b.standardTargetOptionsQueryOnly(args);
1216 return b.resolveTargetQuery(query);
1217}
1218
12161219/// Exposes standard `zig build` options for choosing a target.
1217pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) CrossTarget {
1218 const maybe_triple = self.option(
1220pub fn standardTargetOptionsQueryOnly(b: *Build, args: StandardTargetOptionsArgs) Target.Query {
1221 const maybe_triple = b.option(
12191222 []const u8,
12201223 "target",
12211224 "The CPU architecture, OS, and ABI to build for",
12221225 );
1223 const mcpu = self.option([]const u8, "cpu", "Target CPU features to add or subtract");
1226 const mcpu = b.option([]const u8, "cpu", "Target CPU features to add or subtract");
12241227
12251228 if (maybe_triple == null and mcpu == null) {
12261229 return args.default_target;
......@@ -1228,8 +1231,8 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros
12281231
12291232 const triple = maybe_triple orelse "native";
12301233
1231 var diags: CrossTarget.ParseOptions.Diagnostics = .{};
1232 const selected_target = CrossTarget.parse(.{
1234 var diags: Target.Query.ParseOptions.Diagnostics = .{};
1235 const selected_target = Target.Query.parse(.{
12331236 .arch_os_abi = triple,
12341237 .cpu_features = mcpu,
12351238 .diagnostics = &diags,
......@@ -1242,7 +1245,7 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros
12421245 for (diags.arch.?.allCpuModels()) |cpu| {
12431246 log.err(" {s}", .{cpu.name});
12441247 }
1245 self.markInvalidUserInput();
1248 b.markInvalidUserInput();
12461249 return args.default_target;
12471250 },
12481251 error.UnknownCpuFeature => {
......@@ -1257,7 +1260,7 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros
12571260 for (diags.arch.?.allFeaturesList()) |feature| {
12581261 log.err(" {s}: {s}", .{ feature.name, feature.description });
12591262 }
1260 self.markInvalidUserInput();
1263 b.markInvalidUserInput();
12611264 return args.default_target;
12621265 },
12631266 error.UnknownOperatingSystem => {
......@@ -1266,83 +1269,38 @@ pub fn standardTargetOptions(self: *Build, args: StandardTargetOptionsArgs) Cros
12661269 \\Available operating systems:
12671270 \\
12681271 , .{diags.os_name.?});
1269 inline for (std.meta.fields(std.Target.Os.Tag)) |field| {
1272 inline for (std.meta.fields(Target.Os.Tag)) |field| {
12701273 log.err(" {s}", .{field.name});
12711274 }
1272 self.markInvalidUserInput();
1275 b.markInvalidUserInput();
12731276 return args.default_target;
12741277 },
12751278 else => |e| {
12761279 log.err("Unable to parse target '{s}': {s}\n", .{ triple, @errorName(e) });
1277 self.markInvalidUserInput();
1280 b.markInvalidUserInput();
12781281 return args.default_target;
12791282 },
12801283 };
12811284
1282 const selected_canonicalized_triple = selected_target.zigTriple(self.allocator) catch @panic("OOM");
1283
1284 if (args.whitelist) |list| whitelist_check: {
1285 // Make sure it's a match of one of the list.
1286 var mismatch_triple = true;
1287 var mismatch_cpu_features = true;
1288 var whitelist_item = CrossTarget{};
1289 for (list) |t| {
1290 mismatch_cpu_features = true;
1291 mismatch_triple = true;
1292
1293 const t_triple = t.zigTriple(self.allocator) catch @panic("OOM");
1294 if (mem.eql(u8, t_triple, selected_canonicalized_triple)) {
1295 mismatch_triple = false;
1296 whitelist_item = t;
1297 if (t.getCpuFeatures().isSuperSetOf(selected_target.getCpuFeatures())) {
1298 mismatch_cpu_features = false;
1299 break :whitelist_check;
1300 } else {
1301 break;
1302 }
1303 }
1304 }
1305 if (mismatch_triple) {
1306 log.err("Chosen target '{s}' does not match one of the supported targets:", .{
1307 selected_canonicalized_triple,
1308 });
1309 for (list) |t| {
1310 const t_triple = t.zigTriple(self.allocator) catch @panic("OOM");
1311 log.err(" {s}", .{t_triple});
1312 }
1313 } else {
1314 assert(mismatch_cpu_features);
1315 const whitelist_cpu = whitelist_item.getCpu();
1316 const selected_cpu = selected_target.getCpu();
1317 log.err("Chosen CPU model '{s}' does not match one of the supported targets:", .{
1318 selected_cpu.model.name,
1319 });
1320 log.err(" Supported feature Set: ", .{});
1321 const all_features = whitelist_cpu.arch.allFeaturesList();
1322 var populated_cpu_features = whitelist_cpu.model.features;
1323 populated_cpu_features.populateDependencies(all_features);
1324 for (all_features, 0..) |feature, i_usize| {
1325 const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize));
1326 const in_cpu_set = populated_cpu_features.isEnabled(i);
1327 if (in_cpu_set) {
1328 log.err("{s} ", .{feature.name});
1329 }
1330 }
1331 log.err(" Remove: ", .{});
1332 for (all_features, 0..) |feature, i_usize| {
1333 const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize));
1334 const in_cpu_set = populated_cpu_features.isEnabled(i);
1335 const in_actual_set = selected_cpu.features.isEnabled(i);
1336 if (in_actual_set and !in_cpu_set) {
1337 log.err("{s} ", .{feature.name});
1338 }
1339 }
1340 }
1341 self.markInvalidUserInput();
1342 return args.default_target;
1285 const whitelist = args.whitelist orelse return selected_target;
1286
1287 // Make sure it's a match of one of the list.
1288 for (whitelist) |q| {
1289 if (q.eql(selected_target))
1290 return selected_target;
13431291 }
13441292
1345 return selected_target;
1293 for (whitelist) |q| {
1294 log.info("allowed target: -Dtarget={s} -Dcpu={s}", .{
1295 q.zigTriple(b.allocator) catch @panic("OOM"),
1296 q.serializeCpuAlloc(b.allocator) catch @panic("OOM"),
1297 });
1298 }
1299 log.err("chosen target '{s}' does not match one of the allowed targets", .{
1300 selected_target.zigTriple(b.allocator) catch @panic("OOM"),
1301 });
1302 b.markInvalidUserInput();
1303 return args.default_target;
13461304}
13471305
13481306pub fn addUserInputOption(self: *Build, name_raw: []const u8, value_raw: []const u8) !bool {
......@@ -1422,7 +1380,7 @@ pub fn addUserInputFlag(self: *Build, name_raw: []const u8) !bool {
14221380
14231381fn typeToEnum(comptime T: type) TypeId {
14241382 return switch (T) {
1425 Step.Compile.BuildId => .build_id,
1383 std.zig.BuildId => .build_id,
14261384 else => return switch (@typeInfo(T)) {
14271385 .Int => .int,
14281386 .Float => .float,
......@@ -1490,7 +1448,7 @@ pub fn installFile(self: *Build, src_path: []const u8, dest_rel_path: []const u8
14901448 self.getInstallStep().dependOn(&self.addInstallFileWithDir(.{ .path = src_path }, .prefix, dest_rel_path).step);
14911449}
14921450
1493pub fn installDirectory(self: *Build, options: InstallDirectoryOptions) void {
1451pub fn installDirectory(self: *Build, options: Step.InstallDir.Options) void {
14941452 self.getInstallStep().dependOn(&self.addInstallDirectory(options).step);
14951453}
14961454
......@@ -1536,7 +1494,7 @@ pub fn addInstallFileWithDir(
15361494 return Step.InstallFile.create(self, source.dupe(self), install_dir, dest_rel_path);
15371495}
15381496
1539pub fn addInstallDirectory(self: *Build, options: InstallDirectoryOptions) *Step.InstallDir {
1497pub fn addInstallDirectory(self: *Build, options: Step.InstallDir.Options) *Step.InstallDir {
15401498 return Step.InstallDir.create(self, options);
15411499}
15421500
......@@ -1593,7 +1551,7 @@ pub fn fmt(self: *Build, comptime format: []const u8, args: anytype) []u8 {
15931551
15941552pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []const u8) ![]const u8 {
15951553 // TODO report error for ambiguous situations
1596 const exe_extension = @as(CrossTarget, .{}).exeFileExt();
1554 const exe_extension = @as(Target.Query, .{}).exeFileExt();
15971555 for (self.search_prefixes.items) |search_prefix| {
15981556 for (names) |name| {
15991557 if (fs.path.isAbsolute(name)) {
......@@ -1895,15 +1853,6 @@ pub fn runBuild(b: *Build, build_zig: anytype) anyerror!void {
18951853 }
18961854}
18971855
1898pub const Module = struct {
1899 builder: *Build,
1900 /// This could either be a generated file, in which case the module
1901 /// contains exactly one file, or it could be a path to the root source
1902 /// file of directory of files which constitute the module.
1903 source_file: LazyPath,
1904 dependencies: std.StringArrayHashMap(*Module),
1905};
1906
19071856/// A file that is generated by a build step.
19081857/// This struct is an interface that is meant to be used with `@fieldParentPtr` to implement the actual path logic.
19091858pub const GeneratedFile = struct {
......@@ -2048,34 +1997,6 @@ pub fn dumpBadGetPathHelp(
20481997 tty_config.setColor(w, .reset) catch {};
20491998}
20501999
2051/// Allocates a new string for assigning a value to a named macro.
2052/// If the value is omitted, it is set to 1.
2053/// `name` and `value` need not live longer than the function call.
2054pub fn constructCMacro(allocator: Allocator, name: []const u8, value: ?[]const u8) []const u8 {
2055 var macro = allocator.alloc(
2056 u8,
2057 name.len + if (value) |value_slice| value_slice.len + 1 else 0,
2058 ) catch |err| if (err == error.OutOfMemory) @panic("Out of memory") else unreachable;
2059 @memcpy(macro[0..name.len], name);
2060 if (value) |value_slice| {
2061 macro[name.len] = '=';
2062 @memcpy(macro[name.len + 1 ..][0..value_slice.len], value_slice);
2063 }
2064 return macro;
2065}
2066
2067pub const VcpkgRoot = union(VcpkgRootStatus) {
2068 unattempted: void,
2069 not_found: void,
2070 found: []const u8,
2071};
2072
2073pub const VcpkgRootStatus = enum {
2074 unattempted,
2075 not_found,
2076 found,
2077};
2078
20792000pub const InstallDir = union(enum) {
20802001 prefix: void,
20812002 lib: void,
......@@ -2107,34 +2028,6 @@ pub const InstalledFile = struct {
21072028 }
21082029};
21092030
2110pub fn serializeCpu(allocator: Allocator, cpu: std.Target.Cpu) ![]const u8 {
2111 // TODO this logic can disappear if cpu model + features becomes part of the target triple
2112 const all_features = cpu.arch.allFeaturesList();
2113 var populated_cpu_features = cpu.model.features;
2114 populated_cpu_features.populateDependencies(all_features);
2115
2116 if (populated_cpu_features.eql(cpu.features)) {
2117 // The CPU name alone is sufficient.
2118 return cpu.model.name;
2119 } else {
2120 var mcpu_buffer = ArrayList(u8).init(allocator);
2121 try mcpu_buffer.appendSlice(cpu.model.name);
2122
2123 for (all_features, 0..) |feature, i_usize| {
2124 const i = @as(std.Target.Cpu.Feature.Set.Index, @intCast(i_usize));
2125 const in_cpu_set = populated_cpu_features.isEnabled(i);
2126 const in_actual_set = cpu.features.isEnabled(i);
2127 if (in_cpu_set and !in_actual_set) {
2128 try mcpu_buffer.writer().print("-{s}", .{feature.name});
2129 } else if (!in_cpu_set and in_actual_set) {
2130 try mcpu_buffer.writer().print("+{s}", .{feature.name});
2131 }
2132 }
2133
2134 return try mcpu_buffer.toOwnedSlice();
2135 }
2136}
2137
21382031/// This function is intended to be called in the `configure` phase only.
21392032/// It returns an absolute directory path, which is potentially going to be a
21402033/// source of API breakage in the future, so keep that in mind when using this
......@@ -2165,6 +2058,33 @@ pub fn hex64(x: u64) [16]u8 {
21652058 return result;
21662059}
21672060
2061/// A pair of target query and fully resolved target.
2062/// This type is generally required by build system API that need to be given a
2063/// target. The query is kept because the Zig toolchain needs to know which parts
2064/// of the target are "native". This can apply to the CPU, the OS, or even the ABI.
2065pub const ResolvedTarget = struct {
2066 query: Target.Query,
2067 result: Target,
2068};
2069
2070/// Converts a target query into a fully resolved target that can be passed to
2071/// various parts of the API.
2072pub fn resolveTargetQuery(b: *Build, query: Target.Query) ResolvedTarget {
2073 // This context will likely be required in the future when the target is
2074 // resolved via a WASI API or via the build protocol.
2075 _ = b;
2076
2077 return .{
2078 .query = query,
2079 .result = std.zig.system.resolveTargetQuery(query) catch
2080 @panic("unable to resolve target query"),
2081 };
2082}
2083
2084pub fn wantSharedLibSymLinks(target: Target) bool {
2085 return target.os.tag != .windows;
2086}
2087
21682088test {
21692089 _ = Cache;
21702090 _ = Step;
lib/std/Build/Cache.zig+15-1
......@@ -270,7 +270,7 @@ pub const HashHelper = struct {
270270 .none => {},
271271 }
272272 },
273 std.Build.Step.Compile.BuildId => switch (x) {
273 std.zig.BuildId => switch (x) {
274274 .none, .fast, .uuid, .sha1, .md5 => hh.add(std.meta.activeTag(x)),
275275 .hexstring => |hex_string| hh.addBytes(hex_string.toSlice()),
276276 },
......@@ -312,6 +312,20 @@ pub const HashHelper = struct {
312312 ) catch unreachable;
313313 return out_digest;
314314 }
315
316 pub fn oneShot(bytes: []const u8) [hex_digest_len]u8 {
317 var hasher: Hasher = hasher_init;
318 hasher.update(bytes);
319 var bin_digest: BinDigest = undefined;
320 hasher.final(&bin_digest);
321 var out_digest: [hex_digest_len]u8 = undefined;
322 _ = fmt.bufPrint(
323 &out_digest,
324 "{s}",
325 .{fmt.fmtSliceHexLower(&bin_digest)},
326 ) catch unreachable;
327 return out_digest;
328 }
315329};
316330
317331pub const Lock = struct {
lib/std/Build/Module.zig created+753
......@@ -0,0 +1,753 @@
1/// The one responsible for creating this module.
2owner: *std.Build,
3/// Tracks the set of steps that depend on this `Module`. This ensures that
4/// when making this `Module` depend on other `Module` objects and `Step`
5/// objects, respective `Step` dependencies can be added.
6depending_steps: std.AutoArrayHashMapUnmanaged(*Step.Compile, void),
7root_source_file: ?LazyPath,
8/// The modules that are mapped into this module's import table.
9/// Use `addImport` rather than modifying this field directly in order to
10/// maintain step dependency edges.
11import_table: std.StringArrayHashMapUnmanaged(*Module),
12
13resolved_target: ?std.Build.ResolvedTarget = null,
14optimize: ?std.builtin.OptimizeMode = null,
15dwarf_format: ?std.dwarf.Format,
16
17c_macros: std.ArrayListUnmanaged([]const u8),
18include_dirs: std.ArrayListUnmanaged(IncludeDir),
19lib_paths: std.ArrayListUnmanaged(LazyPath),
20rpaths: std.ArrayListUnmanaged(RPath),
21frameworks: std.StringArrayHashMapUnmanaged(LinkFrameworkOptions),
22c_std: std.Build.CStd,
23link_objects: std.ArrayListUnmanaged(LinkObject),
24
25strip: ?bool,
26unwind_tables: ?bool,
27single_threaded: ?bool,
28stack_protector: ?bool,
29stack_check: ?bool,
30sanitize_c: ?bool,
31sanitize_thread: ?bool,
32code_model: std.builtin.CodeModel,
33valgrind: ?bool,
34pic: ?bool,
35red_zone: ?bool,
36omit_frame_pointer: ?bool,
37error_tracing: ?bool,
38link_libc: ?bool,
39link_libcpp: ?bool,
40
41/// Symbols to be exported when compiling to WebAssembly.
42export_symbol_names: []const []const u8 = &.{},
43
44pub const RPath = union(enum) {
45 lazy_path: LazyPath,
46 special: []const u8,
47};
48
49pub const LinkObject = union(enum) {
50 static_path: LazyPath,
51 other_step: *Step.Compile,
52 system_lib: SystemLib,
53 assembly_file: LazyPath,
54 c_source_file: *CSourceFile,
55 c_source_files: *CSourceFiles,
56 win32_resource_file: *RcSourceFile,
57};
58
59pub const SystemLib = struct {
60 name: []const u8,
61 needed: bool,
62 weak: bool,
63 use_pkg_config: UsePkgConfig,
64 preferred_link_mode: std.builtin.LinkMode,
65 search_strategy: SystemLib.SearchStrategy,
66
67 pub const UsePkgConfig = enum {
68 /// Don't use pkg-config, just pass -lfoo where foo is name.
69 no,
70 /// Try to get information on how to link the library from pkg-config.
71 /// If that fails, fall back to passing -lfoo where foo is name.
72 yes,
73 /// Try to get information on how to link the library from pkg-config.
74 /// If that fails, error out.
75 force,
76 };
77
78 pub const SearchStrategy = enum { paths_first, mode_first, no_fallback };
79};
80
81pub const CSourceFiles = struct {
82 dependency: ?*std.Build.Dependency,
83 /// If `dependency` is not null relative to it,
84 /// else relative to the build root.
85 files: []const []const u8,
86 flags: []const []const u8,
87};
88
89pub const CSourceFile = struct {
90 file: LazyPath,
91 flags: []const []const u8 = &.{},
92
93 pub fn dupe(self: CSourceFile, b: *std.Build) CSourceFile {
94 return .{
95 .file = self.file.dupe(b),
96 .flags = b.dupeStrings(self.flags),
97 };
98 }
99};
100
101pub const RcSourceFile = struct {
102 file: LazyPath,
103 /// Any option that rc.exe accepts will work here, with the exception of:
104 /// - `/fo`: The output filename is set by the build system
105 /// - `/p`: Only running the preprocessor is not supported in this context
106 /// - `/:no-preprocess` (non-standard option): Not supported in this context
107 /// - Any MUI-related option
108 /// https://learn.microsoft.com/en-us/windows/win32/menurc/using-rc-the-rc-command-line-
109 ///
110 /// Implicitly defined options:
111 /// /x (ignore the INCLUDE environment variable)
112 /// /D_DEBUG or /DNDEBUG depending on the optimization mode
113 flags: []const []const u8 = &.{},
114
115 pub fn dupe(self: RcSourceFile, b: *std.Build) RcSourceFile {
116 return .{
117 .file = self.file.dupe(b),
118 .flags = b.dupeStrings(self.flags),
119 };
120 }
121};
122
123pub const IncludeDir = union(enum) {
124 path: LazyPath,
125 path_system: LazyPath,
126 path_after: LazyPath,
127 framework_path: LazyPath,
128 framework_path_system: LazyPath,
129 other_step: *Step.Compile,
130 config_header_step: *Step.ConfigHeader,
131};
132
133pub const LinkFrameworkOptions = struct {
134 needed: bool = false,
135 weak: bool = false,
136};
137
138/// Unspecified options here will be inherited from parent `Module` when
139/// inserted into an import table.
140pub const CreateOptions = struct {
141 /// This could either be a generated file, in which case the module
142 /// contains exactly one file, or it could be a path to the root source
143 /// file of directory of files which constitute the module.
144 /// If `null`, it means this module is made up of only `link_objects`.
145 root_source_file: ?LazyPath = null,
146
147 /// The table of other modules that this module can access via `@import`.
148 /// Imports are allowed to be cyclical, so this table can be added to after
149 /// the `Module` is created via `addImport`.
150 imports: []const Import = &.{},
151
152 target: ?std.Build.ResolvedTarget = null,
153 optimize: ?std.builtin.OptimizeMode = null,
154
155 /// `true` requires a compilation that includes this Module to link libc.
156 /// `false` causes a build failure if a compilation that includes this Module would link libc.
157 /// `null` neither requires nor prevents libc from being linked.
158 link_libc: ?bool = null,
159 /// `true` requires a compilation that includes this Module to link libc++.
160 /// `false` causes a build failure if a compilation that includes this Module would link libc++.
161 /// `null` neither requires nor prevents libc++ from being linked.
162 link_libcpp: ?bool = null,
163 single_threaded: ?bool = null,
164 strip: ?bool = null,
165 unwind_tables: ?bool = null,
166 dwarf_format: ?std.dwarf.Format = null,
167 c_std: std.Build.CStd = .C99,
168 code_model: std.builtin.CodeModel = .default,
169 stack_protector: ?bool = null,
170 stack_check: ?bool = null,
171 sanitize_c: ?bool = null,
172 sanitize_thread: ?bool = null,
173 /// Whether to emit machine code that integrates with Valgrind.
174 valgrind: ?bool = null,
175 /// Position Independent Code
176 pic: ?bool = null,
177 red_zone: ?bool = null,
178 /// Whether to omit the stack frame pointer. Frees up a register and makes it
179 /// more difficult to obtain stack traces. Has target-dependent effects.
180 omit_frame_pointer: ?bool = null,
181 error_tracing: ?bool = null,
182};
183
184pub const Import = struct {
185 name: []const u8,
186 module: *Module,
187};
188
189pub fn init(m: *Module, owner: *std.Build, options: CreateOptions, compile: ?*Step.Compile) void {
190 const allocator = owner.allocator;
191
192 m.* = .{
193 .owner = owner,
194 .depending_steps = .{},
195 .root_source_file = if (options.root_source_file) |lp| lp.dupe(owner) else null,
196 .import_table = .{},
197 .resolved_target = options.target,
198 .optimize = options.optimize,
199 .link_libc = options.link_libc,
200 .link_libcpp = options.link_libcpp,
201 .dwarf_format = options.dwarf_format,
202 .c_macros = .{},
203 .include_dirs = .{},
204 .lib_paths = .{},
205 .rpaths = .{},
206 .frameworks = .{},
207 .c_std = options.c_std,
208 .link_objects = .{},
209 .strip = options.strip,
210 .unwind_tables = options.unwind_tables,
211 .single_threaded = options.single_threaded,
212 .stack_protector = options.stack_protector,
213 .stack_check = options.stack_check,
214 .sanitize_c = options.sanitize_c,
215 .sanitize_thread = options.sanitize_thread,
216 .code_model = options.code_model,
217 .valgrind = options.valgrind,
218 .pic = options.pic,
219 .red_zone = options.red_zone,
220 .omit_frame_pointer = options.omit_frame_pointer,
221 .error_tracing = options.error_tracing,
222 .export_symbol_names = &.{},
223 };
224
225 m.import_table.ensureUnusedCapacity(allocator, options.imports.len) catch @panic("OOM");
226 for (options.imports) |dep| {
227 m.import_table.putAssumeCapacity(dep.name, dep.module);
228 }
229
230 if (compile) |c| {
231 m.depending_steps.put(allocator, c, {}) catch @panic("OOM");
232 }
233
234 // This logic accesses `depending_steps` which was just modified above.
235 var it = m.iterateDependencies(null, false);
236 while (it.next()) |item| addShallowDependencies(m, item.module);
237}
238
239pub fn create(owner: *std.Build, options: CreateOptions) *Module {
240 const m = owner.allocator.create(Module) catch @panic("OOM");
241 m.init(owner, options, null);
242 return m;
243}
244
245/// Adds an existing module to be used with `@import`.
246pub fn addImport(m: *Module, name: []const u8, module: *Module) void {
247 const b = m.owner;
248 m.import_table.put(b.allocator, b.dupe(name), module) catch @panic("OOM");
249
250 var it = module.iterateDependencies(null, false);
251 while (it.next()) |item| addShallowDependencies(m, item.module);
252}
253
254/// Creates step dependencies and updates `depending_steps` of `dependee` so that
255/// subsequent calls to `addImport` on `dependee` will additionally create step
256/// dependencies on `m`'s `depending_steps`.
257fn addShallowDependencies(m: *Module, dependee: *Module) void {
258 if (dependee.root_source_file) |lazy_path| addLazyPathDependencies(m, dependee, lazy_path);
259 for (dependee.lib_paths.items) |lib_path| addLazyPathDependencies(m, dependee, lib_path);
260 for (dependee.rpaths.items) |rpath| switch (rpath) {
261 .lazy_path => |lp| addLazyPathDependencies(m, dependee, lp),
262 .special => {},
263 };
264
265 for (dependee.link_objects.items) |link_object| switch (link_object) {
266 .other_step => |compile| addStepDependencies(m, dependee, &compile.step),
267
268 .static_path,
269 .assembly_file,
270 => |lp| addLazyPathDependencies(m, dependee, lp),
271
272 .c_source_file => |x| addLazyPathDependencies(m, dependee, x.file),
273 .win32_resource_file => |x| addLazyPathDependencies(m, dependee, x.file),
274
275 .c_source_files,
276 .system_lib,
277 => {},
278 };
279}
280
281fn addLazyPathDependencies(m: *Module, module: *Module, lazy_path: LazyPath) void {
282 addLazyPathDependenciesOnly(m, lazy_path);
283 if (m != module) {
284 for (m.depending_steps.keys()) |compile| {
285 module.depending_steps.put(m.owner.allocator, compile, {}) catch @panic("OOM");
286 }
287 }
288}
289
290fn addLazyPathDependenciesOnly(m: *Module, lazy_path: LazyPath) void {
291 for (m.depending_steps.keys()) |compile| {
292 lazy_path.addStepDependencies(&compile.step);
293 }
294}
295
296fn addStepDependencies(m: *Module, module: *Module, dependee: *Step) void {
297 addStepDependenciesOnly(m, dependee);
298 if (m != module) {
299 for (m.depending_steps.keys()) |compile| {
300 module.depending_steps.put(m.owner.allocator, compile, {}) catch @panic("OOM");
301 }
302 }
303}
304
305fn addStepDependenciesOnly(m: *Module, dependee: *Step) void {
306 for (m.depending_steps.keys()) |compile| {
307 compile.step.dependOn(dependee);
308 }
309}
310
311/// Creates a new module and adds it to be used with `@import`.
312pub fn addAnonymousImport(m: *Module, name: []const u8, options: CreateOptions) void {
313 const module = create(m.owner, options);
314 return addImport(m, name, module);
315}
316
317pub fn addOptions(m: *Module, module_name: []const u8, options: *Step.Options) void {
318 addImport(m, module_name, options.createModule());
319}
320
321pub const DependencyIterator = struct {
322 allocator: std.mem.Allocator,
323 index: usize,
324 set: std.AutoArrayHashMapUnmanaged(Key, []const u8),
325 chase_dyn_libs: bool,
326
327 pub const Key = struct {
328 /// The compilation that contains the `Module`. Note that a `Module` might be
329 /// used by more than one compilation.
330 compile: ?*Step.Compile,
331 module: *Module,
332 };
333
334 pub const Item = struct {
335 /// The compilation that contains the `Module`. Note that a `Module` might be
336 /// used by more than one compilation.
337 compile: ?*Step.Compile,
338 module: *Module,
339 name: []const u8,
340 };
341
342 pub fn deinit(it: *DependencyIterator) void {
343 it.set.deinit(it.allocator);
344 it.* = undefined;
345 }
346
347 pub fn next(it: *DependencyIterator) ?Item {
348 if (it.index >= it.set.count()) {
349 it.set.clearAndFree(it.allocator);
350 return null;
351 }
352 const key = it.set.keys()[it.index];
353 const name = it.set.values()[it.index];
354 it.index += 1;
355 const module = key.module;
356 it.set.ensureUnusedCapacity(it.allocator, module.import_table.count()) catch
357 @panic("OOM");
358 for (module.import_table.keys(), module.import_table.values()) |dep_name, dep| {
359 it.set.putAssumeCapacity(.{
360 .module = dep,
361 .compile = key.compile,
362 }, dep_name);
363 }
364
365 if (key.compile != null) {
366 for (module.link_objects.items) |link_object| switch (link_object) {
367 .other_step => |compile| {
368 if (!it.chase_dyn_libs and compile.isDynamicLibrary()) continue;
369
370 it.set.put(it.allocator, .{
371 .module = &compile.root_module,
372 .compile = compile,
373 }, "root") catch @panic("OOM");
374 },
375 else => {},
376 };
377 }
378
379 return .{
380 .compile = key.compile,
381 .module = key.module,
382 .name = name,
383 };
384 }
385};
386
387pub fn iterateDependencies(
388 m: *Module,
389 chase_steps: ?*Step.Compile,
390 chase_dyn_libs: bool,
391) DependencyIterator {
392 var it: DependencyIterator = .{
393 .allocator = m.owner.allocator,
394 .index = 0,
395 .set = .{},
396 .chase_dyn_libs = chase_dyn_libs,
397 };
398 it.set.ensureUnusedCapacity(m.owner.allocator, m.import_table.count() + 1) catch @panic("OOM");
399 it.set.putAssumeCapacity(.{
400 .module = m,
401 .compile = chase_steps,
402 }, "root");
403 return it;
404}
405
406pub const LinkSystemLibraryOptions = struct {
407 needed: bool = false,
408 weak: bool = false,
409 use_pkg_config: SystemLib.UsePkgConfig = .yes,
410 preferred_link_mode: std.builtin.LinkMode = .Dynamic,
411 search_strategy: SystemLib.SearchStrategy = .paths_first,
412};
413
414pub fn linkSystemLibrary(
415 m: *Module,
416 name: []const u8,
417 options: LinkSystemLibraryOptions,
418) void {
419 const b = m.owner;
420
421 const target = m.requireKnownTarget();
422 if (target.is_libc_lib_name(name)) {
423 m.link_libc = true;
424 return;
425 }
426 if (target.is_libcpp_lib_name(name)) {
427 m.link_libcpp = true;
428 return;
429 }
430
431 m.link_objects.append(b.allocator, .{
432 .system_lib = .{
433 .name = b.dupe(name),
434 .needed = options.needed,
435 .weak = options.weak,
436 .use_pkg_config = options.use_pkg_config,
437 .preferred_link_mode = options.preferred_link_mode,
438 .search_strategy = options.search_strategy,
439 },
440 }) catch @panic("OOM");
441}
442
443pub fn linkFramework(m: *Module, name: []const u8, options: LinkFrameworkOptions) void {
444 const b = m.owner;
445 m.frameworks.put(b.allocator, b.dupe(name), options) catch @panic("OOM");
446}
447
448pub const AddCSourceFilesOptions = struct {
449 /// When provided, `files` are relative to `dependency` rather than the
450 /// package that owns the `Compile` step.
451 dependency: ?*std.Build.Dependency = null,
452 files: []const []const u8,
453 flags: []const []const u8 = &.{},
454};
455
456/// Handy when you have many C/C++ source files and want them all to have the same flags.
457pub fn addCSourceFiles(m: *Module, options: AddCSourceFilesOptions) void {
458 const b = m.owner;
459 const allocator = b.allocator;
460 const c_source_files = allocator.create(CSourceFiles) catch @panic("OOM");
461 c_source_files.* = .{
462 .dependency = options.dependency,
463 .files = b.dupeStrings(options.files),
464 .flags = b.dupeStrings(options.flags),
465 };
466 m.link_objects.append(allocator, .{ .c_source_files = c_source_files }) catch @panic("OOM");
467}
468
469pub fn addCSourceFile(m: *Module, source: CSourceFile) void {
470 const b = m.owner;
471 const allocator = b.allocator;
472 const c_source_file = allocator.create(CSourceFile) catch @panic("OOM");
473 c_source_file.* = source.dupe(b);
474 m.link_objects.append(allocator, .{ .c_source_file = c_source_file }) catch @panic("OOM");
475 addLazyPathDependenciesOnly(m, source.file);
476}
477
478/// Resource files must have the extension `.rc`.
479/// Can be called regardless of target. The .rc file will be ignored
480/// if the target object format does not support embedded resources.
481pub fn addWin32ResourceFile(m: *Module, source: RcSourceFile) void {
482 const b = m.owner;
483 const allocator = b.allocator;
484 const target = m.requireKnownTarget();
485 // Only the PE/COFF format has a Resource Table, so for any other target
486 // the resource file is ignored.
487 if (target.ofmt != .coff) return;
488
489 const rc_source_file = allocator.create(RcSourceFile) catch @panic("OOM");
490 rc_source_file.* = source.dupe(b);
491 m.link_objects.append(allocator, .{ .win32_resource_file = rc_source_file }) catch @panic("OOM");
492 addLazyPathDependenciesOnly(m, source.file);
493}
494
495pub fn addAssemblyFile(m: *Module, source: LazyPath) void {
496 const b = m.owner;
497 m.link_objects.append(b.allocator, .{ .assembly_file = source.dupe(b) }) catch @panic("OOM");
498 addLazyPathDependenciesOnly(m, source);
499}
500
501pub fn addObjectFile(m: *Module, object: LazyPath) void {
502 const b = m.owner;
503 m.link_objects.append(b.allocator, .{ .static_path = object.dupe(b) }) catch @panic("OOM");
504 addLazyPathDependenciesOnly(m, object);
505}
506
507pub fn addObject(m: *Module, object: *Step.Compile) void {
508 assert(object.kind == .obj);
509 m.linkLibraryOrObject(object);
510}
511
512pub fn linkLibrary(m: *Module, library: *Step.Compile) void {
513 assert(library.kind == .lib);
514 m.linkLibraryOrObject(library);
515}
516
517pub fn addAfterIncludePath(m: *Module, lazy_path: LazyPath) void {
518 const b = m.owner;
519 m.include_dirs.append(b.allocator, .{ .path_after = lazy_path.dupe(b) }) catch @panic("OOM");
520 addLazyPathDependenciesOnly(m, lazy_path);
521}
522
523pub fn addSystemIncludePath(m: *Module, lazy_path: LazyPath) void {
524 const b = m.owner;
525 m.include_dirs.append(b.allocator, .{ .path_system = lazy_path.dupe(b) }) catch @panic("OOM");
526 addLazyPathDependenciesOnly(m, lazy_path);
527}
528
529pub fn addIncludePath(m: *Module, lazy_path: LazyPath) void {
530 const b = m.owner;
531 m.include_dirs.append(b.allocator, .{ .path = lazy_path.dupe(b) }) catch @panic("OOM");
532 addLazyPathDependenciesOnly(m, lazy_path);
533}
534
535pub fn addConfigHeader(m: *Module, config_header: *Step.ConfigHeader) void {
536 const allocator = m.owner.allocator;
537 m.include_dirs.append(allocator, .{ .config_header_step = config_header }) catch @panic("OOM");
538 addStepDependenciesOnly(m, &config_header.step);
539}
540
541pub fn addSystemFrameworkPath(m: *Module, directory_path: LazyPath) void {
542 const b = m.owner;
543 m.include_dirs.append(b.allocator, .{ .framework_path_system = directory_path.dupe(b) }) catch
544 @panic("OOM");
545 addLazyPathDependenciesOnly(m, directory_path);
546}
547
548pub fn addFrameworkPath(m: *Module, directory_path: LazyPath) void {
549 const b = m.owner;
550 m.include_dirs.append(b.allocator, .{ .framework_path = directory_path.dupe(b) }) catch
551 @panic("OOM");
552 addLazyPathDependenciesOnly(m, directory_path);
553}
554
555pub fn addLibraryPath(m: *Module, directory_path: LazyPath) void {
556 const b = m.owner;
557 m.lib_paths.append(b.allocator, directory_path.dupe(b)) catch @panic("OOM");
558 addLazyPathDependenciesOnly(m, directory_path);
559}
560
561pub fn addRPath(m: *Module, directory_path: LazyPath) void {
562 const b = m.owner;
563 switch (directory_path) {
564 .path, .cwd_relative => |path| {
565 // TODO: remove this check after people upgrade and stop expecting it to work
566 if (std.mem.startsWith(u8, path, "@executable_path") or
567 std.mem.startsWith(u8, path, "@loader_path"))
568 {
569 @panic("this function is for adding directory paths. It does not support special rpaths. use addRPathSpecial for that.");
570 }
571 },
572 else => {},
573 }
574 m.rpaths.append(b.allocator, .{ .lazy_path = directory_path.dupe(b) }) catch @panic("OOM");
575 addLazyPathDependenciesOnly(m, directory_path);
576}
577
578pub fn addRPathSpecial(m: *Module, bytes: []const u8) void {
579 const b = m.owner;
580 m.rpaths.append(b.allocator, .{ .special = b.dupe(bytes) }) catch @panic("OOM");
581}
582
583/// Equvialent to the following C code, applied to all C source files owned by
584/// this `Module`:
585/// ```c
586/// #define name value
587/// ```
588/// `name` and `value` need not live longer than the function call.
589pub fn addCMacro(m: *Module, name: []const u8, value: []const u8) void {
590 const b = m.owner;
591 m.c_macros.append(b.allocator, b.fmt("-D{s}={s}", .{ name, value })) catch @panic("OOM");
592}
593
594pub fn appendZigProcessFlags(
595 m: *Module,
596 zig_args: *std.ArrayList([]const u8),
597 asking_step: ?*Step,
598) !void {
599 const b = m.owner;
600
601 try addFlag(zig_args, m.strip, "-fstrip", "-fno-strip");
602 try addFlag(zig_args, m.unwind_tables, "-funwind-tables", "-fno-unwind-tables");
603 try addFlag(zig_args, m.single_threaded, "-fsingle-threaded", "-fno-single-threaded");
604 try addFlag(zig_args, m.stack_check, "-fstack-check", "-fno-stack-check");
605 try addFlag(zig_args, m.stack_protector, "-fstack-protector", "-fno-stack-protector");
606 try addFlag(zig_args, m.omit_frame_pointer, "-fomit-frame-pointer", "-fno-omit-frame-pointer");
607 try addFlag(zig_args, m.error_tracing, "-ferror-tracing", "-fno-error-tracing");
608 try addFlag(zig_args, m.sanitize_c, "-fsanitize-c", "-fno-sanitize-c");
609 try addFlag(zig_args, m.sanitize_thread, "-fsanitize-thread", "-fno-sanitize-thread");
610 try addFlag(zig_args, m.valgrind, "-fvalgrind", "-fno-valgrind");
611 try addFlag(zig_args, m.pic, "-fPIC", "-fno-PIC");
612 try addFlag(zig_args, m.red_zone, "-mred-zone", "-mno-red-zone");
613
614 if (m.dwarf_format) |dwarf_format| {
615 try zig_args.append(switch (dwarf_format) {
616 .@"32" => "-gdwarf32",
617 .@"64" => "-gdwarf64",
618 });
619 }
620
621 try zig_args.ensureUnusedCapacity(1);
622 if (m.optimize) |optimize| switch (optimize) {
623 .Debug => zig_args.appendAssumeCapacity("-ODebug"),
624 .ReleaseSmall => zig_args.appendAssumeCapacity("-OReleaseSmall"),
625 .ReleaseFast => zig_args.appendAssumeCapacity("-OReleaseFast"),
626 .ReleaseSafe => zig_args.appendAssumeCapacity("-OReleaseSafe"),
627 };
628
629 if (m.code_model != .default) {
630 try zig_args.append("-mcmodel");
631 try zig_args.append(@tagName(m.code_model));
632 }
633
634 if (m.resolved_target) |*target| {
635 // Communicate the query via CLI since it's more compact.
636 if (!target.query.isNative()) {
637 try zig_args.appendSlice(&.{
638 "-target", try target.query.zigTriple(b.allocator),
639 "-mcpu", try target.query.serializeCpuAlloc(b.allocator),
640 });
641
642 if (target.query.dynamic_linker.get()) |dynamic_linker| {
643 try zig_args.append("--dynamic-linker");
644 try zig_args.append(dynamic_linker);
645 }
646 }
647 }
648
649 for (m.export_symbol_names) |symbol_name| {
650 try zig_args.append(b.fmt("--export={s}", .{symbol_name}));
651 }
652
653 for (m.include_dirs.items) |include_dir| {
654 switch (include_dir) {
655 .path => |include_path| {
656 try zig_args.append("-I");
657 try zig_args.append(include_path.getPath(b));
658 },
659 .path_system => |include_path| {
660 try zig_args.append("-isystem");
661 try zig_args.append(include_path.getPath(b));
662 },
663 .path_after => |include_path| {
664 try zig_args.append("-idirafter");
665 try zig_args.append(include_path.getPath(b));
666 },
667 .framework_path => |include_path| {
668 try zig_args.append("-F");
669 try zig_args.append(include_path.getPath2(b, asking_step));
670 },
671 .framework_path_system => |include_path| {
672 try zig_args.append("-iframework");
673 try zig_args.append(include_path.getPath2(b, asking_step));
674 },
675 .other_step => |other| {
676 if (other.generated_h) |header| {
677 try zig_args.append("-isystem");
678 try zig_args.append(std.fs.path.dirname(header.path.?).?);
679 }
680 if (other.installed_headers.items.len > 0) {
681 try zig_args.append("-I");
682 try zig_args.append(b.pathJoin(&.{
683 other.step.owner.install_prefix, "include",
684 }));
685 }
686 },
687 .config_header_step => |config_header| {
688 const full_file_path = config_header.output_file.path.?;
689 const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len];
690 try zig_args.appendSlice(&.{ "-I", header_dir_path });
691 },
692 }
693 }
694
695 try zig_args.appendSlice(m.c_macros.items);
696
697 try zig_args.ensureUnusedCapacity(2 * m.lib_paths.items.len);
698 for (m.lib_paths.items) |lib_path| {
699 zig_args.appendAssumeCapacity("-L");
700 zig_args.appendAssumeCapacity(lib_path.getPath2(b, asking_step));
701 }
702
703 try zig_args.ensureUnusedCapacity(2 * m.rpaths.items.len);
704 for (m.rpaths.items) |rpath| switch (rpath) {
705 .lazy_path => |lp| {
706 zig_args.appendAssumeCapacity("-rpath");
707 zig_args.appendAssumeCapacity(lp.getPath2(b, asking_step));
708 },
709 .special => |bytes| {
710 zig_args.appendAssumeCapacity("-rpath");
711 zig_args.appendAssumeCapacity(bytes);
712 },
713 };
714}
715
716fn addFlag(
717 args: *std.ArrayList([]const u8),
718 opt: ?bool,
719 then_name: []const u8,
720 else_name: []const u8,
721) !void {
722 const cond = opt orelse return;
723 return args.append(if (cond) then_name else else_name);
724}
725
726fn linkLibraryOrObject(m: *Module, other: *Step.Compile) void {
727 const allocator = m.owner.allocator;
728 _ = other.getEmittedBin(); // Indicate there is a dependency on the outputted binary.
729 addStepDependenciesOnly(m, &other.step);
730
731 if (other.rootModuleTarget().os.tag == .windows and other.isDynamicLibrary()) {
732 _ = other.getEmittedImplib(); // Indicate dependency on the outputted implib.
733 }
734
735 m.link_objects.append(allocator, .{ .other_step = other }) catch @panic("OOM");
736 m.include_dirs.append(allocator, .{ .other_step = other }) catch @panic("OOM");
737
738 for (other.installed_headers.items) |install_step| {
739 addStepDependenciesOnly(m, install_step);
740 }
741}
742
743fn requireKnownTarget(m: *Module) std.Target {
744 const resolved_target = m.resolved_target orelse
745 @panic("this API requires the Module to be created with a known 'target' field");
746 return resolved_target.result;
747}
748
749const Module = @This();
750const std = @import("std");
751const assert = std.debug.assert;
752const LazyPath = std.Build.LazyPath;
753const Step = std.Build.Step;
lib/std/Build/Step/CheckObject.zig+26-22
......@@ -44,11 +44,11 @@ pub fn create(
4444
4545const SearchPhrase = struct {
4646 string: []const u8,
47 file_source: ?std.Build.LazyPath = null,
47 lazy_path: ?std.Build.LazyPath = null,
4848
4949 fn resolve(phrase: SearchPhrase, b: *std.Build, step: *Step) []const u8 {
50 const file_source = phrase.file_source orelse return phrase.string;
51 return b.fmt("{s} {s}", .{ phrase.string, file_source.getPath2(b, step) });
50 const lazy_path = phrase.lazy_path orelse return phrase.string;
51 return b.fmt("{s} {s}", .{ phrase.string, lazy_path.getPath2(b, step) });
5252 }
5353};
5454
......@@ -321,14 +321,14 @@ pub fn checkExact(self: *CheckObject, phrase: []const u8) void {
321321
322322/// Like `checkExact()` but takes an additional argument `LazyPath` which will be
323323/// resolved to a full search query in `make()`.
324pub fn checkExactPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void {
325 self.checkExactInner(phrase, file_source);
324pub fn checkExactPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
325 self.checkExactInner(phrase, lazy_path);
326326}
327327
328fn checkExactInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.LazyPath) void {
328fn checkExactInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
329329 assert(self.checks.items.len > 0);
330330 const last = &self.checks.items[self.checks.items.len - 1];
331 last.exact(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
331 last.exact(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
332332}
333333
334334/// Adds a fuzzy match phrase to the latest created Check.
......@@ -336,16 +336,20 @@ pub fn checkContains(self: *CheckObject, phrase: []const u8) void {
336336 self.checkContainsInner(phrase, null);
337337}
338338
339/// Like `checkContains()` but takes an additional argument `FileSource` which will be
339/// Like `checkContains()` but takes an additional argument `lazy_path` which will be
340340/// resolved to a full search query in `make()`.
341pub fn checkContainsPath(self: *CheckObject, phrase: []const u8, file_source: std.Build.LazyPath) void {
342 self.checkContainsInner(phrase, file_source);
341pub fn checkContainsPath(
342 self: *CheckObject,
343 phrase: []const u8,
344 lazy_path: std.Build.LazyPath,
345) void {
346 self.checkContainsInner(phrase, lazy_path);
343347}
344348
345fn checkContainsInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
349fn checkContainsInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
346350 assert(self.checks.items.len > 0);
347351 const last = &self.checks.items[self.checks.items.len - 1];
348 last.contains(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
352 last.contains(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
349353}
350354
351355/// Adds an exact match phrase with variable extractor to the latest created Check.
......@@ -353,16 +357,16 @@ pub fn checkExtract(self: *CheckObject, phrase: []const u8) void {
353357 self.checkExtractInner(phrase, null);
354358}
355359
356/// Like `checkExtract()` but takes an additional argument `FileSource` which will be
360/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be
357361/// resolved to a full search query in `make()`.
358pub fn checkExtractFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void {
359 self.checkExtractInner(phrase, file_source);
362pub fn checkExtractLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
363 self.checkExtractInner(phrase, lazy_path);
360364}
361365
362fn checkExtractInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
366fn checkExtractInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
363367 assert(self.checks.items.len > 0);
364368 const last = &self.checks.items[self.checks.items.len - 1];
365 last.extract(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
369 last.extract(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
366370}
367371
368372/// Adds another searched phrase to the latest created Check
......@@ -371,16 +375,16 @@ pub fn checkNotPresent(self: *CheckObject, phrase: []const u8) void {
371375 self.checkNotPresentInner(phrase, null);
372376}
373377
374/// Like `checkExtract()` but takes an additional argument `FileSource` which will be
378/// Like `checkExtract()` but takes an additional argument `LazyPath` which will be
375379/// resolved to a full search query in `make()`.
376pub fn checkNotPresentFileSource(self: *CheckObject, phrase: []const u8, file_source: std.Build.FileSource) void {
377 self.checkNotPresentInner(phrase, file_source);
380pub fn checkNotPresentLazyPath(self: *CheckObject, phrase: []const u8, lazy_path: std.Build.LazyPath) void {
381 self.checkNotPresentInner(phrase, lazy_path);
378382}
379383
380fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, file_source: ?std.Build.FileSource) void {
384fn checkNotPresentInner(self: *CheckObject, phrase: []const u8, lazy_path: ?std.Build.LazyPath) void {
381385 assert(self.checks.items.len > 0);
382386 const last = &self.checks.items[self.checks.items.len - 1];
383 last.notPresent(.{ .string = self.step.owner.dupe(phrase), .file_source = file_source });
387 last.notPresent(.{ .string = self.step.owner.dupe(phrase), .lazy_path = lazy_path });
384388}
385389
386390/// Creates a new check checking in the file headers (section, program headers, etc.).
lib/std/Build/Step/Compile.zig+450-1104
......@@ -9,14 +9,11 @@ const StringHashMap = std.StringHashMap;
99const Sha256 = std.crypto.hash.sha2.Sha256;
1010const Allocator = mem.Allocator;
1111const Step = std.Build.Step;
12const CrossTarget = std.zig.CrossTarget;
13const NativeTargetInfo = std.zig.system.NativeTargetInfo;
1412const LazyPath = std.Build.LazyPath;
1513const PkgConfigPkg = std.Build.PkgConfigPkg;
1614const PkgConfigError = std.Build.PkgConfigError;
1715const RunError = std.Build.RunError;
1816const Module = std.Build.Module;
19const VcpkgRoot = std.Build.VcpkgRoot;
2017const InstallDir = std.Build.InstallDir;
2118const GeneratedFile = std.Build.GeneratedFile;
2219const Compile = @This();
......@@ -24,36 +21,24 @@ const Compile = @This();
2421pub const base_id: Step.Id = .compile;
2522
2623step: Step,
24root_module: Module,
25
2726name: []const u8,
28target: CrossTarget,
29target_info: NativeTargetInfo,
30optimize: std.builtin.OptimizeMode,
3127linker_script: ?LazyPath = null,
3228version_script: ?[]const u8 = null,
3329out_filename: []const u8,
30out_lib_filename: []const u8,
3431linkage: ?Linkage = null,
3532version: ?std.SemanticVersion,
3633kind: Kind,
3734major_only_filename: ?[]const u8,
3835name_only_filename: ?[]const u8,
39strip: ?bool,
40formatted_panics: ?bool = null,
41unwind_tables: ?bool,
4236// keep in sync with src/link.zig:CompressDebugSections
4337compress_debug_sections: enum { none, zlib, zstd } = .none,
44lib_paths: ArrayList(LazyPath),
45rpaths: ArrayList(LazyPath),
46frameworks: StringHashMap(FrameworkLinkInfo),
4738verbose_link: bool,
4839verbose_cc: bool,
4940bundle_compiler_rt: ?bool = null,
50single_threaded: ?bool,
51stack_protector: ?bool = null,
52disable_stack_probing: bool,
53disable_sanitize_c: bool,
54sanitize_thread: bool,
5541rdynamic: bool,
56dwarf_format: ?std.dwarf.Format = null,
5742import_memory: bool = false,
5843export_memory: bool = false,
5944/// For WebAssembly targets, this will allow for undefined symbols to
......@@ -65,32 +50,16 @@ initial_memory: ?u64 = null,
6550max_memory: ?u64 = null,
6651shared_memory: bool = false,
6752global_base: ?u64 = null,
68c_std: std.Build.CStd,
6953/// Set via options; intended to be read-only after that.
7054zig_lib_dir: ?LazyPath,
71/// Set via options; intended to be read-only after that.
72main_mod_path: ?LazyPath,
7355exec_cmd_args: ?[]const ?[]const u8,
7456filter: ?[]const u8,
7557test_evented_io: bool = false,
7658test_runner: ?[]const u8,
7759test_server_mode: bool,
78code_model: std.builtin.CodeModel = .default,
7960wasi_exec_model: ?std.builtin.WasiExecModel = null,
80/// Symbols to be exported when compiling to wasm
81export_symbol_names: []const []const u8 = &.{},
8261
83root_src: ?LazyPath,
84out_lib_filename: []const u8,
85modules: std.StringArrayHashMap(*Module),
86
87link_objects: ArrayList(LinkObject),
88include_dirs: ArrayList(IncludeDir),
89c_macros: ArrayList([]const u8),
9062installed_headers: ArrayList(*Step),
91is_linking_libc: bool,
92is_linking_libcpp: bool,
93vcpkg_bin_path: ?[]const u8 = null,
9463
9564// keep in sync with src/Compilation.zig:RcIncludes
9665/// Behavior of automatic detection of include directories when compiling .rc files.
......@@ -111,14 +80,13 @@ image_base: ?u64 = null,
11180
11281libc_file: ?LazyPath = null,
11382
114valgrind_support: ?bool = null,
11583each_lib_rpath: ?bool = null,
11684/// On ELF targets, this will emit a link section called ".note.gnu.build-id"
11785/// which can be used to coordinate a stripped binary with its debug symbols.
11886/// As an example, the bloaty project refuses to work unless its inputs have
11987/// build ids, in order to prevent accidental mismatches.
12088/// The default is to not include this section because it slows down linking.
121build_id: ?BuildId = null,
89build_id: ?std.zig.BuildId = null,
12290
12391/// Create a .eh_frame_hdr section and a PT_GNU_EH_FRAME segment in the ELF
12492/// file.
......@@ -177,15 +145,9 @@ headerpad_max_install_names: bool = false,
177145/// (Darwin) Remove dylibs that are unreachable by the entry point or exported symbols.
178146dead_strip_dylibs: bool = false,
179147
180/// Position Independent Code
181force_pic: ?bool = null,
182
183148/// Position Independent Executable
184149pie: ?bool = null,
185150
186red_zone: ?bool = null,
187
188omit_frame_pointer: ?bool = null,
189151dll_export_fns: ?bool = null,
190152
191153subsystem: ?std.Target.SubSystem = null,
......@@ -226,91 +188,17 @@ generated_h: ?*GeneratedFile,
226188/// Defaults to `std.math.maxInt(u16)`
227189error_limit: ?u32 = null,
228190
191/// Computed during make().
192is_linking_libc: bool = false,
193/// Computed during make().
194is_linking_libcpp: bool = false,
195
229196pub const ExpectedCompileErrors = union(enum) {
230197 contains: []const u8,
231198 exact: []const []const u8,
232199};
233200
234pub const CSourceFiles = struct {
235 dependency: ?*std.Build.Dependency,
236 /// If `dependency` is not null relative to it,
237 /// else relative to the build root.
238 files: []const []const u8,
239 flags: []const []const u8,
240};
241
242pub const CSourceFile = struct {
243 file: LazyPath,
244 flags: []const []const u8,
245
246 pub fn dupe(self: CSourceFile, b: *std.Build) CSourceFile {
247 return .{
248 .file = self.file.dupe(b),
249 .flags = b.dupeStrings(self.flags),
250 };
251 }
252};
253
254pub const RcSourceFile = struct {
255 file: LazyPath,
256 /// Any option that rc.exe accepts will work here, with the exception of:
257 /// - `/fo`: The output filename is set by the build system
258 /// - `/p`: Only running the preprocessor is not supported in this context
259 /// - `/:no-preprocess` (non-standard option): Not supported in this context
260 /// - Any MUI-related option
261 /// https://learn.microsoft.com/en-us/windows/win32/menurc/using-rc-the-rc-command-line-
262 ///
263 /// Implicitly defined options:
264 /// /x (ignore the INCLUDE environment variable)
265 /// /D_DEBUG or /DNDEBUG depending on the optimization mode
266 flags: []const []const u8 = &.{},
267
268 pub fn dupe(self: RcSourceFile, b: *std.Build) RcSourceFile {
269 return .{
270 .file = self.file.dupe(b),
271 .flags = b.dupeStrings(self.flags),
272 };
273 }
274};
275
276pub const LinkObject = union(enum) {
277 static_path: LazyPath,
278 other_step: *Compile,
279 system_lib: SystemLib,
280 assembly_file: LazyPath,
281 c_source_file: *CSourceFile,
282 c_source_files: *CSourceFiles,
283 win32_resource_file: *RcSourceFile,
284};
285
286pub const SystemLib = struct {
287 name: []const u8,
288 needed: bool,
289 weak: bool,
290 use_pkg_config: UsePkgConfig,
291 preferred_link_mode: std.builtin.LinkMode,
292 search_strategy: SystemLib.SearchStrategy,
293
294 pub const UsePkgConfig = enum {
295 /// Don't use pkg-config, just pass -lfoo where foo is name.
296 no,
297 /// Try to get information on how to link the library from pkg-config.
298 /// If that fails, fall back to passing -lfoo where foo is name.
299 yes,
300 /// Try to get information on how to link the library from pkg-config.
301 /// If that fails, error out.
302 force,
303 };
304
305 pub const SearchStrategy = enum { paths_first, mode_first, no_fallback };
306};
307
308const FrameworkLinkInfo = struct {
309 needed: bool = false,
310 weak: bool = false,
311};
312
313const Entry = union(enum) {
201pub const Entry = union(enum) {
314202 /// Let the compiler decide whether to make an entry point and what to name
315203 /// it.
316204 default,
......@@ -322,118 +210,24 @@ const Entry = union(enum) {
322210 symbol_name: []const u8,
323211};
324212
325pub const IncludeDir = union(enum) {
326 path: LazyPath,
327 path_system: LazyPath,
328 path_after: LazyPath,
329 framework_path: LazyPath,
330 framework_path_system: LazyPath,
331 other_step: *Compile,
332 config_header_step: *Step.ConfigHeader,
333};
334
335213pub const Options = struct {
336214 name: []const u8,
337 root_source_file: ?LazyPath = null,
338 target: CrossTarget,
339 optimize: std.builtin.OptimizeMode,
215 root_module: Module.CreateOptions,
340216 kind: Kind,
341217 linkage: ?Linkage = null,
342218 version: ?std.SemanticVersion = null,
343219 max_rss: usize = 0,
344220 filter: ?[]const u8 = null,
345221 test_runner: ?[]const u8 = null,
346 link_libc: ?bool = null,
347 single_threaded: ?bool = null,
348222 use_llvm: ?bool = null,
349223 use_lld: ?bool = null,
350224 zig_lib_dir: ?LazyPath = null,
351 main_mod_path: ?LazyPath = null,
352225 /// Embed a `.manifest` file in the compilation if the object format supports it.
353226 /// https://learn.microsoft.com/en-us/windows/win32/sbscs/manifest-files-reference
354227 /// Manifest files must have the extension `.manifest`.
355228 /// Can be set regardless of target. The `.manifest` file will be ignored
356229 /// if the target object format does not support embedded manifests.
357230 win32_manifest: ?LazyPath = null,
358
359 /// deprecated; use `main_mod_path`.
360 main_pkg_path: ?LazyPath = null,
361};
362
363pub const BuildId = union(enum) {
364 none,
365 fast,
366 uuid,
367 sha1,
368 md5,
369 hexstring: HexString,
370
371 pub fn eql(a: BuildId, b: BuildId) bool {
372 const a_tag = std.meta.activeTag(a);
373 const b_tag = std.meta.activeTag(b);
374 if (a_tag != b_tag) return false;
375 return switch (a) {
376 .none, .fast, .uuid, .sha1, .md5 => true,
377 .hexstring => |a_hexstring| mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
378 };
379 }
380
381 pub const HexString = struct {
382 bytes: [32]u8,
383 len: u8,
384
385 /// Result is byte values, *not* hex-encoded.
386 pub fn toSlice(hs: *const HexString) []const u8 {
387 return hs.bytes[0..hs.len];
388 }
389 };
390
391 /// Input is byte values, *not* hex-encoded.
392 /// Asserts `bytes` fits inside `HexString`
393 pub fn initHexString(bytes: []const u8) BuildId {
394 var result: BuildId = .{ .hexstring = .{
395 .bytes = undefined,
396 .len = @as(u8, @intCast(bytes.len)),
397 } };
398 @memcpy(result.hexstring.bytes[0..bytes.len], bytes);
399 return result;
400 }
401
402 /// Converts UTF-8 text to a `BuildId`.
403 pub fn parse(text: []const u8) !BuildId {
404 if (mem.eql(u8, text, "none")) {
405 return .none;
406 } else if (mem.eql(u8, text, "fast")) {
407 return .fast;
408 } else if (mem.eql(u8, text, "uuid")) {
409 return .uuid;
410 } else if (mem.eql(u8, text, "sha1") or mem.eql(u8, text, "tree")) {
411 return .sha1;
412 } else if (mem.eql(u8, text, "md5")) {
413 return .md5;
414 } else if (mem.startsWith(u8, text, "0x")) {
415 var result: BuildId = .{ .hexstring = undefined };
416 const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]);
417 result.hexstring.len = @as(u8, @intCast(slice.len));
418 return result;
419 }
420 return error.InvalidBuildIdStyle;
421 }
422
423 test parse {
424 try std.testing.expectEqual(BuildId.md5, try parse("md5"));
425 try std.testing.expectEqual(BuildId.none, try parse("none"));
426 try std.testing.expectEqual(BuildId.fast, try parse("fast"));
427 try std.testing.expectEqual(BuildId.uuid, try parse("uuid"));
428 try std.testing.expectEqual(BuildId.sha1, try parse("sha1"));
429 try std.testing.expectEqual(BuildId.sha1, try parse("tree"));
430
431 try std.testing.expect(BuildId.initHexString("").eql(try parse("0x")));
432 try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456")));
433 try std.testing.expectError(error.InvalidLength, parse("0x12-34"));
434 try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb"));
435 try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx"));
436 }
437231};
438232
439233pub const Kind = enum {
......@@ -447,7 +241,6 @@ pub const Linkage = enum { dynamic, static };
447241
448242pub fn create(owner: *std.Build, options: Options) *Compile {
449243 const name = owner.dupe(options.name);
450 const root_src: ?LazyPath = if (options.root_source_file) |rsrc| rsrc.dupe(owner) else null;
451244 if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
452245 panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
453246 }
......@@ -458,6 +251,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
458251 else
459252 owner.fmt("{s} ", .{name});
460253
254 const resolved_target = options.root_module.target.?;
255 const target = resolved_target.result;
256
461257 const step_name = owner.fmt("{s} {s}{s} {s}", .{
462258 switch (options.kind) {
463259 .exe => "zig build-exe",
......@@ -466,15 +262,13 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
466262 .@"test" => "zig test",
467263 },
468264 name_adjusted,
469 @tagName(options.optimize),
470 options.target.zigTriple(owner.allocator) catch @panic("OOM"),
265 @tagName(options.root_module.optimize orelse .Debug),
266 resolved_target.query.zigTriple(owner.allocator) catch @panic("OOM"),
471267 });
472268
473 const target_info = NativeTargetInfo.detect(options.target) catch @panic("unhandled error");
474
475269 const out_filename = std.zig.binNameAlloc(owner.allocator, .{
476270 .root_name = name,
477 .target = target_info.target,
271 .target = target,
478272 .output_mode = switch (options.kind) {
479273 .lib => .Lib,
480274 .obj => .Obj,
......@@ -489,17 +283,12 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
489283
490284 const self = owner.allocator.create(Compile) catch @panic("OOM");
491285 self.* = .{
492 .strip = null,
493 .unwind_tables = null,
286 .root_module = undefined,
494287 .verbose_link = false,
495288 .verbose_cc = false,
496 .optimize = options.optimize,
497 .target = options.target,
498289 .linkage = options.linkage,
499290 .kind = options.kind,
500 .root_src = root_src,
501291 .name = name,
502 .frameworks = StringHashMap(FrameworkLinkInfo).init(owner.allocator),
503292 .step = Step.init(.{
504293 .id = base_id,
505294 .name = step_name,
......@@ -512,23 +301,12 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
512301 .out_lib_filename = undefined,
513302 .major_only_filename = null,
514303 .name_only_filename = null,
515 .modules = std.StringArrayHashMap(*Module).init(owner.allocator),
516 .include_dirs = ArrayList(IncludeDir).init(owner.allocator),
517 .link_objects = ArrayList(LinkObject).init(owner.allocator),
518 .c_macros = ArrayList([]const u8).init(owner.allocator),
519 .lib_paths = ArrayList(LazyPath).init(owner.allocator),
520 .rpaths = ArrayList(LazyPath).init(owner.allocator),
521304 .installed_headers = ArrayList(*Step).init(owner.allocator),
522 .c_std = std.Build.CStd.C99,
523305 .zig_lib_dir = null,
524 .main_mod_path = null,
525306 .exec_cmd_args = null,
526307 .filter = options.filter,
527308 .test_runner = options.test_runner,
528309 .test_server_mode = options.test_runner == null,
529 .disable_stack_probing = false,
530 .disable_sanitize_c = false,
531 .sanitize_thread = false,
532310 .rdynamic = false,
533311 .installed_path = null,
534312 .force_undefined_symbols = StringHashMap(void).init(owner.allocator),
......@@ -543,28 +321,20 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
543321 .generated_llvm_ir = null,
544322 .generated_h = null,
545323
546 .target_info = target_info,
547
548 .is_linking_libc = options.link_libc orelse false,
549 .is_linking_libcpp = false,
550 .single_threaded = options.single_threaded,
551324 .use_llvm = options.use_llvm,
552325 .use_lld = options.use_lld,
553326 };
554327
328 self.root_module.init(owner, options.root_module, self);
329
555330 if (options.zig_lib_dir) |lp| {
556331 self.zig_lib_dir = lp.dupe(self.step.owner);
557332 lp.addStepDependencies(&self.step);
558333 }
559334
560 if (options.main_mod_path orelse options.main_pkg_path) |lp| {
561 self.main_mod_path = lp.dupe(self.step.owner);
562 lp.addStepDependencies(&self.step);
563 }
564
565335 // Only the PE/COFF format has a Resource Table which is where the manifest
566336 // gets embedded, so for any other target the manifest file is just ignored.
567 if (self.target.getObjectFormat() == .coff) {
337 if (target.ofmt == .coff) {
568338 if (options.win32_manifest) |lp| {
569339 self.win32_manifest = lp.dupe(self.step.owner);
570340 lp.addStepDependencies(&self.step);
......@@ -575,14 +345,14 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
575345 if (self.linkage != null and self.linkage.? == .static) {
576346 self.out_lib_filename = self.out_filename;
577347 } else if (self.version) |version| {
578 if (target_info.target.isDarwin()) {
348 if (target.isDarwin()) {
579349 self.major_only_filename = owner.fmt("lib{s}.{d}.dylib", .{
580350 self.name,
581351 version.major,
582352 });
583353 self.name_only_filename = owner.fmt("lib{s}.dylib", .{self.name});
584354 self.out_lib_filename = self.out_filename;
585 } else if (target_info.target.os.tag == .windows) {
355 } else if (target.os.tag == .windows) {
586356 self.out_lib_filename = owner.fmt("{s}.lib", .{self.name});
587357 } else {
588358 self.major_only_filename = owner.fmt("lib{s}.so.{d}", .{ self.name, version.major });
......@@ -590,9 +360,9 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
590360 self.out_lib_filename = self.out_filename;
591361 }
592362 } else {
593 if (target_info.target.isDarwin()) {
363 if (target.isDarwin()) {
594364 self.out_lib_filename = self.out_filename;
595 } else if (target_info.target.os.tag == .windows) {
365 } else if (target.os.tag == .windows) {
596366 self.out_lib_filename = owner.fmt("{s}.lib", .{self.name});
597367 } else {
598368 self.out_lib_filename = self.out_filename;
......@@ -600,8 +370,6 @@ pub fn create(owner: *std.Build, options: Options) *Compile {
600370 }
601371 }
602372
603 if (root_src) |rs| rs.addStepDependencies(&self.step);
604
605373 return self;
606374}
607375
......@@ -701,7 +469,7 @@ pub const run = @compileError("deprecated; use std.Build.addRunArtifact");
701469pub const install = @compileError("deprecated; use std.Build.installArtifact");
702470
703471pub fn checkObject(self: *Compile) *Step.CheckObject {
704 return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.target_info.target.ofmt);
472 return Step.CheckObject.create(self.step.owner, self.getEmittedBin(), self.rootModuleTarget().ofmt);
705473}
706474
707475/// deprecated: use `setLinkerScript`
......@@ -718,113 +486,75 @@ pub fn forceUndefinedSymbol(self: *Compile, symbol_name: []const u8) void {
718486 self.force_undefined_symbols.put(b.dupe(symbol_name), {}) catch @panic("OOM");
719487}
720488
721pub fn linkFramework(self: *Compile, framework_name: []const u8) void {
722 const b = self.step.owner;
723 self.frameworks.put(b.dupe(framework_name), .{}) catch @panic("OOM");
724}
725
726pub fn linkFrameworkNeeded(self: *Compile, framework_name: []const u8) void {
727 const b = self.step.owner;
728 self.frameworks.put(b.dupe(framework_name), .{
729 .needed = true,
730 }) catch @panic("OOM");
731}
732
733pub fn linkFrameworkWeak(self: *Compile, framework_name: []const u8) void {
734 const b = self.step.owner;
735 self.frameworks.put(b.dupe(framework_name), .{
736 .weak = true,
737 }) catch @panic("OOM");
738}
739
740489/// Returns whether the library, executable, or object depends on a particular system library.
741pub fn dependsOnSystemLibrary(self: Compile, name: []const u8) bool {
742 if (isLibCLibrary(name)) {
743 return self.is_linking_libc;
490/// Includes transitive dependencies.
491pub fn dependsOnSystemLibrary(self: *const Compile, name: []const u8) bool {
492 var is_linking_libc = false;
493 var is_linking_libcpp = false;
494
495 var it = self.root_module.iterateDependencies(self, true);
496 while (it.next()) |module| {
497 for (module.link_objects.items) |link_object| {
498 switch (link_object) {
499 .system_lib => |lib| if (mem.eql(u8, lib.name, name)) return true,
500 else => continue,
501 }
502 }
503 is_linking_libc = is_linking_libc or module.link_libcpp == true;
504 is_linking_libcpp = is_linking_libcpp or module.link_libcpp == true;
744505 }
745 if (isLibCppLibrary(name)) {
746 return self.is_linking_libcpp;
506
507 if (self.rootModuleTarget().is_libc_lib_name(name)) {
508 return is_linking_libc;
747509 }
748 for (self.link_objects.items) |link_object| {
749 switch (link_object) {
750 .system_lib => |lib| if (mem.eql(u8, lib.name, name)) return true,
751 else => continue,
752 }
510
511 if (self.rootModuleTarget().is_libcpp_lib_name(name)) {
512 return is_linking_libcpp;
753513 }
754 return false;
755}
756514
757pub fn linkLibrary(self: *Compile, lib: *Compile) void {
758 assert(lib.kind == .lib);
759 self.linkLibraryOrObject(lib);
515 return false;
760516}
761517
762pub fn isDynamicLibrary(self: *Compile) bool {
518pub fn isDynamicLibrary(self: *const Compile) bool {
763519 return self.kind == .lib and self.linkage == Linkage.dynamic;
764520}
765521
766pub fn isStaticLibrary(self: *Compile) bool {
522pub fn isStaticLibrary(self: *const Compile) bool {
767523 return self.kind == .lib and self.linkage != Linkage.dynamic;
768524}
769525
770526pub fn producesPdbFile(self: *Compile) bool {
527 const target = self.rootModuleTarget();
771528 // TODO: Is this right? Isn't PDB for *any* PE/COFF file?
772529 // TODO: just share this logic with the compiler, silly!
773 if (!self.target.isWindows() and !self.target.isUefi()) return false;
774 if (self.target.getObjectFormat() == .c) return false;
775 if (self.strip == true or (self.strip == null and self.optimize == .ReleaseSmall)) return false;
530 switch (target.os.tag) {
531 .windows, .uefi => {},
532 else => return false,
533 }
534 if (target.ofmt == .c) return false;
535 if (self.root_module.strip == true or
536 (self.root_module.strip == null and self.root_module.optimize == .ReleaseSmall))
537 {
538 return false;
539 }
776540 return self.isDynamicLibrary() or self.kind == .exe or self.kind == .@"test";
777541}
778542
779543pub fn producesImplib(self: *Compile) bool {
780 return self.isDynamicLibrary() and self.target.isWindows();
544 return self.isDynamicLibrary() and self.rootModuleTarget().os.tag == .windows;
781545}
782546
783547pub fn linkLibC(self: *Compile) void {
784 self.is_linking_libc = true;
548 self.root_module.link_libc = true;
785549}
786550
787551pub fn linkLibCpp(self: *Compile) void {
788 self.is_linking_libcpp = true;
789}
790
791/// If the value is omitted, it is set to 1.
792/// `name` and `value` need not live longer than the function call.
793pub fn defineCMacro(self: *Compile, name: []const u8, value: ?[]const u8) void {
794 const b = self.step.owner;
795 const macro = std.Build.constructCMacro(b.allocator, name, value);
796 self.c_macros.append(macro) catch @panic("OOM");
797}
798
799/// name_and_value looks like [name]=[value]. If the value is omitted, it is set to 1.
800pub fn defineCMacroRaw(self: *Compile, name_and_value: []const u8) void {
801 const b = self.step.owner;
802 self.c_macros.append(b.dupe(name_and_value)) catch @panic("OOM");
803}
804
805/// deprecated: use linkSystemLibrary2
806pub fn linkSystemLibraryName(self: *Compile, name: []const u8) void {
807 return linkSystemLibrary2(self, name, .{ .use_pkg_config = .no });
808}
809
810/// deprecated: use linkSystemLibrary2
811pub fn linkSystemLibraryNeededName(self: *Compile, name: []const u8) void {
812 return linkSystemLibrary2(self, name, .{ .needed = true, .use_pkg_config = .no });
552 self.root_module.link_libcpp = true;
813553}
814554
815/// deprecated: use linkSystemLibrary2
816pub fn linkSystemLibraryWeakName(self: *Compile, name: []const u8) void {
817 return linkSystemLibrary2(self, name, .{ .weak = true, .use_pkg_config = .no });
818}
819
820/// deprecated: use linkSystemLibrary2
821pub fn linkSystemLibraryPkgConfigOnly(self: *Compile, lib_name: []const u8) void {
822 return linkSystemLibrary2(self, lib_name, .{ .use_pkg_config = .force });
823}
824
825/// deprecated: use linkSystemLibrary2
826pub fn linkSystemLibraryNeededPkgConfigOnly(self: *Compile, lib_name: []const u8) void {
827 return linkSystemLibrary2(self, lib_name, .{ .needed = true, .use_pkg_config = .force });
555/// Deprecated. Use `c.root_module.addCMacro`.
556pub fn defineCMacro(c: *Compile, name: []const u8, value: ?[]const u8) void {
557 c.root_module.addCMacro(name, value orelse "1");
828558}
829559
830560/// Run pkg-config for the given library name and parse the output, returning the arguments
......@@ -924,98 +654,45 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) ![]const []const u8 {
924654}
925655
926656pub fn linkSystemLibrary(self: *Compile, name: []const u8) void {
927 self.linkSystemLibrary2(name, .{});
928}
929
930/// deprecated: use linkSystemLibrary2
931pub fn linkSystemLibraryNeeded(self: *Compile, name: []const u8) void {
932 return linkSystemLibrary2(self, name, .{ .needed = true });
657 return self.root_module.linkSystemLibrary(name, .{});
933658}
934659
935/// deprecated: use linkSystemLibrary2
936pub fn linkSystemLibraryWeak(self: *Compile, name: []const u8) void {
937 return linkSystemLibrary2(self, name, .{ .weak = true });
938}
939
940pub const LinkSystemLibraryOptions = struct {
941 needed: bool = false,
942 weak: bool = false,
943 use_pkg_config: SystemLib.UsePkgConfig = .yes,
944 preferred_link_mode: std.builtin.LinkMode = .Dynamic,
945 search_strategy: SystemLib.SearchStrategy = .paths_first,
946};
947
948660pub fn linkSystemLibrary2(
949661 self: *Compile,
950662 name: []const u8,
951 options: LinkSystemLibraryOptions,
663 options: Module.LinkSystemLibraryOptions,
952664) void {
953 const b = self.step.owner;
954 if (isLibCLibrary(name)) {
955 self.linkLibC();
956 return;
957 }
958 if (isLibCppLibrary(name)) {
959 self.linkLibCpp();
960 return;
961 }
962
963 self.link_objects.append(.{
964 .system_lib = .{
965 .name = b.dupe(name),
966 .needed = options.needed,
967 .weak = options.weak,
968 .use_pkg_config = options.use_pkg_config,
969 .preferred_link_mode = options.preferred_link_mode,
970 .search_strategy = options.search_strategy,
971 },
972 }) catch @panic("OOM");
665 return self.root_module.linkSystemLibrary(name, options);
973666}
974667
975pub const AddCSourceFilesOptions = struct {
976 /// When provided, `files` are relative to `dependency` rather than the package that owns the `Compile` step.
977 dependency: ?*std.Build.Dependency = null,
978 files: []const []const u8,
979 flags: []const []const u8 = &.{},
980};
668pub fn linkFramework(c: *Compile, name: []const u8) void {
669 c.root_module.linkFramework(name, .{});
670}
981671
982/// Handy when you have many C/C++ source files and want them all to have the same flags.
983pub fn addCSourceFiles(self: *Compile, options: AddCSourceFilesOptions) void {
984 const b = self.step.owner;
985 const c_source_files = b.allocator.create(CSourceFiles) catch @panic("OOM");
672/// Deprecated. Use `c.root_module.linkFramework`.
673pub fn linkFrameworkNeeded(c: *Compile, name: []const u8) void {
674 c.root_module.linkFramework(name, .{ .needed = true });
675}
986676
987 const files_copy = b.dupeStrings(options.files);
988 const flags_copy = b.dupeStrings(options.flags);
677/// Deprecated. Use `c.root_module.linkFramework`.
678pub fn linkFrameworkWeak(c: *Compile, name: []const u8) void {
679 c.root_module.linkFramework(name, .{ .weak = true });
680}
989681
990 c_source_files.* = .{
991 .dependency = options.dependency,
992 .files = files_copy,
993 .flags = flags_copy,
994 };
995 self.link_objects.append(.{ .c_source_files = c_source_files }) catch @panic("OOM");
682/// Handy when you have many C/C++ source files and want them all to have the same flags.
683pub fn addCSourceFiles(self: *Compile, options: Module.AddCSourceFilesOptions) void {
684 self.root_module.addCSourceFiles(options);
996685}
997686
998pub fn addCSourceFile(self: *Compile, source: CSourceFile) void {
999 const b = self.step.owner;
1000 const c_source_file = b.allocator.create(CSourceFile) catch @panic("OOM");
1001 c_source_file.* = source.dupe(b);
1002 self.link_objects.append(.{ .c_source_file = c_source_file }) catch @panic("OOM");
1003 source.file.addStepDependencies(&self.step);
687pub fn addCSourceFile(self: *Compile, source: Module.CSourceFile) void {
688 self.root_module.addCSourceFile(source);
1004689}
1005690
1006691/// Resource files must have the extension `.rc`.
1007692/// Can be called regardless of target. The .rc file will be ignored
1008693/// if the target object format does not support embedded resources.
1009pub fn addWin32ResourceFile(self: *Compile, source: RcSourceFile) void {
1010 // Only the PE/COFF format has a Resource Table, so for any other target
1011 // the resource file is just ignored.
1012 if (self.target.getObjectFormat() != .coff) return;
1013
1014 const b = self.step.owner;
1015 const rc_source_file = b.allocator.create(RcSourceFile) catch @panic("OOM");
1016 rc_source_file.* = source.dupe(b);
1017 self.link_objects.append(.{ .win32_resource_file = rc_source_file }) catch @panic("OOM");
1018 source.file.addStepDependencies(&self.step);
694pub fn addWin32ResourceFile(self: *Compile, source: Module.RcSourceFile) void {
695 self.root_module.addWin32ResourceFile(source);
1019696}
1020697
1021698pub fn setVerboseLink(self: *Compile, value: bool) void {
......@@ -1042,27 +719,18 @@ fn getEmittedFileGeneric(self: *Compile, output_file: *?*GeneratedFile) LazyPath
1042719 return .{ .generated = generated_file };
1043720}
1044721
1045/// deprecated: use `getEmittedBinDirectory`
1046pub const getOutputDirectorySource = getEmittedBinDirectory;
1047
1048722/// Returns the path to the directory that contains the emitted binary file.
1049723pub fn getEmittedBinDirectory(self: *Compile) LazyPath {
1050724 _ = self.getEmittedBin();
1051725 return self.getEmittedFileGeneric(&self.emit_directory);
1052726}
1053727
1054/// deprecated: use `getEmittedBin`
1055pub const getOutputSource = getEmittedBin;
1056
1057728/// Returns the path to the generated executable, library or object file.
1058729/// To run an executable built with zig build, use `run`, or create an install step and invoke it.
1059730pub fn getEmittedBin(self: *Compile) LazyPath {
1060731 return self.getEmittedFileGeneric(&self.generated_bin);
1061732}
1062733
1063/// deprecated: use `getEmittedImplib`
1064pub const getOutputLibSource = getEmittedImplib;
1065
1066734/// Returns the path to the generated import library.
1067735/// This function can only be called for libraries.
1068736pub fn getEmittedImplib(self: *Compile) LazyPath {
......@@ -1070,9 +738,6 @@ pub fn getEmittedImplib(self: *Compile) LazyPath {
1070738 return self.getEmittedFileGeneric(&self.generated_implib);
1071739}
1072740
1073/// deprecated: use `getEmittedH`
1074pub const getOutputHSource = getEmittedH;
1075
1076741/// Returns the path to the generated header file.
1077742/// This function can only be called for libraries or objects.
1078743pub fn getEmittedH(self: *Compile) LazyPath {
......@@ -1080,9 +745,6 @@ pub fn getEmittedH(self: *Compile) LazyPath {
1080745 return self.getEmittedFileGeneric(&self.generated_h);
1081746}
1082747
1083/// deprecated: use `getEmittedPdb`.
1084pub const getOutputPdbSource = getEmittedPdb;
1085
1086748/// Returns the generated PDB file.
1087749/// If the compilation does not produce a PDB file, this causes a FileNotFound error
1088750/// at build time.
......@@ -1112,138 +774,51 @@ pub fn getEmittedLlvmBc(self: *Compile) LazyPath {
1112774}
1113775
1114776pub fn addAssemblyFile(self: *Compile, source: LazyPath) void {
1115 const b = self.step.owner;
1116 const source_duped = source.dupe(b);
1117 self.link_objects.append(.{ .assembly_file = source_duped }) catch @panic("OOM");
1118 source_duped.addStepDependencies(&self.step);
777 self.root_module.addAssemblyFile(source);
1119778}
1120779
1121780pub fn addObjectFile(self: *Compile, source: LazyPath) void {
1122 const b = self.step.owner;
1123 self.link_objects.append(.{ .static_path = source.dupe(b) }) catch @panic("OOM");
1124 source.addStepDependencies(&self.step);
1125}
1126
1127pub fn addObject(self: *Compile, obj: *Compile) void {
1128 assert(obj.kind == .obj);
1129 self.linkLibraryOrObject(obj);
781 self.root_module.addObjectFile(source);
1130782}
1131783
1132pub fn addAfterIncludePath(self: *Compile, path: LazyPath) void {
1133 const b = self.step.owner;
1134 self.include_dirs.append(IncludeDir{ .path_after = path.dupe(b) }) catch @panic("OOM");
1135 path.addStepDependencies(&self.step);
1136}
1137
1138pub fn addSystemIncludePath(self: *Compile, path: LazyPath) void {
1139 const b = self.step.owner;
1140 self.include_dirs.append(IncludeDir{ .path_system = path.dupe(b) }) catch @panic("OOM");
1141 path.addStepDependencies(&self.step);
784pub fn addObject(self: *Compile, object: *Compile) void {
785 self.root_module.addObject(object);
1142786}
1143787
1144pub fn addIncludePath(self: *Compile, path: LazyPath) void {
1145 const b = self.step.owner;
1146 self.include_dirs.append(IncludeDir{ .path = path.dupe(b) }) catch @panic("OOM");
1147 path.addStepDependencies(&self.step);
1148}
1149
1150pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void {
1151 self.step.dependOn(&config_header.step);
1152 self.include_dirs.append(.{ .config_header_step = config_header }) catch @panic("OOM");
1153}
1154
1155pub fn addLibraryPath(self: *Compile, directory_source: LazyPath) void {
1156 const b = self.step.owner;
1157 self.lib_paths.append(directory_source.dupe(b)) catch @panic("OOM");
1158 directory_source.addStepDependencies(&self.step);
788pub fn linkLibrary(self: *Compile, library: *Compile) void {
789 self.root_module.linkLibrary(library);
1159790}
1160791
1161pub fn addRPath(self: *Compile, directory_source: LazyPath) void {
1162 const b = self.step.owner;
1163 self.rpaths.append(directory_source.dupe(b)) catch @panic("OOM");
1164 directory_source.addStepDependencies(&self.step);
792pub fn addAfterIncludePath(self: *Compile, lazy_path: LazyPath) void {
793 self.root_module.addAfterIncludePath(lazy_path);
1165794}
1166795
1167pub fn addSystemFrameworkPath(self: *Compile, directory_source: LazyPath) void {
1168 const b = self.step.owner;
1169 self.include_dirs.append(IncludeDir{ .framework_path_system = directory_source.dupe(b) }) catch @panic("OOM");
1170 directory_source.addStepDependencies(&self.step);
796pub fn addSystemIncludePath(self: *Compile, lazy_path: LazyPath) void {
797 self.root_module.addSystemIncludePath(lazy_path);
1171798}
1172799
1173pub fn addFrameworkPath(self: *Compile, directory_source: LazyPath) void {
1174 const b = self.step.owner;
1175 self.include_dirs.append(IncludeDir{ .framework_path = directory_source.dupe(b) }) catch @panic("OOM");
1176 directory_source.addStepDependencies(&self.step);
800pub fn addIncludePath(self: *Compile, lazy_path: LazyPath) void {
801 self.root_module.addIncludePath(lazy_path);
1177802}
1178803
1179/// Adds a module to be used with `@import` and exposing it in the current
1180/// package's module table using `name`.
1181pub fn addModule(cs: *Compile, name: []const u8, module: *Module) void {
1182 const b = cs.step.owner;
1183 cs.modules.put(b.dupe(name), module) catch @panic("OOM");
1184
1185 var done = std.AutoHashMap(*Module, void).init(b.allocator);
1186 defer done.deinit();
1187 cs.addRecursiveBuildDeps(module, &done) catch @panic("OOM");
804pub fn addConfigHeader(self: *Compile, config_header: *Step.ConfigHeader) void {
805 self.root_module.addConfigHeader(config_header);
1188806}
1189807
1190/// Adds a module to be used with `@import` without exposing it in the current
1191/// package's module table.
1192pub fn addAnonymousModule(cs: *Compile, name: []const u8, options: std.Build.CreateModuleOptions) void {
1193 const b = cs.step.owner;
1194 const module = b.createModule(options);
1195 return addModule(cs, name, module);
808pub fn addLibraryPath(self: *Compile, directory_path: LazyPath) void {
809 self.root_module.addLibraryPath(directory_path);
1196810}
1197811
1198pub fn addOptions(cs: *Compile, module_name: []const u8, options: *Step.Options) void {
1199 addModule(cs, module_name, options.createModule());
812pub fn addRPath(self: *Compile, directory_path: LazyPath) void {
813 self.root_module.addRPath(directory_path);
1200814}
1201815
1202fn addRecursiveBuildDeps(cs: *Compile, module: *Module, done: *std.AutoHashMap(*Module, void)) !void {
1203 if (done.contains(module)) return;
1204 try done.put(module, {});
1205 module.source_file.addStepDependencies(&cs.step);
1206 for (module.dependencies.values()) |dep| {
1207 try cs.addRecursiveBuildDeps(dep, done);
1208 }
816pub fn addSystemFrameworkPath(self: *Compile, directory_path: LazyPath) void {
817 self.root_module.addSystemFrameworkPath(directory_path);
1209818}
1210819
1211/// If Vcpkg was found on the system, it will be added to include and lib
1212/// paths for the specified target.
1213pub fn addVcpkgPaths(self: *Compile, linkage: Compile.Linkage) !void {
1214 const b = self.step.owner;
1215 // Ideally in the Unattempted case we would call the function recursively
1216 // after findVcpkgRoot and have only one switch statement, but the compiler
1217 // cannot resolve the error set.
1218 switch (b.vcpkg_root) {
1219 .unattempted => {
1220 b.vcpkg_root = if (try findVcpkgRoot(b.allocator)) |root|
1221 VcpkgRoot{ .found = root }
1222 else
1223 .not_found;
1224 },
1225 .not_found => return error.VcpkgNotFound,
1226 .found => {},
1227 }
1228
1229 switch (b.vcpkg_root) {
1230 .unattempted => unreachable,
1231 .not_found => return error.VcpkgNotFound,
1232 .found => |root| {
1233 const allocator = b.allocator;
1234 const triplet = try self.target.vcpkgTriplet(allocator, if (linkage == .static) .Static else .Dynamic);
1235 defer b.allocator.free(triplet);
1236
1237 const include_path = b.pathJoin(&.{ root, "installed", triplet, "include" });
1238 errdefer allocator.free(include_path);
1239 try self.include_dirs.append(IncludeDir{ .path = .{ .path = include_path } });
1240
1241 const lib_path = b.pathJoin(&.{ root, "installed", triplet, "lib" });
1242 try self.lib_paths.append(.{ .path = lib_path });
1243
1244 self.vcpkg_bin_path = b.pathJoin(&.{ root, "installed", triplet, "bin" });
1245 },
1246 }
820pub fn addFrameworkPath(self: *Compile, directory_path: LazyPath) void {
821 self.root_module.addFrameworkPath(directory_path);
1247822}
1248823
1249824pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void {
......@@ -1256,129 +831,42 @@ pub fn setExecCmd(self: *Compile, args: []const ?[]const u8) void {
1256831 self.exec_cmd_args = duped_args;
1257832}
1258833
1259fn linkLibraryOrObject(self: *Compile, other: *Compile) void {
1260 other.getEmittedBin().addStepDependencies(&self.step);
1261 if (other.target.isWindows() and other.isDynamicLibrary()) {
1262 other.getEmittedImplib().addStepDependencies(&self.step);
1263 }
834const CliNamedModules = struct {
835 modules: std.AutoArrayHashMapUnmanaged(*Module, void),
836 names: std.StringArrayHashMapUnmanaged(void),
1264837
1265 self.link_objects.append(.{ .other_step = other }) catch @panic("OOM");
1266 self.include_dirs.append(.{ .other_step = other }) catch @panic("OOM");
1267
1268 for (other.installed_headers.items) |install_step| {
1269 self.step.dependOn(install_step);
1270 }
1271}
1272
1273fn appendModuleArgs(
1274 cs: *Compile,
1275 zig_args: *ArrayList([]const u8),
1276) error{OutOfMemory}!void {
1277 const b = cs.step.owner;
1278 // First, traverse the whole dependency graph and give every module a unique name, ideally one
1279 // named after what it's called somewhere in the graph. It will help here to have both a mapping
1280 // from module to name and a set of all the currently-used names.
1281 var mod_names = std.AutoHashMap(*Module, []const u8).init(b.allocator);
1282 var names = std.StringHashMap(void).init(b.allocator);
1283
1284 var to_name = std.ArrayList(struct {
1285 name: []const u8,
1286 mod: *Module,
1287 }).init(b.allocator);
1288 {
1289 var it = cs.modules.iterator();
1290 while (it.next()) |kv| {
1291 // While we're traversing the root dependencies, let's make sure that no module names
1292 // have colons in them, since the CLI forbids it. We handle this for transitive
1293 // dependencies further down.
1294 if (std.mem.indexOfScalar(u8, kv.key_ptr.*, ':') != null) {
1295 @panic("Module names cannot contain colons");
1296 }
1297 try to_name.append(.{
1298 .name = kv.key_ptr.*,
1299 .mod = kv.value_ptr.*,
1300 });
1301 }
1302 }
1303
1304 while (to_name.popOrNull()) |dep| {
1305 if (mod_names.contains(dep.mod)) continue;
1306
1307 // We'll use this buffer to store the name we decide on
1308 var buf = try b.allocator.alloc(u8, dep.name.len + 32);
1309 // First, try just the exposed dependency name
1310 @memcpy(buf[0..dep.name.len], dep.name);
1311 var name = buf[0..dep.name.len];
1312 var n: usize = 0;
1313 while (names.contains(name)) {
1314 // If that failed, append an incrementing number to the end
1315 name = std.fmt.bufPrint(buf, "{s}{}", .{ dep.name, n }) catch unreachable;
1316 n += 1;
838 /// Traverse the whole dependency graph and give every module a unique
839 /// name, ideally one named after what it's called somewhere in the graph.
840 /// It will help here to have both a mapping from module to name and a set
841 /// of all the currently-used names.
842 fn init(arena: Allocator, root_module: *Module) Allocator.Error!CliNamedModules {
843 var self: CliNamedModules = .{
844 .modules = .{},
845 .names = .{},
846 };
847 var it = root_module.iterateDependencies(null, false);
848 {
849 const item = it.next().?;
850 assert(root_module == item.module);
851 try self.modules.put(arena, root_module, {});
852 try self.names.put(arena, "root", {});
1317853 }
1318
1319 try mod_names.put(dep.mod, name);
1320 try names.put(name, {});
1321
1322 var it = dep.mod.dependencies.iterator();
1323 while (it.next()) |kv| {
1324 // Same colon-in-name check as above, but for transitive dependencies.
1325 if (std.mem.indexOfScalar(u8, kv.key_ptr.*, ':') != null) {
1326 @panic("Module names cannot contain colons");
854 while (it.next()) |item| {
855 var name = item.name;
856 var n: usize = 0;
857 while (true) {
858 const gop = try self.names.getOrPut(arena, name);
859 if (!gop.found_existing) {
860 try self.modules.putNoClobber(arena, item.module, {});
861 break;
862 }
863 name = try std.fmt.allocPrint(arena, "{s}{d}", .{ item.name, n });
864 n += 1;
1327865 }
1328 try to_name.append(.{
1329 .name = kv.key_ptr.*,
1330 .mod = kv.value_ptr.*,
1331 });
1332 }
1333 }
1334
1335 // Since the module names given to the CLI are based off of the exposed names, we already know
1336 // that none of the CLI names have colons in them, so there's no need to check that explicitly.
1337
1338 // Every module in the graph is now named; output their definitions
1339 {
1340 var it = mod_names.iterator();
1341 while (it.next()) |kv| {
1342 const mod = kv.key_ptr.*;
1343 const name = kv.value_ptr.*;
1344
1345 const deps_str = try constructDepString(b.allocator, mod_names, mod.dependencies);
1346 const src = mod.source_file.getPath(mod.builder);
1347 try zig_args.append("--mod");
1348 try zig_args.append(try std.fmt.allocPrint(b.allocator, "{s}:{s}:{s}", .{ name, deps_str, src }));
1349 }
1350 }
1351
1352 // Lastly, output the root dependencies
1353 const deps_str = try constructDepString(b.allocator, mod_names, cs.modules);
1354 if (deps_str.len > 0) {
1355 try zig_args.append("--deps");
1356 try zig_args.append(deps_str);
1357 }
1358}
1359
1360fn constructDepString(
1361 allocator: std.mem.Allocator,
1362 mod_names: std.AutoHashMap(*Module, []const u8),
1363 deps: std.StringArrayHashMap(*Module),
1364) ![]const u8 {
1365 var deps_str = std.ArrayList(u8).init(allocator);
1366 var it = deps.iterator();
1367 while (it.next()) |kv| {
1368 const expose = kv.key_ptr.*;
1369 const name = mod_names.get(kv.value_ptr.*).?;
1370 if (std.mem.eql(u8, expose, name)) {
1371 try deps_str.writer().print("{s},", .{name});
1372 } else {
1373 try deps_str.writer().print("{s}={s},", .{ expose, name });
1374866 }
867 return self;
1375868 }
1376 if (deps_str.items.len > 0) {
1377 return deps_str.items[0 .. deps_str.items.len - 1]; // omit trailing comma
1378 } else {
1379 return "";
1380 }
1381}
869};
1382870
1383871fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_step: ?*Step) []const u8 {
1384872 const maybe_path: ?*GeneratedFile = @field(self, tag_name);
......@@ -1406,13 +894,10 @@ fn getGeneratedFilePath(self: *Compile, comptime tag_name: []const u8, asking_st
1406894
1407895fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1408896 const b = step.owner;
897 const arena = b.allocator;
1409898 const self = @fieldParentPtr(Compile, "step", step);
1410899
1411 if (self.root_src == null and self.link_objects.items.len == 0) {
1412 return step.fail("the linker needs one or more objects to link", .{});
1413 }
1414
1415 var zig_args = ArrayList([]const u8).init(b.allocator);
900 var zig_args = ArrayList([]const u8).init(arena);
1416901 defer zig_args.deinit();
1417902
1418903 try zig_args.append(b.zig_exe);
......@@ -1426,14 +911,14 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1426911 try zig_args.append(cmd);
1427912
1428913 if (b.reference_trace) |some| {
1429 try zig_args.append(try std.fmt.allocPrint(b.allocator, "-freference-trace={d}", .{some}));
914 try zig_args.append(try std.fmt.allocPrint(arena, "-freference-trace={d}", .{some}));
1430915 }
1431916
1432917 try addFlag(&zig_args, "llvm", self.use_llvm);
1433918 try addFlag(&zig_args, "lld", self.use_lld);
1434919
1435 if (self.target.ofmt) |ofmt| {
1436 try zig_args.append(try std.fmt.allocPrint(b.allocator, "-ofmt={s}", .{@tagName(ofmt)}));
920 if (self.root_module.resolved_target.?.query.ofmt) |ofmt| {
921 try zig_args.append(try std.fmt.allocPrint(arena, "-ofmt={s}", .{@tagName(ofmt)}));
1437922 }
1438923
1439924 switch (self.entry) {
......@@ -1441,7 +926,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1441926 .disabled => try zig_args.append("-fno-entry"),
1442927 .enabled => try zig_args.append("-fentry"),
1443928 .symbol_name => |entry_name| {
1444 try zig_args.append(try std.fmt.allocPrint(b.allocator, "-fentry={s}", .{entry_name}));
929 try zig_args.append(try std.fmt.allocPrint(arena, "-fentry={s}", .{entry_name}));
1445930 },
1446931 }
1447932
......@@ -1455,207 +940,316 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
1455940
1456941 if (self.stack_size) |stack_size| {
1457942 try zig_args.append("--stack");
1458 try zig_args.append(try std.fmt.allocPrint(b.allocator, "{}", .{stack_size}));
943 try zig_args.append(try std.fmt.allocPrint(arena, "{}", .{stack_size}));
1459944 }
1460945
1461 if (self.root_src) |root_src| try zig_args.append(root_src.getPath(b));
946 {
947 var seen_system_libs: std.StringHashMapUnmanaged(void) = .{};
948 var frameworks: std.StringArrayHashMapUnmanaged(Module.LinkFrameworkOptions) = .{};
949
950 var prev_has_cflags = false;
951 var prev_has_rcflags = false;
952 var prev_search_strategy: Module.SystemLib.SearchStrategy = .paths_first;
953 var prev_preferred_link_mode: std.builtin.LinkMode = .Dynamic;
954 // Track the number of positional arguments so that a nice error can be
955 // emitted if there is nothing to link.
956 var total_linker_objects: usize = @intFromBool(self.root_module.root_source_file != null);
957
958 {
959 // Fully recursive iteration including dynamic libraries to detect
960 // libc and libc++ linkage.
961 var it = self.root_module.iterateDependencies(self, true);
962 while (it.next()) |key| {
963 if (key.module.link_libc == true) self.is_linking_libc = true;
964 if (key.module.link_libcpp == true) self.is_linking_libcpp = true;
965 }
966 }
1462967
1463 // We will add link objects from transitive dependencies, but we want to keep
1464 // all link objects in the same order provided.
1465 // This array is used to keep self.link_objects immutable.
1466 var transitive_deps: TransitiveDeps = .{
1467 .link_objects = ArrayList(LinkObject).init(b.allocator),
1468 .seen_system_libs = StringHashMap(void).init(b.allocator),
1469 .seen_steps = std.AutoHashMap(*const Step, void).init(b.allocator),
1470 .is_linking_libcpp = self.is_linking_libcpp,
1471 .is_linking_libc = self.is_linking_libc,
1472 .frameworks = &self.frameworks,
1473 };
968 var cli_named_modules = try CliNamedModules.init(arena, &self.root_module);
1474969
1475 try transitive_deps.seen_steps.put(&self.step, {});
1476 try transitive_deps.add(self.link_objects.items);
1477
1478 var prev_has_cflags = false;
1479 var prev_has_rcflags = false;
1480 var prev_search_strategy: SystemLib.SearchStrategy = .paths_first;
1481 var prev_preferred_link_mode: std.builtin.LinkMode = .Dynamic;
1482
1483 for (transitive_deps.link_objects.items) |link_object| {
1484 switch (link_object) {
1485 .static_path => |static_path| try zig_args.append(static_path.getPath(b)),
1486
1487 .other_step => |other| switch (other.kind) {
1488 .exe => @panic("Cannot link with an executable build artifact"),
1489 .@"test" => @panic("Cannot link with a test"),
1490 .obj => {
1491 try zig_args.append(other.getEmittedBin().getPath(b));
1492 },
1493 .lib => l: {
1494 if (self.isStaticLibrary() and other.isStaticLibrary()) {
1495 // Avoid putting a static library inside a static library.
1496 break :l;
1497 }
970 // For this loop, don't chase dynamic libraries because their link
971 // objects are already linked.
972 var it = self.root_module.iterateDependencies(self, false);
1498973
1499 // For DLLs, we gotta link against the implib. For
1500 // everything else, we directly link against the library file.
1501 const full_path_lib = if (other.producesImplib())
1502 other.getGeneratedFilePath("generated_implib", &self.step)
1503 else
1504 other.getGeneratedFilePath("generated_bin", &self.step);
1505 try zig_args.append(full_path_lib);
1506
1507 if (other.linkage == Linkage.dynamic and !self.target.isWindows()) {
1508 if (fs.path.dirname(full_path_lib)) |dirname| {
1509 try zig_args.append("-rpath");
1510 try zig_args.append(dirname);
1511 }
1512 }
1513 },
1514 },
974 while (it.next()) |key| {
975 const module = key.module;
976 const compile = key.compile.?;
1515977
1516 .system_lib => |system_lib| {
1517 if ((system_lib.search_strategy != prev_search_strategy or
1518 system_lib.preferred_link_mode != prev_preferred_link_mode) and
1519 self.linkage != .static)
1520 {
1521 switch (system_lib.search_strategy) {
1522 .no_fallback => switch (system_lib.preferred_link_mode) {
1523 .Dynamic => try zig_args.append("-search_dylibs_only"),
1524 .Static => try zig_args.append("-search_static_only"),
1525 },
1526 .paths_first => switch (system_lib.preferred_link_mode) {
1527 .Dynamic => try zig_args.append("-search_paths_first"),
1528 .Static => try zig_args.append("-search_paths_first_static"),
1529 },
1530 .mode_first => switch (system_lib.preferred_link_mode) {
1531 .Dynamic => try zig_args.append("-search_dylibs_first"),
1532 .Static => try zig_args.append("-search_static_first"),
1533 },
1534 }
1535 prev_search_strategy = system_lib.search_strategy;
1536 prev_preferred_link_mode = system_lib.preferred_link_mode;
978 // While walking transitive dependencies, if a given link object is
979 // already included in a library, it should not redundantly be
980 // placed on the linker line of the dependee.
981 const my_responsibility = compile == self;
982 const already_linked = !my_responsibility and compile.isDynamicLibrary();
983
984 // Inherit dependencies on darwin frameworks.
985 if (!already_linked) {
986 for (module.frameworks.keys(), module.frameworks.values()) |name, info| {
987 try frameworks.put(arena, name, info);
1537988 }
989 }
1538990
1539 const prefix: []const u8 = prefix: {
1540 if (system_lib.needed) break :prefix "-needed-l";
1541 if (system_lib.weak) break :prefix "-weak-l";
1542 break :prefix "-l";
1543 };
1544 switch (system_lib.use_pkg_config) {
1545 .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })),
1546 .yes, .force => {
1547 if (self.runPkgConfig(system_lib.name)) |args| {
1548 try zig_args.appendSlice(args);
1549 } else |err| switch (err) {
1550 error.PkgConfigInvalidOutput,
1551 error.PkgConfigCrashed,
1552 error.PkgConfigFailed,
1553 error.PkgConfigNotInstalled,
1554 error.PackageNotFound,
1555 => switch (system_lib.use_pkg_config) {
1556 .yes => {
1557 // pkg-config failed, so fall back to linking the library
1558 // by name directly.
1559 try zig_args.append(b.fmt("{s}{s}", .{
1560 prefix,
1561 system_lib.name,
1562 }));
991 // Inherit dependencies on system libraries and static libraries.
992 for (module.link_objects.items) |link_object| {
993 switch (link_object) {
994 .static_path => |static_path| {
995 if (my_responsibility) {
996 try zig_args.append(static_path.getPath(b));
997 total_linker_objects += 1;
998 }
999 },
1000 .system_lib => |system_lib| {
1001 if ((try seen_system_libs.fetchPut(arena, system_lib.name, {})) != null)
1002 continue;
1003
1004 if (already_linked)
1005 continue;
1006
1007 if ((system_lib.search_strategy != prev_search_strategy or
1008 system_lib.preferred_link_mode != prev_preferred_link_mode) and
1009 self.linkage != .static)
1010 {
1011 switch (system_lib.search_strategy) {
1012 .no_fallback => switch (system_lib.preferred_link_mode) {
1013 .Dynamic => try zig_args.append("-search_dylibs_only"),
1014 .Static => try zig_args.append("-search_static_only"),
1015 },
1016 .paths_first => switch (system_lib.preferred_link_mode) {
1017 .Dynamic => try zig_args.append("-search_paths_first"),
1018 .Static => try zig_args.append("-search_paths_first_static"),
15631019 },
1564 .force => {
1565 panic("pkg-config failed for library {s}", .{system_lib.name});
1020 .mode_first => switch (system_lib.preferred_link_mode) {
1021 .Dynamic => try zig_args.append("-search_dylibs_first"),
1022 .Static => try zig_args.append("-search_static_first"),
15661023 },
1567 .no => unreachable,
1024 }
1025 prev_search_strategy = system_lib.search_strategy;
1026 prev_preferred_link_mode = system_lib.preferred_link_mode;
1027 }
1028
1029 const prefix: []const u8 = prefix: {
1030 if (system_lib.needed) break :prefix "-needed-l";
1031 if (system_lib.weak) break :prefix "-weak-l";
1032 break :prefix "-l";
1033 };
1034 switch (system_lib.use_pkg_config) {
1035 .no => try zig_args.append(b.fmt("{s}{s}", .{ prefix, system_lib.name })),
1036 .yes, .force => {
1037 if (self.runPkgConfig(system_lib.name)) |args| {
1038 try zig_args.appendSlice(args);
1039 } else |err| switch (err) {
1040 error.PkgConfigInvalidOutput,
1041 error.PkgConfigCrashed,
1042 error.PkgConfigFailed,
1043 error.PkgConfigNotInstalled,
1044 error.PackageNotFound,
1045 => switch (system_lib.use_pkg_config) {
1046 .yes => {
1047 // pkg-config failed, so fall back to linking the library
1048 // by name directly.
1049 try zig_args.append(b.fmt("{s}{s}", .{
1050 prefix,
1051 system_lib.name,
1052 }));
1053 },
1054 .force => {
1055 panic("pkg-config failed for library {s}", .{system_lib.name});
1056 },
1057 .no => unreachable,
1058 },
1059
1060 else => |e| return e,
1061 }
15681062 },
1063 }
1064 },
1065 .other_step => |other| {
1066 switch (other.kind) {
1067 .exe => return step.fail("cannot link with an executable build artifact", .{}),
1068 .@"test" => return step.fail("cannot link with a test", .{}),
1069 .obj => {
1070 const included_in_lib = !my_responsibility and
1071 compile.kind == .lib and other.kind == .obj;
1072 if (!already_linked and !included_in_lib) {
1073 try zig_args.append(other.getEmittedBin().getPath(b));
1074 total_linker_objects += 1;
1075 }
1076 },
1077 .lib => l: {
1078 const other_produces_implib = other.producesImplib();
1079 const other_is_static = other_produces_implib or other.isStaticLibrary();
1080
1081 if (self.isStaticLibrary() and other_is_static) {
1082 // Avoid putting a static library inside a static library.
1083 break :l;
1084 }
1085
1086 // For DLLs, we must link against the implib.
1087 // For everything else, we directly link
1088 // against the library file.
1089 const full_path_lib = if (other_produces_implib)
1090 other.getGeneratedFilePath("generated_implib", &self.step)
1091 else
1092 other.getGeneratedFilePath("generated_bin", &self.step);
1093
1094 try zig_args.append(full_path_lib);
1095 total_linker_objects += 1;
1096
1097 if (other.linkage == Linkage.dynamic and
1098 self.rootModuleTarget().os.tag != .windows)
1099 {
1100 if (fs.path.dirname(full_path_lib)) |dirname| {
1101 try zig_args.append("-rpath");
1102 try zig_args.append(dirname);
1103 }
1104 }
1105 },
1106 }
1107 },
1108 .assembly_file => |asm_file| l: {
1109 if (!my_responsibility) break :l;
15691110
1570 else => |e| return e,
1111 if (prev_has_cflags) {
1112 try zig_args.append("-cflags");
1113 try zig_args.append("--");
1114 prev_has_cflags = false;
15711115 }
1116 try zig_args.append(asm_file.getPath(b));
1117 total_linker_objects += 1;
15721118 },
1573 }
1574 },
15751119
1576 .assembly_file => |asm_file| {
1577 if (prev_has_cflags) {
1578 try zig_args.append("-cflags");
1579 try zig_args.append("--");
1580 prev_has_cflags = false;
1581 }
1582 try zig_args.append(asm_file.getPath(b));
1583 },
1120 .c_source_file => |c_source_file| l: {
1121 if (!my_responsibility) break :l;
1122
1123 if (c_source_file.flags.len == 0) {
1124 if (prev_has_cflags) {
1125 try zig_args.append("-cflags");
1126 try zig_args.append("--");
1127 prev_has_cflags = false;
1128 }
1129 } else {
1130 try zig_args.append("-cflags");
1131 for (c_source_file.flags) |arg| {
1132 try zig_args.append(arg);
1133 }
1134 try zig_args.append("--");
1135 prev_has_cflags = true;
1136 }
1137 try zig_args.append(c_source_file.file.getPath(b));
1138 total_linker_objects += 1;
1139 },
15841140
1585 .c_source_file => |c_source_file| {
1586 if (c_source_file.flags.len == 0) {
1587 if (prev_has_cflags) {
1588 try zig_args.append("-cflags");
1589 try zig_args.append("--");
1590 prev_has_cflags = false;
1591 }
1592 } else {
1593 try zig_args.append("-cflags");
1594 for (c_source_file.flags) |arg| {
1595 try zig_args.append(arg);
1596 }
1597 try zig_args.append("--");
1598 prev_has_cflags = true;
1599 }
1600 try zig_args.append(c_source_file.file.getPath(b));
1601 },
1141 .c_source_files => |c_source_files| l: {
1142 if (!my_responsibility) break :l;
1143
1144 if (c_source_files.flags.len == 0) {
1145 if (prev_has_cflags) {
1146 try zig_args.append("-cflags");
1147 try zig_args.append("--");
1148 prev_has_cflags = false;
1149 }
1150 } else {
1151 try zig_args.append("-cflags");
1152 for (c_source_files.flags) |flag| {
1153 try zig_args.append(flag);
1154 }
1155 try zig_args.append("--");
1156 prev_has_cflags = true;
1157 }
16021158
1603 .c_source_files => |c_source_files| {
1604 if (c_source_files.flags.len == 0) {
1605 if (prev_has_cflags) {
1606 try zig_args.append("-cflags");
1607 try zig_args.append("--");
1608 prev_has_cflags = false;
1609 }
1610 } else {
1611 try zig_args.append("-cflags");
1612 for (c_source_files.flags) |flag| {
1613 try zig_args.append(flag);
1614 }
1615 try zig_args.append("--");
1616 prev_has_cflags = true;
1159 if (c_source_files.dependency) |dep| {
1160 for (c_source_files.files) |file| {
1161 try zig_args.append(dep.builder.pathFromRoot(file));
1162 }
1163 } else {
1164 for (c_source_files.files) |file| {
1165 try zig_args.append(b.pathFromRoot(file));
1166 }
1167 }
1168 total_linker_objects += c_source_files.files.len;
1169 },
1170
1171 .win32_resource_file => |rc_source_file| l: {
1172 if (!my_responsibility) break :l;
1173
1174 if (rc_source_file.flags.len == 0) {
1175 if (prev_has_rcflags) {
1176 try zig_args.append("-rcflags");
1177 try zig_args.append("--");
1178 prev_has_rcflags = false;
1179 }
1180 } else {
1181 try zig_args.append("-rcflags");
1182 for (rc_source_file.flags) |arg| {
1183 try zig_args.append(arg);
1184 }
1185 try zig_args.append("--");
1186 prev_has_rcflags = true;
1187 }
1188 try zig_args.append(rc_source_file.file.getPath(b));
1189 total_linker_objects += 1;
1190 },
16171191 }
1618 if (c_source_files.dependency) |dep| {
1619 for (c_source_files.files) |file| {
1620 try zig_args.append(dep.builder.pathFromRoot(file));
1621 }
1622 } else {
1623 for (c_source_files.files) |file| {
1624 try zig_args.append(b.pathFromRoot(file));
1192 }
1193
1194 // We need to emit the --mod argument here so that the above link objects
1195 // have the correct parent module, but only if the module is part of
1196 // this compilation.
1197 if (cli_named_modules.modules.getIndex(module)) |module_cli_index| {
1198 const module_cli_name = cli_named_modules.names.keys()[module_cli_index];
1199 try module.appendZigProcessFlags(&zig_args, step);
1200
1201 // --dep arguments
1202 try zig_args.ensureUnusedCapacity(module.import_table.count() * 2);
1203 for (module.import_table.keys(), module.import_table.values()) |name, dep| {
1204 const dep_index = cli_named_modules.modules.getIndex(dep).?;
1205 const dep_cli_name = cli_named_modules.names.keys()[dep_index];
1206 zig_args.appendAssumeCapacity("--dep");
1207 if (std.mem.eql(u8, dep_cli_name, name)) {
1208 zig_args.appendAssumeCapacity(dep_cli_name);
1209 } else {
1210 zig_args.appendAssumeCapacity(b.fmt("{s}={s}", .{ name, dep_cli_name }));
16251211 }
16261212 }
1627 },
16281213
1629 .win32_resource_file => |rc_source_file| {
1630 if (rc_source_file.flags.len == 0) {
1631 if (prev_has_rcflags) {
1632 try zig_args.append("-rcflags");
1633 try zig_args.append("--");
1634 prev_has_rcflags = false;
1635 }
1636 } else {
1637 try zig_args.append("-rcflags");
1638 for (rc_source_file.flags) |arg| {
1639 try zig_args.append(arg);
1640 }
1641 try zig_args.append("--");
1642 prev_has_rcflags = true;
1214 // The CLI assumes if it sees a --mod argument that it is a zig
1215 // compilation unit. If there is no root source file, then this
1216 // is not a zig compilation unit - it is perhaps a set of
1217 // linker objects, or C source files instead.
1218 // In such case, there will be only one module, so we can leave
1219 // off the naming here.
1220 if (module.root_source_file) |lp| {
1221 const src = lp.getPath2(b, step);
1222 try zig_args.appendSlice(&.{ "--mod", module_cli_name, src });
16431223 }
1644 try zig_args.append(rc_source_file.file.getPath(b));
1645 },
1224 }
16461225 }
1647 }
16481226
1649 if (self.win32_manifest) |manifest_file| {
1650 try zig_args.append(manifest_file.getPath(b));
1651 }
1227 if (total_linker_objects == 0) {
1228 return step.fail("the linker needs one or more objects to link", .{});
1229 }
16521230
1653 if (transitive_deps.is_linking_libcpp) {
1654 try zig_args.append("-lc++");
1231 for (frameworks.keys(), frameworks.values()) |name, info| {
1232 if (info.needed) {
1233 try zig_args.append("-needed_framework");
1234 } else if (info.weak) {
1235 try zig_args.append("-weak_framework");
1236 } else {
1237 try zig_args.append("-framework");
1238 }
1239 try zig_args.append(name);
1240 }
1241
1242 if (self.is_linking_libcpp) {
1243 try zig_args.append("-lc++");
1244 }
1245
1246 if (self.is_linking_libc) {
1247 try zig_args.append("-lc");
1248 }
16551249 }
16561250
1657 if (transitive_deps.is_linking_libc) {
1658 try zig_args.append("-lc");
1251 if (self.win32_manifest) |manifest_file| {
1252 try zig_args.append(manifest_file.getPath(b));
16591253 }
16601254
16611255 if (self.image_base) |image_base| {
......@@ -1702,17 +1296,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
17021296 if (self.generated_llvm_ir != null) try zig_args.append("-femit-llvm-ir");
17031297 if (self.generated_h != null) try zig_args.append("-femit-h");
17041298
1705 try addFlag(&zig_args, "strip", self.strip);
1706 try addFlag(&zig_args, "formatted-panics", self.formatted_panics);
1707 try addFlag(&zig_args, "unwind-tables", self.unwind_tables);
1708
1709 if (self.dwarf_format) |dwarf_format| {
1710 try zig_args.append(switch (dwarf_format) {
1711 .@"32" => "-gdwarf32",
1712 .@"64" => "-gdwarf64",
1713 });
1714 }
1715
17161299 switch (self.compress_debug_sections) {
17171300 .none => {},
17181301 .zlib => try zig_args.append("--compress-debug-sections=zlib"),
......@@ -1769,11 +1352,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
17691352 try zig_args.append(libc_file);
17701353 }
17711354
1772 switch (self.optimize) {
1773 .Debug => {}, // Skip since it's the default.
1774 else => try zig_args.append(b.fmt("-O{s}", .{@tagName(self.optimize)})),
1775 }
1776
17771355 try zig_args.append("--cache-dir");
17781356 try zig_args.append(b.cache_root.path orelse ".");
17791357
......@@ -1793,11 +1371,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
17931371 try zig_args.append(b.fmt("{}", .{version}));
17941372 }
17951373
1796 if (self.target.isDarwin()) {
1374 if (self.rootModuleTarget().isDarwin()) {
17971375 const install_name = self.install_name orelse b.fmt("@rpath/{s}{s}{s}", .{
1798 self.target.libPrefix(),
1376 self.rootModuleTarget().libPrefix(),
17991377 self.name,
1800 self.target.dynamicLibSuffix(),
1378 self.rootModuleTarget().dynamicLibSuffix(),
18011379 });
18021380 try zig_args.append("-install_name");
18031381 try zig_args.append(install_name);
......@@ -1808,11 +1386,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
18081386 try zig_args.appendSlice(&[_][]const u8{ "--entitlements", entitlements });
18091387 }
18101388 if (self.pagezero_size) |pagezero_size| {
1811 const size = try std.fmt.allocPrint(b.allocator, "{x}", .{pagezero_size});
1389 const size = try std.fmt.allocPrint(arena, "{x}", .{pagezero_size});
18121390 try zig_args.appendSlice(&[_][]const u8{ "-pagezero_size", size });
18131391 }
18141392 if (self.headerpad_size) |headerpad_size| {
1815 const size = try std.fmt.allocPrint(b.allocator, "{x}", .{headerpad_size});
1393 const size = try std.fmt.allocPrint(arena, "{x}", .{headerpad_size});
18161394 try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size });
18171395 }
18181396 if (self.headerpad_max_install_names) {
......@@ -1823,27 +1401,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
18231401 }
18241402
18251403 try addFlag(&zig_args, "compiler-rt", self.bundle_compiler_rt);
1826 try addFlag(&zig_args, "single-threaded", self.single_threaded);
1827 if (self.disable_stack_probing) {
1828 try zig_args.append("-fno-stack-check");
1829 }
1830 try addFlag(&zig_args, "stack-protector", self.stack_protector);
1831 if (self.red_zone) |red_zone| {
1832 if (red_zone) {
1833 try zig_args.append("-mred-zone");
1834 } else {
1835 try zig_args.append("-mno-red-zone");
1836 }
1837 }
1838 try addFlag(&zig_args, "omit-frame-pointer", self.omit_frame_pointer);
18391404 try addFlag(&zig_args, "dll-export-fns", self.dll_export_fns);
1840
1841 if (self.disable_sanitize_c) {
1842 try zig_args.append("-fno-sanitize-c");
1843 }
1844 if (self.sanitize_thread) {
1845 try zig_args.append("-fsanitize-thread");
1846 }
18471405 if (self.rdynamic) {
18481406 try zig_args.append("-rdynamic");
18491407 }
......@@ -1875,29 +1433,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
18751433 try zig_args.append(b.fmt("--global-base={d}", .{global_base}));
18761434 }
18771435
1878 if (self.code_model != .default) {
1879 try zig_args.append("-mcmodel");
1880 try zig_args.append(@tagName(self.code_model));
1881 }
18821436 if (self.wasi_exec_model) |model| {
18831437 try zig_args.append(b.fmt("-mexec-model={s}", .{@tagName(model)}));
18841438 }
1885 for (self.export_symbol_names) |symbol_name| {
1886 try zig_args.append(b.fmt("--export={s}", .{symbol_name}));
1887 }
1888
1889 if (!self.target.isNative()) {
1890 try zig_args.appendSlice(&.{
1891 "-target", try self.target.zigTriple(b.allocator),
1892 "-mcpu", try std.Build.serializeCpu(b.allocator, self.target.getCpu()),
1893 });
1894
1895 if (self.target.dynamic_linker.get()) |dynamic_linker| {
1896 try zig_args.append("--dynamic-linker");
1897 try zig_args.append(dynamic_linker);
1898 }
1899 }
1900
19011439 if (self.linker_script) |linker_script| {
19021440 try zig_args.append("--script");
19031441 try zig_args.append(linker_script.getPath(b));
......@@ -1921,103 +1459,11 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
19211459 }
19221460 }
19231461
1924 try self.appendModuleArgs(&zig_args);
1925
1926 for (self.include_dirs.items) |include_dir| {
1927 switch (include_dir) {
1928 .path => |include_path| {
1929 try zig_args.append("-I");
1930 try zig_args.append(include_path.getPath(b));
1931 },
1932 .path_system => |include_path| {
1933 try zig_args.append("-isystem");
1934 try zig_args.append(include_path.getPath(b));
1935 },
1936 .path_after => |include_path| {
1937 try zig_args.append("-idirafter");
1938 try zig_args.append(include_path.getPath(b));
1939 },
1940 .framework_path => |include_path| {
1941 try zig_args.append("-F");
1942 try zig_args.append(include_path.getPath2(b, step));
1943 },
1944 .framework_path_system => |include_path| {
1945 try zig_args.append("-iframework");
1946 try zig_args.append(include_path.getPath2(b, step));
1947 },
1948 .other_step => |other| {
1949 if (other.generated_h) |header| {
1950 try zig_args.append("-isystem");
1951 try zig_args.append(fs.path.dirname(header.path.?).?);
1952 }
1953 if (other.installed_headers.items.len > 0) {
1954 try zig_args.append("-I");
1955 try zig_args.append(b.pathJoin(&.{
1956 other.step.owner.install_prefix, "include",
1957 }));
1958 }
1959 },
1960 .config_header_step => |config_header| {
1961 const full_file_path = config_header.output_file.path.?;
1962 const header_dir_path = full_file_path[0 .. full_file_path.len - config_header.include_path.len];
1963 try zig_args.appendSlice(&.{ "-I", header_dir_path });
1964 },
1965 }
1966 }
1967
1968 for (self.c_macros.items) |c_macro| {
1969 try zig_args.append("-D");
1970 try zig_args.append(c_macro);
1971 }
1972
1973 try zig_args.ensureUnusedCapacity(2 * self.lib_paths.items.len);
1974 for (self.lib_paths.items) |lib_path| {
1975 zig_args.appendAssumeCapacity("-L");
1976 zig_args.appendAssumeCapacity(lib_path.getPath2(b, step));
1977 }
1978
1979 try zig_args.ensureUnusedCapacity(2 * self.rpaths.items.len);
1980 for (self.rpaths.items) |rpath| {
1981 zig_args.appendAssumeCapacity("-rpath");
1982
1983 if (self.target_info.target.isDarwin()) switch (rpath) {
1984 .path, .cwd_relative => |path| {
1985 // On Darwin, we should not try to expand special runtime paths such as
1986 // * @executable_path
1987 // * @loader_path
1988 if (mem.startsWith(u8, path, "@executable_path") or
1989 mem.startsWith(u8, path, "@loader_path"))
1990 {
1991 zig_args.appendAssumeCapacity(path);
1992 continue;
1993 }
1994 },
1995 .generated, .dependency => {},
1996 };
1997
1998 zig_args.appendAssumeCapacity(rpath.getPath2(b, step));
1999 }
2000
2001 {
2002 var it = self.frameworks.iterator();
2003 while (it.next()) |entry| {
2004 const name = entry.key_ptr.*;
2005 const info = entry.value_ptr.*;
2006 if (info.needed) {
2007 try zig_args.append("-needed_framework");
2008 } else if (info.weak) {
2009 try zig_args.append("-weak_framework");
2010 } else {
2011 try zig_args.append("-framework");
2012 }
2013 try zig_args.append(name);
2014 }
2015 }
2016
20171462 if (b.sysroot) |sysroot| {
20181463 try zig_args.appendSlice(&[_][]const u8{ "--sysroot", sysroot });
20191464 }
20201465
1466 // -I and -L arguments that appear after the last --mod argument apply to all modules.
20211467 for (b.search_prefixes.items) |search_prefix| {
20221468 var prefix_dir = fs.cwd().openDir(search_prefix, .{}) catch |err| {
20231469 return step.fail("unable to open prefix directory '{s}': {s}", .{
......@@ -2032,7 +1478,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
20321478
20331479 if (prefix_dir.accessZ("lib", .{})) |_| {
20341480 try zig_args.appendSlice(&.{
2035 "-L", try fs.path.join(b.allocator, &.{ search_prefix, "lib" }),
1481 "-L", try fs.path.join(arena, &.{ search_prefix, "lib" }),
20361482 });
20371483 } else |err| switch (err) {
20381484 error.FileNotFound => {},
......@@ -2043,7 +1489,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
20431489
20441490 if (prefix_dir.accessZ("include", .{})) |_| {
20451491 try zig_args.appendSlice(&.{
2046 "-I", try fs.path.join(b.allocator, &.{ search_prefix, "include" }),
1492 "-I", try fs.path.join(arena, &.{ search_prefix, "include" }),
20471493 });
20481494 } else |err| switch (err) {
20491495 error.FileNotFound => {},
......@@ -2058,7 +1504,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
20581504 try zig_args.append(@tagName(self.rc_includes));
20591505 }
20601506
2061 try addFlag(&zig_args, "valgrind", self.valgrind_support);
20621507 try addFlag(&zig_args, "each-lib-rpath", self.each_lib_rpath);
20631508
20641509 if (self.build_id) |build_id| {
......@@ -2075,12 +1520,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
20751520 try zig_args.append(dir.getPath(b));
20761521 }
20771522
2078 if (self.main_mod_path) |dir| {
2079 try zig_args.append("--main-mod-path");
2080 try zig_args.append(dir.getPath(b));
2081 }
2082
2083 try addFlag(&zig_args, "PIC", self.force_pic);
20841523 try addFlag(&zig_args, "PIE", self.pie);
20851524 try addFlag(&zig_args, "lto", self.want_lto);
20861525
......@@ -2117,12 +1556,12 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
21171556 try b.cache_root.handle.makePath("args");
21181557
21191558 const args_to_escape = zig_args.items[2..];
2120 var escaped_args = try ArrayList([]const u8).initCapacity(b.allocator, args_to_escape.len);
1559 var escaped_args = try ArrayList([]const u8).initCapacity(arena, args_to_escape.len);
21211560 arg_blk: for (args_to_escape) |arg| {
21221561 for (arg, 0..) |c, arg_idx| {
21231562 if (c == '\\' or c == '"') {
21241563 // Slow path for arguments that need to be escaped. We'll need to allocate and copy
2125 var escaped = try ArrayList(u8).initCapacity(b.allocator, arg.len + 1);
1564 var escaped = try ArrayList(u8).initCapacity(arena, arg.len + 1);
21261565 const writer = escaped.writer();
21271566 try writer.writeAll(arg[0..arg_idx]);
21281567 for (arg[arg_idx..]) |to_escape| {
......@@ -2138,8 +1577,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
21381577
21391578 // Write the args to zig-cache/args/<SHA256 hash of args> to avoid conflicts with
21401579 // other zig build commands running in parallel.
2141 const partially_quoted = try std.mem.join(b.allocator, "\" \"", escaped_args.items);
2142 const args = try std.mem.concat(b.allocator, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
1580 const partially_quoted = try std.mem.join(arena, "\" \"", escaped_args.items);
1581 const args = try std.mem.concat(arena, u8, &[_][]const u8{ "\"", partially_quoted, "\"" });
21431582
21441583 var args_hash: [Sha256.digest_length]u8 = undefined;
21451584 Sha256.hash(args, &args_hash, .{});
......@@ -2153,9 +1592,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
21531592 const args_file = "args" ++ fs.path.sep_str ++ args_hex_hash;
21541593 try b.cache_root.handle.writeFile(args_file, args);
21551594
2156 const resolved_args_file = try mem.concat(b.allocator, u8, &.{
1595 const resolved_args_file = try mem.concat(arena, u8, &.{
21571596 "@",
2158 try b.cache_root.join(b.allocator, &.{args_file}),
1597 try b.cache_root.join(arena, &.{args_file}),
21591598 });
21601599
21611600 zig_args.shrinkRetainingCapacity(2);
......@@ -2223,7 +1662,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
22231662 }
22241663
22251664 if (self.kind == .lib and self.linkage != null and self.linkage.? == .dynamic and
2226 self.version != null and self.target.wantSharedLibSymLinks())
1665 self.version != null and std.Build.wantSharedLibSymLinks(self.rootModuleTarget()))
22271666 {
22281667 try doAtomicSymLinks(
22291668 step,
......@@ -2234,43 +1673,6 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
22341673 }
22351674}
22361675
2237fn isLibCLibrary(name: []const u8) bool {
2238 const libc_libraries = [_][]const u8{ "c", "m", "dl", "rt", "pthread" };
2239 for (libc_libraries) |libc_lib_name| {
2240 if (mem.eql(u8, name, libc_lib_name))
2241 return true;
2242 }
2243 return false;
2244}
2245
2246fn isLibCppLibrary(name: []const u8) bool {
2247 const libcpp_libraries = [_][]const u8{ "c++", "stdc++" };
2248 for (libcpp_libraries) |libcpp_lib_name| {
2249 if (mem.eql(u8, name, libcpp_lib_name))
2250 return true;
2251 }
2252 return false;
2253}
2254
2255/// Returned slice must be freed by the caller.
2256fn findVcpkgRoot(allocator: Allocator) !?[]const u8 {
2257 const appdata_path = try fs.getAppDataDir(allocator, "vcpkg");
2258 defer allocator.free(appdata_path);
2259
2260 const path_file = try fs.path.join(allocator, &[_][]const u8{ appdata_path, "vcpkg.path.txt" });
2261 defer allocator.free(path_file);
2262
2263 const file = fs.cwd().openFile(path_file, .{}) catch return null;
2264 defer file.close();
2265
2266 const size = @as(usize, @intCast(try file.getEndPos()));
2267 const vcpkg_path = try allocator.alloc(u8, size);
2268 const size_read = try file.read(vcpkg_path);
2269 std.debug.assert(size == size_read);
2270
2271 return vcpkg_path;
2272}
2273
22741676pub fn doAtomicSymLinks(
22751677 step: *Step,
22761678 output_path: []const u8,
......@@ -2345,67 +1747,6 @@ fn addFlag(args: *ArrayList([]const u8), comptime name: []const u8, opt: ?bool)
23451747 }
23461748}
23471749
2348const TransitiveDeps = struct {
2349 link_objects: ArrayList(LinkObject),
2350 seen_system_libs: StringHashMap(void),
2351 seen_steps: std.AutoHashMap(*const Step, void),
2352 is_linking_libcpp: bool,
2353 is_linking_libc: bool,
2354 frameworks: *StringHashMap(FrameworkLinkInfo),
2355
2356 fn add(td: *TransitiveDeps, link_objects: []const LinkObject) !void {
2357 try td.link_objects.ensureUnusedCapacity(link_objects.len);
2358
2359 for (link_objects) |link_object| {
2360 try td.link_objects.append(link_object);
2361 switch (link_object) {
2362 .other_step => |other| try addInner(td, other, other.isDynamicLibrary()),
2363 else => {},
2364 }
2365 }
2366 }
2367
2368 fn addInner(td: *TransitiveDeps, other: *Compile, dyn: bool) !void {
2369 // Inherit dependency on libc and libc++
2370 td.is_linking_libcpp = td.is_linking_libcpp or other.is_linking_libcpp;
2371 td.is_linking_libc = td.is_linking_libc or other.is_linking_libc;
2372
2373 // Inherit dependencies on darwin frameworks
2374 if (!dyn) {
2375 var it = other.frameworks.iterator();
2376 while (it.next()) |framework| {
2377 try td.frameworks.put(framework.key_ptr.*, framework.value_ptr.*);
2378 }
2379 }
2380
2381 // Inherit dependencies on system libraries and static libraries.
2382 for (other.link_objects.items) |other_link_object| {
2383 switch (other_link_object) {
2384 .system_lib => |system_lib| {
2385 if ((try td.seen_system_libs.fetchPut(system_lib.name, {})) != null)
2386 continue;
2387
2388 if (dyn)
2389 continue;
2390
2391 try td.link_objects.append(other_link_object);
2392 },
2393 .other_step => |inner_other| {
2394 if ((try td.seen_steps.fetchPut(&inner_other.step, {})) != null)
2395 continue;
2396
2397 const included_in_lib = (other.kind == .lib and inner_other.kind == .obj);
2398 if (!dyn and !included_in_lib)
2399 try td.link_objects.append(other_link_object);
2400
2401 try addInner(td, inner_other, dyn or inner_other.isDynamicLibrary());
2402 },
2403 else => continue,
2404 }
2405 }
2406 }
2407};
2408
24091750fn checkCompileErrors(self: *Compile) !void {
24101751 // Clear this field so that it does not get printed by the build runner.
24111752 const actual_eb = self.step.result_error_bundle;
......@@ -2490,3 +1831,8 @@ fn matchCompileError(actual: []const u8, expected: []const u8) bool {
24901831 }
24911832 return false;
24921833}
1834
1835pub fn rootModuleTarget(c: *Compile) std.Target {
1836 // The root module is always given a target, so we know this to be non-null.
1837 return c.root_module.resolved_target.?.result;
1838}
lib/std/Build/Step/ConfigHeader.zig-6
......@@ -15,9 +15,6 @@ pub const Style = union(enum) {
1515 /// Start with nothing, like blank, and output a nasm .asm file.
1616 nasm,
1717
18 /// deprecated: use `getPath`
19 pub const getFileSource = getPath;
20
2118 pub fn getPath(style: Style) ?std.Build.LazyPath {
2219 switch (style) {
2320 .autoconf, .cmake => |s| return s,
......@@ -107,9 +104,6 @@ pub fn addValues(self: *ConfigHeader, values: anytype) void {
107104 return addValuesInner(self, values) catch @panic("OOM");
108105}
109106
110/// deprecated: use `getOutput`
111pub const getFileSource = getOutput;
112
113107pub fn getOutput(self: *ConfigHeader) std.Build.LazyPath {
114108 return .{ .generated = &self.output_file };
115109}
lib/std/Build/Step/InstallArtifact.zig+1-1
......@@ -94,7 +94,7 @@ pub fn create(owner: *std.Build, artifact: *Step.Compile, options: Options) *Ins
9494 .dylib_symlinks = if (options.dylib_symlinks orelse (dest_dir != null and
9595 artifact.isDynamicLibrary() and
9696 artifact.version != null and
97 artifact.target.wantSharedLibSymLinks())) .{
97 std.Build.wantSharedLibSymLinks(artifact.rootModuleTarget()))) .{
9898 .major_only_filename = artifact.major_only_filename.?,
9999 .name_only_filename = artifact.name_only_filename.?,
100100 } else null,
lib/std/Build/Step/Options.zig+5-6
......@@ -165,9 +165,6 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void {
165165 }
166166}
167167
168/// deprecated: use `addOptionPath`
169pub const addOptionFileSource = addOptionPath;
170
171168/// The value is the path in the cache dir.
172169/// Adds a dependency automatically.
173170pub fn addOptionPath(
......@@ -189,8 +186,7 @@ pub fn addOptionArtifact(self: *Options, name: []const u8, artifact: *Step.Compi
189186
190187pub fn createModule(self: *Options) *std.Build.Module {
191188 return self.step.owner.createModule(.{
192 .source_file = self.getOutput(),
193 .dependencies = &.{},
189 .root_source_file = self.getOutput(),
194190 });
195191}
196192
......@@ -298,7 +294,10 @@ test Options {
298294 var arena = std.heap.ArenaAllocator.init(std.testing.allocator);
299295 defer arena.deinit();
300296
301 const host = try std.zig.system.NativeTargetInfo.detect(.{});
297 const host: std.Build.ResolvedTarget = .{
298 .query = .{},
299 .result = try std.zig.system.resolveTargetQuery(.{}),
300 };
302301
303302 var cache: std.Build.Cache = .{
304303 .gpa = arena.allocator(),
lib/std/Build/Step/Run.zig+23-27
......@@ -197,16 +197,10 @@ pub fn addPrefixedOutputFileArg(
197197 return .{ .generated = &output.generated_file };
198198}
199199
200/// deprecated: use `addFileArg`
201pub const addFileSourceArg = addFileArg;
202
203200pub fn addFileArg(self: *Run, lp: std.Build.LazyPath) void {
204201 self.addPrefixedFileArg("", lp);
205202}
206203
207// deprecated: use `addPrefixedFileArg`
208pub const addPrefixedFileSourceArg = addPrefixedFileArg;
209
210204pub fn addPrefixedFileArg(self: *Run, prefix: []const u8, lp: std.Build.LazyPath) void {
211205 const b = self.step.owner;
212206
......@@ -488,7 +482,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
488482 man.hash.addBytes(file_path);
489483 },
490484 .artifact => |artifact| {
491 if (artifact.target.isWindows()) {
485 if (artifact.rootModuleTarget().os.tag == .windows) {
492486 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
493487 self.addPathForDynLibs(artifact);
494488 }
......@@ -682,8 +676,10 @@ fn runCommand(
682676 else => break :interpret,
683677 }
684678
685 const need_cross_glibc = exe.target.isGnuLibC() and exe.is_linking_libc;
686 switch (b.host.getExternalExecutor(&exe.target_info, .{
679 const need_cross_glibc = exe.rootModuleTarget().isGnuLibC() and
680 exe.is_linking_libc;
681 const other_target = exe.root_module.resolved_target.?.result;
682 switch (std.zig.system.getExternalExecutor(b.host.result, &other_target, .{
687683 .qemu_fixes_dl = need_cross_glibc and b.glibc_runtimes_dir != null,
688684 .link_libc = exe.is_linking_libc,
689685 })) {
......@@ -714,9 +710,9 @@ fn runCommand(
714710 // needs the directory to be called "i686" rather than
715711 // "x86" which is why we do it manually here.
716712 const fmt_str = "{s}" ++ fs.path.sep_str ++ "{s}-{s}-{s}";
717 const cpu_arch = exe.target.getCpuArch();
718 const os_tag = exe.target.getOsTag();
719 const abi = exe.target.getAbi();
713 const cpu_arch = exe.rootModuleTarget().cpu.arch;
714 const os_tag = exe.rootModuleTarget().os.tag;
715 const abi = exe.rootModuleTarget().abi;
720716 const cpu_arch_name: []const u8 = if (cpu_arch == .x86)
721717 "i686"
722718 else
......@@ -756,7 +752,7 @@ fn runCommand(
756752 .bad_dl => |foreign_dl| {
757753 if (allow_skip) return error.MakeSkipped;
758754
759 const host_dl = b.host.dynamic_linker.get() orelse "(none)";
755 const host_dl = b.host.result.dynamic_linker.get() orelse "(none)";
760756
761757 return step.fail(
762758 \\the host system is unable to execute binaries from the target
......@@ -768,8 +764,8 @@ fn runCommand(
768764 .bad_os_or_cpu => {
769765 if (allow_skip) return error.MakeSkipped;
770766
771 const host_name = try b.host.target.zigTriple(b.allocator);
772 const foreign_name = try exe.target.zigTriple(b.allocator);
767 const host_name = try b.host.result.zigTriple(b.allocator);
768 const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
773769
774770 return step.fail("the host system ({s}) is unable to execute binaries from the target ({s})", .{
775771 host_name, foreign_name,
......@@ -777,7 +773,7 @@ fn runCommand(
777773 },
778774 }
779775
780 if (exe.target.isWindows()) {
776 if (exe.rootModuleTarget().os.tag == .windows) {
781777 // On Windows we don't have rpaths so we have to add .dll search paths to PATH
782778 self.addPathForDynLibs(exe);
783779 }
......@@ -1295,15 +1291,15 @@ fn evalGeneric(self: *Run, child: *std.process.Child) !StdIoResult {
12951291
12961292fn addPathForDynLibs(self: *Run, artifact: *Step.Compile) void {
12971293 const b = self.step.owner;
1298 for (artifact.link_objects.items) |link_object| {
1299 switch (link_object) {
1300 .other_step => |other| {
1301 if (other.target.isWindows() and other.isDynamicLibrary()) {
1302 addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?);
1303 addPathForDynLibs(self, other);
1304 }
1305 },
1306 else => {},
1294 var it = artifact.root_module.iterateDependencies(artifact, true);
1295 while (it.next()) |item| {
1296 const other = item.compile.?;
1297 if (item.module == &other.root_module) {
1298 if (item.module.resolved_target.?.result.os.tag == .windows and
1299 other.isDynamicLibrary())
1300 {
1301 addPathDir(self, fs.path.dirname(other.getEmittedBin().getPath(b)).?);
1302 }
13071303 }
13081304 }
13091305}
......@@ -1320,8 +1316,8 @@ fn failForeign(
13201316 return error.MakeSkipped;
13211317
13221318 const b = self.step.owner;
1323 const host_name = try b.host.target.zigTriple(b.allocator);
1324 const foreign_name = try exe.target.zigTriple(b.allocator);
1319 const host_name = try b.host.result.zigTriple(b.allocator);
1320 const foreign_name = try exe.rootModuleTarget().zigTriple(b.allocator);
13251321
13261322 return self.step.fail(
13271323 \\unable to spawn foreign binary '{s}' ({s}) on host system ({s})
lib/std/Build/Step/TranslateC.zig+5-6
......@@ -2,7 +2,6 @@ const std = @import("std");
22const Step = std.Build.Step;
33const fs = std.fs;
44const mem = std.mem;
5const CrossTarget = std.zig.CrossTarget;
65
76const TranslateC = @This();
87
......@@ -13,7 +12,7 @@ source: std.Build.LazyPath,
1312include_dirs: std.ArrayList([]const u8),
1413c_macros: std.ArrayList([]const u8),
1514out_basename: []const u8,
16target: CrossTarget,
15target: std.Build.ResolvedTarget,
1716optimize: std.builtin.OptimizeMode,
1817output_file: std.Build.GeneratedFile,
1918link_libc: bool,
......@@ -21,7 +20,7 @@ use_clang: bool,
2120
2221pub const Options = struct {
2322 source_file: std.Build.LazyPath,
24 target: CrossTarget,
23 target: std.Build.ResolvedTarget,
2524 optimize: std.builtin.OptimizeMode,
2625 link_libc: bool = true,
2726 use_clang: bool = true,
......@@ -54,7 +53,7 @@ pub fn create(owner: *std.Build, options: Options) *TranslateC {
5453pub const AddExecutableOptions = struct {
5554 name: ?[]const u8 = null,
5655 version: ?std.SemanticVersion = null,
57 target: ?CrossTarget = null,
56 target: ?std.Build.ResolvedTarget = null,
5857 optimize: ?std.builtin.OptimizeMode = null,
5958 linkage: ?Step.Compile.Linkage = null,
6059};
......@@ -139,9 +138,9 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
139138
140139 try argv_list.append("--listen=-");
141140
142 if (!self.target.isNative()) {
141 if (!self.target.query.isNative()) {
143142 try argv_list.append("-target");
144 try argv_list.append(try self.target.zigTriple(b.allocator));
143 try argv_list.append(try self.target.query.zigTriple(b.allocator));
145144 }
146145
147146 switch (self.optimize) {
lib/std/Build/Step/WriteFile.zig-7
......@@ -28,9 +28,6 @@ pub const File = struct {
2828 sub_path: []const u8,
2929 contents: Contents,
3030
31 /// deprecated: use `getPath`
32 pub const getFileSource = getPath;
33
3431 pub fn getPath(self: *File) std.Build.LazyPath {
3532 return .{ .generated = &self.generated_file };
3633 }
......@@ -126,10 +123,6 @@ pub fn addBytesToSource(wf: *WriteFile, bytes: []const u8, sub_path: []const u8)
126123 }) catch @panic("OOM");
127124}
128125
129pub const getFileSource = @compileError("Deprecated; use the return value from add()/addCopyFile(), or use files[i].getPath()");
130
131pub const getDirectorySource = getDirectory;
132
133126/// Returns a `LazyPath` representing the base directory that contains all the
134127/// files from this `WriteFile`.
135128pub fn getDirectory(wf: *WriteFile) std.Build.LazyPath {
lib/std/Target.zig created+2727
......@@ -0,0 +1,2727 @@
1//! All the details about the machine that will be executing code.
2//! Unlike `Query` which might leave some things as "default" or "host", this
3//! data is fully resolved into a concrete set of OS versions, CPU features,
4//! etc.
5
6cpu: Cpu,
7os: Os,
8abi: Abi,
9ofmt: ObjectFormat,
10dynamic_linker: DynamicLinker = DynamicLinker.none,
11
12pub const Query = @import("Target/Query.zig");
13
14pub const Os = struct {
15 tag: Tag,
16 version_range: VersionRange,
17
18 pub const Tag = enum {
19 freestanding,
20 ananas,
21 cloudabi,
22 dragonfly,
23 freebsd,
24 fuchsia,
25 ios,
26 kfreebsd,
27 linux,
28 lv2,
29 macos,
30 netbsd,
31 openbsd,
32 solaris,
33 uefi,
34 windows,
35 zos,
36 haiku,
37 minix,
38 rtems,
39 nacl,
40 aix,
41 cuda,
42 nvcl,
43 amdhsa,
44 ps4,
45 ps5,
46 elfiamcu,
47 tvos,
48 watchos,
49 driverkit,
50 mesa3d,
51 contiki,
52 amdpal,
53 hermit,
54 hurd,
55 wasi,
56 emscripten,
57 shadermodel,
58 liteos,
59 opencl,
60 glsl450,
61 vulkan,
62 plan9,
63 illumos,
64 other,
65
66 pub inline fn isDarwin(tag: Tag) bool {
67 return switch (tag) {
68 .ios, .macos, .watchos, .tvos => true,
69 else => false,
70 };
71 }
72
73 pub inline fn isBSD(tag: Tag) bool {
74 return tag.isDarwin() or switch (tag) {
75 .kfreebsd, .freebsd, .openbsd, .netbsd, .dragonfly => true,
76 else => false,
77 };
78 }
79
80 pub inline fn isSolarish(tag: Tag) bool {
81 return tag == .solaris or tag == .illumos;
82 }
83
84 pub fn dynamicLibSuffix(tag: Tag) [:0]const u8 {
85 if (tag.isDarwin()) {
86 return ".dylib";
87 }
88 switch (tag) {
89 .windows => return ".dll",
90 else => return ".so",
91 }
92 }
93
94 pub fn defaultVersionRange(tag: Tag, arch: Cpu.Arch) Os {
95 return .{
96 .tag = tag,
97 .version_range = VersionRange.default(tag, arch),
98 };
99 }
100 };
101
102 /// Based on NTDDI version constants from
103 /// https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
104 pub const WindowsVersion = enum(u32) {
105 nt4 = 0x04000000,
106 win2k = 0x05000000,
107 xp = 0x05010000,
108 ws2003 = 0x05020000,
109 vista = 0x06000000,
110 win7 = 0x06010000,
111 win8 = 0x06020000,
112 win8_1 = 0x06030000,
113 win10 = 0x0A000000, //aka win10_th1
114 win10_th2 = 0x0A000001,
115 win10_rs1 = 0x0A000002,
116 win10_rs2 = 0x0A000003,
117 win10_rs3 = 0x0A000004,
118 win10_rs4 = 0x0A000005,
119 win10_rs5 = 0x0A000006,
120 win10_19h1 = 0x0A000007,
121 win10_vb = 0x0A000008, //aka win10_19h2
122 win10_mn = 0x0A000009, //aka win10_20h1
123 win10_fe = 0x0A00000A, //aka win10_20h2
124 _,
125
126 /// Latest Windows version that the Zig Standard Library is aware of
127 pub const latest = WindowsVersion.win10_fe;
128
129 /// Compared against build numbers reported by the runtime to distinguish win10 versions,
130 /// where 0x0A000000 + index corresponds to the WindowsVersion u32 value.
131 pub const known_win10_build_numbers = [_]u32{
132 10240, //win10 aka win10_th1
133 10586, //win10_th2
134 14393, //win10_rs1
135 15063, //win10_rs2
136 16299, //win10_rs3
137 17134, //win10_rs4
138 17763, //win10_rs5
139 18362, //win10_19h1
140 18363, //win10_vb aka win10_19h2
141 19041, //win10_mn aka win10_20h1
142 19042, //win10_fe aka win10_20h2
143 };
144
145 /// Returns whether the first version `self` is newer (greater) than or equal to the second version `ver`.
146 pub inline fn isAtLeast(self: WindowsVersion, ver: WindowsVersion) bool {
147 return @intFromEnum(self) >= @intFromEnum(ver);
148 }
149
150 pub const Range = struct {
151 min: WindowsVersion,
152 max: WindowsVersion,
153
154 pub inline fn includesVersion(self: Range, ver: WindowsVersion) bool {
155 return @intFromEnum(ver) >= @intFromEnum(self.min) and @intFromEnum(ver) <= @intFromEnum(self.max);
156 }
157
158 /// Checks if system is guaranteed to be at least `version` or older than `version`.
159 /// Returns `null` if a runtime check is required.
160 pub inline fn isAtLeast(self: Range, ver: WindowsVersion) ?bool {
161 if (@intFromEnum(self.min) >= @intFromEnum(ver)) return true;
162 if (@intFromEnum(self.max) < @intFromEnum(ver)) return false;
163 return null;
164 }
165 };
166
167 /// This function is defined to serialize a Zig source code representation of this
168 /// type, that, when parsed, will deserialize into the same data.
169 pub fn format(
170 self: WindowsVersion,
171 comptime fmt: []const u8,
172 _: std.fmt.FormatOptions,
173 out_stream: anytype,
174 ) !void {
175 if (comptime std.mem.eql(u8, fmt, "s")) {
176 if (@intFromEnum(self) >= @intFromEnum(WindowsVersion.nt4) and @intFromEnum(self) <= @intFromEnum(WindowsVersion.latest)) {
177 try std.fmt.format(out_stream, ".{s}", .{@tagName(self)});
178 } else {
179 // TODO this code path breaks zig triples, but it is used in `builtin`
180 try std.fmt.format(out_stream, "@enumFromInt(Target.Os.WindowsVersion, 0x{X:0>8})", .{@intFromEnum(self)});
181 }
182 } else if (fmt.len == 0) {
183 if (@intFromEnum(self) >= @intFromEnum(WindowsVersion.nt4) and @intFromEnum(self) <= @intFromEnum(WindowsVersion.latest)) {
184 try std.fmt.format(out_stream, "WindowsVersion.{s}", .{@tagName(self)});
185 } else {
186 try std.fmt.format(out_stream, "WindowsVersion(0x{X:0>8})", .{@intFromEnum(self)});
187 }
188 } else {
189 std.fmt.invalidFmtError(fmt, self);
190 }
191 }
192 };
193
194 pub const LinuxVersionRange = struct {
195 range: std.SemanticVersion.Range,
196 glibc: std.SemanticVersion,
197
198 pub inline fn includesVersion(self: LinuxVersionRange, ver: std.SemanticVersion) bool {
199 return self.range.includesVersion(ver);
200 }
201
202 /// Checks if system is guaranteed to be at least `version` or older than `version`.
203 /// Returns `null` if a runtime check is required.
204 pub inline fn isAtLeast(self: LinuxVersionRange, ver: std.SemanticVersion) ?bool {
205 return self.range.isAtLeast(ver);
206 }
207 };
208
209 /// The version ranges here represent the minimum OS version to be supported
210 /// and the maximum OS version to be supported. The default values represent
211 /// the range that the Zig Standard Library bases its abstractions on.
212 ///
213 /// The minimum version of the range is the main setting to tweak for a target.
214 /// Usually, the maximum target OS version will remain the default, which is
215 /// the latest released version of the OS.
216 ///
217 /// To test at compile time if the target is guaranteed to support a given OS feature,
218 /// one should check that the minimum version of the range is greater than or equal to
219 /// the version the feature was introduced in.
220 ///
221 /// To test at compile time if the target certainly will not support a given OS feature,
222 /// one should check that the maximum version of the range is less than the version the
223 /// feature was introduced in.
224 ///
225 /// If neither of these cases apply, a runtime check should be used to determine if the
226 /// target supports a given OS feature.
227 ///
228 /// Binaries built with a given maximum version will continue to function on newer
229 /// operating system versions. However, such a binary may not take full advantage of the
230 /// newer operating system APIs.
231 ///
232 /// See `Os.isAtLeast`.
233 pub const VersionRange = union {
234 none: void,
235 semver: std.SemanticVersion.Range,
236 linux: LinuxVersionRange,
237 windows: WindowsVersion.Range,
238
239 /// The default `VersionRange` represents the range that the Zig Standard Library
240 /// bases its abstractions on.
241 pub fn default(tag: Tag, arch: Cpu.Arch) VersionRange {
242 switch (tag) {
243 .freestanding,
244 .ananas,
245 .cloudabi,
246 .fuchsia,
247 .kfreebsd,
248 .lv2,
249 .zos,
250 .haiku,
251 .minix,
252 .rtems,
253 .nacl,
254 .aix,
255 .cuda,
256 .nvcl,
257 .amdhsa,
258 .ps4,
259 .ps5,
260 .elfiamcu,
261 .mesa3d,
262 .contiki,
263 .amdpal,
264 .hermit,
265 .hurd,
266 .wasi,
267 .emscripten,
268 .driverkit,
269 .shadermodel,
270 .liteos,
271 .uefi,
272 .opencl, // TODO: OpenCL versions
273 .glsl450, // TODO: GLSL versions
274 .vulkan,
275 .plan9,
276 .illumos,
277 .other,
278 => return .{ .none = {} },
279
280 .freebsd => return .{
281 .semver = std.SemanticVersion.Range{
282 .min = .{ .major = 12, .minor = 0, .patch = 0 },
283 .max = .{ .major = 14, .minor = 0, .patch = 0 },
284 },
285 },
286 .macos => return switch (arch) {
287 .aarch64 => VersionRange{
288 .semver = .{
289 .min = .{ .major = 11, .minor = 7, .patch = 1 },
290 .max = .{ .major = 14, .minor = 1, .patch = 0 },
291 },
292 },
293 .x86_64 => VersionRange{
294 .semver = .{
295 .min = .{ .major = 11, .minor = 7, .patch = 1 },
296 .max = .{ .major = 14, .minor = 1, .patch = 0 },
297 },
298 },
299 else => unreachable,
300 },
301 .ios => return .{
302 .semver = .{
303 .min = .{ .major = 12, .minor = 0, .patch = 0 },
304 .max = .{ .major = 17, .minor = 1, .patch = 0 },
305 },
306 },
307 .watchos => return .{
308 .semver = .{
309 .min = .{ .major = 6, .minor = 0, .patch = 0 },
310 .max = .{ .major = 10, .minor = 1, .patch = 0 },
311 },
312 },
313 .tvos => return .{
314 .semver = .{
315 .min = .{ .major = 13, .minor = 0, .patch = 0 },
316 .max = .{ .major = 17, .minor = 1, .patch = 0 },
317 },
318 },
319 .netbsd => return .{
320 .semver = .{
321 .min = .{ .major = 8, .minor = 0, .patch = 0 },
322 .max = .{ .major = 10, .minor = 0, .patch = 0 },
323 },
324 },
325 .openbsd => return .{
326 .semver = .{
327 .min = .{ .major = 6, .minor = 8, .patch = 0 },
328 .max = .{ .major = 7, .minor = 4, .patch = 0 },
329 },
330 },
331 .dragonfly => return .{
332 .semver = .{
333 .min = .{ .major = 5, .minor = 8, .patch = 0 },
334 .max = .{ .major = 6, .minor = 4, .patch = 0 },
335 },
336 },
337 .solaris => return .{
338 .semver = .{
339 .min = .{ .major = 5, .minor = 11, .patch = 0 },
340 .max = .{ .major = 5, .minor = 11, .patch = 0 },
341 },
342 },
343
344 .linux => return .{
345 .linux = .{
346 .range = .{
347 .min = .{ .major = 4, .minor = 19, .patch = 0 },
348 .max = .{ .major = 6, .minor = 5, .patch = 7 },
349 },
350 .glibc = .{ .major = 2, .minor = 28, .patch = 0 },
351 },
352 },
353
354 .windows => return .{
355 .windows = .{
356 .min = .win8_1,
357 .max = WindowsVersion.latest,
358 },
359 },
360 }
361 }
362 };
363
364 pub const TaggedVersionRange = union(enum) {
365 none: void,
366 semver: std.SemanticVersion.Range,
367 linux: LinuxVersionRange,
368 windows: WindowsVersion.Range,
369 };
370
371 /// Provides a tagged union. `Target` does not store the tag because it is
372 /// redundant with the OS tag; this function abstracts that part away.
373 pub inline fn getVersionRange(self: Os) TaggedVersionRange {
374 switch (self.tag) {
375 .linux => return TaggedVersionRange{ .linux = self.version_range.linux },
376 .windows => return TaggedVersionRange{ .windows = self.version_range.windows },
377
378 .freebsd,
379 .macos,
380 .ios,
381 .tvos,
382 .watchos,
383 .netbsd,
384 .openbsd,
385 .dragonfly,
386 .solaris,
387 => return TaggedVersionRange{ .semver = self.version_range.semver },
388
389 else => return .none,
390 }
391 }
392
393 /// Checks if system is guaranteed to be at least `version` or older than `version`.
394 /// Returns `null` if a runtime check is required.
395 pub inline fn isAtLeast(self: Os, comptime tag: Tag, version: anytype) ?bool {
396 if (self.tag != tag) return false;
397
398 return switch (tag) {
399 .linux => self.version_range.linux.isAtLeast(version),
400 .windows => self.version_range.windows.isAtLeast(version),
401 else => self.version_range.semver.isAtLeast(version),
402 };
403 }
404
405 /// On Darwin, we always link libSystem which contains libc.
406 /// Similarly on FreeBSD and NetBSD we always link system libc
407 /// since this is the stable syscall interface.
408 pub fn requiresLibC(os: Os) bool {
409 return switch (os.tag) {
410 .freebsd,
411 .netbsd,
412 .macos,
413 .ios,
414 .tvos,
415 .watchos,
416 .dragonfly,
417 .openbsd,
418 .haiku,
419 .solaris,
420 .illumos,
421 => true,
422
423 .linux,
424 .windows,
425 .freestanding,
426 .ananas,
427 .cloudabi,
428 .fuchsia,
429 .kfreebsd,
430 .lv2,
431 .zos,
432 .minix,
433 .rtems,
434 .nacl,
435 .aix,
436 .cuda,
437 .nvcl,
438 .amdhsa,
439 .ps4,
440 .ps5,
441 .elfiamcu,
442 .mesa3d,
443 .contiki,
444 .amdpal,
445 .hermit,
446 .hurd,
447 .wasi,
448 .emscripten,
449 .driverkit,
450 .shadermodel,
451 .liteos,
452 .uefi,
453 .opencl,
454 .glsl450,
455 .vulkan,
456 .plan9,
457 .other,
458 => false,
459 };
460 }
461};
462
463pub const aarch64 = @import("Target/aarch64.zig");
464pub const arc = @import("Target/arc.zig");
465pub const amdgpu = @import("Target/amdgpu.zig");
466pub const arm = @import("Target/arm.zig");
467pub const avr = @import("Target/avr.zig");
468pub const bpf = @import("Target/bpf.zig");
469pub const csky = @import("Target/csky.zig");
470pub const hexagon = @import("Target/hexagon.zig");
471pub const loongarch = @import("Target/loongarch.zig");
472pub const m68k = @import("Target/m68k.zig");
473pub const mips = @import("Target/mips.zig");
474pub const msp430 = @import("Target/msp430.zig");
475pub const nvptx = @import("Target/nvptx.zig");
476pub const powerpc = @import("Target/powerpc.zig");
477pub const riscv = @import("Target/riscv.zig");
478pub const sparc = @import("Target/sparc.zig");
479pub const spirv = @import("Target/spirv.zig");
480pub const s390x = @import("Target/s390x.zig");
481pub const ve = @import("Target/ve.zig");
482pub const wasm = @import("Target/wasm.zig");
483pub const x86 = @import("Target/x86.zig");
484pub const xtensa = @import("Target/xtensa.zig");
485
486pub const Abi = enum {
487 none,
488 gnu,
489 gnuabin32,
490 gnuabi64,
491 gnueabi,
492 gnueabihf,
493 gnuf32,
494 gnuf64,
495 gnusf,
496 gnux32,
497 gnuilp32,
498 code16,
499 eabi,
500 eabihf,
501 android,
502 musl,
503 musleabi,
504 musleabihf,
505 muslx32,
506 msvc,
507 itanium,
508 cygnus,
509 coreclr,
510 simulator,
511 macabi,
512 pixel,
513 vertex,
514 geometry,
515 hull,
516 domain,
517 compute,
518 library,
519 raygeneration,
520 intersection,
521 anyhit,
522 closesthit,
523 miss,
524 callable,
525 mesh,
526 amplification,
527
528 pub fn default(arch: Cpu.Arch, target_os: Os) Abi {
529 if (arch.isWasm()) {
530 return .musl;
531 }
532 switch (target_os.tag) {
533 .freestanding,
534 .ananas,
535 .cloudabi,
536 .dragonfly,
537 .lv2,
538 .zos,
539 .minix,
540 .rtems,
541 .nacl,
542 .aix,
543 .cuda,
544 .nvcl,
545 .amdhsa,
546 .ps4,
547 .ps5,
548 .elfiamcu,
549 .mesa3d,
550 .contiki,
551 .amdpal,
552 .hermit,
553 .other,
554 => return .eabi,
555 .openbsd,
556 .freebsd,
557 .fuchsia,
558 .kfreebsd,
559 .netbsd,
560 .hurd,
561 .haiku,
562 .windows,
563 => return .gnu,
564 .uefi => return .msvc,
565 .linux,
566 .wasi,
567 .emscripten,
568 => return .musl,
569 .opencl, // TODO: SPIR-V ABIs with Linkage capability
570 .glsl450,
571 .vulkan,
572 .plan9, // TODO specify abi
573 .macos,
574 .ios,
575 .tvos,
576 .watchos,
577 .driverkit,
578 .shadermodel,
579 .liteos, // TODO: audit this
580 .solaris,
581 .illumos,
582 => return .none,
583 }
584 }
585
586 pub inline fn isGnu(abi: Abi) bool {
587 return switch (abi) {
588 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
589 else => false,
590 };
591 }
592
593 pub inline fn isMusl(abi: Abi) bool {
594 return switch (abi) {
595 .musl, .musleabi, .musleabihf => true,
596 else => false,
597 };
598 }
599
600 pub inline fn floatAbi(abi: Abi) FloatAbi {
601 return switch (abi) {
602 .gnueabihf,
603 .eabihf,
604 .musleabihf,
605 => .hard,
606 else => .soft,
607 };
608 }
609};
610
611pub const ObjectFormat = enum {
612 /// Common Object File Format (Windows)
613 coff,
614 /// DirectX Container
615 dxcontainer,
616 /// Executable and Linking Format
617 elf,
618 /// macOS relocatables
619 macho,
620 /// Standard, Portable Intermediate Representation V
621 spirv,
622 /// WebAssembly
623 wasm,
624 /// C source code
625 c,
626 /// Intel IHEX
627 hex,
628 /// Machine code with no metadata.
629 raw,
630 /// Plan 9 from Bell Labs
631 plan9,
632 /// Nvidia PTX format
633 nvptx,
634
635 pub fn fileExt(of: ObjectFormat, cpu_arch: Cpu.Arch) [:0]const u8 {
636 return switch (of) {
637 .coff => ".obj",
638 .elf, .macho, .wasm => ".o",
639 .c => ".c",
640 .spirv => ".spv",
641 .hex => ".ihex",
642 .raw => ".bin",
643 .plan9 => plan9Ext(cpu_arch),
644 .nvptx => ".ptx",
645 .dxcontainer => ".dxil",
646 };
647 }
648
649 pub fn default(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat {
650 return switch (os_tag) {
651 .windows, .uefi => .coff,
652 .ios, .macos, .watchos, .tvos => .macho,
653 .plan9 => .plan9,
654 else => return switch (cpu_arch) {
655 .wasm32, .wasm64 => .wasm,
656 .spirv32, .spirv64 => .spirv,
657 .nvptx, .nvptx64 => .nvptx,
658 else => .elf,
659 },
660 };
661 }
662};
663
664pub const SubSystem = enum {
665 Console,
666 Windows,
667 Posix,
668 Native,
669 EfiApplication,
670 EfiBootServiceDriver,
671 EfiRom,
672 EfiRuntimeDriver,
673};
674
675pub const Cpu = struct {
676 /// Architecture
677 arch: Arch,
678
679 /// The CPU model to target. It has a set of features
680 /// which are overridden with the `features` field.
681 model: *const Model,
682
683 /// An explicit list of the entire CPU feature set. It may differ from the specific CPU model's features.
684 features: Feature.Set,
685
686 pub const Feature = struct {
687 /// The bit index into `Set`. Has a default value of `undefined` because the canonical
688 /// structures are populated via comptime logic.
689 index: Set.Index = undefined,
690
691 /// Has a default value of `undefined` because the canonical
692 /// structures are populated via comptime logic.
693 name: []const u8 = undefined,
694
695 /// If this corresponds to an LLVM-recognized feature, this will be populated;
696 /// otherwise null.
697 llvm_name: ?[:0]const u8,
698
699 /// Human-friendly UTF-8 text.
700 description: []const u8,
701
702 /// Sparse `Set` of features this depends on.
703 dependencies: Set,
704
705 /// A bit set of all the features.
706 pub const Set = struct {
707 ints: [usize_count]usize,
708
709 pub const needed_bit_count = 288;
710 pub const byte_count = (needed_bit_count + 7) / 8;
711 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
712 pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));
713 pub const ShiftInt = std.math.Log2Int(usize);
714
715 pub const empty = Set{ .ints = [1]usize{0} ** usize_count };
716
717 pub fn isEmpty(set: Set) bool {
718 return for (set.ints) |x| {
719 if (x != 0) break false;
720 } else true;
721 }
722
723 pub fn isEnabled(set: Set, arch_feature_index: Index) bool {
724 const usize_index = arch_feature_index / @bitSizeOf(usize);
725 const bit_index = @as(ShiftInt, @intCast(arch_feature_index % @bitSizeOf(usize)));
726 return (set.ints[usize_index] & (@as(usize, 1) << bit_index)) != 0;
727 }
728
729 /// Adds the specified feature but not its dependencies.
730 pub fn addFeature(set: *Set, arch_feature_index: Index) void {
731 const usize_index = arch_feature_index / @bitSizeOf(usize);
732 const bit_index = @as(ShiftInt, @intCast(arch_feature_index % @bitSizeOf(usize)));
733 set.ints[usize_index] |= @as(usize, 1) << bit_index;
734 }
735
736 /// Adds the specified feature set but not its dependencies.
737 pub fn addFeatureSet(set: *Set, other_set: Set) void {
738 switch (builtin.zig_backend) {
739 .stage2_x86_64 => {
740 for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* |= other_set_int;
741 },
742 else => {
743 set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints);
744 },
745 }
746 }
747
748 /// Removes the specified feature but not its dependents.
749 pub fn removeFeature(set: *Set, arch_feature_index: Index) void {
750 const usize_index = arch_feature_index / @bitSizeOf(usize);
751 const bit_index = @as(ShiftInt, @intCast(arch_feature_index % @bitSizeOf(usize)));
752 set.ints[usize_index] &= ~(@as(usize, 1) << bit_index);
753 }
754
755 /// Removes the specified feature but not its dependents.
756 pub fn removeFeatureSet(set: *Set, other_set: Set) void {
757 switch (builtin.zig_backend) {
758 .stage2_x86_64 => {
759 for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* &= ~other_set_int;
760 },
761 else => {
762 set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints);
763 },
764 }
765 }
766
767 pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void {
768 @setEvalBranchQuota(1000000);
769
770 var old = set.ints;
771 while (true) {
772 for (all_features_list, 0..) |feature, index_usize| {
773 const index = @as(Index, @intCast(index_usize));
774 if (set.isEnabled(index)) {
775 set.addFeatureSet(feature.dependencies);
776 }
777 }
778 const nothing_changed = std.mem.eql(usize, &old, &set.ints);
779 if (nothing_changed) return;
780 old = set.ints;
781 }
782 }
783
784 pub fn asBytes(set: *const Set) *const [byte_count]u8 {
785 return @as(*const [byte_count]u8, @ptrCast(&set.ints));
786 }
787
788 pub fn eql(set: Set, other_set: Set) bool {
789 return std.mem.eql(usize, &set.ints, &other_set.ints);
790 }
791
792 pub fn isSuperSetOf(set: Set, other_set: Set) bool {
793 switch (builtin.zig_backend) {
794 .stage2_x86_64 => {
795 var result = true;
796 for (&set.ints, other_set.ints) |*set_int, other_set_int|
797 result = result and (set_int.* & other_set_int) == other_set_int;
798 return result;
799 },
800 else => {
801 const V = @Vector(usize_count, usize);
802 const set_v: V = set.ints;
803 const other_v: V = other_set.ints;
804 return @reduce(.And, (set_v & other_v) == other_v);
805 },
806 }
807 }
808 };
809
810 pub fn feature_set_fns(comptime F: type) type {
811 return struct {
812 /// Populates only the feature bits specified.
813 pub fn featureSet(features: []const F) Set {
814 var x = Set.empty;
815 for (features) |feature| {
816 x.addFeature(@intFromEnum(feature));
817 }
818 return x;
819 }
820
821 /// Returns true if the specified feature is enabled.
822 pub fn featureSetHas(set: Set, feature: F) bool {
823 return set.isEnabled(@intFromEnum(feature));
824 }
825
826 /// Returns true if any specified feature is enabled.
827 pub fn featureSetHasAny(set: Set, features: anytype) bool {
828 inline for (features) |feature| {
829 if (set.isEnabled(@intFromEnum(@as(F, feature)))) return true;
830 }
831 return false;
832 }
833
834 /// Returns true if every specified feature is enabled.
835 pub fn featureSetHasAll(set: Set, features: anytype) bool {
836 inline for (features) |feature| {
837 if (!set.isEnabled(@intFromEnum(@as(F, feature)))) return false;
838 }
839 return true;
840 }
841 };
842 }
843 };
844
845 pub const Arch = enum {
846 arm,
847 armeb,
848 aarch64,
849 aarch64_be,
850 aarch64_32,
851 arc,
852 avr,
853 bpfel,
854 bpfeb,
855 csky,
856 dxil,
857 hexagon,
858 loongarch32,
859 loongarch64,
860 m68k,
861 mips,
862 mipsel,
863 mips64,
864 mips64el,
865 msp430,
866 powerpc,
867 powerpcle,
868 powerpc64,
869 powerpc64le,
870 r600,
871 amdgcn,
872 riscv32,
873 riscv64,
874 sparc,
875 sparc64,
876 sparcel,
877 s390x,
878 tce,
879 tcele,
880 thumb,
881 thumbeb,
882 x86,
883 x86_64,
884 xcore,
885 xtensa,
886 nvptx,
887 nvptx64,
888 le32,
889 le64,
890 amdil,
891 amdil64,
892 hsail,
893 hsail64,
894 spir,
895 spir64,
896 spirv32,
897 spirv64,
898 kalimba,
899 shave,
900 lanai,
901 wasm32,
902 wasm64,
903 renderscript32,
904 renderscript64,
905 ve,
906 // Stage1 currently assumes that architectures above this comment
907 // map one-to-one with the ZigLLVM_ArchType enum.
908 spu_2,
909
910 pub inline fn isX86(arch: Arch) bool {
911 return switch (arch) {
912 .x86, .x86_64 => true,
913 else => false,
914 };
915 }
916
917 pub inline fn isARM(arch: Arch) bool {
918 return switch (arch) {
919 .arm, .armeb => true,
920 else => false,
921 };
922 }
923
924 pub inline fn isAARCH64(arch: Arch) bool {
925 return switch (arch) {
926 .aarch64, .aarch64_be, .aarch64_32 => true,
927 else => false,
928 };
929 }
930
931 pub inline fn isThumb(arch: Arch) bool {
932 return switch (arch) {
933 .thumb, .thumbeb => true,
934 else => false,
935 };
936 }
937
938 pub inline fn isArmOrThumb(arch: Arch) bool {
939 return arch.isARM() or arch.isThumb();
940 }
941
942 pub inline fn isWasm(arch: Arch) bool {
943 return switch (arch) {
944 .wasm32, .wasm64 => true,
945 else => false,
946 };
947 }
948
949 pub inline fn isRISCV(arch: Arch) bool {
950 return switch (arch) {
951 .riscv32, .riscv64 => true,
952 else => false,
953 };
954 }
955
956 pub inline fn isMIPS(arch: Arch) bool {
957 return switch (arch) {
958 .mips, .mipsel, .mips64, .mips64el => true,
959 else => false,
960 };
961 }
962
963 pub inline fn isPPC(arch: Arch) bool {
964 return switch (arch) {
965 .powerpc, .powerpcle => true,
966 else => false,
967 };
968 }
969
970 pub inline fn isPPC64(arch: Arch) bool {
971 return switch (arch) {
972 .powerpc64, .powerpc64le => true,
973 else => false,
974 };
975 }
976
977 pub inline fn isSPARC(arch: Arch) bool {
978 return switch (arch) {
979 .sparc, .sparcel, .sparc64 => true,
980 else => false,
981 };
982 }
983
984 pub inline fn isSpirV(arch: Arch) bool {
985 return switch (arch) {
986 .spirv32, .spirv64 => true,
987 else => false,
988 };
989 }
990
991 pub inline fn isBpf(arch: Arch) bool {
992 return switch (arch) {
993 .bpfel, .bpfeb => true,
994 else => false,
995 };
996 }
997
998 pub inline fn isNvptx(arch: Arch) bool {
999 return switch (arch) {
1000 .nvptx, .nvptx64 => true,
1001 else => false,
1002 };
1003 }
1004
1005 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
1006 for (arch.allCpuModels()) |cpu| {
1007 if (std.mem.eql(u8, cpu_name, cpu.name)) {
1008 return cpu;
1009 }
1010 }
1011 return error.UnknownCpuModel;
1012 }
1013
1014 pub fn toElfMachine(arch: Arch) std.elf.EM {
1015 return switch (arch) {
1016 .avr => .AVR,
1017 .msp430 => .MSP430,
1018 .arc => .ARC,
1019 .arm => .ARM,
1020 .armeb => .ARM,
1021 .hexagon => .HEXAGON,
1022 .dxil => .NONE,
1023 .m68k => .@"68K",
1024 .le32 => .NONE,
1025 .mips => .MIPS,
1026 .mipsel => .MIPS_RS3_LE,
1027 .powerpc, .powerpcle => .PPC,
1028 .r600 => .NONE,
1029 .riscv32 => .RISCV,
1030 .sparc => .SPARC,
1031 .sparcel => .SPARC,
1032 .tce => .NONE,
1033 .tcele => .NONE,
1034 .thumb => .ARM,
1035 .thumbeb => .ARM,
1036 .x86 => .@"386",
1037 .xcore => .XCORE,
1038 .xtensa => .XTENSA,
1039 .nvptx => .NONE,
1040 .amdil => .NONE,
1041 .hsail => .NONE,
1042 .spir => .NONE,
1043 .kalimba => .CSR_KALIMBA,
1044 .shave => .NONE,
1045 .lanai => .LANAI,
1046 .wasm32 => .NONE,
1047 .renderscript32 => .NONE,
1048 .aarch64_32 => .AARCH64,
1049 .aarch64 => .AARCH64,
1050 .aarch64_be => .AARCH64,
1051 .mips64 => .MIPS,
1052 .mips64el => .MIPS_RS3_LE,
1053 .powerpc64 => .PPC64,
1054 .powerpc64le => .PPC64,
1055 .riscv64 => .RISCV,
1056 .x86_64 => .X86_64,
1057 .nvptx64 => .NONE,
1058 .le64 => .NONE,
1059 .amdil64 => .NONE,
1060 .hsail64 => .NONE,
1061 .spir64 => .NONE,
1062 .wasm64 => .NONE,
1063 .renderscript64 => .NONE,
1064 .amdgcn => .AMDGPU,
1065 .bpfel => .BPF,
1066 .bpfeb => .BPF,
1067 .csky => .CSKY,
1068 .sparc64 => .SPARCV9,
1069 .s390x => .S390,
1070 .ve => .NONE,
1071 .spu_2 => .SPU_2,
1072 .spirv32 => .NONE,
1073 .spirv64 => .NONE,
1074 .loongarch32 => .NONE,
1075 .loongarch64 => .NONE,
1076 };
1077 }
1078
1079 pub fn toCoffMachine(arch: Arch) std.coff.MachineType {
1080 return switch (arch) {
1081 .avr => .Unknown,
1082 .msp430 => .Unknown,
1083 .arc => .Unknown,
1084 .arm => .ARM,
1085 .armeb => .Unknown,
1086 .dxil => .Unknown,
1087 .hexagon => .Unknown,
1088 .m68k => .Unknown,
1089 .le32 => .Unknown,
1090 .mips => .Unknown,
1091 .mipsel => .Unknown,
1092 .powerpc, .powerpcle => .POWERPC,
1093 .r600 => .Unknown,
1094 .riscv32 => .RISCV32,
1095 .sparc => .Unknown,
1096 .sparcel => .Unknown,
1097 .tce => .Unknown,
1098 .tcele => .Unknown,
1099 .thumb => .Thumb,
1100 .thumbeb => .Thumb,
1101 .x86 => .I386,
1102 .xcore => .Unknown,
1103 .xtensa => .Unknown,
1104 .nvptx => .Unknown,
1105 .amdil => .Unknown,
1106 .hsail => .Unknown,
1107 .spir => .Unknown,
1108 .kalimba => .Unknown,
1109 .shave => .Unknown,
1110 .lanai => .Unknown,
1111 .wasm32 => .Unknown,
1112 .renderscript32 => .Unknown,
1113 .aarch64_32 => .ARM64,
1114 .aarch64 => .ARM64,
1115 .aarch64_be => .ARM64,
1116 .mips64 => .Unknown,
1117 .mips64el => .Unknown,
1118 .powerpc64 => .Unknown,
1119 .powerpc64le => .Unknown,
1120 .riscv64 => .RISCV64,
1121 .x86_64 => .X64,
1122 .nvptx64 => .Unknown,
1123 .le64 => .Unknown,
1124 .amdil64 => .Unknown,
1125 .hsail64 => .Unknown,
1126 .spir64 => .Unknown,
1127 .wasm64 => .Unknown,
1128 .renderscript64 => .Unknown,
1129 .amdgcn => .Unknown,
1130 .bpfel => .Unknown,
1131 .bpfeb => .Unknown,
1132 .csky => .Unknown,
1133 .sparc64 => .Unknown,
1134 .s390x => .Unknown,
1135 .ve => .Unknown,
1136 .spu_2 => .Unknown,
1137 .spirv32 => .Unknown,
1138 .spirv64 => .Unknown,
1139 .loongarch32 => .Unknown,
1140 .loongarch64 => .Unknown,
1141 };
1142 }
1143
1144 pub fn endian(arch: Arch) std.builtin.Endian {
1145 return switch (arch) {
1146 .avr,
1147 .arm,
1148 .aarch64_32,
1149 .aarch64,
1150 .amdgcn,
1151 .amdil,
1152 .amdil64,
1153 .bpfel,
1154 .csky,
1155 .xtensa,
1156 .hexagon,
1157 .hsail,
1158 .hsail64,
1159 .kalimba,
1160 .le32,
1161 .le64,
1162 .mipsel,
1163 .mips64el,
1164 .msp430,
1165 .nvptx,
1166 .nvptx64,
1167 .sparcel,
1168 .tcele,
1169 .powerpcle,
1170 .powerpc64le,
1171 .r600,
1172 .riscv32,
1173 .riscv64,
1174 .x86,
1175 .x86_64,
1176 .wasm32,
1177 .wasm64,
1178 .xcore,
1179 .thumb,
1180 .spir,
1181 .spir64,
1182 .renderscript32,
1183 .renderscript64,
1184 .shave,
1185 .ve,
1186 .spu_2,
1187 // GPU bitness is opaque. For now, assume little endian.
1188 .spirv32,
1189 .spirv64,
1190 .dxil,
1191 .loongarch32,
1192 .loongarch64,
1193 .arc,
1194 => .little,
1195
1196 .armeb,
1197 .aarch64_be,
1198 .bpfeb,
1199 .m68k,
1200 .mips,
1201 .mips64,
1202 .powerpc,
1203 .powerpc64,
1204 .thumbeb,
1205 .sparc,
1206 .sparc64,
1207 .tce,
1208 .lanai,
1209 .s390x,
1210 => .big,
1211 };
1212 }
1213
1214 /// Returns whether this architecture supports the address space
1215 pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
1216 const is_nvptx = arch == .nvptx or arch == .nvptx64;
1217 const is_spirv = arch == .spirv32 or arch == .spirv64;
1218 const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
1219 return switch (address_space) {
1220 .generic => true,
1221 .fs, .gs, .ss => arch == .x86_64 or arch == .x86,
1222 .global, .constant, .local, .shared => is_gpu,
1223 .param => is_nvptx,
1224 // TODO this should also check how many flash banks the cpu has
1225 .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
1226 };
1227 }
1228
1229 /// Returns a name that matches the lib/std/target/* source file name.
1230 pub fn genericName(arch: Arch) []const u8 {
1231 return switch (arch) {
1232 .arm, .armeb, .thumb, .thumbeb => "arm",
1233 .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
1234 .bpfel, .bpfeb => "bpf",
1235 .loongarch32, .loongarch64 => "loongarch",
1236 .mips, .mipsel, .mips64, .mips64el => "mips",
1237 .powerpc, .powerpcle, .powerpc64, .powerpc64le => "powerpc",
1238 .amdgcn => "amdgpu",
1239 .riscv32, .riscv64 => "riscv",
1240 .sparc, .sparc64, .sparcel => "sparc",
1241 .s390x => "s390x",
1242 .x86, .x86_64 => "x86",
1243 .nvptx, .nvptx64 => "nvptx",
1244 .wasm32, .wasm64 => "wasm",
1245 .spirv32, .spirv64 => "spirv",
1246 else => @tagName(arch),
1247 };
1248 }
1249
1250 /// All CPU features Zig is aware of, sorted lexicographically by name.
1251 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
1252 return switch (arch) {
1253 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
1254 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
1255 .arc => &arc.all_features,
1256 .avr => &avr.all_features,
1257 .bpfel, .bpfeb => &bpf.all_features,
1258 .csky => &csky.all_features,
1259 .hexagon => &hexagon.all_features,
1260 .loongarch32, .loongarch64 => &loongarch.all_features,
1261 .m68k => &m68k.all_features,
1262 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
1263 .msp430 => &msp430.all_features,
1264 .powerpc, .powerpcle, .powerpc64, .powerpc64le => &powerpc.all_features,
1265 .amdgcn => &amdgpu.all_features,
1266 .riscv32, .riscv64 => &riscv.all_features,
1267 .sparc, .sparc64, .sparcel => &sparc.all_features,
1268 .spirv32, .spirv64 => &spirv.all_features,
1269 .s390x => &s390x.all_features,
1270 .x86, .x86_64 => &x86.all_features,
1271 .xtensa => &xtensa.all_features,
1272 .nvptx, .nvptx64 => &nvptx.all_features,
1273 .ve => &ve.all_features,
1274 .wasm32, .wasm64 => &wasm.all_features,
1275
1276 else => &[0]Cpu.Feature{},
1277 };
1278 }
1279
1280 /// All processors Zig is aware of, sorted lexicographically by name.
1281 pub fn allCpuModels(arch: Arch) []const *const Cpu.Model {
1282 return switch (arch) {
1283 .arc => comptime allCpusFromDecls(arc.cpu),
1284 .arm, .armeb, .thumb, .thumbeb => comptime allCpusFromDecls(arm.cpu),
1285 .aarch64, .aarch64_be, .aarch64_32 => comptime allCpusFromDecls(aarch64.cpu),
1286 .avr => comptime allCpusFromDecls(avr.cpu),
1287 .bpfel, .bpfeb => comptime allCpusFromDecls(bpf.cpu),
1288 .csky => comptime allCpusFromDecls(csky.cpu),
1289 .hexagon => comptime allCpusFromDecls(hexagon.cpu),
1290 .loongarch32, .loongarch64 => comptime allCpusFromDecls(loongarch.cpu),
1291 .m68k => comptime allCpusFromDecls(m68k.cpu),
1292 .mips, .mipsel, .mips64, .mips64el => comptime allCpusFromDecls(mips.cpu),
1293 .msp430 => comptime allCpusFromDecls(msp430.cpu),
1294 .powerpc, .powerpcle, .powerpc64, .powerpc64le => comptime allCpusFromDecls(powerpc.cpu),
1295 .amdgcn => comptime allCpusFromDecls(amdgpu.cpu),
1296 .riscv32, .riscv64 => comptime allCpusFromDecls(riscv.cpu),
1297 .sparc, .sparc64, .sparcel => comptime allCpusFromDecls(sparc.cpu),
1298 .spirv32, .spirv64 => comptime allCpusFromDecls(spirv.cpu),
1299 .s390x => comptime allCpusFromDecls(s390x.cpu),
1300 .x86, .x86_64 => comptime allCpusFromDecls(x86.cpu),
1301 .xtensa => comptime allCpusFromDecls(xtensa.cpu),
1302 .nvptx, .nvptx64 => comptime allCpusFromDecls(nvptx.cpu),
1303 .ve => comptime allCpusFromDecls(ve.cpu),
1304 .wasm32, .wasm64 => comptime allCpusFromDecls(wasm.cpu),
1305
1306 else => &[0]*const Model{},
1307 };
1308 }
1309
1310 fn allCpusFromDecls(comptime cpus: type) []const *const Cpu.Model {
1311 const decls = @typeInfo(cpus).Struct.decls;
1312 var array: [decls.len]*const Cpu.Model = undefined;
1313 for (decls, 0..) |decl, i| {
1314 array[i] = &@field(cpus, decl.name);
1315 }
1316 return &array;
1317 }
1318 };
1319
1320 pub const Model = struct {
1321 name: []const u8,
1322 llvm_name: ?[:0]const u8,
1323 features: Feature.Set,
1324
1325 pub fn toCpu(model: *const Model, arch: Arch) Cpu {
1326 var features = model.features;
1327 features.populateDependencies(arch.allFeaturesList());
1328 return .{
1329 .arch = arch,
1330 .model = model,
1331 .features = features,
1332 };
1333 }
1334
1335 pub fn generic(arch: Arch) *const Model {
1336 const S = struct {
1337 const generic_model = Model{
1338 .name = "generic",
1339 .llvm_name = null,
1340 .features = Cpu.Feature.Set.empty,
1341 };
1342 };
1343 return switch (arch) {
1344 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
1345 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
1346 .avr => &avr.cpu.avr2,
1347 .bpfel, .bpfeb => &bpf.cpu.generic,
1348 .hexagon => &hexagon.cpu.generic,
1349 .loongarch32 => &loongarch.cpu.generic_la32,
1350 .loongarch64 => &loongarch.cpu.generic_la64,
1351 .m68k => &m68k.cpu.generic,
1352 .mips, .mipsel => &mips.cpu.mips32,
1353 .mips64, .mips64el => &mips.cpu.mips64,
1354 .msp430 => &msp430.cpu.generic,
1355 .powerpc => &powerpc.cpu.ppc,
1356 .powerpcle => &powerpc.cpu.ppc,
1357 .powerpc64 => &powerpc.cpu.ppc64,
1358 .powerpc64le => &powerpc.cpu.ppc64le,
1359 .amdgcn => &amdgpu.cpu.generic,
1360 .riscv32 => &riscv.cpu.generic_rv32,
1361 .riscv64 => &riscv.cpu.generic_rv64,
1362 .spirv32, .spirv64 => &spirv.cpu.generic,
1363 .sparc, .sparcel => &sparc.cpu.generic,
1364 .sparc64 => &sparc.cpu.v9, // 64-bit SPARC needs v9 as the baseline
1365 .s390x => &s390x.cpu.generic,
1366 .x86 => &x86.cpu.i386,
1367 .x86_64 => &x86.cpu.x86_64,
1368 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
1369 .ve => &ve.cpu.generic,
1370 .wasm32, .wasm64 => &wasm.cpu.generic,
1371
1372 else => &S.generic_model,
1373 };
1374 }
1375
1376 pub fn baseline(arch: Arch) *const Model {
1377 return switch (arch) {
1378 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline,
1379 .riscv32 => &riscv.cpu.baseline_rv32,
1380 .riscv64 => &riscv.cpu.baseline_rv64,
1381 .x86 => &x86.cpu.pentium4,
1382 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
1383 .sparc, .sparcel => &sparc.cpu.v8,
1384
1385 else => generic(arch),
1386 };
1387 }
1388 };
1389
1390 /// The "default" set of CPU features for cross-compiling. A conservative set
1391 /// of features that is expected to be supported on most available hardware.
1392 pub fn baseline(arch: Arch) Cpu {
1393 return Model.baseline(arch).toCpu(arch);
1394 }
1395};
1396
1397pub fn zigTriple(self: Target, allocator: Allocator) Allocator.Error![]u8 {
1398 return Query.fromTarget(self).zigTriple(allocator);
1399}
1400
1401pub fn linuxTripleSimple(allocator: Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
1402 return std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
1403}
1404
1405pub fn linuxTriple(self: Target, allocator: Allocator) ![]u8 {
1406 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
1407}
1408
1409pub fn exeFileExtSimple(cpu_arch: Cpu.Arch, os_tag: Os.Tag) [:0]const u8 {
1410 return switch (os_tag) {
1411 .windows => ".exe",
1412 .uefi => ".efi",
1413 .plan9 => plan9Ext(cpu_arch),
1414 else => switch (cpu_arch) {
1415 .wasm32, .wasm64 => ".wasm",
1416 else => "",
1417 },
1418 };
1419}
1420
1421pub fn exeFileExt(self: Target) [:0]const u8 {
1422 return exeFileExtSimple(self.cpu.arch, self.os.tag);
1423}
1424
1425pub fn staticLibSuffix_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 {
1426 if (abi == .msvc) {
1427 return ".lib";
1428 }
1429 switch (os_tag) {
1430 .windows, .uefi => return ".lib",
1431 else => return ".a",
1432 }
1433}
1434
1435pub fn staticLibSuffix(self: Target) [:0]const u8 {
1436 return staticLibSuffix_os_abi(self.os.tag, self.abi);
1437}
1438
1439pub fn dynamicLibSuffix(self: Target) [:0]const u8 {
1440 return self.os.tag.dynamicLibSuffix();
1441}
1442
1443pub fn libPrefix_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 {
1444 if (abi == .msvc) {
1445 return "";
1446 }
1447 switch (os_tag) {
1448 .windows, .uefi => return "",
1449 else => return "lib",
1450 }
1451}
1452
1453pub fn libPrefix(self: Target) [:0]const u8 {
1454 return libPrefix_os_abi(self.os.tag, self.abi);
1455}
1456
1457pub inline fn isMinGW(self: Target) bool {
1458 return self.os.tag == .windows and self.isGnu();
1459}
1460
1461pub inline fn isGnu(self: Target) bool {
1462 return self.abi.isGnu();
1463}
1464
1465pub inline fn isMusl(self: Target) bool {
1466 return self.abi.isMusl();
1467}
1468
1469pub inline fn isAndroid(self: Target) bool {
1470 return self.abi == .android;
1471}
1472
1473pub inline fn isWasm(self: Target) bool {
1474 return self.cpu.arch.isWasm();
1475}
1476
1477pub inline fn isDarwin(self: Target) bool {
1478 return self.os.tag.isDarwin();
1479}
1480
1481pub inline fn isBSD(self: Target) bool {
1482 return self.os.tag.isBSD();
1483}
1484
1485pub inline fn isBpfFreestanding(self: Target) bool {
1486 return self.cpu.arch.isBpf() and self.os.tag == .freestanding;
1487}
1488
1489pub inline fn isGnuLibC_os_tag_abi(os_tag: Os.Tag, abi: Abi) bool {
1490 return os_tag == .linux and abi.isGnu();
1491}
1492
1493pub inline fn isGnuLibC(self: Target) bool {
1494 return isGnuLibC_os_tag_abi(self.os.tag, self.abi);
1495}
1496
1497pub inline fn supportsNewStackCall(self: Target) bool {
1498 return !self.cpu.arch.isWasm();
1499}
1500
1501pub inline fn isSpirV(self: Target) bool {
1502 return self.cpu.arch.isSpirV();
1503}
1504
1505pub const FloatAbi = enum {
1506 hard,
1507 soft,
1508};
1509
1510pub inline fn getFloatAbi(self: Target) FloatAbi {
1511 return self.abi.floatAbi();
1512}
1513
1514pub inline fn hasDynamicLinker(self: Target) bool {
1515 if (self.cpu.arch.isWasm()) {
1516 return false;
1517 }
1518 switch (self.os.tag) {
1519 .freestanding,
1520 .ios,
1521 .tvos,
1522 .watchos,
1523 .macos,
1524 .uefi,
1525 .windows,
1526 .emscripten,
1527 .opencl,
1528 .glsl450,
1529 .vulkan,
1530 .plan9,
1531 .other,
1532 => return false,
1533 else => return true,
1534 }
1535}
1536
1537pub const DynamicLinker = struct {
1538 /// Contains the memory used to store the dynamic linker path. This field
1539 /// should not be used directly. See `get` and `set`. This field exists so
1540 /// that this API requires no allocator.
1541 buffer: [255]u8,
1542
1543 /// Used to construct the dynamic linker path. This field should not be used
1544 /// directly. See `get` and `set`.
1545 max_byte: ?u8,
1546
1547 pub const none: DynamicLinker = .{
1548 .buffer = undefined,
1549 .max_byte = null,
1550 };
1551
1552 /// Asserts that the length is less than or equal to 255 bytes.
1553 pub fn init(dl_or_null: ?[]const u8) DynamicLinker {
1554 var result: DynamicLinker = undefined;
1555 result.set(dl_or_null);
1556 return result;
1557 }
1558
1559 /// The returned memory has the same lifetime as the `DynamicLinker`.
1560 pub fn get(self: *const DynamicLinker) ?[]const u8 {
1561 const m: usize = self.max_byte orelse return null;
1562 return self.buffer[0 .. m + 1];
1563 }
1564
1565 /// Asserts that the length is less than or equal to 255 bytes.
1566 pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void {
1567 if (dl_or_null) |dl| {
1568 @memcpy(self.buffer[0..dl.len], dl);
1569 self.max_byte = @intCast(dl.len - 1);
1570 } else {
1571 self.max_byte = null;
1572 }
1573 }
1574
1575 pub fn eql(a: DynamicLinker, b: DynamicLinker) bool {
1576 const a_m = a.max_byte orelse return b.max_byte == null;
1577 const b_m = b.max_byte orelse return false;
1578 if (a_m != b_m) return false;
1579 const a_s = a.buffer[0 .. a_m + 1];
1580 const b_s = b.buffer[0 .. a_m + 1];
1581 return std.mem.eql(u8, a_s, b_s);
1582 }
1583};
1584
1585pub fn standardDynamicLinkerPath(target: Target) DynamicLinker {
1586 return standardDynamicLinkerPath_cpu_os_abi(target.cpu, target.os.tag, target.abi);
1587}
1588
1589pub fn standardDynamicLinkerPath_cpu_os_abi(cpu: Cpu, os_tag: Os.Tag, abi: Abi) DynamicLinker {
1590 var result = DynamicLinker.none;
1591 const S = struct {
1592 fn print(r: *DynamicLinker, comptime fmt: []const u8, args: anytype) DynamicLinker {
1593 r.max_byte = @as(u8, @intCast((std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1));
1594 return r.*;
1595 }
1596 fn copy(r: *DynamicLinker, s: []const u8) DynamicLinker {
1597 @memcpy(r.buffer[0..s.len], s);
1598 r.max_byte = @as(u8, @intCast(s.len - 1));
1599 return r.*;
1600 }
1601 };
1602 const print = S.print;
1603 const copy = S.copy;
1604
1605 if (abi == .android) {
1606 const suffix = if (ptrBitWidth_cpu_abi(cpu, abi) == 64) "64" else "";
1607 return print(&result, "/system/bin/linker{s}", .{suffix});
1608 }
1609
1610 if (abi.isMusl()) {
1611 const is_arm = switch (cpu.arch) {
1612 .arm, .armeb, .thumb, .thumbeb => true,
1613 else => false,
1614 };
1615 const arch_part = switch (cpu.arch) {
1616 .arm, .thumb => "arm",
1617 .armeb, .thumbeb => "armeb",
1618 else => |arch| @tagName(arch),
1619 };
1620 const arch_suffix = if (is_arm and abi.floatAbi() == .hard) "hf" else "";
1621 return print(&result, "/lib/ld-musl-{s}{s}.so.1", .{ arch_part, arch_suffix });
1622 }
1623
1624 switch (os_tag) {
1625 .freebsd => return copy(&result, "/libexec/ld-elf.so.1"),
1626 .netbsd => return copy(&result, "/libexec/ld.elf_so"),
1627 .openbsd => return copy(&result, "/usr/libexec/ld.so"),
1628 .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
1629 .solaris, .illumos => return copy(&result, "/lib/64/ld.so.1"),
1630 .linux => switch (cpu.arch) {
1631 .x86,
1632 .sparc,
1633 .sparcel,
1634 => return copy(&result, "/lib/ld-linux.so.2"),
1635
1636 .aarch64 => return copy(&result, "/lib/ld-linux-aarch64.so.1"),
1637 .aarch64_be => return copy(&result, "/lib/ld-linux-aarch64_be.so.1"),
1638 .aarch64_32 => return copy(&result, "/lib/ld-linux-aarch64_32.so.1"),
1639
1640 .arm,
1641 .armeb,
1642 .thumb,
1643 .thumbeb,
1644 => return copy(&result, switch (abi.floatAbi()) {
1645 .hard => "/lib/ld-linux-armhf.so.3",
1646 else => "/lib/ld-linux.so.3",
1647 }),
1648
1649 .mips,
1650 .mipsel,
1651 .mips64,
1652 .mips64el,
1653 => {
1654 const lib_suffix = switch (abi) {
1655 .gnuabin32, .gnux32 => "32",
1656 .gnuabi64 => "64",
1657 else => "",
1658 };
1659 const is_nan_2008 = mips.featureSetHas(cpu.features, .nan2008);
1660 const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1";
1661 return print(&result, "/lib{s}/{s}", .{ lib_suffix, loader });
1662 },
1663
1664 .powerpc, .powerpcle => return copy(&result, "/lib/ld.so.1"),
1665 .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"),
1666 .s390x => return copy(&result, "/lib64/ld64.so.1"),
1667 .sparc64 => return copy(&result, "/lib64/ld-linux.so.2"),
1668 .x86_64 => return copy(&result, switch (abi) {
1669 .gnux32 => "/libx32/ld-linux-x32.so.2",
1670 else => "/lib64/ld-linux-x86-64.so.2",
1671 }),
1672
1673 .riscv32 => return copy(&result, "/lib/ld-linux-riscv32-ilp32.so.1"),
1674 .riscv64 => return copy(&result, "/lib/ld-linux-riscv64-lp64.so.1"),
1675
1676 // Architectures in this list have been verified as not having a standard
1677 // dynamic linker path.
1678 .wasm32,
1679 .wasm64,
1680 .bpfel,
1681 .bpfeb,
1682 .nvptx,
1683 .nvptx64,
1684 .spu_2,
1685 .avr,
1686 .spirv32,
1687 .spirv64,
1688 => return result,
1689
1690 // TODO go over each item in this list and either move it to the above list, or
1691 // implement the standard dynamic linker path code for it.
1692 .arc,
1693 .csky,
1694 .hexagon,
1695 .m68k,
1696 .msp430,
1697 .r600,
1698 .amdgcn,
1699 .tce,
1700 .tcele,
1701 .xcore,
1702 .le32,
1703 .le64,
1704 .amdil,
1705 .amdil64,
1706 .hsail,
1707 .hsail64,
1708 .spir,
1709 .spir64,
1710 .kalimba,
1711 .shave,
1712 .lanai,
1713 .renderscript32,
1714 .renderscript64,
1715 .ve,
1716 .dxil,
1717 .loongarch32,
1718 .loongarch64,
1719 .xtensa,
1720 => return result,
1721 },
1722
1723 .ios,
1724 .tvos,
1725 .watchos,
1726 .macos,
1727 => return copy(&result, "/usr/lib/dyld"),
1728
1729 // Operating systems in this list have been verified as not having a standard
1730 // dynamic linker path.
1731 .freestanding,
1732 .uefi,
1733 .windows,
1734 .emscripten,
1735 .wasi,
1736 .opencl,
1737 .glsl450,
1738 .vulkan,
1739 .other,
1740 .plan9,
1741 => return result,
1742
1743 // TODO revisit when multi-arch for Haiku is available
1744 .haiku => return copy(&result, "/system/runtime_loader"),
1745
1746 // TODO go over each item in this list and either move it to the above list, or
1747 // implement the standard dynamic linker path code for it.
1748 .ananas,
1749 .cloudabi,
1750 .fuchsia,
1751 .kfreebsd,
1752 .lv2,
1753 .zos,
1754 .minix,
1755 .rtems,
1756 .nacl,
1757 .aix,
1758 .cuda,
1759 .nvcl,
1760 .amdhsa,
1761 .ps4,
1762 .ps5,
1763 .elfiamcu,
1764 .mesa3d,
1765 .contiki,
1766 .amdpal,
1767 .hermit,
1768 .hurd,
1769 .driverkit,
1770 .shadermodel,
1771 .liteos,
1772 => return result,
1773 }
1774}
1775
1776/// 0c spim little-endian MIPS 3000 family
1777/// 1c 68000 Motorola MC68000
1778/// 2c 68020 Motorola MC68020
1779/// 5c arm little-endian ARM
1780/// 6c amd64 AMD64 and compatibles (e.g., Intel EM64T)
1781/// 7c arm64 ARM64 (ARMv8)
1782/// 8c 386 Intel x86, i486, Pentium, etc.
1783/// kc sparc Sun SPARC
1784/// qc power Power PC
1785/// vc mips big-endian MIPS 3000 family
1786pub fn plan9Ext(cpu_arch: Cpu.Arch) [:0]const u8 {
1787 return switch (cpu_arch) {
1788 .arm => ".5",
1789 .x86_64 => ".6",
1790 .aarch64 => ".7",
1791 .x86 => ".8",
1792 .sparc => ".k",
1793 .powerpc, .powerpcle => ".q",
1794 .mips, .mipsel => ".v",
1795 // ISAs without designated characters get 'X' for lack of a better option.
1796 else => ".X",
1797 };
1798}
1799
1800pub fn maxIntAlignment(target: Target) u16 {
1801 return switch (target.cpu.arch) {
1802 .avr => 1,
1803 .msp430 => 2,
1804 .xcore => 4,
1805
1806 .arm,
1807 .armeb,
1808 .thumb,
1809 .thumbeb,
1810 .hexagon,
1811 .mips,
1812 .mipsel,
1813 .powerpc,
1814 .powerpcle,
1815 .r600,
1816 .amdgcn,
1817 .riscv32,
1818 .sparc,
1819 .sparcel,
1820 .s390x,
1821 .lanai,
1822 .wasm32,
1823 .wasm64,
1824 => 8,
1825
1826 .x86 => if (target.ofmt == .c) 16 else return switch (target.os.tag) {
1827 .windows, .uefi => 8,
1828 else => 4,
1829 },
1830
1831 // For these, LLVMABIAlignmentOfType(i128) reports 8. Note that 16
1832 // is a relevant number in three cases:
1833 // 1. Different machine code instruction when loading into SIMD register.
1834 // 2. The C ABI wants 16 for extern structs.
1835 // 3. 16-byte cmpxchg needs 16-byte alignment.
1836 // Same logic for powerpc64, mips64, sparc64.
1837 .x86_64,
1838 .powerpc64,
1839 .powerpc64le,
1840 .mips64,
1841 .mips64el,
1842 .sparc64,
1843 => return switch (target.ofmt) {
1844 .c => 16,
1845 else => 8,
1846 },
1847
1848 // Even LLVMABIAlignmentOfType(i128) agrees on these targets.
1849 .aarch64,
1850 .aarch64_be,
1851 .aarch64_32,
1852 .riscv64,
1853 .bpfel,
1854 .bpfeb,
1855 .nvptx,
1856 .nvptx64,
1857 => 16,
1858
1859 // Below this comment are unverified but based on the fact that C requires
1860 // int128_t to be 16 bytes aligned, it's a safe default.
1861 .spu_2,
1862 .csky,
1863 .arc,
1864 .m68k,
1865 .tce,
1866 .tcele,
1867 .le32,
1868 .amdil,
1869 .hsail,
1870 .spir,
1871 .kalimba,
1872 .renderscript32,
1873 .spirv32,
1874 .shave,
1875 .le64,
1876 .amdil64,
1877 .hsail64,
1878 .spir64,
1879 .renderscript64,
1880 .ve,
1881 .spirv64,
1882 .dxil,
1883 .loongarch32,
1884 .loongarch64,
1885 .xtensa,
1886 => 16,
1887 };
1888}
1889
1890pub fn ptrBitWidth_cpu_abi(cpu: Cpu, abi: Abi) u16 {
1891 switch (abi) {
1892 .gnux32, .muslx32, .gnuabin32, .gnuilp32 => return 32,
1893 .gnuabi64 => return 64,
1894 else => {},
1895 }
1896 return switch (cpu.arch) {
1897 .avr,
1898 .msp430,
1899 .spu_2,
1900 => 16,
1901
1902 .arc,
1903 .arm,
1904 .armeb,
1905 .csky,
1906 .hexagon,
1907 .m68k,
1908 .le32,
1909 .mips,
1910 .mipsel,
1911 .powerpc,
1912 .powerpcle,
1913 .r600,
1914 .riscv32,
1915 .sparcel,
1916 .tce,
1917 .tcele,
1918 .thumb,
1919 .thumbeb,
1920 .x86,
1921 .xcore,
1922 .nvptx,
1923 .amdil,
1924 .hsail,
1925 .spir,
1926 .kalimba,
1927 .shave,
1928 .lanai,
1929 .wasm32,
1930 .renderscript32,
1931 .aarch64_32,
1932 .spirv32,
1933 .loongarch32,
1934 .dxil,
1935 .xtensa,
1936 => 32,
1937
1938 .aarch64,
1939 .aarch64_be,
1940 .mips64,
1941 .mips64el,
1942 .powerpc64,
1943 .powerpc64le,
1944 .riscv64,
1945 .x86_64,
1946 .nvptx64,
1947 .le64,
1948 .amdil64,
1949 .hsail64,
1950 .spir64,
1951 .wasm64,
1952 .renderscript64,
1953 .amdgcn,
1954 .bpfel,
1955 .bpfeb,
1956 .sparc64,
1957 .s390x,
1958 .ve,
1959 .spirv64,
1960 .loongarch64,
1961 => 64,
1962
1963 .sparc => if (std.Target.sparc.featureSetHas(cpu.features, .v9)) 64 else 32,
1964 };
1965}
1966
1967pub fn ptrBitWidth(target: Target) u16 {
1968 return ptrBitWidth_cpu_abi(target.cpu, target.abi);
1969}
1970
1971pub fn stackAlignment(target: Target) u16 {
1972 return switch (target.cpu.arch) {
1973 .m68k => 2,
1974 .amdgcn => 4,
1975 .x86 => switch (target.os.tag) {
1976 .windows, .uefi => 4,
1977 else => 16,
1978 },
1979 .arm,
1980 .armeb,
1981 .thumb,
1982 .thumbeb,
1983 .mips,
1984 .mipsel,
1985 .sparc,
1986 .sparcel,
1987 => 8,
1988 .aarch64,
1989 .aarch64_be,
1990 .aarch64_32,
1991 .bpfeb,
1992 .bpfel,
1993 .mips64,
1994 .mips64el,
1995 .riscv32,
1996 .riscv64,
1997 .sparc64,
1998 .x86_64,
1999 .ve,
2000 .wasm32,
2001 .wasm64,
2002 => 16,
2003 .powerpc64,
2004 .powerpc64le,
2005 => switch (target.os.tag) {
2006 else => 8,
2007 .linux => 16,
2008 },
2009 else => @divExact(target.ptrBitWidth(), 8),
2010 };
2011}
2012
2013/// Default signedness of `char` for the native C compiler for this target
2014/// Note that char signedness is implementation-defined and many compilers provide
2015/// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char
2016pub fn charSignedness(target: Target) std.builtin.Signedness {
2017 switch (target.cpu.arch) {
2018 .aarch64,
2019 .aarch64_32,
2020 .aarch64_be,
2021 .arm,
2022 .armeb,
2023 .thumb,
2024 .thumbeb,
2025 => return if (target.os.tag.isDarwin() or target.os.tag == .windows) .signed else .unsigned,
2026 .powerpc, .powerpc64 => return if (target.os.tag.isDarwin()) .signed else .unsigned,
2027 .powerpcle,
2028 .powerpc64le,
2029 .s390x,
2030 .xcore,
2031 .arc,
2032 .msp430,
2033 .riscv32,
2034 .riscv64,
2035 => return .unsigned,
2036 else => return .signed,
2037 }
2038}
2039
2040pub const CType = enum {
2041 char,
2042 short,
2043 ushort,
2044 int,
2045 uint,
2046 long,
2047 ulong,
2048 longlong,
2049 ulonglong,
2050 float,
2051 double,
2052 longdouble,
2053};
2054
2055pub fn c_type_byte_size(t: Target, c_type: CType) u16 {
2056 return switch (c_type) {
2057 .char,
2058 .short,
2059 .ushort,
2060 .int,
2061 .uint,
2062 .long,
2063 .ulong,
2064 .longlong,
2065 .ulonglong,
2066 .float,
2067 .double,
2068 => @divExact(c_type_bit_size(t, c_type), 8),
2069
2070 .longdouble => switch (c_type_bit_size(t, c_type)) {
2071 16 => 2,
2072 32 => 4,
2073 64 => 8,
2074 80 => @as(u16, @intCast(std.mem.alignForward(usize, 10, c_type_alignment(t, .longdouble)))),
2075 128 => 16,
2076 else => unreachable,
2077 },
2078 };
2079}
2080
2081pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
2082 switch (target.os.tag) {
2083 .freestanding, .other => switch (target.cpu.arch) {
2084 .msp430 => switch (c_type) {
2085 .char => return 8,
2086 .short, .ushort, .int, .uint => return 16,
2087 .float, .long, .ulong => return 32,
2088 .longlong, .ulonglong, .double, .longdouble => return 64,
2089 },
2090 .avr => switch (c_type) {
2091 .char => return 8,
2092 .short, .ushort, .int, .uint => return 16,
2093 .long, .ulong, .float, .double, .longdouble => return 32,
2094 .longlong, .ulonglong => return 64,
2095 },
2096 .tce, .tcele => switch (c_type) {
2097 .char => return 8,
2098 .short, .ushort => return 16,
2099 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
2100 .float, .double, .longdouble => return 32,
2101 },
2102 .mips64, .mips64el => switch (c_type) {
2103 .char => return 8,
2104 .short, .ushort => return 16,
2105 .int, .uint, .float => return 32,
2106 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
2107 .longlong, .ulonglong, .double => return 64,
2108 .longdouble => return 128,
2109 },
2110 .x86_64 => switch (c_type) {
2111 .char => return 8,
2112 .short, .ushort => return 16,
2113 .int, .uint, .float => return 32,
2114 .long, .ulong => switch (target.abi) {
2115 .gnux32, .muslx32 => return 32,
2116 else => return 64,
2117 },
2118 .longlong, .ulonglong, .double => return 64,
2119 .longdouble => return 80,
2120 },
2121 else => switch (c_type) {
2122 .char => return 8,
2123 .short, .ushort => return 16,
2124 .int, .uint, .float => return 32,
2125 .long, .ulong => return target.ptrBitWidth(),
2126 .longlong, .ulonglong, .double => return 64,
2127 .longdouble => switch (target.cpu.arch) {
2128 .x86 => switch (target.abi) {
2129 .android => return 64,
2130 else => return 80,
2131 },
2132
2133 .powerpc,
2134 .powerpcle,
2135 .powerpc64,
2136 .powerpc64le,
2137 => switch (target.abi) {
2138 .musl,
2139 .musleabi,
2140 .musleabihf,
2141 .muslx32,
2142 => return 64,
2143 else => return 128,
2144 },
2145
2146 .riscv32,
2147 .riscv64,
2148 .aarch64,
2149 .aarch64_be,
2150 .aarch64_32,
2151 .s390x,
2152 .sparc,
2153 .sparc64,
2154 .sparcel,
2155 .wasm32,
2156 .wasm64,
2157 => return 128,
2158
2159 else => return 64,
2160 },
2161 },
2162 },
2163
2164 .linux,
2165 .freebsd,
2166 .netbsd,
2167 .dragonfly,
2168 .openbsd,
2169 .wasi,
2170 .emscripten,
2171 .plan9,
2172 .solaris,
2173 .illumos,
2174 .haiku,
2175 .ananas,
2176 .fuchsia,
2177 .minix,
2178 => switch (target.cpu.arch) {
2179 .msp430 => switch (c_type) {
2180 .char => return 8,
2181 .short, .ushort, .int, .uint => return 16,
2182 .long, .ulong, .float => return 32,
2183 .longlong, .ulonglong, .double, .longdouble => return 64,
2184 },
2185 .avr => switch (c_type) {
2186 .char => return 8,
2187 .short, .ushort, .int, .uint => return 16,
2188 .long, .ulong, .float, .double, .longdouble => return 32,
2189 .longlong, .ulonglong => return 64,
2190 },
2191 .tce, .tcele => switch (c_type) {
2192 .char => return 8,
2193 .short, .ushort => return 16,
2194 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
2195 .float, .double, .longdouble => return 32,
2196 },
2197 .mips64, .mips64el => switch (c_type) {
2198 .char => return 8,
2199 .short, .ushort => return 16,
2200 .int, .uint, .float => return 32,
2201 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
2202 .longlong, .ulonglong, .double => return 64,
2203 .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
2204 },
2205 .x86_64 => switch (c_type) {
2206 .char => return 8,
2207 .short, .ushort => return 16,
2208 .int, .uint, .float => return 32,
2209 .long, .ulong => switch (target.abi) {
2210 .gnux32, .muslx32 => return 32,
2211 else => return 64,
2212 },
2213 .longlong, .ulonglong, .double => return 64,
2214 .longdouble => return 80,
2215 },
2216 else => switch (c_type) {
2217 .char => return 8,
2218 .short, .ushort => return 16,
2219 .int, .uint, .float => return 32,
2220 .long, .ulong => return target.ptrBitWidth(),
2221 .longlong, .ulonglong, .double => return 64,
2222 .longdouble => switch (target.cpu.arch) {
2223 .x86 => switch (target.abi) {
2224 .android => return 64,
2225 else => return 80,
2226 },
2227
2228 .powerpc,
2229 .powerpcle,
2230 => switch (target.abi) {
2231 .musl,
2232 .musleabi,
2233 .musleabihf,
2234 .muslx32,
2235 => return 64,
2236 else => switch (target.os.tag) {
2237 .freebsd, .netbsd, .openbsd => return 64,
2238 else => return 128,
2239 },
2240 },
2241
2242 .powerpc64,
2243 .powerpc64le,
2244 => switch (target.abi) {
2245 .musl,
2246 .musleabi,
2247 .musleabihf,
2248 .muslx32,
2249 => return 64,
2250 else => switch (target.os.tag) {
2251 .freebsd, .openbsd => return 64,
2252 else => return 128,
2253 },
2254 },
2255
2256 .riscv32,
2257 .riscv64,
2258 .aarch64,
2259 .aarch64_be,
2260 .aarch64_32,
2261 .s390x,
2262 .mips64,
2263 .mips64el,
2264 .sparc,
2265 .sparc64,
2266 .sparcel,
2267 .wasm32,
2268 .wasm64,
2269 => return 128,
2270
2271 else => return 64,
2272 },
2273 },
2274 },
2275
2276 .windows, .uefi => switch (target.cpu.arch) {
2277 .x86 => switch (c_type) {
2278 .char => return 8,
2279 .short, .ushort => return 16,
2280 .int, .uint, .float => return 32,
2281 .long, .ulong => return 32,
2282 .longlong, .ulonglong, .double => return 64,
2283 .longdouble => switch (target.abi) {
2284 .gnu, .gnuilp32, .cygnus => return 80,
2285 else => return 64,
2286 },
2287 },
2288 .x86_64 => switch (c_type) {
2289 .char => return 8,
2290 .short, .ushort => return 16,
2291 .int, .uint, .float => return 32,
2292 .long, .ulong => switch (target.abi) {
2293 .cygnus => return 64,
2294 else => return 32,
2295 },
2296 .longlong, .ulonglong, .double => return 64,
2297 .longdouble => switch (target.abi) {
2298 .gnu, .gnuilp32, .cygnus => return 80,
2299 else => return 64,
2300 },
2301 },
2302 else => switch (c_type) {
2303 .char => return 8,
2304 .short, .ushort => return 16,
2305 .int, .uint, .float => return 32,
2306 .long, .ulong => return 32,
2307 .longlong, .ulonglong, .double => return 64,
2308 .longdouble => return 64,
2309 },
2310 },
2311
2312 .macos, .ios, .tvos, .watchos => switch (c_type) {
2313 .char => return 8,
2314 .short, .ushort => return 16,
2315 .int, .uint, .float => return 32,
2316 .long, .ulong => switch (target.cpu.arch) {
2317 .x86, .arm, .aarch64_32 => return 32,
2318 .x86_64 => switch (target.abi) {
2319 .gnux32, .muslx32 => return 32,
2320 else => return 64,
2321 },
2322 else => return 64,
2323 },
2324 .longlong, .ulonglong, .double => return 64,
2325 .longdouble => switch (target.cpu.arch) {
2326 .x86 => switch (target.abi) {
2327 .android => return 64,
2328 else => return 80,
2329 },
2330 .x86_64 => return 80,
2331 else => return 64,
2332 },
2333 },
2334
2335 .nvcl, .cuda => switch (c_type) {
2336 .char => return 8,
2337 .short, .ushort => return 16,
2338 .int, .uint, .float => return 32,
2339 .long, .ulong => switch (target.cpu.arch) {
2340 .nvptx => return 32,
2341 .nvptx64 => return 64,
2342 else => return 64,
2343 },
2344 .longlong, .ulonglong, .double => return 64,
2345 .longdouble => return 64,
2346 },
2347
2348 .amdhsa, .amdpal => switch (c_type) {
2349 .char => return 8,
2350 .short, .ushort => return 16,
2351 .int, .uint, .float => return 32,
2352 .long, .ulong, .longlong, .ulonglong, .double => return 64,
2353 .longdouble => return 128,
2354 },
2355
2356 .opencl => switch (c_type) {
2357 .char => return 8,
2358 .short, .ushort => return 16,
2359 .int, .uint, .float => return 32,
2360 .long, .ulong, .double => return 64,
2361 .longlong, .ulonglong => return 128,
2362 // Note: The OpenCL specification does not guarantee a particular size for long double,
2363 // but clang uses 128 bits.
2364 .longdouble => return 128,
2365 },
2366
2367 .ps4, .ps5 => switch (c_type) {
2368 .char => return 8,
2369 .short, .ushort => return 16,
2370 .int, .uint, .float => return 32,
2371 .long, .ulong => return 64,
2372 .longlong, .ulonglong, .double => return 64,
2373 .longdouble => return 80,
2374 },
2375
2376 .cloudabi,
2377 .kfreebsd,
2378 .lv2,
2379 .zos,
2380 .rtems,
2381 .nacl,
2382 .aix,
2383 .elfiamcu,
2384 .mesa3d,
2385 .contiki,
2386 .hermit,
2387 .hurd,
2388 .glsl450,
2389 .vulkan,
2390 .driverkit,
2391 .shadermodel,
2392 .liteos,
2393 => @panic("TODO specify the C integer and float type sizes for this OS"),
2394 }
2395}
2396
2397pub fn c_type_alignment(target: Target, c_type: CType) u16 {
2398 // Overrides for unusual alignments
2399 switch (target.cpu.arch) {
2400 .avr => return 1,
2401 .x86 => switch (target.os.tag) {
2402 .windows, .uefi => switch (c_type) {
2403 .longlong, .ulonglong, .double => return 8,
2404 .longdouble => switch (target.abi) {
2405 .gnu, .gnuilp32, .cygnus => return 4,
2406 else => return 8,
2407 },
2408 else => {},
2409 },
2410 else => {},
2411 },
2412 else => {},
2413 }
2414
2415 // Next-power-of-two-aligned, up to a maximum.
2416 return @min(
2417 std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
2418 switch (target.cpu.arch) {
2419 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
2420 .netbsd => switch (target.abi) {
2421 .gnueabi,
2422 .gnueabihf,
2423 .eabi,
2424 .eabihf,
2425 .android,
2426 .musleabi,
2427 .musleabihf,
2428 => 8,
2429
2430 else => @as(u16, 4),
2431 },
2432 .ios, .tvos, .watchos => 4,
2433 else => 8,
2434 },
2435
2436 .msp430,
2437 .avr,
2438 => 2,
2439
2440 .arc,
2441 .csky,
2442 .x86,
2443 .xcore,
2444 .dxil,
2445 .loongarch32,
2446 .tce,
2447 .tcele,
2448 .le32,
2449 .amdil,
2450 .hsail,
2451 .spir,
2452 .spirv32,
2453 .kalimba,
2454 .shave,
2455 .renderscript32,
2456 .ve,
2457 .spu_2,
2458 .xtensa,
2459 => 4,
2460
2461 .aarch64_32,
2462 .amdgcn,
2463 .amdil64,
2464 .bpfel,
2465 .bpfeb,
2466 .hexagon,
2467 .hsail64,
2468 .loongarch64,
2469 .m68k,
2470 .mips,
2471 .mipsel,
2472 .sparc,
2473 .sparcel,
2474 .sparc64,
2475 .lanai,
2476 .le64,
2477 .nvptx,
2478 .nvptx64,
2479 .r600,
2480 .s390x,
2481 .spir64,
2482 .spirv64,
2483 .renderscript64,
2484 => 8,
2485
2486 .aarch64,
2487 .aarch64_be,
2488 .mips64,
2489 .mips64el,
2490 .powerpc,
2491 .powerpcle,
2492 .powerpc64,
2493 .powerpc64le,
2494 .riscv32,
2495 .riscv64,
2496 .x86_64,
2497 .wasm32,
2498 .wasm64,
2499 => 16,
2500 },
2501 );
2502}
2503
2504pub fn c_type_preferred_alignment(target: Target, c_type: CType) u16 {
2505 // Overrides for unusual alignments
2506 switch (target.cpu.arch) {
2507 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
2508 .netbsd => switch (target.abi) {
2509 .gnueabi,
2510 .gnueabihf,
2511 .eabi,
2512 .eabihf,
2513 .android,
2514 .musleabi,
2515 .musleabihf,
2516 => {},
2517
2518 else => switch (c_type) {
2519 .longdouble => return 4,
2520 else => {},
2521 },
2522 },
2523 .ios, .tvos, .watchos => switch (c_type) {
2524 .longdouble => return 4,
2525 else => {},
2526 },
2527 else => {},
2528 },
2529 .arc => switch (c_type) {
2530 .longdouble => return 4,
2531 else => {},
2532 },
2533 .avr => switch (c_type) {
2534 .char, .int, .uint, .long, .ulong, .float, .longdouble => return 1,
2535 .short, .ushort => return 2,
2536 .double => return 4,
2537 .longlong, .ulonglong => return 8,
2538 },
2539 .x86 => switch (target.os.tag) {
2540 .windows, .uefi => switch (c_type) {
2541 .longdouble => switch (target.abi) {
2542 .gnu, .gnuilp32, .cygnus => return 4,
2543 else => return 8,
2544 },
2545 else => {},
2546 },
2547 else => switch (c_type) {
2548 .longdouble => return 4,
2549 else => {},
2550 },
2551 },
2552 else => {},
2553 }
2554
2555 // Next-power-of-two-aligned, up to a maximum.
2556 return @min(
2557 std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
2558 switch (target.cpu.arch) {
2559 .msp430 => @as(u16, 2),
2560
2561 .csky,
2562 .xcore,
2563 .dxil,
2564 .loongarch32,
2565 .tce,
2566 .tcele,
2567 .le32,
2568 .amdil,
2569 .hsail,
2570 .spir,
2571 .spirv32,
2572 .kalimba,
2573 .shave,
2574 .renderscript32,
2575 .ve,
2576 .spu_2,
2577 .xtensa,
2578 => 4,
2579
2580 .arc,
2581 .arm,
2582 .armeb,
2583 .avr,
2584 .thumb,
2585 .thumbeb,
2586 .aarch64_32,
2587 .amdgcn,
2588 .amdil64,
2589 .bpfel,
2590 .bpfeb,
2591 .hexagon,
2592 .hsail64,
2593 .x86,
2594 .loongarch64,
2595 .m68k,
2596 .mips,
2597 .mipsel,
2598 .sparc,
2599 .sparcel,
2600 .sparc64,
2601 .lanai,
2602 .le64,
2603 .nvptx,
2604 .nvptx64,
2605 .r600,
2606 .s390x,
2607 .spir64,
2608 .spirv64,
2609 .renderscript64,
2610 => 8,
2611
2612 .aarch64,
2613 .aarch64_be,
2614 .mips64,
2615 .mips64el,
2616 .powerpc,
2617 .powerpcle,
2618 .powerpc64,
2619 .powerpc64le,
2620 .riscv32,
2621 .riscv64,
2622 .x86_64,
2623 .wasm32,
2624 .wasm64,
2625 => 16,
2626 },
2627 );
2628}
2629
2630pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool {
2631 const ignore_case = target.os.tag == .macos or target.os.tag == .windows;
2632
2633 if (eqlIgnoreCase(ignore_case, name, "c"))
2634 return true;
2635
2636 if (target.isMinGW()) {
2637 if (eqlIgnoreCase(ignore_case, name, "m"))
2638 return true;
2639 if (eqlIgnoreCase(ignore_case, name, "uuid"))
2640 return true;
2641 if (eqlIgnoreCase(ignore_case, name, "mingw32"))
2642 return true;
2643 if (eqlIgnoreCase(ignore_case, name, "msvcrt-os"))
2644 return true;
2645 if (eqlIgnoreCase(ignore_case, name, "mingwex"))
2646 return true;
2647
2648 return false;
2649 }
2650
2651 if (target.abi.isGnu() or target.abi.isMusl()) {
2652 if (eqlIgnoreCase(ignore_case, name, "m"))
2653 return true;
2654 if (eqlIgnoreCase(ignore_case, name, "rt"))
2655 return true;
2656 if (eqlIgnoreCase(ignore_case, name, "pthread"))
2657 return true;
2658 if (eqlIgnoreCase(ignore_case, name, "util"))
2659 return true;
2660 if (eqlIgnoreCase(ignore_case, name, "xnet"))
2661 return true;
2662 if (eqlIgnoreCase(ignore_case, name, "resolv"))
2663 return true;
2664 if (eqlIgnoreCase(ignore_case, name, "dl"))
2665 return true;
2666 }
2667
2668 if (target.abi.isMusl()) {
2669 if (eqlIgnoreCase(ignore_case, name, "crypt"))
2670 return true;
2671 }
2672
2673 if (target.os.tag.isDarwin()) {
2674 if (eqlIgnoreCase(ignore_case, name, "System"))
2675 return true;
2676 if (eqlIgnoreCase(ignore_case, name, "c"))
2677 return true;
2678 if (eqlIgnoreCase(ignore_case, name, "dbm"))
2679 return true;
2680 if (eqlIgnoreCase(ignore_case, name, "dl"))
2681 return true;
2682 if (eqlIgnoreCase(ignore_case, name, "info"))
2683 return true;
2684 if (eqlIgnoreCase(ignore_case, name, "m"))
2685 return true;
2686 if (eqlIgnoreCase(ignore_case, name, "poll"))
2687 return true;
2688 if (eqlIgnoreCase(ignore_case, name, "proc"))
2689 return true;
2690 if (eqlIgnoreCase(ignore_case, name, "pthread"))
2691 return true;
2692 if (eqlIgnoreCase(ignore_case, name, "rpcsvc"))
2693 return true;
2694 }
2695
2696 if (target.os.isAtLeast(.macos, .{ .major = 10, .minor = 8, .patch = 0 }) orelse false) {
2697 if (eqlIgnoreCase(ignore_case, name, "mx"))
2698 return true;
2699 }
2700
2701 return false;
2702}
2703
2704pub fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool {
2705 const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
2706
2707 return eqlIgnoreCase(ignore_case, name, "c++") or
2708 eqlIgnoreCase(ignore_case, name, "stdc++") or
2709 eqlIgnoreCase(ignore_case, name, "c++abi");
2710}
2711
2712fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
2713 if (ignore_case) {
2714 return std.ascii.eqlIgnoreCase(a, b);
2715 } else {
2716 return std.mem.eql(u8, a, b);
2717 }
2718}
2719
2720const Target = @This();
2721const std = @import("std.zig");
2722const builtin = @import("builtin");
2723const Allocator = std.mem.Allocator;
2724
2725test {
2726 std.testing.refAllDecls(Cpu.Arch);
2727}
lib/std/Target/Query.zig created+777
......@@ -0,0 +1,777 @@
1//! Contains all the same data as `Target`, additionally introducing the
2//! concept of "the native target". The purpose of this abstraction is to
3//! provide meaningful and unsurprising defaults. This struct does reference
4//! any resources and it is copyable.
5
6/// `null` means native.
7cpu_arch: ?Target.Cpu.Arch = null,
8
9cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
10
11/// Sparse set of CPU features to add to the set from `cpu_model`.
12cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
13
14/// Sparse set of CPU features to remove from the set from `cpu_model`.
15cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
16
17/// `null` means native.
18os_tag: ?Target.Os.Tag = null,
19
20/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native)
21/// then `null` for this field means native.
22os_version_min: ?OsVersion = null,
23
24/// When cross compiling, `null` means default (latest known OS version).
25/// When `os_tag` is native, `null` means equal to the native OS version.
26os_version_max: ?OsVersion = null,
27
28/// `null` means default when cross compiling, or native when os_tag is native.
29/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
30glibc_version: ?SemanticVersion = null,
31
32/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
33abi: ?Target.Abi = null,
34
35/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path
36/// based on the `os_tag`.
37dynamic_linker: Target.DynamicLinker = Target.DynamicLinker.none,
38
39/// `null` means default for the cpu/arch/os combo.
40ofmt: ?Target.ObjectFormat = null,
41
42pub const CpuModel = union(enum) {
43 /// Always native
44 native,
45
46 /// Always baseline
47 baseline,
48
49 /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
50 /// it will be baseline.
51 determined_by_cpu_arch,
52
53 explicit: *const Target.Cpu.Model,
54
55 pub fn eql(a: CpuModel, b: CpuModel) bool {
56 const Tag = @typeInfo(CpuModel).Union.tag_type.?;
57 const a_tag: Tag = a;
58 const b_tag: Tag = b;
59 if (a_tag != b_tag) return false;
60 return switch (a) {
61 .native, .baseline, .determined_by_cpu_arch => true,
62 .explicit => |a_model| a_model == b.explicit,
63 };
64 }
65};
66
67pub const OsVersion = union(enum) {
68 none: void,
69 semver: SemanticVersion,
70 windows: Target.Os.WindowsVersion,
71
72 pub fn eql(a: OsVersion, b: OsVersion) bool {
73 const Tag = @typeInfo(OsVersion).Union.tag_type.?;
74 const a_tag: Tag = a;
75 const b_tag: Tag = b;
76 if (a_tag != b_tag) return false;
77 return switch (a) {
78 .none => true,
79 .semver => |a_semver| a_semver.order(b.semver) == .eq,
80 .windows => |a_windows| a_windows == b.windows,
81 };
82 }
83
84 pub fn eqlOpt(a: ?OsVersion, b: ?OsVersion) bool {
85 if (a == null and b == null) return true;
86 if (a == null or b == null) return false;
87 return OsVersion.eql(a.?, b.?);
88 }
89};
90
91pub const SemanticVersion = std.SemanticVersion;
92
93pub fn fromTarget(target: Target) Query {
94 var result: Query = .{
95 .cpu_arch = target.cpu.arch,
96 .cpu_model = .{ .explicit = target.cpu.model },
97 .os_tag = target.os.tag,
98 .os_version_min = undefined,
99 .os_version_max = undefined,
100 .abi = target.abi,
101 .glibc_version = if (target.isGnuLibC())
102 target.os.version_range.linux.glibc
103 else
104 null,
105 };
106 result.updateOsVersionRange(target.os);
107
108 const all_features = target.cpu.arch.allFeaturesList();
109 var cpu_model_set = target.cpu.model.features;
110 cpu_model_set.populateDependencies(all_features);
111 {
112 // The "add" set is the full set with the CPU Model set removed.
113 const add_set = &result.cpu_features_add;
114 add_set.* = target.cpu.features;
115 add_set.removeFeatureSet(cpu_model_set);
116 }
117 {
118 // The "sub" set is the features that are on in CPU Model set and off in the full set.
119 const sub_set = &result.cpu_features_sub;
120 sub_set.* = cpu_model_set;
121 sub_set.removeFeatureSet(target.cpu.features);
122 }
123 return result;
124}
125
126fn updateOsVersionRange(self: *Query, os: Target.Os) void {
127 switch (os.tag) {
128 .freestanding,
129 .ananas,
130 .cloudabi,
131 .fuchsia,
132 .kfreebsd,
133 .lv2,
134 .solaris,
135 .illumos,
136 .zos,
137 .haiku,
138 .minix,
139 .rtems,
140 .nacl,
141 .aix,
142 .cuda,
143 .nvcl,
144 .amdhsa,
145 .ps4,
146 .ps5,
147 .elfiamcu,
148 .mesa3d,
149 .contiki,
150 .amdpal,
151 .hermit,
152 .hurd,
153 .wasi,
154 .emscripten,
155 .driverkit,
156 .shadermodel,
157 .liteos,
158 .uefi,
159 .opencl,
160 .glsl450,
161 .vulkan,
162 .plan9,
163 .other,
164 => {
165 self.os_version_min = .{ .none = {} };
166 self.os_version_max = .{ .none = {} };
167 },
168
169 .freebsd,
170 .macos,
171 .ios,
172 .tvos,
173 .watchos,
174 .netbsd,
175 .openbsd,
176 .dragonfly,
177 => {
178 self.os_version_min = .{ .semver = os.version_range.semver.min };
179 self.os_version_max = .{ .semver = os.version_range.semver.max };
180 },
181
182 .linux => {
183 self.os_version_min = .{ .semver = os.version_range.linux.range.min };
184 self.os_version_max = .{ .semver = os.version_range.linux.range.max };
185 },
186
187 .windows => {
188 self.os_version_min = .{ .windows = os.version_range.windows.min };
189 self.os_version_max = .{ .windows = os.version_range.windows.max };
190 },
191 }
192}
193
194pub const ParseOptions = struct {
195 /// This is sometimes called a "triple". It looks roughly like this:
196 /// riscv64-linux-musl
197 /// The fields are, respectively:
198 /// * CPU Architecture
199 /// * Operating System (and optional version range)
200 /// * C ABI (optional, with optional glibc version)
201 /// The string "native" can be used for CPU architecture as well as Operating System.
202 /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
203 arch_os_abi: []const u8 = "native",
204
205 /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
206 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
207 /// to remove from the set.
208 /// The following special strings are recognized for CPU Model name:
209 /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set
210 /// of features that is expected to be supported on most available hardware.
211 /// * "native" - The native CPU model is to be detected when compiling.
212 /// If this field is not provided (`null`), then the value will depend on the
213 /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline".
214 cpu_features: ?[]const u8 = null,
215
216 /// Absolute path to dynamic linker, to override the default, which is either a natively
217 /// detected path, or a standard path.
218 dynamic_linker: ?[]const u8 = null,
219
220 object_format: ?[]const u8 = null,
221
222 /// If this is provided, the function will populate some information about parsing failures,
223 /// so that user-friendly error messages can be delivered.
224 diagnostics: ?*Diagnostics = null,
225
226 pub const Diagnostics = struct {
227 /// If the architecture was determined, this will be populated.
228 arch: ?Target.Cpu.Arch = null,
229
230 /// If the OS name was determined, this will be populated.
231 os_name: ?[]const u8 = null,
232
233 /// If the OS tag was determined, this will be populated.
234 os_tag: ?Target.Os.Tag = null,
235
236 /// If the ABI was determined, this will be populated.
237 abi: ?Target.Abi = null,
238
239 /// If the CPU name was determined, this will be populated.
240 cpu_name: ?[]const u8 = null,
241
242 /// If error.UnknownCpuFeature is returned, this will be populated.
243 unknown_feature_name: ?[]const u8 = null,
244 };
245};
246
247pub fn parse(args: ParseOptions) !Query {
248 var dummy_diags: ParseOptions.Diagnostics = undefined;
249 const diags = args.diagnostics orelse &dummy_diags;
250
251 var result: Query = .{
252 .dynamic_linker = Target.DynamicLinker.init(args.dynamic_linker),
253 };
254
255 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
256 const arch_name = it.first();
257 const arch_is_native = mem.eql(u8, arch_name, "native");
258 if (!arch_is_native) {
259 result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse
260 return error.UnknownArchitecture;
261 }
262 const arch = result.cpu_arch orelse builtin.cpu.arch;
263 diags.arch = arch;
264
265 if (it.next()) |os_text| {
266 try parseOs(&result, diags, os_text);
267 } else if (!arch_is_native) {
268 return error.MissingOperatingSystem;
269 }
270
271 const opt_abi_text = it.next();
272 if (opt_abi_text) |abi_text| {
273 var abi_it = mem.splitScalar(u8, abi_text, '.');
274 const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse
275 return error.UnknownApplicationBinaryInterface;
276 result.abi = abi;
277 diags.abi = abi;
278
279 const abi_ver_text = abi_it.rest();
280 if (abi_it.next() != null) {
281 if (Target.isGnuLibC_os_tag_abi(result.os_tag orelse builtin.os.tag, abi)) {
282 result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
283 error.Overflow => return error.InvalidAbiVersion,
284 error.InvalidVersion => return error.InvalidAbiVersion,
285 };
286 } else {
287 return error.InvalidAbiVersion;
288 }
289 }
290 }
291
292 if (it.next() != null) return error.UnexpectedExtraField;
293
294 if (args.cpu_features) |cpu_features| {
295 const all_features = arch.allFeaturesList();
296 var index: usize = 0;
297 while (index < cpu_features.len and
298 cpu_features[index] != '+' and
299 cpu_features[index] != '-')
300 {
301 index += 1;
302 }
303 const cpu_name = cpu_features[0..index];
304 diags.cpu_name = cpu_name;
305
306 const add_set = &result.cpu_features_add;
307 const sub_set = &result.cpu_features_sub;
308 if (mem.eql(u8, cpu_name, "native")) {
309 result.cpu_model = .native;
310 } else if (mem.eql(u8, cpu_name, "baseline")) {
311 result.cpu_model = .baseline;
312 } else {
313 result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
314 }
315
316 while (index < cpu_features.len) {
317 const op = cpu_features[index];
318 const set = switch (op) {
319 '+' => add_set,
320 '-' => sub_set,
321 else => unreachable,
322 };
323 index += 1;
324 const start = index;
325 while (index < cpu_features.len and
326 cpu_features[index] != '+' and
327 cpu_features[index] != '-')
328 {
329 index += 1;
330 }
331 const feature_name = cpu_features[start..index];
332 for (all_features, 0..) |feature, feat_index_usize| {
333 const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize));
334 if (mem.eql(u8, feature_name, feature.name)) {
335 set.addFeature(feat_index);
336 break;
337 }
338 } else {
339 diags.unknown_feature_name = feature_name;
340 return error.UnknownCpuFeature;
341 }
342 }
343 }
344
345 if (args.object_format) |ofmt_name| {
346 result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
347 return error.UnknownObjectFormat;
348 }
349
350 return result;
351}
352
353/// Similar to `parse` except instead of fully parsing, it only determines the CPU
354/// architecture and returns it if it can be determined, and returns `null` otherwise.
355/// This is intended to be used if the API user of Query needs to learn the
356/// target CPU architecture in order to fully populate `ParseOptions`.
357pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
358 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
359 const arch_name = it.first();
360 const arch_is_native = mem.eql(u8, arch_name, "native");
361 if (arch_is_native) {
362 return builtin.cpu.arch;
363 } else {
364 return std.meta.stringToEnum(Target.Cpu.Arch, arch_name);
365 }
366}
367
368/// Similar to `SemanticVersion.parse`, but with following changes:
369/// * Leading zeroes are allowed.
370/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
371pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
372 const parseVersionComponentFn = (struct {
373 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
374 return std.fmt.parseUnsigned(usize, component, 10) catch |err| switch (err) {
375 error.InvalidCharacter => return error.InvalidVersion,
376 error.Overflow => return error.Overflow,
377 };
378 }
379 }).parseVersionComponentInner;
380 var version_components = mem.splitScalar(u8, ver, '.');
381 const major = version_components.first();
382 const minor = version_components.next() orelse return error.InvalidVersion;
383 const patch = version_components.next() orelse "0";
384 if (version_components.next() != null) return error.InvalidVersion;
385 return .{
386 .major = try parseVersionComponentFn(major),
387 .minor = try parseVersionComponentFn(minor),
388 .patch = try parseVersionComponentFn(patch),
389 };
390}
391
392test parseVersion {
393 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
394 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
395 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
396 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
397}
398
399pub fn isNativeCpu(self: Query) bool {
400 return self.cpu_arch == null and
401 (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
402 self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
403}
404
405pub fn isNativeOs(self: Query) bool {
406 return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
407 self.dynamic_linker.get() == null and self.glibc_version == null;
408}
409
410pub fn isNativeAbi(self: Query) bool {
411 return self.os_tag == null and self.abi == null;
412}
413
414pub fn isNative(self: Query) bool {
415 return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
416}
417
418/// Formats a version with the patch component omitted if it is zero,
419/// unlike SemanticVersion.format which formats all its version components regardless.
420fn formatVersion(version: SemanticVersion, writer: anytype) !void {
421 if (version.patch == 0) {
422 try writer.print("{d}.{d}", .{ version.major, version.minor });
423 } else {
424 try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch });
425 }
426}
427
428pub fn zigTriple(self: Query, allocator: Allocator) Allocator.Error![]u8 {
429 if (self.isNative()) {
430 return allocator.dupe(u8, "native");
431 }
432
433 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
434 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
435
436 var result = std.ArrayList(u8).init(allocator);
437 defer result.deinit();
438
439 try result.writer().print("{s}-{s}", .{ arch_name, os_name });
440
441 // The zig target syntax does not allow specifying a max os version with no min, so
442 // if either are present, we need the min.
443 if (self.os_version_min) |min| {
444 switch (min) {
445 .none => {},
446 .semver => |v| {
447 try result.writer().writeAll(".");
448 try formatVersion(v, result.writer());
449 },
450 .windows => |v| {
451 try result.writer().print("{s}", .{v});
452 },
453 }
454 }
455 if (self.os_version_max) |max| {
456 switch (max) {
457 .none => {},
458 .semver => |v| {
459 try result.writer().writeAll("...");
460 try formatVersion(v, result.writer());
461 },
462 .windows => |v| {
463 // This is counting on a custom format() function defined on `WindowsVersion`
464 // to add a prefix '.' and make there be a total of three dots.
465 try result.writer().print("..{s}", .{v});
466 },
467 }
468 }
469
470 if (self.glibc_version) |v| {
471 const name = @tagName(self.abi orelse builtin.target.abi);
472 try result.ensureUnusedCapacity(name.len + 2);
473 result.appendAssumeCapacity('-');
474 result.appendSliceAssumeCapacity(name);
475 result.appendAssumeCapacity('.');
476 try formatVersion(v, result.writer());
477 } else if (self.abi) |abi| {
478 const name = @tagName(abi);
479 try result.ensureUnusedCapacity(name.len + 1);
480 result.appendAssumeCapacity('-');
481 result.appendSliceAssumeCapacity(name);
482 }
483
484 return result.toOwnedSlice();
485}
486
487/// Renders the query into a textual representation that can be parsed via the
488/// `-mcpu` flag passed to the Zig compiler.
489/// Appends the result to `buffer`.
490pub fn serializeCpu(q: Query, buffer: *std.ArrayList(u8)) Allocator.Error!void {
491 try buffer.ensureUnusedCapacity(8);
492 switch (q.cpu_model) {
493 .native => {
494 buffer.appendSliceAssumeCapacity("native");
495 },
496 .baseline => {
497 buffer.appendSliceAssumeCapacity("baseline");
498 },
499 .determined_by_cpu_arch => {
500 if (q.cpu_arch == null) {
501 buffer.appendSliceAssumeCapacity("native");
502 } else {
503 buffer.appendSliceAssumeCapacity("baseline");
504 }
505 },
506 .explicit => |model| {
507 try buffer.appendSlice(model.name);
508 },
509 }
510
511 if (q.cpu_features_add.isEmpty() and q.cpu_features_sub.isEmpty()) {
512 // The CPU name alone is sufficient.
513 return;
514 }
515
516 const cpu_arch = q.cpu_arch orelse builtin.cpu.arch;
517 const all_features = cpu_arch.allFeaturesList();
518
519 for (all_features, 0..) |feature, i_usize| {
520 const i: Target.Cpu.Feature.Set.Index = @intCast(i_usize);
521 try buffer.ensureUnusedCapacity(feature.name.len + 1);
522 if (q.cpu_features_sub.isEnabled(i)) {
523 buffer.appendAssumeCapacity('-');
524 buffer.appendSliceAssumeCapacity(feature.name);
525 } else if (q.cpu_features_add.isEnabled(i)) {
526 buffer.appendAssumeCapacity('+');
527 buffer.appendSliceAssumeCapacity(feature.name);
528 }
529 }
530}
531
532pub fn serializeCpuAlloc(q: Query, ally: Allocator) Allocator.Error![]u8 {
533 var buffer = std.ArrayList(u8).init(ally);
534 try serializeCpu(q, &buffer);
535 return buffer.toOwnedSlice();
536}
537
538pub fn allocDescription(self: Query, allocator: Allocator) ![]u8 {
539 // TODO is there anything else worthy of the description that is not
540 // already captured in the triple?
541 return self.zigTriple(allocator);
542}
543
544pub fn setGnuLibCVersion(self: *Query, major: u32, minor: u32, patch: u32) void {
545 self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch };
546}
547
548fn parseOs(result: *Query, diags: *ParseOptions.Diagnostics, text: []const u8) !void {
549 var it = mem.splitScalar(u8, text, '.');
550 const os_name = it.first();
551 diags.os_name = os_name;
552 const os_is_native = mem.eql(u8, os_name, "native");
553 if (!os_is_native) {
554 result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse
555 return error.UnknownOperatingSystem;
556 }
557 const tag = result.os_tag orelse builtin.os.tag;
558 diags.os_tag = tag;
559
560 const version_text = it.rest();
561 if (it.next() == null) return;
562
563 switch (tag) {
564 .freestanding,
565 .ananas,
566 .cloudabi,
567 .fuchsia,
568 .kfreebsd,
569 .lv2,
570 .solaris,
571 .illumos,
572 .zos,
573 .haiku,
574 .minix,
575 .rtems,
576 .nacl,
577 .aix,
578 .cuda,
579 .nvcl,
580 .amdhsa,
581 .ps4,
582 .ps5,
583 .elfiamcu,
584 .mesa3d,
585 .contiki,
586 .amdpal,
587 .hermit,
588 .hurd,
589 .wasi,
590 .emscripten,
591 .uefi,
592 .opencl,
593 .glsl450,
594 .vulkan,
595 .plan9,
596 .driverkit,
597 .shadermodel,
598 .liteos,
599 .other,
600 => return error.InvalidOperatingSystemVersion,
601
602 .freebsd,
603 .macos,
604 .ios,
605 .tvos,
606 .watchos,
607 .netbsd,
608 .openbsd,
609 .linux,
610 .dragonfly,
611 => {
612 var range_it = mem.splitSequence(u8, version_text, "...");
613
614 const min_text = range_it.next().?;
615 const min_ver = parseVersion(min_text) catch |err| switch (err) {
616 error.Overflow => return error.InvalidOperatingSystemVersion,
617 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
618 };
619 result.os_version_min = .{ .semver = min_ver };
620
621 const max_text = range_it.next() orelse return;
622 const max_ver = parseVersion(max_text) catch |err| switch (err) {
623 error.Overflow => return error.InvalidOperatingSystemVersion,
624 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
625 };
626 result.os_version_max = .{ .semver = max_ver };
627 },
628
629 .windows => {
630 var range_it = mem.splitSequence(u8, version_text, "...");
631
632 const min_text = range_it.first();
633 const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse
634 return error.InvalidOperatingSystemVersion;
635 result.os_version_min = .{ .windows = min_ver };
636
637 const max_text = range_it.next() orelse return;
638 const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse
639 return error.InvalidOperatingSystemVersion;
640 result.os_version_max = .{ .windows = max_ver };
641 },
642 }
643}
644
645pub fn eql(a: Query, b: Query) bool {
646 if (a.cpu_arch != b.cpu_arch) return false;
647 if (!a.cpu_model.eql(b.cpu_model)) return false;
648 if (!a.cpu_features_add.eql(b.cpu_features_add)) return false;
649 if (!a.cpu_features_sub.eql(b.cpu_features_sub)) return false;
650 if (a.os_tag != b.os_tag) return false;
651 if (!OsVersion.eqlOpt(a.os_version_min, b.os_version_min)) return false;
652 if (!OsVersion.eqlOpt(a.os_version_max, b.os_version_max)) return false;
653 if (!versionEqualOpt(a.glibc_version, b.glibc_version)) return false;
654 if (a.abi != b.abi) return false;
655 if (!a.dynamic_linker.eql(b.dynamic_linker)) return false;
656 if (a.ofmt != b.ofmt) return false;
657
658 return true;
659}
660
661fn versionEqualOpt(a: ?SemanticVersion, b: ?SemanticVersion) bool {
662 if (a == null and b == null) return true;
663 if (a == null or b == null) return false;
664 return SemanticVersion.order(a.?, b.?) == .eq;
665}
666
667const Query = @This();
668const std = @import("../std.zig");
669const builtin = @import("builtin");
670const assert = std.debug.assert;
671const Target = std.Target;
672const mem = std.mem;
673const Allocator = std.mem.Allocator;
674
675test parse {
676 if (builtin.target.isGnuLibC()) {
677 var query = try Query.parse(.{});
678 query.setGnuLibCVersion(2, 1, 1);
679
680 const text = try query.zigTriple(std.testing.allocator);
681 defer std.testing.allocator.free(text);
682
683 var buf: [256]u8 = undefined;
684 const triple = std.fmt.bufPrint(
685 buf[0..],
686 "native-native-{s}.2.1.1",
687 .{@tagName(builtin.target.abi)},
688 ) catch unreachable;
689
690 try std.testing.expectEqualSlices(u8, triple, text);
691 }
692 {
693 const query = try Query.parse(.{
694 .arch_os_abi = "aarch64-linux",
695 .cpu_features = "native",
696 });
697
698 try std.testing.expect(query.cpu_arch.? == .aarch64);
699 try std.testing.expect(query.cpu_model == .native);
700 }
701 {
702 const query = try Query.parse(.{ .arch_os_abi = "native" });
703
704 try std.testing.expect(query.cpu_arch == null);
705 try std.testing.expect(query.isNative());
706
707 const text = try query.zigTriple(std.testing.allocator);
708 defer std.testing.allocator.free(text);
709 try std.testing.expectEqualSlices(u8, "native", text);
710 }
711 {
712 const query = try Query.parse(.{
713 .arch_os_abi = "x86_64-linux-gnu",
714 .cpu_features = "x86_64-sse-sse2-avx-cx8",
715 });
716 const target = try std.zig.system.resolveTargetQuery(query);
717
718 try std.testing.expect(target.os.tag == .linux);
719 try std.testing.expect(target.abi == .gnu);
720 try std.testing.expect(target.cpu.arch == .x86_64);
721 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
722 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
723 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
724 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
725 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
726
727 try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
728 try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
729 try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
730 try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
731
732 const text = try query.zigTriple(std.testing.allocator);
733 defer std.testing.allocator.free(text);
734 try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
735 }
736 {
737 const query = try Query.parse(.{
738 .arch_os_abi = "arm-linux-musleabihf",
739 .cpu_features = "generic+v8a",
740 });
741 const target = try std.zig.system.resolveTargetQuery(query);
742
743 try std.testing.expect(target.os.tag == .linux);
744 try std.testing.expect(target.abi == .musleabihf);
745 try std.testing.expect(target.cpu.arch == .arm);
746 try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
747 try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
748
749 const text = try query.zigTriple(std.testing.allocator);
750 defer std.testing.allocator.free(text);
751 try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
752 }
753 {
754 const query = try Query.parse(.{
755 .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
756 .cpu_features = "generic+v8a",
757 });
758 const target = try std.zig.system.resolveTargetQuery(query);
759
760 try std.testing.expect(target.cpu.arch == .aarch64);
761 try std.testing.expect(target.os.tag == .linux);
762 try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
763 try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
764 try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
765 try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
766 try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
767 try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
768 try std.testing.expect(target.os.version_range.linux.glibc.major == 2);
769 try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
770 try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
771 try std.testing.expect(target.abi == .gnu);
772
773 const text = try query.zigTriple(std.testing.allocator);
774 defer std.testing.allocator.free(text);
775 try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
776 }
777}
lib/std/Target/aarch64.zig created+2656
......@@ -0,0 +1,2656 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 a510,
9 a65,
10 a710,
11 a76,
12 a78,
13 a78c,
14 aes,
15 aggressive_fma,
16 alternate_sextload_cvt_f32_pattern,
17 altnzcv,
18 am,
19 amvs,
20 arith_bcc_fusion,
21 arith_cbz_fusion,
22 ascend_store_address,
23 b16b16,
24 balance_fp_ops,
25 bf16,
26 brbe,
27 bti,
28 call_saved_x10,
29 call_saved_x11,
30 call_saved_x12,
31 call_saved_x13,
32 call_saved_x14,
33 call_saved_x15,
34 call_saved_x18,
35 call_saved_x8,
36 call_saved_x9,
37 ccdp,
38 ccidx,
39 ccpp,
40 chk,
41 clrbhb,
42 cmp_bcc_fusion,
43 complxnum,
44 contextidr_el2,
45 cortex_r82,
46 crc,
47 crypto,
48 cssc,
49 custom_cheap_as_move,
50 d128,
51 disable_latency_sched_heuristic,
52 dit,
53 dotprod,
54 ecv,
55 el2vmsa,
56 el3,
57 enable_select_opt,
58 ete,
59 exynos_cheap_as_move,
60 f32mm,
61 f64mm,
62 fgt,
63 fix_cortex_a53_835769,
64 flagm,
65 fmv,
66 force_32bit_jump_tables,
67 fp16fml,
68 fp_armv8,
69 fptoint,
70 fullfp16,
71 fuse_address,
72 fuse_addsub_2reg_const1,
73 fuse_adrp_add,
74 fuse_aes,
75 fuse_arith_logic,
76 fuse_crypto_eor,
77 fuse_csel,
78 fuse_literals,
79 gcs,
80 harden_sls_blr,
81 harden_sls_nocomdat,
82 harden_sls_retbr,
83 hbc,
84 hcx,
85 i8mm,
86 ite,
87 jsconv,
88 lor,
89 ls64,
90 lse,
91 lse128,
92 lse2,
93 lsl_fast,
94 mec,
95 mops,
96 mpam,
97 mte,
98 neon,
99 nmi,
100 no_bti_at_return_twice,
101 no_neg_immediates,
102 no_sve_fp_ld1r,
103 no_zcz_fp,
104 nv,
105 outline_atomics,
106 pan,
107 pan_rwv,
108 pauth,
109 perfmon,
110 predictable_select_expensive,
111 predres,
112 prfm_slc_target,
113 rand,
114 ras,
115 rasv2,
116 rcpc,
117 rcpc3,
118 rcpc_immo,
119 rdm,
120 reserve_x1,
121 reserve_x10,
122 reserve_x11,
123 reserve_x12,
124 reserve_x13,
125 reserve_x14,
126 reserve_x15,
127 reserve_x18,
128 reserve_x2,
129 reserve_x20,
130 reserve_x21,
131 reserve_x22,
132 reserve_x23,
133 reserve_x24,
134 reserve_x25,
135 reserve_x26,
136 reserve_x27,
137 reserve_x28,
138 reserve_x3,
139 reserve_x30,
140 reserve_x4,
141 reserve_x5,
142 reserve_x6,
143 reserve_x7,
144 reserve_x9,
145 rme,
146 sb,
147 sel2,
148 sha2,
149 sha3,
150 slow_misaligned_128store,
151 slow_paired_128,
152 slow_strqro_store,
153 sm4,
154 sme,
155 sme2,
156 sme2p1,
157 sme_f16f16,
158 sme_f64f64,
159 sme_i16i64,
160 spe,
161 spe_eef,
162 specres2,
163 specrestrict,
164 ssbs,
165 strict_align,
166 sve,
167 sve2,
168 sve2_aes,
169 sve2_bitperm,
170 sve2_sha3,
171 sve2_sm4,
172 sve2p1,
173 tagged_globals,
174 the,
175 tlb_rmi,
176 tme,
177 tpidr_el1,
178 tpidr_el2,
179 tpidr_el3,
180 tpidrro_el0,
181 tracev8_4,
182 trbe,
183 uaops,
184 use_experimental_zeroing_pseudos,
185 use_postra_scheduler,
186 use_reciprocal_square_root,
187 use_scalar_inc_vl,
188 v8_1a,
189 v8_2a,
190 v8_3a,
191 v8_4a,
192 v8_5a,
193 v8_6a,
194 v8_7a,
195 v8_8a,
196 v8_9a,
197 v8a,
198 v8r,
199 v9_1a,
200 v9_2a,
201 v9_3a,
202 v9_4a,
203 v9a,
204 vh,
205 wfxt,
206 xs,
207 zcm,
208 zcz,
209 zcz_fp_workaround,
210 zcz_gp,
211};
212
213pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
214pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
215pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
216pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
217
218pub const all_features = blk: {
219 @setEvalBranchQuota(2000);
220 const len = @typeInfo(Feature).Enum.fields.len;
221 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
222 var result: [len]CpuFeature = undefined;
223 result[@intFromEnum(Feature.a510)] = .{
224 .llvm_name = "a510",
225 .description = "Cortex-A510 ARM processors",
226 .dependencies = featureSet(&[_]Feature{
227 .fuse_adrp_add,
228 .fuse_aes,
229 .use_postra_scheduler,
230 }),
231 };
232 result[@intFromEnum(Feature.a65)] = .{
233 .llvm_name = "a65",
234 .description = "Cortex-A65 ARM processors",
235 .dependencies = featureSet(&[_]Feature{
236 .enable_select_opt,
237 .fuse_address,
238 .fuse_adrp_add,
239 .fuse_aes,
240 .fuse_literals,
241 .predictable_select_expensive,
242 }),
243 };
244 result[@intFromEnum(Feature.a710)] = .{
245 .llvm_name = "a710",
246 .description = "Cortex-A710 ARM processors",
247 .dependencies = featureSet(&[_]Feature{
248 .cmp_bcc_fusion,
249 .enable_select_opt,
250 .fuse_adrp_add,
251 .fuse_aes,
252 .lsl_fast,
253 .predictable_select_expensive,
254 .use_postra_scheduler,
255 }),
256 };
257 result[@intFromEnum(Feature.a76)] = .{
258 .llvm_name = "a76",
259 .description = "Cortex-A76 ARM processors",
260 .dependencies = featureSet(&[_]Feature{
261 .enable_select_opt,
262 .fuse_adrp_add,
263 .fuse_aes,
264 .lsl_fast,
265 .predictable_select_expensive,
266 }),
267 };
268 result[@intFromEnum(Feature.a78)] = .{
269 .llvm_name = "a78",
270 .description = "Cortex-A78 ARM processors",
271 .dependencies = featureSet(&[_]Feature{
272 .cmp_bcc_fusion,
273 .enable_select_opt,
274 .fuse_adrp_add,
275 .fuse_aes,
276 .lsl_fast,
277 .predictable_select_expensive,
278 .use_postra_scheduler,
279 }),
280 };
281 result[@intFromEnum(Feature.a78c)] = .{
282 .llvm_name = "a78c",
283 .description = "Cortex-A78C ARM processors",
284 .dependencies = featureSet(&[_]Feature{
285 .cmp_bcc_fusion,
286 .enable_select_opt,
287 .fuse_adrp_add,
288 .fuse_aes,
289 .lsl_fast,
290 .predictable_select_expensive,
291 .use_postra_scheduler,
292 }),
293 };
294 result[@intFromEnum(Feature.aes)] = .{
295 .llvm_name = "aes",
296 .description = "Enable AES support (FEAT_AES, FEAT_PMULL)",
297 .dependencies = featureSet(&[_]Feature{
298 .neon,
299 }),
300 };
301 result[@intFromEnum(Feature.aggressive_fma)] = .{
302 .llvm_name = "aggressive-fma",
303 .description = "Enable Aggressive FMA for floating-point.",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@intFromEnum(Feature.alternate_sextload_cvt_f32_pattern)] = .{
307 .llvm_name = "alternate-sextload-cvt-f32-pattern",
308 .description = "Use alternative pattern for sextload convert to f32",
309 .dependencies = featureSet(&[_]Feature{}),
310 };
311 result[@intFromEnum(Feature.altnzcv)] = .{
312 .llvm_name = "altnzcv",
313 .description = "Enable alternative NZCV format for floating point comparisons (FEAT_FlagM2)",
314 .dependencies = featureSet(&[_]Feature{}),
315 };
316 result[@intFromEnum(Feature.am)] = .{
317 .llvm_name = "am",
318 .description = "Enable v8.4-A Activity Monitors extension (FEAT_AMUv1)",
319 .dependencies = featureSet(&[_]Feature{}),
320 };
321 result[@intFromEnum(Feature.amvs)] = .{
322 .llvm_name = "amvs",
323 .description = "Enable v8.6-A Activity Monitors Virtualization support (FEAT_AMUv1p1)",
324 .dependencies = featureSet(&[_]Feature{
325 .am,
326 }),
327 };
328 result[@intFromEnum(Feature.arith_bcc_fusion)] = .{
329 .llvm_name = "arith-bcc-fusion",
330 .description = "CPU fuses arithmetic+bcc operations",
331 .dependencies = featureSet(&[_]Feature{}),
332 };
333 result[@intFromEnum(Feature.arith_cbz_fusion)] = .{
334 .llvm_name = "arith-cbz-fusion",
335 .description = "CPU fuses arithmetic + cbz/cbnz operations",
336 .dependencies = featureSet(&[_]Feature{}),
337 };
338 result[@intFromEnum(Feature.ascend_store_address)] = .{
339 .llvm_name = "ascend-store-address",
340 .description = "Schedule vector stores by ascending address",
341 .dependencies = featureSet(&[_]Feature{}),
342 };
343 result[@intFromEnum(Feature.b16b16)] = .{
344 .llvm_name = "b16b16",
345 .description = "Enable SVE2.1 or SME2.1 non-widening BFloat16 to BFloat16 instructions (FEAT_B16B16)",
346 .dependencies = featureSet(&[_]Feature{}),
347 };
348 result[@intFromEnum(Feature.balance_fp_ops)] = .{
349 .llvm_name = "balance-fp-ops",
350 .description = "balance mix of odd and even D-registers for fp multiply(-accumulate) ops",
351 .dependencies = featureSet(&[_]Feature{}),
352 };
353 result[@intFromEnum(Feature.bf16)] = .{
354 .llvm_name = "bf16",
355 .description = "Enable BFloat16 Extension (FEAT_BF16)",
356 .dependencies = featureSet(&[_]Feature{}),
357 };
358 result[@intFromEnum(Feature.brbe)] = .{
359 .llvm_name = "brbe",
360 .description = "Enable Branch Record Buffer Extension (FEAT_BRBE)",
361 .dependencies = featureSet(&[_]Feature{}),
362 };
363 result[@intFromEnum(Feature.bti)] = .{
364 .llvm_name = "bti",
365 .description = "Enable Branch Target Identification (FEAT_BTI)",
366 .dependencies = featureSet(&[_]Feature{}),
367 };
368 result[@intFromEnum(Feature.call_saved_x10)] = .{
369 .llvm_name = "call-saved-x10",
370 .description = "Make X10 callee saved.",
371 .dependencies = featureSet(&[_]Feature{}),
372 };
373 result[@intFromEnum(Feature.call_saved_x11)] = .{
374 .llvm_name = "call-saved-x11",
375 .description = "Make X11 callee saved.",
376 .dependencies = featureSet(&[_]Feature{}),
377 };
378 result[@intFromEnum(Feature.call_saved_x12)] = .{
379 .llvm_name = "call-saved-x12",
380 .description = "Make X12 callee saved.",
381 .dependencies = featureSet(&[_]Feature{}),
382 };
383 result[@intFromEnum(Feature.call_saved_x13)] = .{
384 .llvm_name = "call-saved-x13",
385 .description = "Make X13 callee saved.",
386 .dependencies = featureSet(&[_]Feature{}),
387 };
388 result[@intFromEnum(Feature.call_saved_x14)] = .{
389 .llvm_name = "call-saved-x14",
390 .description = "Make X14 callee saved.",
391 .dependencies = featureSet(&[_]Feature{}),
392 };
393 result[@intFromEnum(Feature.call_saved_x15)] = .{
394 .llvm_name = "call-saved-x15",
395 .description = "Make X15 callee saved.",
396 .dependencies = featureSet(&[_]Feature{}),
397 };
398 result[@intFromEnum(Feature.call_saved_x18)] = .{
399 .llvm_name = "call-saved-x18",
400 .description = "Make X18 callee saved.",
401 .dependencies = featureSet(&[_]Feature{}),
402 };
403 result[@intFromEnum(Feature.call_saved_x8)] = .{
404 .llvm_name = "call-saved-x8",
405 .description = "Make X8 callee saved.",
406 .dependencies = featureSet(&[_]Feature{}),
407 };
408 result[@intFromEnum(Feature.call_saved_x9)] = .{
409 .llvm_name = "call-saved-x9",
410 .description = "Make X9 callee saved.",
411 .dependencies = featureSet(&[_]Feature{}),
412 };
413 result[@intFromEnum(Feature.ccdp)] = .{
414 .llvm_name = "ccdp",
415 .description = "Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)",
416 .dependencies = featureSet(&[_]Feature{}),
417 };
418 result[@intFromEnum(Feature.ccidx)] = .{
419 .llvm_name = "ccidx",
420 .description = "Enable v8.3-A Extend of the CCSIDR number of sets (FEAT_CCIDX)",
421 .dependencies = featureSet(&[_]Feature{}),
422 };
423 result[@intFromEnum(Feature.ccpp)] = .{
424 .llvm_name = "ccpp",
425 .description = "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)",
426 .dependencies = featureSet(&[_]Feature{}),
427 };
428 result[@intFromEnum(Feature.chk)] = .{
429 .llvm_name = "chk",
430 .description = "Enable Armv8.0-A Check Feature Status Extension (FEAT_CHK)",
431 .dependencies = featureSet(&[_]Feature{}),
432 };
433 result[@intFromEnum(Feature.clrbhb)] = .{
434 .llvm_name = "clrbhb",
435 .description = "Enable Clear BHB instruction (FEAT_CLRBHB)",
436 .dependencies = featureSet(&[_]Feature{}),
437 };
438 result[@intFromEnum(Feature.cmp_bcc_fusion)] = .{
439 .llvm_name = "cmp-bcc-fusion",
440 .description = "CPU fuses cmp+bcc operations",
441 .dependencies = featureSet(&[_]Feature{}),
442 };
443 result[@intFromEnum(Feature.complxnum)] = .{
444 .llvm_name = "complxnum",
445 .description = "Enable v8.3-A Floating-point complex number support (FEAT_FCMA)",
446 .dependencies = featureSet(&[_]Feature{
447 .neon,
448 }),
449 };
450 result[@intFromEnum(Feature.contextidr_el2)] = .{
451 .llvm_name = "CONTEXTIDREL2",
452 .description = "Enable RW operand Context ID Register (EL2)",
453 .dependencies = featureSet(&[_]Feature{}),
454 };
455 result[@intFromEnum(Feature.cortex_r82)] = .{
456 .llvm_name = "cortex-r82",
457 .description = "Cortex-R82 ARM processors",
458 .dependencies = featureSet(&[_]Feature{
459 .use_postra_scheduler,
460 }),
461 };
462 result[@intFromEnum(Feature.crc)] = .{
463 .llvm_name = "crc",
464 .description = "Enable ARMv8 CRC-32 checksum instructions (FEAT_CRC32)",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@intFromEnum(Feature.crypto)] = .{
468 .llvm_name = "crypto",
469 .description = "Enable cryptographic instructions",
470 .dependencies = featureSet(&[_]Feature{
471 .aes,
472 .sha2,
473 }),
474 };
475 result[@intFromEnum(Feature.cssc)] = .{
476 .llvm_name = "cssc",
477 .description = "Enable Common Short Sequence Compression (CSSC) instructions (FEAT_CSSC)",
478 .dependencies = featureSet(&[_]Feature{}),
479 };
480 result[@intFromEnum(Feature.custom_cheap_as_move)] = .{
481 .llvm_name = "custom-cheap-as-move",
482 .description = "Use custom handling of cheap instructions",
483 .dependencies = featureSet(&[_]Feature{}),
484 };
485 result[@intFromEnum(Feature.d128)] = .{
486 .llvm_name = "d128",
487 .description = "Enable Armv9.4-A 128-bit Page Table Descriptors, System Registers and Instructions (FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, FEAT_SYSINSTR128)",
488 .dependencies = featureSet(&[_]Feature{
489 .lse128,
490 }),
491 };
492 result[@intFromEnum(Feature.disable_latency_sched_heuristic)] = .{
493 .llvm_name = "disable-latency-sched-heuristic",
494 .description = "Disable latency scheduling heuristic",
495 .dependencies = featureSet(&[_]Feature{}),
496 };
497 result[@intFromEnum(Feature.dit)] = .{
498 .llvm_name = "dit",
499 .description = "Enable v8.4-A Data Independent Timing instructions (FEAT_DIT)",
500 .dependencies = featureSet(&[_]Feature{}),
501 };
502 result[@intFromEnum(Feature.dotprod)] = .{
503 .llvm_name = "dotprod",
504 .description = "Enable dot product support (FEAT_DotProd)",
505 .dependencies = featureSet(&[_]Feature{}),
506 };
507 result[@intFromEnum(Feature.ecv)] = .{
508 .llvm_name = "ecv",
509 .description = "Enable enhanced counter virtualization extension (FEAT_ECV)",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@intFromEnum(Feature.el2vmsa)] = .{
513 .llvm_name = "el2vmsa",
514 .description = "Enable Exception Level 2 Virtual Memory System Architecture",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@intFromEnum(Feature.el3)] = .{
518 .llvm_name = "el3",
519 .description = "Enable Exception Level 3",
520 .dependencies = featureSet(&[_]Feature{}),
521 };
522 result[@intFromEnum(Feature.enable_select_opt)] = .{
523 .llvm_name = "enable-select-opt",
524 .description = "Enable the select optimize pass for select loop heuristics",
525 .dependencies = featureSet(&[_]Feature{}),
526 };
527 result[@intFromEnum(Feature.ete)] = .{
528 .llvm_name = "ete",
529 .description = "Enable Embedded Trace Extension (FEAT_ETE)",
530 .dependencies = featureSet(&[_]Feature{
531 .trbe,
532 }),
533 };
534 result[@intFromEnum(Feature.exynos_cheap_as_move)] = .{
535 .llvm_name = "exynos-cheap-as-move",
536 .description = "Use Exynos specific handling of cheap instructions",
537 .dependencies = featureSet(&[_]Feature{
538 .custom_cheap_as_move,
539 }),
540 };
541 result[@intFromEnum(Feature.f32mm)] = .{
542 .llvm_name = "f32mm",
543 .description = "Enable Matrix Multiply FP32 Extension (FEAT_F32MM)",
544 .dependencies = featureSet(&[_]Feature{
545 .sve,
546 }),
547 };
548 result[@intFromEnum(Feature.f64mm)] = .{
549 .llvm_name = "f64mm",
550 .description = "Enable Matrix Multiply FP64 Extension (FEAT_F64MM)",
551 .dependencies = featureSet(&[_]Feature{
552 .sve,
553 }),
554 };
555 result[@intFromEnum(Feature.fgt)] = .{
556 .llvm_name = "fgt",
557 .description = "Enable fine grained virtualization traps extension (FEAT_FGT)",
558 .dependencies = featureSet(&[_]Feature{}),
559 };
560 result[@intFromEnum(Feature.fix_cortex_a53_835769)] = .{
561 .llvm_name = "fix-cortex-a53-835769",
562 .description = "Mitigate Cortex-A53 Erratum 835769",
563 .dependencies = featureSet(&[_]Feature{}),
564 };
565 result[@intFromEnum(Feature.flagm)] = .{
566 .llvm_name = "flagm",
567 .description = "Enable v8.4-A Flag Manipulation Instructions (FEAT_FlagM)",
568 .dependencies = featureSet(&[_]Feature{}),
569 };
570 result[@intFromEnum(Feature.fmv)] = .{
571 .llvm_name = "fmv",
572 .description = "Enable Function Multi Versioning support.",
573 .dependencies = featureSet(&[_]Feature{}),
574 };
575 result[@intFromEnum(Feature.force_32bit_jump_tables)] = .{
576 .llvm_name = "force-32bit-jump-tables",
577 .description = "Force jump table entries to be 32-bits wide except at MinSize",
578 .dependencies = featureSet(&[_]Feature{}),
579 };
580 result[@intFromEnum(Feature.fp16fml)] = .{
581 .llvm_name = "fp16fml",
582 .description = "Enable FP16 FML instructions (FEAT_FHM)",
583 .dependencies = featureSet(&[_]Feature{
584 .fullfp16,
585 }),
586 };
587 result[@intFromEnum(Feature.fp_armv8)] = .{
588 .llvm_name = "fp-armv8",
589 .description = "Enable ARMv8 FP (FEAT_FP)",
590 .dependencies = featureSet(&[_]Feature{}),
591 };
592 result[@intFromEnum(Feature.fptoint)] = .{
593 .llvm_name = "fptoint",
594 .description = "Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int (FEAT_FRINTTS)",
595 .dependencies = featureSet(&[_]Feature{}),
596 };
597 result[@intFromEnum(Feature.fullfp16)] = .{
598 .llvm_name = "fullfp16",
599 .description = "Full FP16 (FEAT_FP16)",
600 .dependencies = featureSet(&[_]Feature{
601 .fp_armv8,
602 }),
603 };
604 result[@intFromEnum(Feature.fuse_address)] = .{
605 .llvm_name = "fuse-address",
606 .description = "CPU fuses address generation and memory operations",
607 .dependencies = featureSet(&[_]Feature{}),
608 };
609 result[@intFromEnum(Feature.fuse_addsub_2reg_const1)] = .{
610 .llvm_name = "fuse-addsub-2reg-const1",
611 .description = "CPU fuses (a + b + 1) and (a - b - 1)",
612 .dependencies = featureSet(&[_]Feature{}),
613 };
614 result[@intFromEnum(Feature.fuse_adrp_add)] = .{
615 .llvm_name = "fuse-adrp-add",
616 .description = "CPU fuses adrp+add operations",
617 .dependencies = featureSet(&[_]Feature{}),
618 };
619 result[@intFromEnum(Feature.fuse_aes)] = .{
620 .llvm_name = "fuse-aes",
621 .description = "CPU fuses AES crypto operations",
622 .dependencies = featureSet(&[_]Feature{}),
623 };
624 result[@intFromEnum(Feature.fuse_arith_logic)] = .{
625 .llvm_name = "fuse-arith-logic",
626 .description = "CPU fuses arithmetic and logic operations",
627 .dependencies = featureSet(&[_]Feature{}),
628 };
629 result[@intFromEnum(Feature.fuse_crypto_eor)] = .{
630 .llvm_name = "fuse-crypto-eor",
631 .description = "CPU fuses AES/PMULL and EOR operations",
632 .dependencies = featureSet(&[_]Feature{}),
633 };
634 result[@intFromEnum(Feature.fuse_csel)] = .{
635 .llvm_name = "fuse-csel",
636 .description = "CPU fuses conditional select operations",
637 .dependencies = featureSet(&[_]Feature{}),
638 };
639 result[@intFromEnum(Feature.fuse_literals)] = .{
640 .llvm_name = "fuse-literals",
641 .description = "CPU fuses literal generation operations",
642 .dependencies = featureSet(&[_]Feature{}),
643 };
644 result[@intFromEnum(Feature.gcs)] = .{
645 .llvm_name = "gcs",
646 .description = "Enable Armv9.4-A Guarded Call Stack Extension",
647 .dependencies = featureSet(&[_]Feature{
648 .chk,
649 }),
650 };
651 result[@intFromEnum(Feature.harden_sls_blr)] = .{
652 .llvm_name = "harden-sls-blr",
653 .description = "Harden against straight line speculation across BLR instructions",
654 .dependencies = featureSet(&[_]Feature{}),
655 };
656 result[@intFromEnum(Feature.harden_sls_nocomdat)] = .{
657 .llvm_name = "harden-sls-nocomdat",
658 .description = "Generate thunk code for SLS mitigation in the normal text section",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.harden_sls_retbr)] = .{
662 .llvm_name = "harden-sls-retbr",
663 .description = "Harden against straight line speculation across RET and BR instructions",
664 .dependencies = featureSet(&[_]Feature{}),
665 };
666 result[@intFromEnum(Feature.hbc)] = .{
667 .llvm_name = "hbc",
668 .description = "Enable Armv8.8-A Hinted Conditional Branches Extension (FEAT_HBC)",
669 .dependencies = featureSet(&[_]Feature{}),
670 };
671 result[@intFromEnum(Feature.hcx)] = .{
672 .llvm_name = "hcx",
673 .description = "Enable Armv8.7-A HCRX_EL2 system register (FEAT_HCX)",
674 .dependencies = featureSet(&[_]Feature{}),
675 };
676 result[@intFromEnum(Feature.i8mm)] = .{
677 .llvm_name = "i8mm",
678 .description = "Enable Matrix Multiply Int8 Extension (FEAT_I8MM)",
679 .dependencies = featureSet(&[_]Feature{}),
680 };
681 result[@intFromEnum(Feature.ite)] = .{
682 .llvm_name = "ite",
683 .description = "Enable Armv9.4-A Instrumentation Extension FEAT_ITE",
684 .dependencies = featureSet(&[_]Feature{
685 .ete,
686 }),
687 };
688 result[@intFromEnum(Feature.jsconv)] = .{
689 .llvm_name = "jsconv",
690 .description = "Enable v8.3-A JavaScript FP conversion instructions (FEAT_JSCVT)",
691 .dependencies = featureSet(&[_]Feature{
692 .fp_armv8,
693 }),
694 };
695 result[@intFromEnum(Feature.lor)] = .{
696 .llvm_name = "lor",
697 .description = "Enables ARM v8.1 Limited Ordering Regions extension (FEAT_LOR)",
698 .dependencies = featureSet(&[_]Feature{}),
699 };
700 result[@intFromEnum(Feature.ls64)] = .{
701 .llvm_name = "ls64",
702 .description = "Enable Armv8.7-A LD64B/ST64B Accelerator Extension (FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA)",
703 .dependencies = featureSet(&[_]Feature{}),
704 };
705 result[@intFromEnum(Feature.lse)] = .{
706 .llvm_name = "lse",
707 .description = "Enable ARMv8.1 Large System Extension (LSE) atomic instructions (FEAT_LSE)",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.lse128)] = .{
711 .llvm_name = "lse128",
712 .description = "Enable Armv9.4-A 128-bit Atomic Instructions (FEAT_LSE128)",
713 .dependencies = featureSet(&[_]Feature{
714 .lse,
715 }),
716 };
717 result[@intFromEnum(Feature.lse2)] = .{
718 .llvm_name = "lse2",
719 .description = "Enable ARMv8.4 Large System Extension 2 (LSE2) atomicity rules (FEAT_LSE2)",
720 .dependencies = featureSet(&[_]Feature{}),
721 };
722 result[@intFromEnum(Feature.lsl_fast)] = .{
723 .llvm_name = "lsl-fast",
724 .description = "CPU has a fastpath logical shift of up to 3 places",
725 .dependencies = featureSet(&[_]Feature{}),
726 };
727 result[@intFromEnum(Feature.mec)] = .{
728 .llvm_name = "mec",
729 .description = "Enable Memory Encryption Contexts Extension",
730 .dependencies = featureSet(&[_]Feature{
731 .rme,
732 }),
733 };
734 result[@intFromEnum(Feature.mops)] = .{
735 .llvm_name = "mops",
736 .description = "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)",
737 .dependencies = featureSet(&[_]Feature{}),
738 };
739 result[@intFromEnum(Feature.mpam)] = .{
740 .llvm_name = "mpam",
741 .description = "Enable v8.4-A Memory system Partitioning and Monitoring extension (FEAT_MPAM)",
742 .dependencies = featureSet(&[_]Feature{}),
743 };
744 result[@intFromEnum(Feature.mte)] = .{
745 .llvm_name = "mte",
746 .description = "Enable Memory Tagging Extension (FEAT_MTE, FEAT_MTE2)",
747 .dependencies = featureSet(&[_]Feature{}),
748 };
749 result[@intFromEnum(Feature.neon)] = .{
750 .llvm_name = "neon",
751 .description = "Enable Advanced SIMD instructions (FEAT_AdvSIMD)",
752 .dependencies = featureSet(&[_]Feature{
753 .fp_armv8,
754 }),
755 };
756 result[@intFromEnum(Feature.nmi)] = .{
757 .llvm_name = "nmi",
758 .description = "Enable Armv8.8-A Non-maskable Interrupts (FEAT_NMI, FEAT_GICv3_NMI)",
759 .dependencies = featureSet(&[_]Feature{}),
760 };
761 result[@intFromEnum(Feature.no_bti_at_return_twice)] = .{
762 .llvm_name = "no-bti-at-return-twice",
763 .description = "Don't place a BTI instruction after a return-twice",
764 .dependencies = featureSet(&[_]Feature{}),
765 };
766 result[@intFromEnum(Feature.no_neg_immediates)] = .{
767 .llvm_name = "no-neg-immediates",
768 .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
769 .dependencies = featureSet(&[_]Feature{}),
770 };
771 result[@intFromEnum(Feature.no_sve_fp_ld1r)] = .{
772 .llvm_name = "no-sve-fp-ld1r",
773 .description = "Avoid using LD1RX instructions for FP",
774 .dependencies = featureSet(&[_]Feature{}),
775 };
776 result[@intFromEnum(Feature.no_zcz_fp)] = .{
777 .llvm_name = "no-zcz-fp",
778 .description = "Has no zero-cycle zeroing instructions for FP registers",
779 .dependencies = featureSet(&[_]Feature{}),
780 };
781 result[@intFromEnum(Feature.nv)] = .{
782 .llvm_name = "nv",
783 .description = "Enable v8.4-A Nested Virtualization Enchancement (FEAT_NV, FEAT_NV2)",
784 .dependencies = featureSet(&[_]Feature{}),
785 };
786 result[@intFromEnum(Feature.outline_atomics)] = .{
787 .llvm_name = "outline-atomics",
788 .description = "Enable out of line atomics to support LSE instructions",
789 .dependencies = featureSet(&[_]Feature{}),
790 };
791 result[@intFromEnum(Feature.pan)] = .{
792 .llvm_name = "pan",
793 .description = "Enables ARM v8.1 Privileged Access-Never extension (FEAT_PAN)",
794 .dependencies = featureSet(&[_]Feature{}),
795 };
796 result[@intFromEnum(Feature.pan_rwv)] = .{
797 .llvm_name = "pan-rwv",
798 .description = "Enable v8.2 PAN s1e1R and s1e1W Variants (FEAT_PAN2)",
799 .dependencies = featureSet(&[_]Feature{
800 .pan,
801 }),
802 };
803 result[@intFromEnum(Feature.pauth)] = .{
804 .llvm_name = "pauth",
805 .description = "Enable v8.3-A Pointer Authentication extension (FEAT_PAuth)",
806 .dependencies = featureSet(&[_]Feature{}),
807 };
808 result[@intFromEnum(Feature.perfmon)] = .{
809 .llvm_name = "perfmon",
810 .description = "Enable Code Generation for ARMv8 PMUv3 Performance Monitors extension (FEAT_PMUv3)",
811 .dependencies = featureSet(&[_]Feature{}),
812 };
813 result[@intFromEnum(Feature.predictable_select_expensive)] = .{
814 .llvm_name = "predictable-select-expensive",
815 .description = "Prefer likely predicted branches over selects",
816 .dependencies = featureSet(&[_]Feature{}),
817 };
818 result[@intFromEnum(Feature.predres)] = .{
819 .llvm_name = "predres",
820 .description = "Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)",
821 .dependencies = featureSet(&[_]Feature{}),
822 };
823 result[@intFromEnum(Feature.prfm_slc_target)] = .{
824 .llvm_name = "prfm-slc-target",
825 .description = "Enable SLC target for PRFM instruction",
826 .dependencies = featureSet(&[_]Feature{}),
827 };
828 result[@intFromEnum(Feature.rand)] = .{
829 .llvm_name = "rand",
830 .description = "Enable Random Number generation instructions (FEAT_RNG)",
831 .dependencies = featureSet(&[_]Feature{}),
832 };
833 result[@intFromEnum(Feature.ras)] = .{
834 .llvm_name = "ras",
835 .description = "Enable ARMv8 Reliability, Availability and Serviceability Extensions (FEAT_RAS, FEAT_RASv1p1)",
836 .dependencies = featureSet(&[_]Feature{}),
837 };
838 result[@intFromEnum(Feature.rasv2)] = .{
839 .llvm_name = "rasv2",
840 .description = "Enable ARMv8.9-A Reliability, Availability and Serviceability Extensions (FEAT_RASv2)",
841 .dependencies = featureSet(&[_]Feature{
842 .ras,
843 }),
844 };
845 result[@intFromEnum(Feature.rcpc)] = .{
846 .llvm_name = "rcpc",
847 .description = "Enable support for RCPC extension (FEAT_LRCPC)",
848 .dependencies = featureSet(&[_]Feature{}),
849 };
850 result[@intFromEnum(Feature.rcpc3)] = .{
851 .llvm_name = "rcpc3",
852 .description = "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)",
853 .dependencies = featureSet(&[_]Feature{
854 .rcpc_immo,
855 }),
856 };
857 result[@intFromEnum(Feature.rcpc_immo)] = .{
858 .llvm_name = "rcpc-immo",
859 .description = "Enable v8.4-A RCPC instructions with Immediate Offsets (FEAT_LRCPC2)",
860 .dependencies = featureSet(&[_]Feature{
861 .rcpc,
862 }),
863 };
864 result[@intFromEnum(Feature.rdm)] = .{
865 .llvm_name = "rdm",
866 .description = "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions (FEAT_RDM)",
867 .dependencies = featureSet(&[_]Feature{}),
868 };
869 result[@intFromEnum(Feature.reserve_x1)] = .{
870 .llvm_name = "reserve-x1",
871 .description = "Reserve X1, making it unavailable as a GPR",
872 .dependencies = featureSet(&[_]Feature{}),
873 };
874 result[@intFromEnum(Feature.reserve_x10)] = .{
875 .llvm_name = "reserve-x10",
876 .description = "Reserve X10, making it unavailable as a GPR",
877 .dependencies = featureSet(&[_]Feature{}),
878 };
879 result[@intFromEnum(Feature.reserve_x11)] = .{
880 .llvm_name = "reserve-x11",
881 .description = "Reserve X11, making it unavailable as a GPR",
882 .dependencies = featureSet(&[_]Feature{}),
883 };
884 result[@intFromEnum(Feature.reserve_x12)] = .{
885 .llvm_name = "reserve-x12",
886 .description = "Reserve X12, making it unavailable as a GPR",
887 .dependencies = featureSet(&[_]Feature{}),
888 };
889 result[@intFromEnum(Feature.reserve_x13)] = .{
890 .llvm_name = "reserve-x13",
891 .description = "Reserve X13, making it unavailable as a GPR",
892 .dependencies = featureSet(&[_]Feature{}),
893 };
894 result[@intFromEnum(Feature.reserve_x14)] = .{
895 .llvm_name = "reserve-x14",
896 .description = "Reserve X14, making it unavailable as a GPR",
897 .dependencies = featureSet(&[_]Feature{}),
898 };
899 result[@intFromEnum(Feature.reserve_x15)] = .{
900 .llvm_name = "reserve-x15",
901 .description = "Reserve X15, making it unavailable as a GPR",
902 .dependencies = featureSet(&[_]Feature{}),
903 };
904 result[@intFromEnum(Feature.reserve_x18)] = .{
905 .llvm_name = "reserve-x18",
906 .description = "Reserve X18, making it unavailable as a GPR",
907 .dependencies = featureSet(&[_]Feature{}),
908 };
909 result[@intFromEnum(Feature.reserve_x2)] = .{
910 .llvm_name = "reserve-x2",
911 .description = "Reserve X2, making it unavailable as a GPR",
912 .dependencies = featureSet(&[_]Feature{}),
913 };
914 result[@intFromEnum(Feature.reserve_x20)] = .{
915 .llvm_name = "reserve-x20",
916 .description = "Reserve X20, making it unavailable as a GPR",
917 .dependencies = featureSet(&[_]Feature{}),
918 };
919 result[@intFromEnum(Feature.reserve_x21)] = .{
920 .llvm_name = "reserve-x21",
921 .description = "Reserve X21, making it unavailable as a GPR",
922 .dependencies = featureSet(&[_]Feature{}),
923 };
924 result[@intFromEnum(Feature.reserve_x22)] = .{
925 .llvm_name = "reserve-x22",
926 .description = "Reserve X22, making it unavailable as a GPR",
927 .dependencies = featureSet(&[_]Feature{}),
928 };
929 result[@intFromEnum(Feature.reserve_x23)] = .{
930 .llvm_name = "reserve-x23",
931 .description = "Reserve X23, making it unavailable as a GPR",
932 .dependencies = featureSet(&[_]Feature{}),
933 };
934 result[@intFromEnum(Feature.reserve_x24)] = .{
935 .llvm_name = "reserve-x24",
936 .description = "Reserve X24, making it unavailable as a GPR",
937 .dependencies = featureSet(&[_]Feature{}),
938 };
939 result[@intFromEnum(Feature.reserve_x25)] = .{
940 .llvm_name = "reserve-x25",
941 .description = "Reserve X25, making it unavailable as a GPR",
942 .dependencies = featureSet(&[_]Feature{}),
943 };
944 result[@intFromEnum(Feature.reserve_x26)] = .{
945 .llvm_name = "reserve-x26",
946 .description = "Reserve X26, making it unavailable as a GPR",
947 .dependencies = featureSet(&[_]Feature{}),
948 };
949 result[@intFromEnum(Feature.reserve_x27)] = .{
950 .llvm_name = "reserve-x27",
951 .description = "Reserve X27, making it unavailable as a GPR",
952 .dependencies = featureSet(&[_]Feature{}),
953 };
954 result[@intFromEnum(Feature.reserve_x28)] = .{
955 .llvm_name = "reserve-x28",
956 .description = "Reserve X28, making it unavailable as a GPR",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.reserve_x3)] = .{
960 .llvm_name = "reserve-x3",
961 .description = "Reserve X3, making it unavailable as a GPR",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.reserve_x30)] = .{
965 .llvm_name = "reserve-x30",
966 .description = "Reserve X30, making it unavailable as a GPR",
967 .dependencies = featureSet(&[_]Feature{}),
968 };
969 result[@intFromEnum(Feature.reserve_x4)] = .{
970 .llvm_name = "reserve-x4",
971 .description = "Reserve X4, making it unavailable as a GPR",
972 .dependencies = featureSet(&[_]Feature{}),
973 };
974 result[@intFromEnum(Feature.reserve_x5)] = .{
975 .llvm_name = "reserve-x5",
976 .description = "Reserve X5, making it unavailable as a GPR",
977 .dependencies = featureSet(&[_]Feature{}),
978 };
979 result[@intFromEnum(Feature.reserve_x6)] = .{
980 .llvm_name = "reserve-x6",
981 .description = "Reserve X6, making it unavailable as a GPR",
982 .dependencies = featureSet(&[_]Feature{}),
983 };
984 result[@intFromEnum(Feature.reserve_x7)] = .{
985 .llvm_name = "reserve-x7",
986 .description = "Reserve X7, making it unavailable as a GPR",
987 .dependencies = featureSet(&[_]Feature{}),
988 };
989 result[@intFromEnum(Feature.reserve_x9)] = .{
990 .llvm_name = "reserve-x9",
991 .description = "Reserve X9, making it unavailable as a GPR",
992 .dependencies = featureSet(&[_]Feature{}),
993 };
994 result[@intFromEnum(Feature.rme)] = .{
995 .llvm_name = "rme",
996 .description = "Enable Realm Management Extension (FEAT_RME)",
997 .dependencies = featureSet(&[_]Feature{}),
998 };
999 result[@intFromEnum(Feature.sb)] = .{
1000 .llvm_name = "sb",
1001 .description = "Enable v8.5 Speculation Barrier (FEAT_SB)",
1002 .dependencies = featureSet(&[_]Feature{}),
1003 };
1004 result[@intFromEnum(Feature.sel2)] = .{
1005 .llvm_name = "sel2",
1006 .description = "Enable v8.4-A Secure Exception Level 2 extension (FEAT_SEL2)",
1007 .dependencies = featureSet(&[_]Feature{}),
1008 };
1009 result[@intFromEnum(Feature.sha2)] = .{
1010 .llvm_name = "sha2",
1011 .description = "Enable SHA1 and SHA256 support (FEAT_SHA1, FEAT_SHA256)",
1012 .dependencies = featureSet(&[_]Feature{
1013 .neon,
1014 }),
1015 };
1016 result[@intFromEnum(Feature.sha3)] = .{
1017 .llvm_name = "sha3",
1018 .description = "Enable SHA512 and SHA3 support (FEAT_SHA3, FEAT_SHA512)",
1019 .dependencies = featureSet(&[_]Feature{
1020 .sha2,
1021 }),
1022 };
1023 result[@intFromEnum(Feature.slow_misaligned_128store)] = .{
1024 .llvm_name = "slow-misaligned-128store",
1025 .description = "Misaligned 128 bit stores are slow",
1026 .dependencies = featureSet(&[_]Feature{}),
1027 };
1028 result[@intFromEnum(Feature.slow_paired_128)] = .{
1029 .llvm_name = "slow-paired-128",
1030 .description = "Paired 128 bit loads and stores are slow",
1031 .dependencies = featureSet(&[_]Feature{}),
1032 };
1033 result[@intFromEnum(Feature.slow_strqro_store)] = .{
1034 .llvm_name = "slow-strqro-store",
1035 .description = "STR of Q register with register offset is slow",
1036 .dependencies = featureSet(&[_]Feature{}),
1037 };
1038 result[@intFromEnum(Feature.sm4)] = .{
1039 .llvm_name = "sm4",
1040 .description = "Enable SM3 and SM4 support (FEAT_SM4, FEAT_SM3)",
1041 .dependencies = featureSet(&[_]Feature{
1042 .neon,
1043 }),
1044 };
1045 result[@intFromEnum(Feature.sme)] = .{
1046 .llvm_name = "sme",
1047 .description = "Enable Scalable Matrix Extension (SME) (FEAT_SME)",
1048 .dependencies = featureSet(&[_]Feature{
1049 .bf16,
1050 .use_scalar_inc_vl,
1051 }),
1052 };
1053 result[@intFromEnum(Feature.sme2)] = .{
1054 .llvm_name = "sme2",
1055 .description = "Enable Scalable Matrix Extension 2 (SME2) instructions",
1056 .dependencies = featureSet(&[_]Feature{
1057 .sme,
1058 }),
1059 };
1060 result[@intFromEnum(Feature.sme2p1)] = .{
1061 .llvm_name = "sme2p1",
1062 .description = "Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions",
1063 .dependencies = featureSet(&[_]Feature{
1064 .sme2,
1065 }),
1066 };
1067 result[@intFromEnum(Feature.sme_f16f16)] = .{
1068 .llvm_name = "sme-f16f16",
1069 .description = "Enable SME2.1 non-widening Float16 instructions (FEAT_SME_F16F16)",
1070 .dependencies = featureSet(&[_]Feature{}),
1071 };
1072 result[@intFromEnum(Feature.sme_f64f64)] = .{
1073 .llvm_name = "sme-f64f64",
1074 .description = "Enable Scalable Matrix Extension (SME) F64F64 instructions (FEAT_SME_F64F64)",
1075 .dependencies = featureSet(&[_]Feature{
1076 .sme,
1077 }),
1078 };
1079 result[@intFromEnum(Feature.sme_i16i64)] = .{
1080 .llvm_name = "sme-i16i64",
1081 .description = "Enable Scalable Matrix Extension (SME) I16I64 instructions (FEAT_SME_I16I64)",
1082 .dependencies = featureSet(&[_]Feature{
1083 .sme,
1084 }),
1085 };
1086 result[@intFromEnum(Feature.spe)] = .{
1087 .llvm_name = "spe",
1088 .description = "Enable Statistical Profiling extension (FEAT_SPE)",
1089 .dependencies = featureSet(&[_]Feature{}),
1090 };
1091 result[@intFromEnum(Feature.spe_eef)] = .{
1092 .llvm_name = "spe-eef",
1093 .description = "Enable extra register in the Statistical Profiling Extension (FEAT_SPEv1p2)",
1094 .dependencies = featureSet(&[_]Feature{}),
1095 };
1096 result[@intFromEnum(Feature.specres2)] = .{
1097 .llvm_name = "specres2",
1098 .description = "Enable Speculation Restriction Instruction (FEAT_SPECRES2)",
1099 .dependencies = featureSet(&[_]Feature{
1100 .predres,
1101 }),
1102 };
1103 result[@intFromEnum(Feature.specrestrict)] = .{
1104 .llvm_name = "specrestrict",
1105 .description = "Enable architectural speculation restriction (FEAT_CSV2_2)",
1106 .dependencies = featureSet(&[_]Feature{}),
1107 };
1108 result[@intFromEnum(Feature.ssbs)] = .{
1109 .llvm_name = "ssbs",
1110 .description = "Enable Speculative Store Bypass Safe bit (FEAT_SSBS, FEAT_SSBS2)",
1111 .dependencies = featureSet(&[_]Feature{}),
1112 };
1113 result[@intFromEnum(Feature.strict_align)] = .{
1114 .llvm_name = "strict-align",
1115 .description = "Disallow all unaligned memory access",
1116 .dependencies = featureSet(&[_]Feature{}),
1117 };
1118 result[@intFromEnum(Feature.sve)] = .{
1119 .llvm_name = "sve",
1120 .description = "Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)",
1121 .dependencies = featureSet(&[_]Feature{
1122 .fullfp16,
1123 }),
1124 };
1125 result[@intFromEnum(Feature.sve2)] = .{
1126 .llvm_name = "sve2",
1127 .description = "Enable Scalable Vector Extension 2 (SVE2) instructions (FEAT_SVE2)",
1128 .dependencies = featureSet(&[_]Feature{
1129 .sve,
1130 .use_scalar_inc_vl,
1131 }),
1132 };
1133 result[@intFromEnum(Feature.sve2_aes)] = .{
1134 .llvm_name = "sve2-aes",
1135 .description = "Enable AES SVE2 instructions (FEAT_SVE_AES, FEAT_SVE_PMULL128)",
1136 .dependencies = featureSet(&[_]Feature{
1137 .aes,
1138 .sve2,
1139 }),
1140 };
1141 result[@intFromEnum(Feature.sve2_bitperm)] = .{
1142 .llvm_name = "sve2-bitperm",
1143 .description = "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)",
1144 .dependencies = featureSet(&[_]Feature{
1145 .sve2,
1146 }),
1147 };
1148 result[@intFromEnum(Feature.sve2_sha3)] = .{
1149 .llvm_name = "sve2-sha3",
1150 .description = "Enable SHA3 SVE2 instructions (FEAT_SVE_SHA3)",
1151 .dependencies = featureSet(&[_]Feature{
1152 .sha3,
1153 .sve2,
1154 }),
1155 };
1156 result[@intFromEnum(Feature.sve2_sm4)] = .{
1157 .llvm_name = "sve2-sm4",
1158 .description = "Enable SM4 SVE2 instructions (FEAT_SVE_SM4)",
1159 .dependencies = featureSet(&[_]Feature{
1160 .sm4,
1161 .sve2,
1162 }),
1163 };
1164 result[@intFromEnum(Feature.sve2p1)] = .{
1165 .llvm_name = "sve2p1",
1166 .description = "Enable Scalable Vector Extension 2.1 instructions",
1167 .dependencies = featureSet(&[_]Feature{
1168 .sve2,
1169 }),
1170 };
1171 result[@intFromEnum(Feature.tagged_globals)] = .{
1172 .llvm_name = "tagged-globals",
1173 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",
1174 .dependencies = featureSet(&[_]Feature{}),
1175 };
1176 result[@intFromEnum(Feature.the)] = .{
1177 .llvm_name = "the",
1178 .description = "Enable Armv8.9-A Translation Hardening Extension (FEAT_THE)",
1179 .dependencies = featureSet(&[_]Feature{}),
1180 };
1181 result[@intFromEnum(Feature.tlb_rmi)] = .{
1182 .llvm_name = "tlb-rmi",
1183 .description = "Enable v8.4-A TLB Range and Maintenance Instructions (FEAT_TLBIOS, FEAT_TLBIRANGE)",
1184 .dependencies = featureSet(&[_]Feature{}),
1185 };
1186 result[@intFromEnum(Feature.tme)] = .{
1187 .llvm_name = "tme",
1188 .description = "Enable Transactional Memory Extension (FEAT_TME)",
1189 .dependencies = featureSet(&[_]Feature{}),
1190 };
1191 result[@intFromEnum(Feature.tpidr_el1)] = .{
1192 .llvm_name = "tpidr-el1",
1193 .description = "Permit use of TPIDR_EL1 for the TLS base",
1194 .dependencies = featureSet(&[_]Feature{}),
1195 };
1196 result[@intFromEnum(Feature.tpidr_el2)] = .{
1197 .llvm_name = "tpidr-el2",
1198 .description = "Permit use of TPIDR_EL2 for the TLS base",
1199 .dependencies = featureSet(&[_]Feature{}),
1200 };
1201 result[@intFromEnum(Feature.tpidr_el3)] = .{
1202 .llvm_name = "tpidr-el3",
1203 .description = "Permit use of TPIDR_EL3 for the TLS base",
1204 .dependencies = featureSet(&[_]Feature{}),
1205 };
1206 result[@intFromEnum(Feature.tpidrro_el0)] = .{
1207 .llvm_name = "tpidrro-el0",
1208 .description = "Permit use of TPIDRRO_EL0 for the TLS base",
1209 .dependencies = featureSet(&[_]Feature{}),
1210 };
1211 result[@intFromEnum(Feature.tracev8_4)] = .{
1212 .llvm_name = "tracev8.4",
1213 .description = "Enable v8.4-A Trace extension (FEAT_TRF)",
1214 .dependencies = featureSet(&[_]Feature{}),
1215 };
1216 result[@intFromEnum(Feature.trbe)] = .{
1217 .llvm_name = "trbe",
1218 .description = "Enable Trace Buffer Extension (FEAT_TRBE)",
1219 .dependencies = featureSet(&[_]Feature{}),
1220 };
1221 result[@intFromEnum(Feature.uaops)] = .{
1222 .llvm_name = "uaops",
1223 .description = "Enable v8.2 UAO PState (FEAT_UAO)",
1224 .dependencies = featureSet(&[_]Feature{}),
1225 };
1226 result[@intFromEnum(Feature.use_experimental_zeroing_pseudos)] = .{
1227 .llvm_name = "use-experimental-zeroing-pseudos",
1228 .description = "Hint to the compiler that the MOVPRFX instruction is merged with destructive operations",
1229 .dependencies = featureSet(&[_]Feature{}),
1230 };
1231 result[@intFromEnum(Feature.use_postra_scheduler)] = .{
1232 .llvm_name = "use-postra-scheduler",
1233 .description = "Schedule again after register allocation",
1234 .dependencies = featureSet(&[_]Feature{}),
1235 };
1236 result[@intFromEnum(Feature.use_reciprocal_square_root)] = .{
1237 .llvm_name = "use-reciprocal-square-root",
1238 .description = "Use the reciprocal square root approximation",
1239 .dependencies = featureSet(&[_]Feature{}),
1240 };
1241 result[@intFromEnum(Feature.use_scalar_inc_vl)] = .{
1242 .llvm_name = "use-scalar-inc-vl",
1243 .description = "Prefer inc/dec over add+cnt",
1244 .dependencies = featureSet(&[_]Feature{}),
1245 };
1246 result[@intFromEnum(Feature.v8_1a)] = .{
1247 .llvm_name = "v8.1a",
1248 .description = "Support ARM v8.1a instructions",
1249 .dependencies = featureSet(&[_]Feature{
1250 .crc,
1251 .lor,
1252 .lse,
1253 .pan,
1254 .rdm,
1255 .v8a,
1256 .vh,
1257 }),
1258 };
1259 result[@intFromEnum(Feature.v8_2a)] = .{
1260 .llvm_name = "v8.2a",
1261 .description = "Support ARM v8.2a instructions",
1262 .dependencies = featureSet(&[_]Feature{
1263 .ccpp,
1264 .pan_rwv,
1265 .ras,
1266 .uaops,
1267 .v8_1a,
1268 }),
1269 };
1270 result[@intFromEnum(Feature.v8_3a)] = .{
1271 .llvm_name = "v8.3a",
1272 .description = "Support ARM v8.3a instructions",
1273 .dependencies = featureSet(&[_]Feature{
1274 .ccidx,
1275 .complxnum,
1276 .jsconv,
1277 .pauth,
1278 .rcpc,
1279 .v8_2a,
1280 }),
1281 };
1282 result[@intFromEnum(Feature.v8_4a)] = .{
1283 .llvm_name = "v8.4a",
1284 .description = "Support ARM v8.4a instructions",
1285 .dependencies = featureSet(&[_]Feature{
1286 .am,
1287 .dit,
1288 .dotprod,
1289 .flagm,
1290 .lse2,
1291 .mpam,
1292 .nv,
1293 .rcpc_immo,
1294 .sel2,
1295 .tlb_rmi,
1296 .tracev8_4,
1297 .v8_3a,
1298 }),
1299 };
1300 result[@intFromEnum(Feature.v8_5a)] = .{
1301 .llvm_name = "v8.5a",
1302 .description = "Support ARM v8.5a instructions",
1303 .dependencies = featureSet(&[_]Feature{
1304 .altnzcv,
1305 .bti,
1306 .ccdp,
1307 .fptoint,
1308 .predres,
1309 .sb,
1310 .specrestrict,
1311 .ssbs,
1312 .v8_4a,
1313 }),
1314 };
1315 result[@intFromEnum(Feature.v8_6a)] = .{
1316 .llvm_name = "v8.6a",
1317 .description = "Support ARM v8.6a instructions",
1318 .dependencies = featureSet(&[_]Feature{
1319 .amvs,
1320 .bf16,
1321 .ecv,
1322 .fgt,
1323 .i8mm,
1324 .v8_5a,
1325 }),
1326 };
1327 result[@intFromEnum(Feature.v8_7a)] = .{
1328 .llvm_name = "v8.7a",
1329 .description = "Support ARM v8.7a instructions",
1330 .dependencies = featureSet(&[_]Feature{
1331 .hcx,
1332 .v8_6a,
1333 .wfxt,
1334 .xs,
1335 }),
1336 };
1337 result[@intFromEnum(Feature.v8_8a)] = .{
1338 .llvm_name = "v8.8a",
1339 .description = "Support ARM v8.8a instructions",
1340 .dependencies = featureSet(&[_]Feature{
1341 .hbc,
1342 .mops,
1343 .nmi,
1344 .v8_7a,
1345 }),
1346 };
1347 result[@intFromEnum(Feature.v8_9a)] = .{
1348 .llvm_name = "v8.9a",
1349 .description = "Support ARM v8.9a instructions",
1350 .dependencies = featureSet(&[_]Feature{
1351 .chk,
1352 .clrbhb,
1353 .cssc,
1354 .prfm_slc_target,
1355 .rasv2,
1356 .specres2,
1357 .v8_8a,
1358 }),
1359 };
1360 result[@intFromEnum(Feature.v8a)] = .{
1361 .llvm_name = "v8a",
1362 .description = "Support ARM v8.0a instructions",
1363 .dependencies = featureSet(&[_]Feature{
1364 .el2vmsa,
1365 .el3,
1366 .neon,
1367 }),
1368 };
1369 result[@intFromEnum(Feature.v8r)] = .{
1370 .llvm_name = "v8r",
1371 .description = "Support ARM v8r instructions",
1372 .dependencies = featureSet(&[_]Feature{
1373 .ccidx,
1374 .ccpp,
1375 .complxnum,
1376 .contextidr_el2,
1377 .crc,
1378 .dit,
1379 .dotprod,
1380 .flagm,
1381 .jsconv,
1382 .lse,
1383 .pan_rwv,
1384 .pauth,
1385 .ras,
1386 .rcpc_immo,
1387 .rdm,
1388 .sel2,
1389 .specrestrict,
1390 .tlb_rmi,
1391 .tracev8_4,
1392 .uaops,
1393 }),
1394 };
1395 result[@intFromEnum(Feature.v9_1a)] = .{
1396 .llvm_name = "v9.1a",
1397 .description = "Support ARM v9.1a instructions",
1398 .dependencies = featureSet(&[_]Feature{
1399 .v8_6a,
1400 .v9a,
1401 }),
1402 };
1403 result[@intFromEnum(Feature.v9_2a)] = .{
1404 .llvm_name = "v9.2a",
1405 .description = "Support ARM v9.2a instructions",
1406 .dependencies = featureSet(&[_]Feature{
1407 .v8_7a,
1408 .v9_1a,
1409 }),
1410 };
1411 result[@intFromEnum(Feature.v9_3a)] = .{
1412 .llvm_name = "v9.3a",
1413 .description = "Support ARM v9.3a instructions",
1414 .dependencies = featureSet(&[_]Feature{
1415 .v8_8a,
1416 .v9_2a,
1417 }),
1418 };
1419 result[@intFromEnum(Feature.v9_4a)] = .{
1420 .llvm_name = "v9.4a",
1421 .description = "Support ARM v9.4a instructions",
1422 .dependencies = featureSet(&[_]Feature{
1423 .v8_9a,
1424 .v9_3a,
1425 }),
1426 };
1427 result[@intFromEnum(Feature.v9a)] = .{
1428 .llvm_name = "v9a",
1429 .description = "Support ARM v9a instructions",
1430 .dependencies = featureSet(&[_]Feature{
1431 .mec,
1432 .sve2,
1433 .v8_5a,
1434 }),
1435 };
1436 result[@intFromEnum(Feature.vh)] = .{
1437 .llvm_name = "vh",
1438 .description = "Enables ARM v8.1 Virtual Host extension (FEAT_VHE)",
1439 .dependencies = featureSet(&[_]Feature{
1440 .contextidr_el2,
1441 }),
1442 };
1443 result[@intFromEnum(Feature.wfxt)] = .{
1444 .llvm_name = "wfxt",
1445 .description = "Enable Armv8.7-A WFET and WFIT instruction (FEAT_WFxT)",
1446 .dependencies = featureSet(&[_]Feature{}),
1447 };
1448 result[@intFromEnum(Feature.xs)] = .{
1449 .llvm_name = "xs",
1450 .description = "Enable Armv8.7-A limited-TLB-maintenance instruction (FEAT_XS)",
1451 .dependencies = featureSet(&[_]Feature{}),
1452 };
1453 result[@intFromEnum(Feature.zcm)] = .{
1454 .llvm_name = "zcm",
1455 .description = "Has zero-cycle register moves",
1456 .dependencies = featureSet(&[_]Feature{}),
1457 };
1458 result[@intFromEnum(Feature.zcz)] = .{
1459 .llvm_name = "zcz",
1460 .description = "Has zero-cycle zeroing instructions",
1461 .dependencies = featureSet(&[_]Feature{
1462 .zcz_gp,
1463 }),
1464 };
1465 result[@intFromEnum(Feature.zcz_fp_workaround)] = .{
1466 .llvm_name = "zcz-fp-workaround",
1467 .description = "The zero-cycle floating-point zeroing instruction has a bug",
1468 .dependencies = featureSet(&[_]Feature{}),
1469 };
1470 result[@intFromEnum(Feature.zcz_gp)] = .{
1471 .llvm_name = "zcz-gp",
1472 .description = "Has zero-cycle zeroing instructions for generic registers",
1473 .dependencies = featureSet(&[_]Feature{}),
1474 };
1475 const ti = @typeInfo(Feature);
1476 for (&result, 0..) |*elem, i| {
1477 elem.index = i;
1478 elem.name = ti.Enum.fields[i].name;
1479 }
1480 break :blk result;
1481};
1482
1483pub const cpu = struct {
1484 pub const a64fx = CpuModel{
1485 .name = "a64fx",
1486 .llvm_name = "a64fx",
1487 .features = featureSet(&[_]Feature{
1488 .aggressive_fma,
1489 .arith_bcc_fusion,
1490 .complxnum,
1491 .perfmon,
1492 .predictable_select_expensive,
1493 .sha2,
1494 .sve,
1495 .use_postra_scheduler,
1496 .v8_2a,
1497 }),
1498 };
1499 pub const ampere1 = CpuModel{
1500 .name = "ampere1",
1501 .llvm_name = "ampere1",
1502 .features = featureSet(&[_]Feature{
1503 .aes,
1504 .aggressive_fma,
1505 .arith_bcc_fusion,
1506 .cmp_bcc_fusion,
1507 .fuse_address,
1508 .fuse_aes,
1509 .fuse_literals,
1510 .lsl_fast,
1511 .perfmon,
1512 .rand,
1513 .sha3,
1514 .use_postra_scheduler,
1515 .v8_6a,
1516 }),
1517 };
1518 pub const ampere1a = CpuModel{
1519 .name = "ampere1a",
1520 .llvm_name = "ampere1a",
1521 .features = featureSet(&[_]Feature{
1522 .aes,
1523 .aggressive_fma,
1524 .arith_bcc_fusion,
1525 .cmp_bcc_fusion,
1526 .fuse_address,
1527 .fuse_aes,
1528 .fuse_literals,
1529 .lsl_fast,
1530 .mte,
1531 .perfmon,
1532 .rand,
1533 .sha3,
1534 .sm4,
1535 .use_postra_scheduler,
1536 .v8_6a,
1537 }),
1538 };
1539 pub const apple_a10 = CpuModel{
1540 .name = "apple_a10",
1541 .llvm_name = "apple-a10",
1542 .features = featureSet(&[_]Feature{
1543 .alternate_sextload_cvt_f32_pattern,
1544 .arith_bcc_fusion,
1545 .arith_cbz_fusion,
1546 .crc,
1547 .crypto,
1548 .disable_latency_sched_heuristic,
1549 .fuse_aes,
1550 .fuse_crypto_eor,
1551 .lor,
1552 .pan,
1553 .perfmon,
1554 .rdm,
1555 .v8a,
1556 .vh,
1557 .zcm,
1558 .zcz,
1559 }),
1560 };
1561 pub const apple_a11 = CpuModel{
1562 .name = "apple_a11",
1563 .llvm_name = "apple-a11",
1564 .features = featureSet(&[_]Feature{
1565 .alternate_sextload_cvt_f32_pattern,
1566 .arith_bcc_fusion,
1567 .arith_cbz_fusion,
1568 .crypto,
1569 .disable_latency_sched_heuristic,
1570 .fullfp16,
1571 .fuse_aes,
1572 .fuse_crypto_eor,
1573 .perfmon,
1574 .v8_2a,
1575 .zcm,
1576 .zcz,
1577 }),
1578 };
1579 pub const apple_a12 = CpuModel{
1580 .name = "apple_a12",
1581 .llvm_name = "apple-a12",
1582 .features = featureSet(&[_]Feature{
1583 .alternate_sextload_cvt_f32_pattern,
1584 .arith_bcc_fusion,
1585 .arith_cbz_fusion,
1586 .crypto,
1587 .disable_latency_sched_heuristic,
1588 .fullfp16,
1589 .fuse_aes,
1590 .fuse_crypto_eor,
1591 .perfmon,
1592 .v8_3a,
1593 .zcm,
1594 .zcz,
1595 }),
1596 };
1597 pub const apple_a13 = CpuModel{
1598 .name = "apple_a13",
1599 .llvm_name = "apple-a13",
1600 .features = featureSet(&[_]Feature{
1601 .alternate_sextload_cvt_f32_pattern,
1602 .arith_bcc_fusion,
1603 .arith_cbz_fusion,
1604 .crypto,
1605 .disable_latency_sched_heuristic,
1606 .fp16fml,
1607 .fuse_aes,
1608 .fuse_crypto_eor,
1609 .perfmon,
1610 .sha3,
1611 .v8_4a,
1612 .zcm,
1613 .zcz,
1614 }),
1615 };
1616 pub const apple_a14 = CpuModel{
1617 .name = "apple_a14",
1618 .llvm_name = "apple-a14",
1619 .features = featureSet(&[_]Feature{
1620 .aggressive_fma,
1621 .alternate_sextload_cvt_f32_pattern,
1622 .altnzcv,
1623 .arith_bcc_fusion,
1624 .arith_cbz_fusion,
1625 .ccdp,
1626 .crypto,
1627 .disable_latency_sched_heuristic,
1628 .fp16fml,
1629 .fptoint,
1630 .fuse_address,
1631 .fuse_adrp_add,
1632 .fuse_aes,
1633 .fuse_arith_logic,
1634 .fuse_crypto_eor,
1635 .fuse_csel,
1636 .fuse_literals,
1637 .perfmon,
1638 .predres,
1639 .sb,
1640 .sha3,
1641 .specrestrict,
1642 .ssbs,
1643 .v8_4a,
1644 .zcm,
1645 .zcz,
1646 }),
1647 };
1648 pub const apple_a15 = CpuModel{
1649 .name = "apple_a15",
1650 .llvm_name = "apple-a15",
1651 .features = featureSet(&[_]Feature{
1652 .alternate_sextload_cvt_f32_pattern,
1653 .arith_bcc_fusion,
1654 .arith_cbz_fusion,
1655 .crypto,
1656 .disable_latency_sched_heuristic,
1657 .fp16fml,
1658 .fuse_address,
1659 .fuse_aes,
1660 .fuse_arith_logic,
1661 .fuse_crypto_eor,
1662 .fuse_csel,
1663 .fuse_literals,
1664 .perfmon,
1665 .sha3,
1666 .v8_6a,
1667 .zcm,
1668 .zcz,
1669 }),
1670 };
1671 pub const apple_a16 = CpuModel{
1672 .name = "apple_a16",
1673 .llvm_name = "apple-a16",
1674 .features = featureSet(&[_]Feature{
1675 .alternate_sextload_cvt_f32_pattern,
1676 .arith_bcc_fusion,
1677 .arith_cbz_fusion,
1678 .crypto,
1679 .disable_latency_sched_heuristic,
1680 .fp16fml,
1681 .fuse_address,
1682 .fuse_aes,
1683 .fuse_arith_logic,
1684 .fuse_crypto_eor,
1685 .fuse_csel,
1686 .fuse_literals,
1687 .hcx,
1688 .perfmon,
1689 .sha3,
1690 .v8_6a,
1691 .zcm,
1692 .zcz,
1693 }),
1694 };
1695 pub const apple_a7 = CpuModel{
1696 .name = "apple_a7",
1697 .llvm_name = "apple-a7",
1698 .features = featureSet(&[_]Feature{
1699 .alternate_sextload_cvt_f32_pattern,
1700 .arith_bcc_fusion,
1701 .arith_cbz_fusion,
1702 .crypto,
1703 .disable_latency_sched_heuristic,
1704 .fuse_aes,
1705 .fuse_crypto_eor,
1706 .perfmon,
1707 .v8a,
1708 .zcm,
1709 .zcz,
1710 .zcz_fp_workaround,
1711 }),
1712 };
1713 pub const apple_a8 = CpuModel{
1714 .name = "apple_a8",
1715 .llvm_name = "apple-a8",
1716 .features = featureSet(&[_]Feature{
1717 .alternate_sextload_cvt_f32_pattern,
1718 .arith_bcc_fusion,
1719 .arith_cbz_fusion,
1720 .crypto,
1721 .disable_latency_sched_heuristic,
1722 .fuse_aes,
1723 .fuse_crypto_eor,
1724 .perfmon,
1725 .v8a,
1726 .zcm,
1727 .zcz,
1728 .zcz_fp_workaround,
1729 }),
1730 };
1731 pub const apple_a9 = CpuModel{
1732 .name = "apple_a9",
1733 .llvm_name = "apple-a9",
1734 .features = featureSet(&[_]Feature{
1735 .alternate_sextload_cvt_f32_pattern,
1736 .arith_bcc_fusion,
1737 .arith_cbz_fusion,
1738 .crypto,
1739 .disable_latency_sched_heuristic,
1740 .fuse_aes,
1741 .fuse_crypto_eor,
1742 .perfmon,
1743 .v8a,
1744 .zcm,
1745 .zcz,
1746 .zcz_fp_workaround,
1747 }),
1748 };
1749 pub const apple_latest = CpuModel{
1750 .name = "apple_latest",
1751 .llvm_name = "apple-latest",
1752 .features = featureSet(&[_]Feature{
1753 .alternate_sextload_cvt_f32_pattern,
1754 .arith_bcc_fusion,
1755 .arith_cbz_fusion,
1756 .crypto,
1757 .disable_latency_sched_heuristic,
1758 .fp16fml,
1759 .fuse_address,
1760 .fuse_aes,
1761 .fuse_arith_logic,
1762 .fuse_crypto_eor,
1763 .fuse_csel,
1764 .fuse_literals,
1765 .hcx,
1766 .perfmon,
1767 .sha3,
1768 .v8_6a,
1769 .zcm,
1770 .zcz,
1771 }),
1772 };
1773 pub const apple_m1 = CpuModel{
1774 .name = "apple_m1",
1775 .llvm_name = "apple-m1",
1776 .features = featureSet(&[_]Feature{
1777 .aggressive_fma,
1778 .alternate_sextload_cvt_f32_pattern,
1779 .altnzcv,
1780 .arith_bcc_fusion,
1781 .arith_cbz_fusion,
1782 .ccdp,
1783 .crypto,
1784 .disable_latency_sched_heuristic,
1785 .fp16fml,
1786 .fptoint,
1787 .fuse_address,
1788 .fuse_adrp_add,
1789 .fuse_aes,
1790 .fuse_arith_logic,
1791 .fuse_crypto_eor,
1792 .fuse_csel,
1793 .fuse_literals,
1794 .perfmon,
1795 .predres,
1796 .sb,
1797 .sha3,
1798 .specrestrict,
1799 .ssbs,
1800 .v8_4a,
1801 .zcm,
1802 .zcz,
1803 }),
1804 };
1805 pub const apple_m2 = CpuModel{
1806 .name = "apple_m2",
1807 .llvm_name = "apple-m2",
1808 .features = featureSet(&[_]Feature{
1809 .alternate_sextload_cvt_f32_pattern,
1810 .arith_bcc_fusion,
1811 .arith_cbz_fusion,
1812 .crypto,
1813 .disable_latency_sched_heuristic,
1814 .fp16fml,
1815 .fuse_address,
1816 .fuse_aes,
1817 .fuse_arith_logic,
1818 .fuse_crypto_eor,
1819 .fuse_csel,
1820 .fuse_literals,
1821 .perfmon,
1822 .sha3,
1823 .v8_6a,
1824 .zcm,
1825 .zcz,
1826 }),
1827 };
1828 pub const apple_s4 = CpuModel{
1829 .name = "apple_s4",
1830 .llvm_name = "apple-s4",
1831 .features = featureSet(&[_]Feature{
1832 .alternate_sextload_cvt_f32_pattern,
1833 .arith_bcc_fusion,
1834 .arith_cbz_fusion,
1835 .crypto,
1836 .disable_latency_sched_heuristic,
1837 .fullfp16,
1838 .fuse_aes,
1839 .fuse_crypto_eor,
1840 .perfmon,
1841 .v8_3a,
1842 .zcm,
1843 .zcz,
1844 }),
1845 };
1846 pub const apple_s5 = CpuModel{
1847 .name = "apple_s5",
1848 .llvm_name = "apple-s5",
1849 .features = featureSet(&[_]Feature{
1850 .alternate_sextload_cvt_f32_pattern,
1851 .arith_bcc_fusion,
1852 .arith_cbz_fusion,
1853 .crypto,
1854 .disable_latency_sched_heuristic,
1855 .fullfp16,
1856 .fuse_aes,
1857 .fuse_crypto_eor,
1858 .perfmon,
1859 .v8_3a,
1860 .zcm,
1861 .zcz,
1862 }),
1863 };
1864 pub const carmel = CpuModel{
1865 .name = "carmel",
1866 .llvm_name = "carmel",
1867 .features = featureSet(&[_]Feature{
1868 .crypto,
1869 .fullfp16,
1870 .v8_2a,
1871 }),
1872 };
1873 pub const cortex_a34 = CpuModel{
1874 .name = "cortex_a34",
1875 .llvm_name = "cortex-a34",
1876 .features = featureSet(&[_]Feature{
1877 .crc,
1878 .crypto,
1879 .perfmon,
1880 .v8a,
1881 }),
1882 };
1883 pub const cortex_a35 = CpuModel{
1884 .name = "cortex_a35",
1885 .llvm_name = "cortex-a35",
1886 .features = featureSet(&[_]Feature{
1887 .crc,
1888 .crypto,
1889 .perfmon,
1890 .v8a,
1891 }),
1892 };
1893 pub const cortex_a510 = CpuModel{
1894 .name = "cortex_a510",
1895 .llvm_name = "cortex-a510",
1896 .features = featureSet(&[_]Feature{
1897 .a510,
1898 .bf16,
1899 .ete,
1900 .fp16fml,
1901 .i8mm,
1902 .mte,
1903 .perfmon,
1904 .sve2_bitperm,
1905 .v9a,
1906 }),
1907 };
1908 pub const cortex_a53 = CpuModel{
1909 .name = "cortex_a53",
1910 .llvm_name = "cortex-a53",
1911 .features = featureSet(&[_]Feature{
1912 .balance_fp_ops,
1913 .crc,
1914 .crypto,
1915 .custom_cheap_as_move,
1916 .fuse_adrp_add,
1917 .fuse_aes,
1918 .perfmon,
1919 .use_postra_scheduler,
1920 .v8a,
1921 }),
1922 };
1923 pub const cortex_a55 = CpuModel{
1924 .name = "cortex_a55",
1925 .llvm_name = "cortex-a55",
1926 .features = featureSet(&[_]Feature{
1927 .crypto,
1928 .dotprod,
1929 .fullfp16,
1930 .fuse_address,
1931 .fuse_adrp_add,
1932 .fuse_aes,
1933 .perfmon,
1934 .rcpc,
1935 .use_postra_scheduler,
1936 .v8_2a,
1937 }),
1938 };
1939 pub const cortex_a57 = CpuModel{
1940 .name = "cortex_a57",
1941 .llvm_name = "cortex-a57",
1942 .features = featureSet(&[_]Feature{
1943 .balance_fp_ops,
1944 .crc,
1945 .crypto,
1946 .custom_cheap_as_move,
1947 .enable_select_opt,
1948 .fuse_adrp_add,
1949 .fuse_aes,
1950 .fuse_literals,
1951 .perfmon,
1952 .predictable_select_expensive,
1953 .use_postra_scheduler,
1954 .v8a,
1955 }),
1956 };
1957 pub const cortex_a65 = CpuModel{
1958 .name = "cortex_a65",
1959 .llvm_name = "cortex-a65",
1960 .features = featureSet(&[_]Feature{
1961 .a65,
1962 .crypto,
1963 .dotprod,
1964 .fullfp16,
1965 .perfmon,
1966 .rcpc,
1967 .ssbs,
1968 .v8_2a,
1969 }),
1970 };
1971 pub const cortex_a65ae = CpuModel{
1972 .name = "cortex_a65ae",
1973 .llvm_name = "cortex-a65ae",
1974 .features = featureSet(&[_]Feature{
1975 .a65,
1976 .crypto,
1977 .dotprod,
1978 .fullfp16,
1979 .perfmon,
1980 .rcpc,
1981 .ssbs,
1982 .v8_2a,
1983 }),
1984 };
1985 pub const cortex_a710 = CpuModel{
1986 .name = "cortex_a710",
1987 .llvm_name = "cortex-a710",
1988 .features = featureSet(&[_]Feature{
1989 .a710,
1990 .bf16,
1991 .ete,
1992 .fp16fml,
1993 .i8mm,
1994 .mte,
1995 .perfmon,
1996 .sve2_bitperm,
1997 .v9a,
1998 }),
1999 };
2000 pub const cortex_a715 = CpuModel{
2001 .name = "cortex_a715",
2002 .llvm_name = "cortex-a715",
2003 .features = featureSet(&[_]Feature{
2004 .bf16,
2005 .cmp_bcc_fusion,
2006 .enable_select_opt,
2007 .ete,
2008 .fp16fml,
2009 .fuse_adrp_add,
2010 .fuse_aes,
2011 .i8mm,
2012 .lsl_fast,
2013 .mte,
2014 .perfmon,
2015 .predictable_select_expensive,
2016 .spe,
2017 .sve2_bitperm,
2018 .use_postra_scheduler,
2019 .v9a,
2020 }),
2021 };
2022 pub const cortex_a72 = CpuModel{
2023 .name = "cortex_a72",
2024 .llvm_name = "cortex-a72",
2025 .features = featureSet(&[_]Feature{
2026 .crc,
2027 .crypto,
2028 .enable_select_opt,
2029 .fuse_adrp_add,
2030 .fuse_aes,
2031 .fuse_literals,
2032 .perfmon,
2033 .predictable_select_expensive,
2034 .v8a,
2035 }),
2036 };
2037 pub const cortex_a73 = CpuModel{
2038 .name = "cortex_a73",
2039 .llvm_name = "cortex-a73",
2040 .features = featureSet(&[_]Feature{
2041 .crc,
2042 .crypto,
2043 .enable_select_opt,
2044 .fuse_adrp_add,
2045 .fuse_aes,
2046 .perfmon,
2047 .predictable_select_expensive,
2048 .v8a,
2049 }),
2050 };
2051 pub const cortex_a75 = CpuModel{
2052 .name = "cortex_a75",
2053 .llvm_name = "cortex-a75",
2054 .features = featureSet(&[_]Feature{
2055 .crypto,
2056 .dotprod,
2057 .enable_select_opt,
2058 .fullfp16,
2059 .fuse_adrp_add,
2060 .fuse_aes,
2061 .perfmon,
2062 .predictable_select_expensive,
2063 .rcpc,
2064 .v8_2a,
2065 }),
2066 };
2067 pub const cortex_a76 = CpuModel{
2068 .name = "cortex_a76",
2069 .llvm_name = "cortex-a76",
2070 .features = featureSet(&[_]Feature{
2071 .a76,
2072 .crypto,
2073 .dotprod,
2074 .fullfp16,
2075 .perfmon,
2076 .rcpc,
2077 .ssbs,
2078 .v8_2a,
2079 }),
2080 };
2081 pub const cortex_a76ae = CpuModel{
2082 .name = "cortex_a76ae",
2083 .llvm_name = "cortex-a76ae",
2084 .features = featureSet(&[_]Feature{
2085 .a76,
2086 .crypto,
2087 .dotprod,
2088 .fullfp16,
2089 .perfmon,
2090 .rcpc,
2091 .ssbs,
2092 .v8_2a,
2093 }),
2094 };
2095 pub const cortex_a77 = CpuModel{
2096 .name = "cortex_a77",
2097 .llvm_name = "cortex-a77",
2098 .features = featureSet(&[_]Feature{
2099 .cmp_bcc_fusion,
2100 .crypto,
2101 .dotprod,
2102 .enable_select_opt,
2103 .fullfp16,
2104 .fuse_adrp_add,
2105 .fuse_aes,
2106 .lsl_fast,
2107 .perfmon,
2108 .predictable_select_expensive,
2109 .rcpc,
2110 .ssbs,
2111 .v8_2a,
2112 }),
2113 };
2114 pub const cortex_a78 = CpuModel{
2115 .name = "cortex_a78",
2116 .llvm_name = "cortex-a78",
2117 .features = featureSet(&[_]Feature{
2118 .a78,
2119 .crypto,
2120 .dotprod,
2121 .fullfp16,
2122 .perfmon,
2123 .rcpc,
2124 .spe,
2125 .ssbs,
2126 .v8_2a,
2127 }),
2128 };
2129 pub const cortex_a78c = CpuModel{
2130 .name = "cortex_a78c",
2131 .llvm_name = "cortex-a78c",
2132 .features = featureSet(&[_]Feature{
2133 .a78c,
2134 .crypto,
2135 .dotprod,
2136 .flagm,
2137 .fp16fml,
2138 .pauth,
2139 .perfmon,
2140 .rcpc,
2141 .spe,
2142 .ssbs,
2143 .v8_2a,
2144 }),
2145 };
2146 pub const cortex_r82 = CpuModel{
2147 .name = "cortex_r82",
2148 .llvm_name = "cortex-r82",
2149 .features = featureSet(&[_]Feature{
2150 .cortex_r82,
2151 .fp16fml,
2152 .perfmon,
2153 .predres,
2154 .sb,
2155 .ssbs,
2156 .v8r,
2157 }),
2158 };
2159 pub const cortex_x1 = CpuModel{
2160 .name = "cortex_x1",
2161 .llvm_name = "cortex-x1",
2162 .features = featureSet(&[_]Feature{
2163 .cmp_bcc_fusion,
2164 .crypto,
2165 .dotprod,
2166 .enable_select_opt,
2167 .fullfp16,
2168 .fuse_adrp_add,
2169 .fuse_aes,
2170 .lsl_fast,
2171 .perfmon,
2172 .predictable_select_expensive,
2173 .rcpc,
2174 .spe,
2175 .ssbs,
2176 .use_postra_scheduler,
2177 .v8_2a,
2178 }),
2179 };
2180 pub const cortex_x1c = CpuModel{
2181 .name = "cortex_x1c",
2182 .llvm_name = "cortex-x1c",
2183 .features = featureSet(&[_]Feature{
2184 .cmp_bcc_fusion,
2185 .crypto,
2186 .dotprod,
2187 .enable_select_opt,
2188 .flagm,
2189 .fullfp16,
2190 .fuse_adrp_add,
2191 .fuse_aes,
2192 .lse2,
2193 .lsl_fast,
2194 .pauth,
2195 .perfmon,
2196 .predictable_select_expensive,
2197 .rcpc_immo,
2198 .spe,
2199 .ssbs,
2200 .use_postra_scheduler,
2201 .v8_2a,
2202 }),
2203 };
2204 pub const cortex_x2 = CpuModel{
2205 .name = "cortex_x2",
2206 .llvm_name = "cortex-x2",
2207 .features = featureSet(&[_]Feature{
2208 .bf16,
2209 .cmp_bcc_fusion,
2210 .enable_select_opt,
2211 .ete,
2212 .fp16fml,
2213 .fuse_adrp_add,
2214 .fuse_aes,
2215 .i8mm,
2216 .lsl_fast,
2217 .mte,
2218 .perfmon,
2219 .predictable_select_expensive,
2220 .sve2_bitperm,
2221 .use_postra_scheduler,
2222 .v9a,
2223 }),
2224 };
2225 pub const cortex_x3 = CpuModel{
2226 .name = "cortex_x3",
2227 .llvm_name = "cortex-x3",
2228 .features = featureSet(&[_]Feature{
2229 .bf16,
2230 .enable_select_opt,
2231 .ete,
2232 .fp16fml,
2233 .fuse_adrp_add,
2234 .fuse_aes,
2235 .i8mm,
2236 .lsl_fast,
2237 .mte,
2238 .perfmon,
2239 .predictable_select_expensive,
2240 .spe,
2241 .sve2_bitperm,
2242 .use_postra_scheduler,
2243 .v9a,
2244 }),
2245 };
2246 pub const cyclone = CpuModel{
2247 .name = "cyclone",
2248 .llvm_name = "cyclone",
2249 .features = featureSet(&[_]Feature{
2250 .alternate_sextload_cvt_f32_pattern,
2251 .arith_bcc_fusion,
2252 .arith_cbz_fusion,
2253 .crypto,
2254 .disable_latency_sched_heuristic,
2255 .fuse_aes,
2256 .fuse_crypto_eor,
2257 .perfmon,
2258 .v8a,
2259 .zcm,
2260 .zcz,
2261 .zcz_fp_workaround,
2262 }),
2263 };
2264 pub const emag = CpuModel{
2265 .name = "emag",
2266 .llvm_name = null,
2267 .features = featureSet(&[_]Feature{
2268 .crc,
2269 .crypto,
2270 .perfmon,
2271 .v8a,
2272 }),
2273 };
2274 pub const exynos_m1 = CpuModel{
2275 .name = "exynos_m1",
2276 .llvm_name = null,
2277 .features = featureSet(&[_]Feature{
2278 .crc,
2279 .crypto,
2280 .exynos_cheap_as_move,
2281 .force_32bit_jump_tables,
2282 .fuse_aes,
2283 .perfmon,
2284 .slow_misaligned_128store,
2285 .slow_paired_128,
2286 .use_postra_scheduler,
2287 .use_reciprocal_square_root,
2288 .v8a,
2289 }),
2290 };
2291 pub const exynos_m2 = CpuModel{
2292 .name = "exynos_m2",
2293 .llvm_name = null,
2294 .features = featureSet(&[_]Feature{
2295 .crc,
2296 .crypto,
2297 .exynos_cheap_as_move,
2298 .force_32bit_jump_tables,
2299 .fuse_aes,
2300 .perfmon,
2301 .slow_misaligned_128store,
2302 .slow_paired_128,
2303 .use_postra_scheduler,
2304 .v8a,
2305 }),
2306 };
2307 pub const exynos_m3 = CpuModel{
2308 .name = "exynos_m3",
2309 .llvm_name = "exynos-m3",
2310 .features = featureSet(&[_]Feature{
2311 .crc,
2312 .crypto,
2313 .exynos_cheap_as_move,
2314 .force_32bit_jump_tables,
2315 .fuse_address,
2316 .fuse_adrp_add,
2317 .fuse_aes,
2318 .fuse_csel,
2319 .fuse_literals,
2320 .lsl_fast,
2321 .perfmon,
2322 .predictable_select_expensive,
2323 .use_postra_scheduler,
2324 .v8a,
2325 }),
2326 };
2327 pub const exynos_m4 = CpuModel{
2328 .name = "exynos_m4",
2329 .llvm_name = "exynos-m4",
2330 .features = featureSet(&[_]Feature{
2331 .arith_bcc_fusion,
2332 .arith_cbz_fusion,
2333 .crypto,
2334 .dotprod,
2335 .exynos_cheap_as_move,
2336 .force_32bit_jump_tables,
2337 .fullfp16,
2338 .fuse_address,
2339 .fuse_adrp_add,
2340 .fuse_aes,
2341 .fuse_arith_logic,
2342 .fuse_csel,
2343 .fuse_literals,
2344 .lsl_fast,
2345 .perfmon,
2346 .use_postra_scheduler,
2347 .v8_2a,
2348 .zcz,
2349 }),
2350 };
2351 pub const exynos_m5 = CpuModel{
2352 .name = "exynos_m5",
2353 .llvm_name = "exynos-m5",
2354 .features = featureSet(&[_]Feature{
2355 .arith_bcc_fusion,
2356 .arith_cbz_fusion,
2357 .crypto,
2358 .dotprod,
2359 .exynos_cheap_as_move,
2360 .force_32bit_jump_tables,
2361 .fullfp16,
2362 .fuse_address,
2363 .fuse_adrp_add,
2364 .fuse_aes,
2365 .fuse_arith_logic,
2366 .fuse_csel,
2367 .fuse_literals,
2368 .lsl_fast,
2369 .perfmon,
2370 .use_postra_scheduler,
2371 .v8_2a,
2372 .zcz,
2373 }),
2374 };
2375 pub const falkor = CpuModel{
2376 .name = "falkor",
2377 .llvm_name = "falkor",
2378 .features = featureSet(&[_]Feature{
2379 .crc,
2380 .crypto,
2381 .custom_cheap_as_move,
2382 .lsl_fast,
2383 .perfmon,
2384 .predictable_select_expensive,
2385 .rdm,
2386 .slow_strqro_store,
2387 .use_postra_scheduler,
2388 .v8a,
2389 .zcz,
2390 }),
2391 };
2392 pub const generic = CpuModel{
2393 .name = "generic",
2394 .llvm_name = "generic",
2395 .features = featureSet(&[_]Feature{
2396 .enable_select_opt,
2397 .ete,
2398 .fuse_adrp_add,
2399 .fuse_aes,
2400 .neon,
2401 .use_postra_scheduler,
2402 }),
2403 };
2404 pub const kryo = CpuModel{
2405 .name = "kryo",
2406 .llvm_name = "kryo",
2407 .features = featureSet(&[_]Feature{
2408 .crc,
2409 .crypto,
2410 .custom_cheap_as_move,
2411 .lsl_fast,
2412 .perfmon,
2413 .predictable_select_expensive,
2414 .use_postra_scheduler,
2415 .v8a,
2416 .zcz,
2417 }),
2418 };
2419 pub const neoverse_512tvb = CpuModel{
2420 .name = "neoverse_512tvb",
2421 .llvm_name = "neoverse-512tvb",
2422 .features = featureSet(&[_]Feature{
2423 .bf16,
2424 .ccdp,
2425 .crypto,
2426 .enable_select_opt,
2427 .fp16fml,
2428 .fuse_adrp_add,
2429 .fuse_aes,
2430 .i8mm,
2431 .lsl_fast,
2432 .perfmon,
2433 .predictable_select_expensive,
2434 .rand,
2435 .spe,
2436 .ssbs,
2437 .sve,
2438 .use_postra_scheduler,
2439 .v8_4a,
2440 }),
2441 };
2442 pub const neoverse_e1 = CpuModel{
2443 .name = "neoverse_e1",
2444 .llvm_name = "neoverse-e1",
2445 .features = featureSet(&[_]Feature{
2446 .crypto,
2447 .dotprod,
2448 .fullfp16,
2449 .fuse_adrp_add,
2450 .fuse_aes,
2451 .perfmon,
2452 .rcpc,
2453 .ssbs,
2454 .use_postra_scheduler,
2455 .v8_2a,
2456 }),
2457 };
2458 pub const neoverse_n1 = CpuModel{
2459 .name = "neoverse_n1",
2460 .llvm_name = "neoverse-n1",
2461 .features = featureSet(&[_]Feature{
2462 .crypto,
2463 .dotprod,
2464 .enable_select_opt,
2465 .fullfp16,
2466 .fuse_adrp_add,
2467 .fuse_aes,
2468 .lsl_fast,
2469 .perfmon,
2470 .predictable_select_expensive,
2471 .rcpc,
2472 .spe,
2473 .ssbs,
2474 .use_postra_scheduler,
2475 .v8_2a,
2476 }),
2477 };
2478 pub const neoverse_n2 = CpuModel{
2479 .name = "neoverse_n2",
2480 .llvm_name = "neoverse-n2",
2481 .features = featureSet(&[_]Feature{
2482 .bf16,
2483 .crypto,
2484 .enable_select_opt,
2485 .ete,
2486 .fuse_adrp_add,
2487 .fuse_aes,
2488 .i8mm,
2489 .lsl_fast,
2490 .mte,
2491 .perfmon,
2492 .predictable_select_expensive,
2493 .sve2_bitperm,
2494 .use_postra_scheduler,
2495 .v8_5a,
2496 }),
2497 };
2498 pub const neoverse_v1 = CpuModel{
2499 .name = "neoverse_v1",
2500 .llvm_name = "neoverse-v1",
2501 .features = featureSet(&[_]Feature{
2502 .bf16,
2503 .ccdp,
2504 .crypto,
2505 .enable_select_opt,
2506 .fp16fml,
2507 .fuse_adrp_add,
2508 .fuse_aes,
2509 .i8mm,
2510 .lsl_fast,
2511 .no_sve_fp_ld1r,
2512 .perfmon,
2513 .predictable_select_expensive,
2514 .rand,
2515 .spe,
2516 .ssbs,
2517 .sve,
2518 .use_postra_scheduler,
2519 .v8_4a,
2520 }),
2521 };
2522 pub const neoverse_v2 = CpuModel{
2523 .name = "neoverse_v2",
2524 .llvm_name = "neoverse-v2",
2525 .features = featureSet(&[_]Feature{
2526 .bf16,
2527 .enable_select_opt,
2528 .ete,
2529 .fp16fml,
2530 .fuse_aes,
2531 .i8mm,
2532 .lsl_fast,
2533 .mte,
2534 .perfmon,
2535 .predictable_select_expensive,
2536 .rand,
2537 .spe,
2538 .sve2_bitperm,
2539 .use_postra_scheduler,
2540 .v9a,
2541 }),
2542 };
2543 pub const saphira = CpuModel{
2544 .name = "saphira",
2545 .llvm_name = "saphira",
2546 .features = featureSet(&[_]Feature{
2547 .crypto,
2548 .custom_cheap_as_move,
2549 .lsl_fast,
2550 .perfmon,
2551 .predictable_select_expensive,
2552 .spe,
2553 .use_postra_scheduler,
2554 .v8_4a,
2555 .zcz,
2556 }),
2557 };
2558 pub const thunderx = CpuModel{
2559 .name = "thunderx",
2560 .llvm_name = "thunderx",
2561 .features = featureSet(&[_]Feature{
2562 .crc,
2563 .crypto,
2564 .perfmon,
2565 .predictable_select_expensive,
2566 .use_postra_scheduler,
2567 .v8a,
2568 }),
2569 };
2570 pub const thunderx2t99 = CpuModel{
2571 .name = "thunderx2t99",
2572 .llvm_name = "thunderx2t99",
2573 .features = featureSet(&[_]Feature{
2574 .aggressive_fma,
2575 .arith_bcc_fusion,
2576 .crypto,
2577 .predictable_select_expensive,
2578 .use_postra_scheduler,
2579 .v8_1a,
2580 }),
2581 };
2582 pub const thunderx3t110 = CpuModel{
2583 .name = "thunderx3t110",
2584 .llvm_name = "thunderx3t110",
2585 .features = featureSet(&[_]Feature{
2586 .aggressive_fma,
2587 .arith_bcc_fusion,
2588 .balance_fp_ops,
2589 .crypto,
2590 .perfmon,
2591 .predictable_select_expensive,
2592 .strict_align,
2593 .use_postra_scheduler,
2594 .v8_3a,
2595 }),
2596 };
2597 pub const thunderxt81 = CpuModel{
2598 .name = "thunderxt81",
2599 .llvm_name = "thunderxt81",
2600 .features = featureSet(&[_]Feature{
2601 .crc,
2602 .crypto,
2603 .perfmon,
2604 .predictable_select_expensive,
2605 .use_postra_scheduler,
2606 .v8a,
2607 }),
2608 };
2609 pub const thunderxt83 = CpuModel{
2610 .name = "thunderxt83",
2611 .llvm_name = "thunderxt83",
2612 .features = featureSet(&[_]Feature{
2613 .crc,
2614 .crypto,
2615 .perfmon,
2616 .predictable_select_expensive,
2617 .use_postra_scheduler,
2618 .v8a,
2619 }),
2620 };
2621 pub const thunderxt88 = CpuModel{
2622 .name = "thunderxt88",
2623 .llvm_name = "thunderxt88",
2624 .features = featureSet(&[_]Feature{
2625 .crc,
2626 .crypto,
2627 .perfmon,
2628 .predictable_select_expensive,
2629 .use_postra_scheduler,
2630 .v8a,
2631 }),
2632 };
2633 pub const tsv110 = CpuModel{
2634 .name = "tsv110",
2635 .llvm_name = "tsv110",
2636 .features = featureSet(&[_]Feature{
2637 .crypto,
2638 .custom_cheap_as_move,
2639 .dotprod,
2640 .fp16fml,
2641 .fuse_aes,
2642 .perfmon,
2643 .spe,
2644 .use_postra_scheduler,
2645 .v8_2a,
2646 }),
2647 };
2648 pub const xgene1 = CpuModel{
2649 .name = "xgene1",
2650 .llvm_name = null,
2651 .features = featureSet(&[_]Feature{
2652 .perfmon,
2653 .v8a,
2654 }),
2655 };
2656};
lib/std/Target/amdgpu.zig created+2153
......@@ -0,0 +1,2153 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"16_bit_insts",
9 a16,
10 add_no_carry_insts,
11 aperture_regs,
12 architected_flat_scratch,
13 architected_sgprs,
14 atomic_buffer_global_pk_add_f16_insts,
15 atomic_buffer_global_pk_add_f16_no_rtn_insts,
16 atomic_ds_pk_add_16_insts,
17 atomic_fadd_no_rtn_insts,
18 atomic_fadd_rtn_insts,
19 atomic_flat_pk_add_16_insts,
20 atomic_global_pk_add_bf16_inst,
21 auto_waitcnt_before_barrier,
22 back_off_barrier,
23 ci_insts,
24 cumode,
25 dl_insts,
26 dot10_insts,
27 dot1_insts,
28 dot2_insts,
29 dot3_insts,
30 dot4_insts,
31 dot5_insts,
32 dot6_insts,
33 dot7_insts,
34 dot8_insts,
35 dot9_insts,
36 dpp,
37 dpp8,
38 dpp_64bit,
39 ds128,
40 ds_src2_insts,
41 extended_image_insts,
42 fast_denormal_f32,
43 fast_fmaf,
44 flat_address_space,
45 flat_atomic_fadd_f32_inst,
46 flat_for_global,
47 flat_global_insts,
48 flat_inst_offsets,
49 flat_scratch,
50 flat_scratch_insts,
51 flat_segment_offset_bug,
52 fma_mix_insts,
53 fmacf64_inst,
54 fmaf,
55 force_store_sc0_sc1,
56 fp64,
57 fp8_insts,
58 full_rate_64_ops,
59 g16,
60 gcn3_encoding,
61 get_wave_id_inst,
62 gfx10,
63 gfx10_3_insts,
64 gfx10_a_encoding,
65 gfx10_b_encoding,
66 gfx10_insts,
67 gfx11,
68 gfx11_full_vgprs,
69 gfx11_insts,
70 gfx7_gfx8_gfx9_insts,
71 gfx8_insts,
72 gfx9,
73 gfx90a_insts,
74 gfx940_insts,
75 gfx9_insts,
76 half_rate_64_ops,
77 image_gather4_d16_bug,
78 image_insts,
79 image_store_d16_bug,
80 inst_fwd_prefetch_bug,
81 int_clamp_insts,
82 inv_2pi_inline_imm,
83 lds_branch_vmem_war_hazard,
84 lds_misaligned_bug,
85 ldsbankcount16,
86 ldsbankcount32,
87 load_store_opt,
88 localmemorysize32768,
89 localmemorysize65536,
90 mad_intra_fwd_bug,
91 mad_mac_f32_insts,
92 mad_mix_insts,
93 mai_insts,
94 max_private_element_size_16,
95 max_private_element_size_4,
96 max_private_element_size_8,
97 mfma_inline_literal_bug,
98 mimg_r128,
99 movrel,
100 negative_scratch_offset_bug,
101 negative_unaligned_scratch_offset_bug,
102 no_data_dep_hazard,
103 no_sdst_cmpx,
104 nsa_clause_bug,
105 nsa_encoding,
106 nsa_to_vmem_bug,
107 offset_3f_bug,
108 packed_fp32_ops,
109 packed_tid,
110 partial_nsa_encoding,
111 pk_fmac_f16_inst,
112 promote_alloca,
113 prt_strict_null,
114 r128_a16,
115 s_memrealtime,
116 s_memtime_inst,
117 scalar_atomics,
118 scalar_flat_scratch_insts,
119 scalar_stores,
120 sdwa,
121 sdwa_mav,
122 sdwa_omod,
123 sdwa_out_mods_vopc,
124 sdwa_scalar,
125 sdwa_sdst,
126 sea_islands,
127 sgpr_init_bug,
128 shader_cycles_register,
129 si_scheduler,
130 smem_to_vector_write_hazard,
131 southern_islands,
132 sramecc,
133 sramecc_support,
134 tgsplit,
135 trap_handler,
136 trig_reduced_range,
137 true16,
138 unaligned_access_mode,
139 unaligned_buffer_access,
140 unaligned_ds_access,
141 unaligned_scratch_access,
142 unpacked_d16_vmem,
143 unsafe_ds_offset_folding,
144 user_sgpr_init16_bug,
145 valu_trans_use_hazard,
146 vcmpx_exec_war_hazard,
147 vcmpx_permlane_hazard,
148 vgpr_index_mode,
149 vmem_to_scalar_write_hazard,
150 volcanic_islands,
151 vop3_literal,
152 vop3p,
153 vopd,
154 vscnt,
155 wavefrontsize16,
156 wavefrontsize32,
157 wavefrontsize64,
158 xnack,
159 xnack_support,
160};
161
162pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
163pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
164pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
165pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
166
167pub const all_features = blk: {
168 const len = @typeInfo(Feature).Enum.fields.len;
169 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
170 var result: [len]CpuFeature = undefined;
171 result[@intFromEnum(Feature.@"16_bit_insts")] = .{
172 .llvm_name = "16-bit-insts",
173 .description = "Has i16/f16 instructions",
174 .dependencies = featureSet(&[_]Feature{}),
175 };
176 result[@intFromEnum(Feature.a16)] = .{
177 .llvm_name = "a16",
178 .description = "Support A16 for 16-bit coordinates/gradients/lod/clamp/mip image operands",
179 .dependencies = featureSet(&[_]Feature{}),
180 };
181 result[@intFromEnum(Feature.add_no_carry_insts)] = .{
182 .llvm_name = "add-no-carry-insts",
183 .description = "Have VALU add/sub instructions without carry out",
184 .dependencies = featureSet(&[_]Feature{}),
185 };
186 result[@intFromEnum(Feature.aperture_regs)] = .{
187 .llvm_name = "aperture-regs",
188 .description = "Has Memory Aperture Base and Size Registers",
189 .dependencies = featureSet(&[_]Feature{}),
190 };
191 result[@intFromEnum(Feature.architected_flat_scratch)] = .{
192 .llvm_name = "architected-flat-scratch",
193 .description = "Flat Scratch register is a readonly SPI initialized architected register",
194 .dependencies = featureSet(&[_]Feature{}),
195 };
196 result[@intFromEnum(Feature.architected_sgprs)] = .{
197 .llvm_name = "architected-sgprs",
198 .description = "Enable the architected SGPRs",
199 .dependencies = featureSet(&[_]Feature{}),
200 };
201 result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_insts)] = .{
202 .llvm_name = "atomic-buffer-global-pk-add-f16-insts",
203 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that can return original value",
204 .dependencies = featureSet(&[_]Feature{
205 .flat_global_insts,
206 }),
207 };
208 result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_no_rtn_insts)] = .{
209 .llvm_name = "atomic-buffer-global-pk-add-f16-no-rtn-insts",
210 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that don't return original value",
211 .dependencies = featureSet(&[_]Feature{
212 .flat_global_insts,
213 }),
214 };
215 result[@intFromEnum(Feature.atomic_ds_pk_add_16_insts)] = .{
216 .llvm_name = "atomic-ds-pk-add-16-insts",
217 .description = "Has ds_pk_add_bf16, ds_pk_add_f16, ds_pk_add_rtn_bf16, ds_pk_add_rtn_f16 instructions",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
220 result[@intFromEnum(Feature.atomic_fadd_no_rtn_insts)] = .{
221 .llvm_name = "atomic-fadd-no-rtn-insts",
222 .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that don't return original value",
223 .dependencies = featureSet(&[_]Feature{
224 .flat_global_insts,
225 }),
226 };
227 result[@intFromEnum(Feature.atomic_fadd_rtn_insts)] = .{
228 .llvm_name = "atomic-fadd-rtn-insts",
229 .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that return original value",
230 .dependencies = featureSet(&[_]Feature{
231 .flat_global_insts,
232 }),
233 };
234 result[@intFromEnum(Feature.atomic_flat_pk_add_16_insts)] = .{
235 .llvm_name = "atomic-flat-pk-add-16-insts",
236 .description = "Has flat_atomic_pk_add_f16 and flat_atomic_pk_add_bf16 instructions",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.atomic_global_pk_add_bf16_inst)] = .{
240 .llvm_name = "atomic-global-pk-add-bf16-inst",
241 .description = "Has global_atomic_pk_add_bf16 instruction",
242 .dependencies = featureSet(&[_]Feature{
243 .flat_global_insts,
244 }),
245 };
246 result[@intFromEnum(Feature.auto_waitcnt_before_barrier)] = .{
247 .llvm_name = "auto-waitcnt-before-barrier",
248 .description = "Hardware automatically inserts waitcnt before barrier",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.back_off_barrier)] = .{
252 .llvm_name = "back-off-barrier",
253 .description = "Hardware supports backing off s_barrier if an exception occurs",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.ci_insts)] = .{
257 .llvm_name = "ci-insts",
258 .description = "Additional instructions for CI+",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.cumode)] = .{
262 .llvm_name = "cumode",
263 .description = "Enable CU wavefront execution mode",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.dl_insts)] = .{
267 .llvm_name = "dl-insts",
268 .description = "Has v_fmac_f32 and v_xnor_b32 instructions",
269 .dependencies = featureSet(&[_]Feature{}),
270 };
271 result[@intFromEnum(Feature.dot10_insts)] = .{
272 .llvm_name = "dot10-insts",
273 .description = "Has v_dot2_f32_f16 instruction",
274 .dependencies = featureSet(&[_]Feature{}),
275 };
276 result[@intFromEnum(Feature.dot1_insts)] = .{
277 .llvm_name = "dot1-insts",
278 .description = "Has v_dot4_i32_i8 and v_dot8_i32_i4 instructions",
279 .dependencies = featureSet(&[_]Feature{}),
280 };
281 result[@intFromEnum(Feature.dot2_insts)] = .{
282 .llvm_name = "dot2-insts",
283 .description = "Has v_dot2_i32_i16, v_dot2_u32_u16 instructions",
284 .dependencies = featureSet(&[_]Feature{}),
285 };
286 result[@intFromEnum(Feature.dot3_insts)] = .{
287 .llvm_name = "dot3-insts",
288 .description = "Has v_dot8c_i32_i4 instruction",
289 .dependencies = featureSet(&[_]Feature{}),
290 };
291 result[@intFromEnum(Feature.dot4_insts)] = .{
292 .llvm_name = "dot4-insts",
293 .description = "Has v_dot2c_i32_i16 instruction",
294 .dependencies = featureSet(&[_]Feature{}),
295 };
296 result[@intFromEnum(Feature.dot5_insts)] = .{
297 .llvm_name = "dot5-insts",
298 .description = "Has v_dot2c_f32_f16 instruction",
299 .dependencies = featureSet(&[_]Feature{}),
300 };
301 result[@intFromEnum(Feature.dot6_insts)] = .{
302 .llvm_name = "dot6-insts",
303 .description = "Has v_dot4c_i32_i8 instruction",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@intFromEnum(Feature.dot7_insts)] = .{
307 .llvm_name = "dot7-insts",
308 .description = "Has v_dot4_u32_u8, v_dot8_u32_u4 instructions",
309 .dependencies = featureSet(&[_]Feature{}),
310 };
311 result[@intFromEnum(Feature.dot8_insts)] = .{
312 .llvm_name = "dot8-insts",
313 .description = "Has v_dot4_i32_iu8, v_dot8_i32_iu4 instructions",
314 .dependencies = featureSet(&[_]Feature{}),
315 };
316 result[@intFromEnum(Feature.dot9_insts)] = .{
317 .llvm_name = "dot9-insts",
318 .description = "Has v_dot2_f16_f16, v_dot2_bf16_bf16, v_dot2_f32_bf16 instructions",
319 .dependencies = featureSet(&[_]Feature{}),
320 };
321 result[@intFromEnum(Feature.dpp)] = .{
322 .llvm_name = "dpp",
323 .description = "Support DPP (Data Parallel Primitives) extension",
324 .dependencies = featureSet(&[_]Feature{}),
325 };
326 result[@intFromEnum(Feature.dpp8)] = .{
327 .llvm_name = "dpp8",
328 .description = "Support DPP8 (Data Parallel Primitives) extension",
329 .dependencies = featureSet(&[_]Feature{}),
330 };
331 result[@intFromEnum(Feature.dpp_64bit)] = .{
332 .llvm_name = "dpp-64bit",
333 .description = "Support DPP (Data Parallel Primitives) extension",
334 .dependencies = featureSet(&[_]Feature{}),
335 };
336 result[@intFromEnum(Feature.ds128)] = .{
337 .llvm_name = "enable-ds128",
338 .description = "Use ds_{read|write}_b128",
339 .dependencies = featureSet(&[_]Feature{}),
340 };
341 result[@intFromEnum(Feature.ds_src2_insts)] = .{
342 .llvm_name = "ds-src2-insts",
343 .description = "Has ds_*_src2 instructions",
344 .dependencies = featureSet(&[_]Feature{}),
345 };
346 result[@intFromEnum(Feature.extended_image_insts)] = .{
347 .llvm_name = "extended-image-insts",
348 .description = "Support mips != 0, lod != 0, gather4, and get_lod",
349 .dependencies = featureSet(&[_]Feature{}),
350 };
351 result[@intFromEnum(Feature.fast_denormal_f32)] = .{
352 .llvm_name = "fast-denormal-f32",
353 .description = "Enabling denormals does not cause f32 instructions to run at f64 rates",
354 .dependencies = featureSet(&[_]Feature{}),
355 };
356 result[@intFromEnum(Feature.fast_fmaf)] = .{
357 .llvm_name = "fast-fmaf",
358 .description = "Assuming f32 fma is at least as fast as mul + add",
359 .dependencies = featureSet(&[_]Feature{}),
360 };
361 result[@intFromEnum(Feature.flat_address_space)] = .{
362 .llvm_name = "flat-address-space",
363 .description = "Support flat address space",
364 .dependencies = featureSet(&[_]Feature{}),
365 };
366 result[@intFromEnum(Feature.flat_atomic_fadd_f32_inst)] = .{
367 .llvm_name = "flat-atomic-fadd-f32-inst",
368 .description = "Has flat_atomic_add_f32 instruction",
369 .dependencies = featureSet(&[_]Feature{}),
370 };
371 result[@intFromEnum(Feature.flat_for_global)] = .{
372 .llvm_name = "flat-for-global",
373 .description = "Force to generate flat instruction for global",
374 .dependencies = featureSet(&[_]Feature{}),
375 };
376 result[@intFromEnum(Feature.flat_global_insts)] = .{
377 .llvm_name = "flat-global-insts",
378 .description = "Have global_* flat memory instructions",
379 .dependencies = featureSet(&[_]Feature{}),
380 };
381 result[@intFromEnum(Feature.flat_inst_offsets)] = .{
382 .llvm_name = "flat-inst-offsets",
383 .description = "Flat instructions have immediate offset addressing mode",
384 .dependencies = featureSet(&[_]Feature{}),
385 };
386 result[@intFromEnum(Feature.flat_scratch)] = .{
387 .llvm_name = "enable-flat-scratch",
388 .description = "Use scratch_* flat memory instructions to access scratch",
389 .dependencies = featureSet(&[_]Feature{}),
390 };
391 result[@intFromEnum(Feature.flat_scratch_insts)] = .{
392 .llvm_name = "flat-scratch-insts",
393 .description = "Have scratch_* flat memory instructions",
394 .dependencies = featureSet(&[_]Feature{}),
395 };
396 result[@intFromEnum(Feature.flat_segment_offset_bug)] = .{
397 .llvm_name = "flat-segment-offset-bug",
398 .description = "GFX10 bug where inst_offset is ignored when flat instructions access global memory",
399 .dependencies = featureSet(&[_]Feature{}),
400 };
401 result[@intFromEnum(Feature.fma_mix_insts)] = .{
402 .llvm_name = "fma-mix-insts",
403 .description = "Has v_fma_mix_f32, v_fma_mixlo_f16, v_fma_mixhi_f16 instructions",
404 .dependencies = featureSet(&[_]Feature{}),
405 };
406 result[@intFromEnum(Feature.fmacf64_inst)] = .{
407 .llvm_name = "fmacf64-inst",
408 .description = "Has v_fmac_f64 instruction",
409 .dependencies = featureSet(&[_]Feature{}),
410 };
411 result[@intFromEnum(Feature.fmaf)] = .{
412 .llvm_name = "fmaf",
413 .description = "Enable single precision FMA (not as fast as mul+add, but fused)",
414 .dependencies = featureSet(&[_]Feature{}),
415 };
416 result[@intFromEnum(Feature.force_store_sc0_sc1)] = .{
417 .llvm_name = "force-store-sc0-sc1",
418 .description = "Has SC0 and SC1 on stores",
419 .dependencies = featureSet(&[_]Feature{}),
420 };
421 result[@intFromEnum(Feature.fp64)] = .{
422 .llvm_name = "fp64",
423 .description = "Enable double precision operations",
424 .dependencies = featureSet(&[_]Feature{}),
425 };
426 result[@intFromEnum(Feature.fp8_insts)] = .{
427 .llvm_name = "fp8-insts",
428 .description = "Has fp8 and bf8 instructions",
429 .dependencies = featureSet(&[_]Feature{}),
430 };
431 result[@intFromEnum(Feature.full_rate_64_ops)] = .{
432 .llvm_name = "full-rate-64-ops",
433 .description = "Most fp64 instructions are full rate",
434 .dependencies = featureSet(&[_]Feature{}),
435 };
436 result[@intFromEnum(Feature.g16)] = .{
437 .llvm_name = "g16",
438 .description = "Support G16 for 16-bit gradient image operands",
439 .dependencies = featureSet(&[_]Feature{}),
440 };
441 result[@intFromEnum(Feature.gcn3_encoding)] = .{
442 .llvm_name = "gcn3-encoding",
443 .description = "Encoding format for VI",
444 .dependencies = featureSet(&[_]Feature{}),
445 };
446 result[@intFromEnum(Feature.get_wave_id_inst)] = .{
447 .llvm_name = "get-wave-id-inst",
448 .description = "Has s_get_waveid_in_workgroup instruction",
449 .dependencies = featureSet(&[_]Feature{}),
450 };
451 result[@intFromEnum(Feature.gfx10)] = .{
452 .llvm_name = "gfx10",
453 .description = "GFX10 GPU generation",
454 .dependencies = featureSet(&[_]Feature{
455 .@"16_bit_insts",
456 .a16,
457 .add_no_carry_insts,
458 .aperture_regs,
459 .ci_insts,
460 .dpp,
461 .dpp8,
462 .extended_image_insts,
463 .fast_denormal_f32,
464 .fast_fmaf,
465 .flat_address_space,
466 .flat_global_insts,
467 .flat_inst_offsets,
468 .flat_scratch_insts,
469 .fma_mix_insts,
470 .fp64,
471 .g16,
472 .gfx10_insts,
473 .gfx8_insts,
474 .gfx9_insts,
475 .image_insts,
476 .int_clamp_insts,
477 .inv_2pi_inline_imm,
478 .localmemorysize65536,
479 .mimg_r128,
480 .movrel,
481 .no_data_dep_hazard,
482 .no_sdst_cmpx,
483 .pk_fmac_f16_inst,
484 .s_memrealtime,
485 .s_memtime_inst,
486 .sdwa,
487 .sdwa_omod,
488 .sdwa_scalar,
489 .sdwa_sdst,
490 .unaligned_buffer_access,
491 .unaligned_ds_access,
492 .vop3_literal,
493 .vop3p,
494 .vscnt,
495 }),
496 };
497 result[@intFromEnum(Feature.gfx10_3_insts)] = .{
498 .llvm_name = "gfx10-3-insts",
499 .description = "Additional instructions for GFX10.3",
500 .dependencies = featureSet(&[_]Feature{}),
501 };
502 result[@intFromEnum(Feature.gfx10_a_encoding)] = .{
503 .llvm_name = "gfx10_a-encoding",
504 .description = "Has BVH ray tracing instructions",
505 .dependencies = featureSet(&[_]Feature{}),
506 };
507 result[@intFromEnum(Feature.gfx10_b_encoding)] = .{
508 .llvm_name = "gfx10_b-encoding",
509 .description = "Encoding format GFX10_B",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@intFromEnum(Feature.gfx10_insts)] = .{
513 .llvm_name = "gfx10-insts",
514 .description = "Additional instructions for GFX10+",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@intFromEnum(Feature.gfx11)] = .{
518 .llvm_name = "gfx11",
519 .description = "GFX11 GPU generation",
520 .dependencies = featureSet(&[_]Feature{
521 .@"16_bit_insts",
522 .a16,
523 .add_no_carry_insts,
524 .aperture_regs,
525 .ci_insts,
526 .dpp,
527 .dpp8,
528 .extended_image_insts,
529 .fast_denormal_f32,
530 .fast_fmaf,
531 .flat_address_space,
532 .flat_global_insts,
533 .flat_inst_offsets,
534 .flat_scratch_insts,
535 .fma_mix_insts,
536 .fp64,
537 .g16,
538 .gfx10_3_insts,
539 .gfx10_a_encoding,
540 .gfx10_b_encoding,
541 .gfx10_insts,
542 .gfx11_insts,
543 .gfx8_insts,
544 .gfx9_insts,
545 .int_clamp_insts,
546 .inv_2pi_inline_imm,
547 .localmemorysize65536,
548 .mimg_r128,
549 .movrel,
550 .no_data_dep_hazard,
551 .no_sdst_cmpx,
552 .pk_fmac_f16_inst,
553 .true16,
554 .unaligned_buffer_access,
555 .unaligned_ds_access,
556 .vop3_literal,
557 .vop3p,
558 .vopd,
559 .vscnt,
560 }),
561 };
562 result[@intFromEnum(Feature.gfx11_full_vgprs)] = .{
563 .llvm_name = "gfx11-full-vgprs",
564 .description = "GFX11 with 50% more physical VGPRs and 50% larger allocation granule than GFX10",
565 .dependencies = featureSet(&[_]Feature{}),
566 };
567 result[@intFromEnum(Feature.gfx11_insts)] = .{
568 .llvm_name = "gfx11-insts",
569 .description = "Additional instructions for GFX11+",
570 .dependencies = featureSet(&[_]Feature{}),
571 };
572 result[@intFromEnum(Feature.gfx7_gfx8_gfx9_insts)] = .{
573 .llvm_name = "gfx7-gfx8-gfx9-insts",
574 .description = "Instructions shared in GFX7, GFX8, GFX9",
575 .dependencies = featureSet(&[_]Feature{}),
576 };
577 result[@intFromEnum(Feature.gfx8_insts)] = .{
578 .llvm_name = "gfx8-insts",
579 .description = "Additional instructions for GFX8+",
580 .dependencies = featureSet(&[_]Feature{}),
581 };
582 result[@intFromEnum(Feature.gfx9)] = .{
583 .llvm_name = "gfx9",
584 .description = "GFX9 GPU generation",
585 .dependencies = featureSet(&[_]Feature{
586 .@"16_bit_insts",
587 .a16,
588 .add_no_carry_insts,
589 .aperture_regs,
590 .ci_insts,
591 .dpp,
592 .fast_denormal_f32,
593 .fast_fmaf,
594 .flat_address_space,
595 .flat_global_insts,
596 .flat_inst_offsets,
597 .flat_scratch_insts,
598 .fp64,
599 .gcn3_encoding,
600 .gfx7_gfx8_gfx9_insts,
601 .gfx8_insts,
602 .gfx9_insts,
603 .int_clamp_insts,
604 .inv_2pi_inline_imm,
605 .localmemorysize65536,
606 .negative_scratch_offset_bug,
607 .r128_a16,
608 .s_memrealtime,
609 .s_memtime_inst,
610 .scalar_atomics,
611 .scalar_flat_scratch_insts,
612 .scalar_stores,
613 .sdwa,
614 .sdwa_omod,
615 .sdwa_scalar,
616 .sdwa_sdst,
617 .unaligned_buffer_access,
618 .unaligned_ds_access,
619 .vgpr_index_mode,
620 .vop3p,
621 .wavefrontsize64,
622 .xnack_support,
623 }),
624 };
625 result[@intFromEnum(Feature.gfx90a_insts)] = .{
626 .llvm_name = "gfx90a-insts",
627 .description = "Additional instructions for GFX90A+",
628 .dependencies = featureSet(&[_]Feature{}),
629 };
630 result[@intFromEnum(Feature.gfx940_insts)] = .{
631 .llvm_name = "gfx940-insts",
632 .description = "Additional instructions for GFX940+",
633 .dependencies = featureSet(&[_]Feature{}),
634 };
635 result[@intFromEnum(Feature.gfx9_insts)] = .{
636 .llvm_name = "gfx9-insts",
637 .description = "Additional instructions for GFX9+",
638 .dependencies = featureSet(&[_]Feature{}),
639 };
640 result[@intFromEnum(Feature.half_rate_64_ops)] = .{
641 .llvm_name = "half-rate-64-ops",
642 .description = "Most fp64 instructions are half rate instead of quarter",
643 .dependencies = featureSet(&[_]Feature{}),
644 };
645 result[@intFromEnum(Feature.image_gather4_d16_bug)] = .{
646 .llvm_name = "image-gather4-d16-bug",
647 .description = "Image Gather4 D16 hardware bug",
648 .dependencies = featureSet(&[_]Feature{}),
649 };
650 result[@intFromEnum(Feature.image_insts)] = .{
651 .llvm_name = "image-insts",
652 .description = "Support image instructions",
653 .dependencies = featureSet(&[_]Feature{}),
654 };
655 result[@intFromEnum(Feature.image_store_d16_bug)] = .{
656 .llvm_name = "image-store-d16-bug",
657 .description = "Image Store D16 hardware bug",
658 .dependencies = featureSet(&[_]Feature{}),
659 };
660 result[@intFromEnum(Feature.inst_fwd_prefetch_bug)] = .{
661 .llvm_name = "inst-fwd-prefetch-bug",
662 .description = "S_INST_PREFETCH instruction causes shader to hang",
663 .dependencies = featureSet(&[_]Feature{}),
664 };
665 result[@intFromEnum(Feature.int_clamp_insts)] = .{
666 .llvm_name = "int-clamp-insts",
667 .description = "Support clamp for integer destination",
668 .dependencies = featureSet(&[_]Feature{}),
669 };
670 result[@intFromEnum(Feature.inv_2pi_inline_imm)] = .{
671 .llvm_name = "inv-2pi-inline-imm",
672 .description = "Has 1 / (2 * pi) as inline immediate",
673 .dependencies = featureSet(&[_]Feature{}),
674 };
675 result[@intFromEnum(Feature.lds_branch_vmem_war_hazard)] = .{
676 .llvm_name = "lds-branch-vmem-war-hazard",
677 .description = "Switching between LDS and VMEM-tex not waiting VM_VSRC=0",
678 .dependencies = featureSet(&[_]Feature{}),
679 };
680 result[@intFromEnum(Feature.lds_misaligned_bug)] = .{
681 .llvm_name = "lds-misaligned-bug",
682 .description = "Some GFX10 bug with multi-dword LDS and flat access that is not naturally aligned in WGP mode",
683 .dependencies = featureSet(&[_]Feature{}),
684 };
685 result[@intFromEnum(Feature.ldsbankcount16)] = .{
686 .llvm_name = "ldsbankcount16",
687 .description = "The number of LDS banks per compute unit.",
688 .dependencies = featureSet(&[_]Feature{}),
689 };
690 result[@intFromEnum(Feature.ldsbankcount32)] = .{
691 .llvm_name = "ldsbankcount32",
692 .description = "The number of LDS banks per compute unit.",
693 .dependencies = featureSet(&[_]Feature{}),
694 };
695 result[@intFromEnum(Feature.load_store_opt)] = .{
696 .llvm_name = "load-store-opt",
697 .description = "Enable SI load/store optimizer pass",
698 .dependencies = featureSet(&[_]Feature{}),
699 };
700 result[@intFromEnum(Feature.localmemorysize32768)] = .{
701 .llvm_name = "localmemorysize32768",
702 .description = "The size of local memory in bytes",
703 .dependencies = featureSet(&[_]Feature{}),
704 };
705 result[@intFromEnum(Feature.localmemorysize65536)] = .{
706 .llvm_name = "localmemorysize65536",
707 .description = "The size of local memory in bytes",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.mad_intra_fwd_bug)] = .{
711 .llvm_name = "mad-intra-fwd-bug",
712 .description = "MAD_U64/I64 intra instruction forwarding bug",
713 .dependencies = featureSet(&[_]Feature{}),
714 };
715 result[@intFromEnum(Feature.mad_mac_f32_insts)] = .{
716 .llvm_name = "mad-mac-f32-insts",
717 .description = "Has v_mad_f32/v_mac_f32/v_madak_f32/v_madmk_f32 instructions",
718 .dependencies = featureSet(&[_]Feature{}),
719 };
720 result[@intFromEnum(Feature.mad_mix_insts)] = .{
721 .llvm_name = "mad-mix-insts",
722 .description = "Has v_mad_mix_f32, v_mad_mixlo_f16, v_mad_mixhi_f16 instructions",
723 .dependencies = featureSet(&[_]Feature{}),
724 };
725 result[@intFromEnum(Feature.mai_insts)] = .{
726 .llvm_name = "mai-insts",
727 .description = "Has mAI instructions",
728 .dependencies = featureSet(&[_]Feature{}),
729 };
730 result[@intFromEnum(Feature.max_private_element_size_16)] = .{
731 .llvm_name = "max-private-element-size-16",
732 .description = "Maximum private access size may be 16",
733 .dependencies = featureSet(&[_]Feature{}),
734 };
735 result[@intFromEnum(Feature.max_private_element_size_4)] = .{
736 .llvm_name = "max-private-element-size-4",
737 .description = "Maximum private access size may be 4",
738 .dependencies = featureSet(&[_]Feature{}),
739 };
740 result[@intFromEnum(Feature.max_private_element_size_8)] = .{
741 .llvm_name = "max-private-element-size-8",
742 .description = "Maximum private access size may be 8",
743 .dependencies = featureSet(&[_]Feature{}),
744 };
745 result[@intFromEnum(Feature.mfma_inline_literal_bug)] = .{
746 .llvm_name = "mfma-inline-literal-bug",
747 .description = "MFMA cannot use inline literal as SrcC",
748 .dependencies = featureSet(&[_]Feature{}),
749 };
750 result[@intFromEnum(Feature.mimg_r128)] = .{
751 .llvm_name = "mimg-r128",
752 .description = "Support 128-bit texture resources",
753 .dependencies = featureSet(&[_]Feature{}),
754 };
755 result[@intFromEnum(Feature.movrel)] = .{
756 .llvm_name = "movrel",
757 .description = "Has v_movrel*_b32 instructions",
758 .dependencies = featureSet(&[_]Feature{}),
759 };
760 result[@intFromEnum(Feature.negative_scratch_offset_bug)] = .{
761 .llvm_name = "negative-scratch-offset-bug",
762 .description = "Negative immediate offsets in scratch instructions with an SGPR offset page fault on GFX9",
763 .dependencies = featureSet(&[_]Feature{}),
764 };
765 result[@intFromEnum(Feature.negative_unaligned_scratch_offset_bug)] = .{
766 .llvm_name = "negative-unaligned-scratch-offset-bug",
767 .description = "Scratch instructions with a VGPR offset and a negative immediate offset that is not a multiple of 4 read wrong memory on GFX10",
768 .dependencies = featureSet(&[_]Feature{}),
769 };
770 result[@intFromEnum(Feature.no_data_dep_hazard)] = .{
771 .llvm_name = "no-data-dep-hazard",
772 .description = "Does not need SW waitstates",
773 .dependencies = featureSet(&[_]Feature{}),
774 };
775 result[@intFromEnum(Feature.no_sdst_cmpx)] = .{
776 .llvm_name = "no-sdst-cmpx",
777 .description = "V_CMPX does not write VCC/SGPR in addition to EXEC",
778 .dependencies = featureSet(&[_]Feature{}),
779 };
780 result[@intFromEnum(Feature.nsa_clause_bug)] = .{
781 .llvm_name = "nsa-clause-bug",
782 .description = "MIMG-NSA in a hard clause has unpredictable results on GFX10.1",
783 .dependencies = featureSet(&[_]Feature{}),
784 };
785 result[@intFromEnum(Feature.nsa_encoding)] = .{
786 .llvm_name = "nsa-encoding",
787 .description = "Support NSA encoding for image instructions",
788 .dependencies = featureSet(&[_]Feature{}),
789 };
790 result[@intFromEnum(Feature.nsa_to_vmem_bug)] = .{
791 .llvm_name = "nsa-to-vmem-bug",
792 .description = "MIMG-NSA followed by VMEM fail if EXEC_LO or EXEC_HI equals zero",
793 .dependencies = featureSet(&[_]Feature{}),
794 };
795 result[@intFromEnum(Feature.offset_3f_bug)] = .{
796 .llvm_name = "offset-3f-bug",
797 .description = "Branch offset of 3f hardware bug",
798 .dependencies = featureSet(&[_]Feature{}),
799 };
800 result[@intFromEnum(Feature.packed_fp32_ops)] = .{
801 .llvm_name = "packed-fp32-ops",
802 .description = "Support packed fp32 instructions",
803 .dependencies = featureSet(&[_]Feature{}),
804 };
805 result[@intFromEnum(Feature.packed_tid)] = .{
806 .llvm_name = "packed-tid",
807 .description = "Workitem IDs are packed into v0 at kernel launch",
808 .dependencies = featureSet(&[_]Feature{}),
809 };
810 result[@intFromEnum(Feature.partial_nsa_encoding)] = .{
811 .llvm_name = "partial-nsa-encoding",
812 .description = "Support partial NSA encoding for image instructions",
813 .dependencies = featureSet(&[_]Feature{}),
814 };
815 result[@intFromEnum(Feature.pk_fmac_f16_inst)] = .{
816 .llvm_name = "pk-fmac-f16-inst",
817 .description = "Has v_pk_fmac_f16 instruction",
818 .dependencies = featureSet(&[_]Feature{}),
819 };
820 result[@intFromEnum(Feature.promote_alloca)] = .{
821 .llvm_name = "promote-alloca",
822 .description = "Enable promote alloca pass",
823 .dependencies = featureSet(&[_]Feature{}),
824 };
825 result[@intFromEnum(Feature.prt_strict_null)] = .{
826 .llvm_name = "enable-prt-strict-null",
827 .description = "Enable zeroing of result registers for sparse texture fetches",
828 .dependencies = featureSet(&[_]Feature{}),
829 };
830 result[@intFromEnum(Feature.r128_a16)] = .{
831 .llvm_name = "r128-a16",
832 .description = "Support gfx9-style A16 for 16-bit coordinates/gradients/lod/clamp/mip image operands, where a16 is aliased with r128",
833 .dependencies = featureSet(&[_]Feature{}),
834 };
835 result[@intFromEnum(Feature.s_memrealtime)] = .{
836 .llvm_name = "s-memrealtime",
837 .description = "Has s_memrealtime instruction",
838 .dependencies = featureSet(&[_]Feature{}),
839 };
840 result[@intFromEnum(Feature.s_memtime_inst)] = .{
841 .llvm_name = "s-memtime-inst",
842 .description = "Has s_memtime instruction",
843 .dependencies = featureSet(&[_]Feature{}),
844 };
845 result[@intFromEnum(Feature.scalar_atomics)] = .{
846 .llvm_name = "scalar-atomics",
847 .description = "Has atomic scalar memory instructions",
848 .dependencies = featureSet(&[_]Feature{}),
849 };
850 result[@intFromEnum(Feature.scalar_flat_scratch_insts)] = .{
851 .llvm_name = "scalar-flat-scratch-insts",
852 .description = "Have s_scratch_* flat memory instructions",
853 .dependencies = featureSet(&[_]Feature{}),
854 };
855 result[@intFromEnum(Feature.scalar_stores)] = .{
856 .llvm_name = "scalar-stores",
857 .description = "Has store scalar memory instructions",
858 .dependencies = featureSet(&[_]Feature{}),
859 };
860 result[@intFromEnum(Feature.sdwa)] = .{
861 .llvm_name = "sdwa",
862 .description = "Support SDWA (Sub-DWORD Addressing) extension",
863 .dependencies = featureSet(&[_]Feature{}),
864 };
865 result[@intFromEnum(Feature.sdwa_mav)] = .{
866 .llvm_name = "sdwa-mav",
867 .description = "Support v_mac_f32/f16 with SDWA (Sub-DWORD Addressing) extension",
868 .dependencies = featureSet(&[_]Feature{}),
869 };
870 result[@intFromEnum(Feature.sdwa_omod)] = .{
871 .llvm_name = "sdwa-omod",
872 .description = "Support OMod with SDWA (Sub-DWORD Addressing) extension",
873 .dependencies = featureSet(&[_]Feature{}),
874 };
875 result[@intFromEnum(Feature.sdwa_out_mods_vopc)] = .{
876 .llvm_name = "sdwa-out-mods-vopc",
877 .description = "Support clamp for VOPC with SDWA (Sub-DWORD Addressing) extension",
878 .dependencies = featureSet(&[_]Feature{}),
879 };
880 result[@intFromEnum(Feature.sdwa_scalar)] = .{
881 .llvm_name = "sdwa-scalar",
882 .description = "Support scalar register with SDWA (Sub-DWORD Addressing) extension",
883 .dependencies = featureSet(&[_]Feature{}),
884 };
885 result[@intFromEnum(Feature.sdwa_sdst)] = .{
886 .llvm_name = "sdwa-sdst",
887 .description = "Support scalar dst for VOPC with SDWA (Sub-DWORD Addressing) extension",
888 .dependencies = featureSet(&[_]Feature{}),
889 };
890 result[@intFromEnum(Feature.sea_islands)] = .{
891 .llvm_name = "sea-islands",
892 .description = "SEA_ISLANDS GPU generation",
893 .dependencies = featureSet(&[_]Feature{
894 .ci_insts,
895 .ds_src2_insts,
896 .extended_image_insts,
897 .flat_address_space,
898 .fp64,
899 .gfx7_gfx8_gfx9_insts,
900 .image_insts,
901 .localmemorysize65536,
902 .mad_mac_f32_insts,
903 .mimg_r128,
904 .movrel,
905 .s_memtime_inst,
906 .trig_reduced_range,
907 .unaligned_buffer_access,
908 .wavefrontsize64,
909 }),
910 };
911 result[@intFromEnum(Feature.sgpr_init_bug)] = .{
912 .llvm_name = "sgpr-init-bug",
913 .description = "VI SGPR initialization bug requiring a fixed SGPR allocation size",
914 .dependencies = featureSet(&[_]Feature{}),
915 };
916 result[@intFromEnum(Feature.shader_cycles_register)] = .{
917 .llvm_name = "shader-cycles-register",
918 .description = "Has SHADER_CYCLES hardware register",
919 .dependencies = featureSet(&[_]Feature{}),
920 };
921 result[@intFromEnum(Feature.si_scheduler)] = .{
922 .llvm_name = "si-scheduler",
923 .description = "Enable SI Machine Scheduler",
924 .dependencies = featureSet(&[_]Feature{}),
925 };
926 result[@intFromEnum(Feature.smem_to_vector_write_hazard)] = .{
927 .llvm_name = "smem-to-vector-write-hazard",
928 .description = "s_load_dword followed by v_cmp page faults",
929 .dependencies = featureSet(&[_]Feature{}),
930 };
931 result[@intFromEnum(Feature.southern_islands)] = .{
932 .llvm_name = "southern-islands",
933 .description = "SOUTHERN_ISLANDS GPU generation",
934 .dependencies = featureSet(&[_]Feature{
935 .ds_src2_insts,
936 .extended_image_insts,
937 .fp64,
938 .image_insts,
939 .ldsbankcount32,
940 .localmemorysize32768,
941 .mad_mac_f32_insts,
942 .mimg_r128,
943 .movrel,
944 .s_memtime_inst,
945 .trig_reduced_range,
946 .wavefrontsize64,
947 }),
948 };
949 result[@intFromEnum(Feature.sramecc)] = .{
950 .llvm_name = "sramecc",
951 .description = "Enable SRAMECC",
952 .dependencies = featureSet(&[_]Feature{}),
953 };
954 result[@intFromEnum(Feature.sramecc_support)] = .{
955 .llvm_name = "sramecc-support",
956 .description = "Hardware supports SRAMECC",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.tgsplit)] = .{
960 .llvm_name = "tgsplit",
961 .description = "Enable threadgroup split execution",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.trap_handler)] = .{
965 .llvm_name = "trap-handler",
966 .description = "Trap handler support",
967 .dependencies = featureSet(&[_]Feature{}),
968 };
969 result[@intFromEnum(Feature.trig_reduced_range)] = .{
970 .llvm_name = "trig-reduced-range",
971 .description = "Requires use of fract on arguments to trig instructions",
972 .dependencies = featureSet(&[_]Feature{}),
973 };
974 result[@intFromEnum(Feature.true16)] = .{
975 .llvm_name = "true16",
976 .description = "True 16-bit operand instructions",
977 .dependencies = featureSet(&[_]Feature{}),
978 };
979 result[@intFromEnum(Feature.unaligned_access_mode)] = .{
980 .llvm_name = "unaligned-access-mode",
981 .description = "Enable unaligned global, local and region loads and stores if the hardware supports it",
982 .dependencies = featureSet(&[_]Feature{}),
983 };
984 result[@intFromEnum(Feature.unaligned_buffer_access)] = .{
985 .llvm_name = "unaligned-buffer-access",
986 .description = "Hardware supports unaligned global loads and stores",
987 .dependencies = featureSet(&[_]Feature{}),
988 };
989 result[@intFromEnum(Feature.unaligned_ds_access)] = .{
990 .llvm_name = "unaligned-ds-access",
991 .description = "Hardware supports unaligned local and region loads and stores",
992 .dependencies = featureSet(&[_]Feature{}),
993 };
994 result[@intFromEnum(Feature.unaligned_scratch_access)] = .{
995 .llvm_name = "unaligned-scratch-access",
996 .description = "Support unaligned scratch loads and stores",
997 .dependencies = featureSet(&[_]Feature{}),
998 };
999 result[@intFromEnum(Feature.unpacked_d16_vmem)] = .{
1000 .llvm_name = "unpacked-d16-vmem",
1001 .description = "Has unpacked d16 vmem instructions",
1002 .dependencies = featureSet(&[_]Feature{}),
1003 };
1004 result[@intFromEnum(Feature.unsafe_ds_offset_folding)] = .{
1005 .llvm_name = "unsafe-ds-offset-folding",
1006 .description = "Force using DS instruction immediate offsets on SI",
1007 .dependencies = featureSet(&[_]Feature{}),
1008 };
1009 result[@intFromEnum(Feature.user_sgpr_init16_bug)] = .{
1010 .llvm_name = "user-sgpr-init16-bug",
1011 .description = "Bug requiring at least 16 user+system SGPRs to be enabled",
1012 .dependencies = featureSet(&[_]Feature{}),
1013 };
1014 result[@intFromEnum(Feature.valu_trans_use_hazard)] = .{
1015 .llvm_name = "valu-trans-use-hazard",
1016 .description = "Hazard when TRANS instructions are closely followed by a use of the result",
1017 .dependencies = featureSet(&[_]Feature{}),
1018 };
1019 result[@intFromEnum(Feature.vcmpx_exec_war_hazard)] = .{
1020 .llvm_name = "vcmpx-exec-war-hazard",
1021 .description = "V_CMPX WAR hazard on EXEC (V_CMPX issue ONLY)",
1022 .dependencies = featureSet(&[_]Feature{}),
1023 };
1024 result[@intFromEnum(Feature.vcmpx_permlane_hazard)] = .{
1025 .llvm_name = "vcmpx-permlane-hazard",
1026 .description = "TODO: describe me",
1027 .dependencies = featureSet(&[_]Feature{}),
1028 };
1029 result[@intFromEnum(Feature.vgpr_index_mode)] = .{
1030 .llvm_name = "vgpr-index-mode",
1031 .description = "Has VGPR mode register indexing",
1032 .dependencies = featureSet(&[_]Feature{}),
1033 };
1034 result[@intFromEnum(Feature.vmem_to_scalar_write_hazard)] = .{
1035 .llvm_name = "vmem-to-scalar-write-hazard",
1036 .description = "VMEM instruction followed by scalar writing to EXEC mask, M0 or SGPR leads to incorrect execution.",
1037 .dependencies = featureSet(&[_]Feature{}),
1038 };
1039 result[@intFromEnum(Feature.volcanic_islands)] = .{
1040 .llvm_name = "volcanic-islands",
1041 .description = "VOLCANIC_ISLANDS GPU generation",
1042 .dependencies = featureSet(&[_]Feature{
1043 .@"16_bit_insts",
1044 .ci_insts,
1045 .dpp,
1046 .ds_src2_insts,
1047 .extended_image_insts,
1048 .fast_denormal_f32,
1049 .flat_address_space,
1050 .fp64,
1051 .gcn3_encoding,
1052 .gfx7_gfx8_gfx9_insts,
1053 .gfx8_insts,
1054 .image_insts,
1055 .int_clamp_insts,
1056 .inv_2pi_inline_imm,
1057 .localmemorysize65536,
1058 .mad_mac_f32_insts,
1059 .mimg_r128,
1060 .movrel,
1061 .s_memrealtime,
1062 .s_memtime_inst,
1063 .scalar_stores,
1064 .sdwa,
1065 .sdwa_mav,
1066 .sdwa_out_mods_vopc,
1067 .trig_reduced_range,
1068 .unaligned_buffer_access,
1069 .vgpr_index_mode,
1070 .wavefrontsize64,
1071 }),
1072 };
1073 result[@intFromEnum(Feature.vop3_literal)] = .{
1074 .llvm_name = "vop3-literal",
1075 .description = "Can use one literal in VOP3",
1076 .dependencies = featureSet(&[_]Feature{}),
1077 };
1078 result[@intFromEnum(Feature.vop3p)] = .{
1079 .llvm_name = "vop3p",
1080 .description = "Has VOP3P packed instructions",
1081 .dependencies = featureSet(&[_]Feature{}),
1082 };
1083 result[@intFromEnum(Feature.vopd)] = .{
1084 .llvm_name = "vopd",
1085 .description = "Has VOPD dual issue wave32 instructions",
1086 .dependencies = featureSet(&[_]Feature{}),
1087 };
1088 result[@intFromEnum(Feature.vscnt)] = .{
1089 .llvm_name = "vscnt",
1090 .description = "Has separate store vscnt counter",
1091 .dependencies = featureSet(&[_]Feature{}),
1092 };
1093 result[@intFromEnum(Feature.wavefrontsize16)] = .{
1094 .llvm_name = "wavefrontsize16",
1095 .description = "The number of threads per wavefront",
1096 .dependencies = featureSet(&[_]Feature{}),
1097 };
1098 result[@intFromEnum(Feature.wavefrontsize32)] = .{
1099 .llvm_name = "wavefrontsize32",
1100 .description = "The number of threads per wavefront",
1101 .dependencies = featureSet(&[_]Feature{}),
1102 };
1103 result[@intFromEnum(Feature.wavefrontsize64)] = .{
1104 .llvm_name = "wavefrontsize64",
1105 .description = "The number of threads per wavefront",
1106 .dependencies = featureSet(&[_]Feature{}),
1107 };
1108 result[@intFromEnum(Feature.xnack)] = .{
1109 .llvm_name = "xnack",
1110 .description = "Enable XNACK support",
1111 .dependencies = featureSet(&[_]Feature{}),
1112 };
1113 result[@intFromEnum(Feature.xnack_support)] = .{
1114 .llvm_name = "xnack-support",
1115 .description = "Hardware supports XNACK",
1116 .dependencies = featureSet(&[_]Feature{}),
1117 };
1118 const ti = @typeInfo(Feature);
1119 for (&result, 0..) |*elem, i| {
1120 elem.index = i;
1121 elem.name = ti.Enum.fields[i].name;
1122 }
1123 break :blk result;
1124};
1125
1126pub const cpu = struct {
1127 pub const bonaire = CpuModel{
1128 .name = "bonaire",
1129 .llvm_name = "bonaire",
1130 .features = featureSet(&[_]Feature{
1131 .ldsbankcount32,
1132 .sea_islands,
1133 }),
1134 };
1135 pub const carrizo = CpuModel{
1136 .name = "carrizo",
1137 .llvm_name = "carrizo",
1138 .features = featureSet(&[_]Feature{
1139 .fast_fmaf,
1140 .half_rate_64_ops,
1141 .ldsbankcount32,
1142 .unpacked_d16_vmem,
1143 .volcanic_islands,
1144 .xnack_support,
1145 }),
1146 };
1147 pub const fiji = CpuModel{
1148 .name = "fiji",
1149 .llvm_name = "fiji",
1150 .features = featureSet(&[_]Feature{
1151 .ldsbankcount32,
1152 .unpacked_d16_vmem,
1153 .volcanic_islands,
1154 }),
1155 };
1156 pub const generic = CpuModel{
1157 .name = "generic",
1158 .llvm_name = "generic",
1159 .features = featureSet(&[_]Feature{
1160 .wavefrontsize64,
1161 }),
1162 };
1163 pub const generic_hsa = CpuModel{
1164 .name = "generic_hsa",
1165 .llvm_name = "generic-hsa",
1166 .features = featureSet(&[_]Feature{
1167 .flat_address_space,
1168 .wavefrontsize64,
1169 }),
1170 };
1171 pub const gfx1010 = CpuModel{
1172 .name = "gfx1010",
1173 .llvm_name = "gfx1010",
1174 .features = featureSet(&[_]Feature{
1175 .back_off_barrier,
1176 .dl_insts,
1177 .ds_src2_insts,
1178 .flat_segment_offset_bug,
1179 .get_wave_id_inst,
1180 .gfx10,
1181 .inst_fwd_prefetch_bug,
1182 .lds_branch_vmem_war_hazard,
1183 .lds_misaligned_bug,
1184 .ldsbankcount32,
1185 .mad_mac_f32_insts,
1186 .negative_unaligned_scratch_offset_bug,
1187 .nsa_clause_bug,
1188 .nsa_encoding,
1189 .nsa_to_vmem_bug,
1190 .offset_3f_bug,
1191 .scalar_atomics,
1192 .scalar_flat_scratch_insts,
1193 .scalar_stores,
1194 .smem_to_vector_write_hazard,
1195 .vcmpx_exec_war_hazard,
1196 .vcmpx_permlane_hazard,
1197 .vmem_to_scalar_write_hazard,
1198 .wavefrontsize32,
1199 .xnack_support,
1200 }),
1201 };
1202 pub const gfx1011 = CpuModel{
1203 .name = "gfx1011",
1204 .llvm_name = "gfx1011",
1205 .features = featureSet(&[_]Feature{
1206 .back_off_barrier,
1207 .dl_insts,
1208 .dot10_insts,
1209 .dot1_insts,
1210 .dot2_insts,
1211 .dot5_insts,
1212 .dot6_insts,
1213 .dot7_insts,
1214 .ds_src2_insts,
1215 .flat_segment_offset_bug,
1216 .get_wave_id_inst,
1217 .gfx10,
1218 .inst_fwd_prefetch_bug,
1219 .lds_branch_vmem_war_hazard,
1220 .lds_misaligned_bug,
1221 .ldsbankcount32,
1222 .mad_mac_f32_insts,
1223 .negative_unaligned_scratch_offset_bug,
1224 .nsa_clause_bug,
1225 .nsa_encoding,
1226 .nsa_to_vmem_bug,
1227 .offset_3f_bug,
1228 .scalar_atomics,
1229 .scalar_flat_scratch_insts,
1230 .scalar_stores,
1231 .smem_to_vector_write_hazard,
1232 .vcmpx_exec_war_hazard,
1233 .vcmpx_permlane_hazard,
1234 .vmem_to_scalar_write_hazard,
1235 .wavefrontsize32,
1236 .xnack_support,
1237 }),
1238 };
1239 pub const gfx1012 = CpuModel{
1240 .name = "gfx1012",
1241 .llvm_name = "gfx1012",
1242 .features = featureSet(&[_]Feature{
1243 .back_off_barrier,
1244 .dl_insts,
1245 .dot10_insts,
1246 .dot1_insts,
1247 .dot2_insts,
1248 .dot5_insts,
1249 .dot6_insts,
1250 .dot7_insts,
1251 .ds_src2_insts,
1252 .flat_segment_offset_bug,
1253 .get_wave_id_inst,
1254 .gfx10,
1255 .inst_fwd_prefetch_bug,
1256 .lds_branch_vmem_war_hazard,
1257 .lds_misaligned_bug,
1258 .ldsbankcount32,
1259 .mad_mac_f32_insts,
1260 .negative_unaligned_scratch_offset_bug,
1261 .nsa_clause_bug,
1262 .nsa_encoding,
1263 .nsa_to_vmem_bug,
1264 .offset_3f_bug,
1265 .scalar_atomics,
1266 .scalar_flat_scratch_insts,
1267 .scalar_stores,
1268 .smem_to_vector_write_hazard,
1269 .vcmpx_exec_war_hazard,
1270 .vcmpx_permlane_hazard,
1271 .vmem_to_scalar_write_hazard,
1272 .wavefrontsize32,
1273 .xnack_support,
1274 }),
1275 };
1276 pub const gfx1013 = CpuModel{
1277 .name = "gfx1013",
1278 .llvm_name = "gfx1013",
1279 .features = featureSet(&[_]Feature{
1280 .back_off_barrier,
1281 .dl_insts,
1282 .ds_src2_insts,
1283 .flat_segment_offset_bug,
1284 .get_wave_id_inst,
1285 .gfx10,
1286 .gfx10_a_encoding,
1287 .inst_fwd_prefetch_bug,
1288 .lds_branch_vmem_war_hazard,
1289 .lds_misaligned_bug,
1290 .ldsbankcount32,
1291 .mad_mac_f32_insts,
1292 .negative_unaligned_scratch_offset_bug,
1293 .nsa_clause_bug,
1294 .nsa_encoding,
1295 .nsa_to_vmem_bug,
1296 .offset_3f_bug,
1297 .scalar_atomics,
1298 .scalar_flat_scratch_insts,
1299 .scalar_stores,
1300 .smem_to_vector_write_hazard,
1301 .vcmpx_exec_war_hazard,
1302 .vcmpx_permlane_hazard,
1303 .vmem_to_scalar_write_hazard,
1304 .wavefrontsize32,
1305 .xnack_support,
1306 }),
1307 };
1308 pub const gfx1030 = CpuModel{
1309 .name = "gfx1030",
1310 .llvm_name = "gfx1030",
1311 .features = featureSet(&[_]Feature{
1312 .back_off_barrier,
1313 .dl_insts,
1314 .dot10_insts,
1315 .dot1_insts,
1316 .dot2_insts,
1317 .dot5_insts,
1318 .dot6_insts,
1319 .dot7_insts,
1320 .gfx10,
1321 .gfx10_3_insts,
1322 .gfx10_a_encoding,
1323 .gfx10_b_encoding,
1324 .ldsbankcount32,
1325 .nsa_encoding,
1326 .shader_cycles_register,
1327 .wavefrontsize32,
1328 }),
1329 };
1330 pub const gfx1031 = CpuModel{
1331 .name = "gfx1031",
1332 .llvm_name = "gfx1031",
1333 .features = featureSet(&[_]Feature{
1334 .back_off_barrier,
1335 .dl_insts,
1336 .dot10_insts,
1337 .dot1_insts,
1338 .dot2_insts,
1339 .dot5_insts,
1340 .dot6_insts,
1341 .dot7_insts,
1342 .gfx10,
1343 .gfx10_3_insts,
1344 .gfx10_a_encoding,
1345 .gfx10_b_encoding,
1346 .ldsbankcount32,
1347 .nsa_encoding,
1348 .shader_cycles_register,
1349 .wavefrontsize32,
1350 }),
1351 };
1352 pub const gfx1032 = CpuModel{
1353 .name = "gfx1032",
1354 .llvm_name = "gfx1032",
1355 .features = featureSet(&[_]Feature{
1356 .back_off_barrier,
1357 .dl_insts,
1358 .dot10_insts,
1359 .dot1_insts,
1360 .dot2_insts,
1361 .dot5_insts,
1362 .dot6_insts,
1363 .dot7_insts,
1364 .gfx10,
1365 .gfx10_3_insts,
1366 .gfx10_a_encoding,
1367 .gfx10_b_encoding,
1368 .ldsbankcount32,
1369 .nsa_encoding,
1370 .shader_cycles_register,
1371 .wavefrontsize32,
1372 }),
1373 };
1374 pub const gfx1033 = CpuModel{
1375 .name = "gfx1033",
1376 .llvm_name = "gfx1033",
1377 .features = featureSet(&[_]Feature{
1378 .back_off_barrier,
1379 .dl_insts,
1380 .dot10_insts,
1381 .dot1_insts,
1382 .dot2_insts,
1383 .dot5_insts,
1384 .dot6_insts,
1385 .dot7_insts,
1386 .gfx10,
1387 .gfx10_3_insts,
1388 .gfx10_a_encoding,
1389 .gfx10_b_encoding,
1390 .ldsbankcount32,
1391 .nsa_encoding,
1392 .shader_cycles_register,
1393 .wavefrontsize32,
1394 }),
1395 };
1396 pub const gfx1034 = CpuModel{
1397 .name = "gfx1034",
1398 .llvm_name = "gfx1034",
1399 .features = featureSet(&[_]Feature{
1400 .back_off_barrier,
1401 .dl_insts,
1402 .dot10_insts,
1403 .dot1_insts,
1404 .dot2_insts,
1405 .dot5_insts,
1406 .dot6_insts,
1407 .dot7_insts,
1408 .gfx10,
1409 .gfx10_3_insts,
1410 .gfx10_a_encoding,
1411 .gfx10_b_encoding,
1412 .ldsbankcount32,
1413 .nsa_encoding,
1414 .shader_cycles_register,
1415 .wavefrontsize32,
1416 }),
1417 };
1418 pub const gfx1035 = CpuModel{
1419 .name = "gfx1035",
1420 .llvm_name = "gfx1035",
1421 .features = featureSet(&[_]Feature{
1422 .back_off_barrier,
1423 .dl_insts,
1424 .dot10_insts,
1425 .dot1_insts,
1426 .dot2_insts,
1427 .dot5_insts,
1428 .dot6_insts,
1429 .dot7_insts,
1430 .gfx10,
1431 .gfx10_3_insts,
1432 .gfx10_a_encoding,
1433 .gfx10_b_encoding,
1434 .ldsbankcount32,
1435 .nsa_encoding,
1436 .shader_cycles_register,
1437 .wavefrontsize32,
1438 }),
1439 };
1440 pub const gfx1036 = CpuModel{
1441 .name = "gfx1036",
1442 .llvm_name = "gfx1036",
1443 .features = featureSet(&[_]Feature{
1444 .back_off_barrier,
1445 .dl_insts,
1446 .dot10_insts,
1447 .dot1_insts,
1448 .dot2_insts,
1449 .dot5_insts,
1450 .dot6_insts,
1451 .dot7_insts,
1452 .gfx10,
1453 .gfx10_3_insts,
1454 .gfx10_a_encoding,
1455 .gfx10_b_encoding,
1456 .ldsbankcount32,
1457 .nsa_encoding,
1458 .shader_cycles_register,
1459 .wavefrontsize32,
1460 }),
1461 };
1462 pub const gfx1100 = CpuModel{
1463 .name = "gfx1100",
1464 .llvm_name = "gfx1100",
1465 .features = featureSet(&[_]Feature{
1466 .architected_flat_scratch,
1467 .atomic_fadd_no_rtn_insts,
1468 .atomic_fadd_rtn_insts,
1469 .dl_insts,
1470 .dot10_insts,
1471 .dot5_insts,
1472 .dot7_insts,
1473 .dot8_insts,
1474 .dot9_insts,
1475 .flat_atomic_fadd_f32_inst,
1476 .gfx11,
1477 .gfx11_full_vgprs,
1478 .image_insts,
1479 .ldsbankcount32,
1480 .mad_intra_fwd_bug,
1481 .nsa_encoding,
1482 .packed_tid,
1483 .partial_nsa_encoding,
1484 .shader_cycles_register,
1485 .user_sgpr_init16_bug,
1486 .valu_trans_use_hazard,
1487 .vcmpx_permlane_hazard,
1488 .wavefrontsize32,
1489 }),
1490 };
1491 pub const gfx1101 = CpuModel{
1492 .name = "gfx1101",
1493 .llvm_name = "gfx1101",
1494 .features = featureSet(&[_]Feature{
1495 .architected_flat_scratch,
1496 .atomic_fadd_no_rtn_insts,
1497 .atomic_fadd_rtn_insts,
1498 .dl_insts,
1499 .dot10_insts,
1500 .dot5_insts,
1501 .dot7_insts,
1502 .dot8_insts,
1503 .dot9_insts,
1504 .flat_atomic_fadd_f32_inst,
1505 .gfx11,
1506 .gfx11_full_vgprs,
1507 .image_insts,
1508 .ldsbankcount32,
1509 .mad_intra_fwd_bug,
1510 .nsa_encoding,
1511 .packed_tid,
1512 .partial_nsa_encoding,
1513 .shader_cycles_register,
1514 .valu_trans_use_hazard,
1515 .vcmpx_permlane_hazard,
1516 .wavefrontsize32,
1517 }),
1518 };
1519 pub const gfx1102 = CpuModel{
1520 .name = "gfx1102",
1521 .llvm_name = "gfx1102",
1522 .features = featureSet(&[_]Feature{
1523 .architected_flat_scratch,
1524 .atomic_fadd_no_rtn_insts,
1525 .atomic_fadd_rtn_insts,
1526 .dl_insts,
1527 .dot10_insts,
1528 .dot5_insts,
1529 .dot7_insts,
1530 .dot8_insts,
1531 .dot9_insts,
1532 .flat_atomic_fadd_f32_inst,
1533 .gfx11,
1534 .image_insts,
1535 .ldsbankcount32,
1536 .mad_intra_fwd_bug,
1537 .nsa_encoding,
1538 .packed_tid,
1539 .partial_nsa_encoding,
1540 .shader_cycles_register,
1541 .user_sgpr_init16_bug,
1542 .valu_trans_use_hazard,
1543 .vcmpx_permlane_hazard,
1544 .wavefrontsize32,
1545 }),
1546 };
1547 pub const gfx1103 = CpuModel{
1548 .name = "gfx1103",
1549 .llvm_name = "gfx1103",
1550 .features = featureSet(&[_]Feature{
1551 .architected_flat_scratch,
1552 .atomic_fadd_no_rtn_insts,
1553 .atomic_fadd_rtn_insts,
1554 .dl_insts,
1555 .dot10_insts,
1556 .dot5_insts,
1557 .dot7_insts,
1558 .dot8_insts,
1559 .dot9_insts,
1560 .flat_atomic_fadd_f32_inst,
1561 .gfx11,
1562 .image_insts,
1563 .ldsbankcount32,
1564 .mad_intra_fwd_bug,
1565 .nsa_encoding,
1566 .packed_tid,
1567 .partial_nsa_encoding,
1568 .shader_cycles_register,
1569 .valu_trans_use_hazard,
1570 .vcmpx_permlane_hazard,
1571 .wavefrontsize32,
1572 }),
1573 };
1574 pub const gfx1150 = CpuModel{
1575 .name = "gfx1150",
1576 .llvm_name = "gfx1150",
1577 .features = featureSet(&[_]Feature{
1578 .architected_flat_scratch,
1579 .atomic_fadd_no_rtn_insts,
1580 .atomic_fadd_rtn_insts,
1581 .dl_insts,
1582 .dot10_insts,
1583 .dot5_insts,
1584 .dot7_insts,
1585 .dot8_insts,
1586 .dot9_insts,
1587 .flat_atomic_fadd_f32_inst,
1588 .gfx11,
1589 .image_insts,
1590 .ldsbankcount32,
1591 .mad_intra_fwd_bug,
1592 .nsa_encoding,
1593 .packed_tid,
1594 .partial_nsa_encoding,
1595 .shader_cycles_register,
1596 .vcmpx_permlane_hazard,
1597 .wavefrontsize32,
1598 }),
1599 };
1600 pub const gfx1151 = CpuModel{
1601 .name = "gfx1151",
1602 .llvm_name = "gfx1151",
1603 .features = featureSet(&[_]Feature{
1604 .architected_flat_scratch,
1605 .atomic_fadd_no_rtn_insts,
1606 .atomic_fadd_rtn_insts,
1607 .dl_insts,
1608 .dot10_insts,
1609 .dot5_insts,
1610 .dot7_insts,
1611 .dot8_insts,
1612 .dot9_insts,
1613 .flat_atomic_fadd_f32_inst,
1614 .gfx11,
1615 .gfx11_full_vgprs,
1616 .image_insts,
1617 .ldsbankcount32,
1618 .mad_intra_fwd_bug,
1619 .nsa_encoding,
1620 .packed_tid,
1621 .partial_nsa_encoding,
1622 .shader_cycles_register,
1623 .vcmpx_permlane_hazard,
1624 .wavefrontsize32,
1625 }),
1626 };
1627 pub const gfx600 = CpuModel{
1628 .name = "gfx600",
1629 .llvm_name = "gfx600",
1630 .features = featureSet(&[_]Feature{
1631 .fast_fmaf,
1632 .half_rate_64_ops,
1633 .southern_islands,
1634 }),
1635 };
1636 pub const gfx601 = CpuModel{
1637 .name = "gfx601",
1638 .llvm_name = "gfx601",
1639 .features = featureSet(&[_]Feature{
1640 .southern_islands,
1641 }),
1642 };
1643 pub const gfx602 = CpuModel{
1644 .name = "gfx602",
1645 .llvm_name = "gfx602",
1646 .features = featureSet(&[_]Feature{
1647 .southern_islands,
1648 }),
1649 };
1650 pub const gfx700 = CpuModel{
1651 .name = "gfx700",
1652 .llvm_name = "gfx700",
1653 .features = featureSet(&[_]Feature{
1654 .ldsbankcount32,
1655 .sea_islands,
1656 }),
1657 };
1658 pub const gfx701 = CpuModel{
1659 .name = "gfx701",
1660 .llvm_name = "gfx701",
1661 .features = featureSet(&[_]Feature{
1662 .fast_fmaf,
1663 .half_rate_64_ops,
1664 .ldsbankcount32,
1665 .sea_islands,
1666 }),
1667 };
1668 pub const gfx702 = CpuModel{
1669 .name = "gfx702",
1670 .llvm_name = "gfx702",
1671 .features = featureSet(&[_]Feature{
1672 .fast_fmaf,
1673 .ldsbankcount16,
1674 .sea_islands,
1675 }),
1676 };
1677 pub const gfx703 = CpuModel{
1678 .name = "gfx703",
1679 .llvm_name = "gfx703",
1680 .features = featureSet(&[_]Feature{
1681 .ldsbankcount16,
1682 .sea_islands,
1683 }),
1684 };
1685 pub const gfx704 = CpuModel{
1686 .name = "gfx704",
1687 .llvm_name = "gfx704",
1688 .features = featureSet(&[_]Feature{
1689 .ldsbankcount32,
1690 .sea_islands,
1691 }),
1692 };
1693 pub const gfx705 = CpuModel{
1694 .name = "gfx705",
1695 .llvm_name = "gfx705",
1696 .features = featureSet(&[_]Feature{
1697 .ldsbankcount16,
1698 .sea_islands,
1699 }),
1700 };
1701 pub const gfx801 = CpuModel{
1702 .name = "gfx801",
1703 .llvm_name = "gfx801",
1704 .features = featureSet(&[_]Feature{
1705 .fast_fmaf,
1706 .half_rate_64_ops,
1707 .ldsbankcount32,
1708 .unpacked_d16_vmem,
1709 .volcanic_islands,
1710 .xnack_support,
1711 }),
1712 };
1713 pub const gfx802 = CpuModel{
1714 .name = "gfx802",
1715 .llvm_name = "gfx802",
1716 .features = featureSet(&[_]Feature{
1717 .ldsbankcount32,
1718 .sgpr_init_bug,
1719 .unpacked_d16_vmem,
1720 .volcanic_islands,
1721 }),
1722 };
1723 pub const gfx803 = CpuModel{
1724 .name = "gfx803",
1725 .llvm_name = "gfx803",
1726 .features = featureSet(&[_]Feature{
1727 .ldsbankcount32,
1728 .unpacked_d16_vmem,
1729 .volcanic_islands,
1730 }),
1731 };
1732 pub const gfx805 = CpuModel{
1733 .name = "gfx805",
1734 .llvm_name = "gfx805",
1735 .features = featureSet(&[_]Feature{
1736 .ldsbankcount32,
1737 .sgpr_init_bug,
1738 .unpacked_d16_vmem,
1739 .volcanic_islands,
1740 }),
1741 };
1742 pub const gfx810 = CpuModel{
1743 .name = "gfx810",
1744 .llvm_name = "gfx810",
1745 .features = featureSet(&[_]Feature{
1746 .image_gather4_d16_bug,
1747 .image_store_d16_bug,
1748 .ldsbankcount16,
1749 .volcanic_islands,
1750 .xnack_support,
1751 }),
1752 };
1753 pub const gfx900 = CpuModel{
1754 .name = "gfx900",
1755 .llvm_name = "gfx900",
1756 .features = featureSet(&[_]Feature{
1757 .ds_src2_insts,
1758 .extended_image_insts,
1759 .gfx9,
1760 .image_gather4_d16_bug,
1761 .image_insts,
1762 .ldsbankcount32,
1763 .mad_mac_f32_insts,
1764 .mad_mix_insts,
1765 }),
1766 };
1767 pub const gfx902 = CpuModel{
1768 .name = "gfx902",
1769 .llvm_name = "gfx902",
1770 .features = featureSet(&[_]Feature{
1771 .ds_src2_insts,
1772 .extended_image_insts,
1773 .gfx9,
1774 .image_gather4_d16_bug,
1775 .image_insts,
1776 .ldsbankcount32,
1777 .mad_mac_f32_insts,
1778 .mad_mix_insts,
1779 }),
1780 };
1781 pub const gfx904 = CpuModel{
1782 .name = "gfx904",
1783 .llvm_name = "gfx904",
1784 .features = featureSet(&[_]Feature{
1785 .ds_src2_insts,
1786 .extended_image_insts,
1787 .fma_mix_insts,
1788 .gfx9,
1789 .image_gather4_d16_bug,
1790 .image_insts,
1791 .ldsbankcount32,
1792 .mad_mac_f32_insts,
1793 }),
1794 };
1795 pub const gfx906 = CpuModel{
1796 .name = "gfx906",
1797 .llvm_name = "gfx906",
1798 .features = featureSet(&[_]Feature{
1799 .dl_insts,
1800 .dot10_insts,
1801 .dot1_insts,
1802 .dot2_insts,
1803 .dot7_insts,
1804 .ds_src2_insts,
1805 .extended_image_insts,
1806 .fma_mix_insts,
1807 .gfx9,
1808 .half_rate_64_ops,
1809 .image_gather4_d16_bug,
1810 .image_insts,
1811 .ldsbankcount32,
1812 .mad_mac_f32_insts,
1813 .sramecc_support,
1814 }),
1815 };
1816 pub const gfx908 = CpuModel{
1817 .name = "gfx908",
1818 .llvm_name = "gfx908",
1819 .features = featureSet(&[_]Feature{
1820 .atomic_buffer_global_pk_add_f16_no_rtn_insts,
1821 .atomic_fadd_no_rtn_insts,
1822 .dl_insts,
1823 .dot10_insts,
1824 .dot1_insts,
1825 .dot2_insts,
1826 .dot3_insts,
1827 .dot4_insts,
1828 .dot5_insts,
1829 .dot6_insts,
1830 .dot7_insts,
1831 .ds_src2_insts,
1832 .extended_image_insts,
1833 .fma_mix_insts,
1834 .gfx9,
1835 .half_rate_64_ops,
1836 .image_gather4_d16_bug,
1837 .image_insts,
1838 .ldsbankcount32,
1839 .mad_mac_f32_insts,
1840 .mai_insts,
1841 .mfma_inline_literal_bug,
1842 .pk_fmac_f16_inst,
1843 .sramecc_support,
1844 }),
1845 };
1846 pub const gfx909 = CpuModel{
1847 .name = "gfx909",
1848 .llvm_name = "gfx909",
1849 .features = featureSet(&[_]Feature{
1850 .ds_src2_insts,
1851 .extended_image_insts,
1852 .gfx9,
1853 .image_gather4_d16_bug,
1854 .image_insts,
1855 .ldsbankcount32,
1856 .mad_mac_f32_insts,
1857 .mad_mix_insts,
1858 }),
1859 };
1860 pub const gfx90a = CpuModel{
1861 .name = "gfx90a",
1862 .llvm_name = "gfx90a",
1863 .features = featureSet(&[_]Feature{
1864 .atomic_buffer_global_pk_add_f16_insts,
1865 .atomic_fadd_no_rtn_insts,
1866 .atomic_fadd_rtn_insts,
1867 .back_off_barrier,
1868 .dl_insts,
1869 .dot10_insts,
1870 .dot1_insts,
1871 .dot2_insts,
1872 .dot3_insts,
1873 .dot4_insts,
1874 .dot5_insts,
1875 .dot6_insts,
1876 .dot7_insts,
1877 .dpp_64bit,
1878 .fma_mix_insts,
1879 .fmacf64_inst,
1880 .full_rate_64_ops,
1881 .gfx9,
1882 .gfx90a_insts,
1883 .image_insts,
1884 .ldsbankcount32,
1885 .mad_mac_f32_insts,
1886 .mai_insts,
1887 .packed_fp32_ops,
1888 .packed_tid,
1889 .pk_fmac_f16_inst,
1890 .sramecc_support,
1891 }),
1892 };
1893 pub const gfx90c = CpuModel{
1894 .name = "gfx90c",
1895 .llvm_name = "gfx90c",
1896 .features = featureSet(&[_]Feature{
1897 .ds_src2_insts,
1898 .extended_image_insts,
1899 .gfx9,
1900 .image_gather4_d16_bug,
1901 .image_insts,
1902 .ldsbankcount32,
1903 .mad_mac_f32_insts,
1904 .mad_mix_insts,
1905 }),
1906 };
1907 pub const gfx940 = CpuModel{
1908 .name = "gfx940",
1909 .llvm_name = "gfx940",
1910 .features = featureSet(&[_]Feature{
1911 .architected_flat_scratch,
1912 .atomic_buffer_global_pk_add_f16_insts,
1913 .atomic_ds_pk_add_16_insts,
1914 .atomic_fadd_no_rtn_insts,
1915 .atomic_fadd_rtn_insts,
1916 .atomic_flat_pk_add_16_insts,
1917 .atomic_global_pk_add_bf16_inst,
1918 .back_off_barrier,
1919 .dl_insts,
1920 .dot10_insts,
1921 .dot1_insts,
1922 .dot2_insts,
1923 .dot3_insts,
1924 .dot4_insts,
1925 .dot5_insts,
1926 .dot6_insts,
1927 .dot7_insts,
1928 .dpp_64bit,
1929 .flat_atomic_fadd_f32_inst,
1930 .fma_mix_insts,
1931 .fmacf64_inst,
1932 .force_store_sc0_sc1,
1933 .fp8_insts,
1934 .full_rate_64_ops,
1935 .gfx9,
1936 .gfx90a_insts,
1937 .gfx940_insts,
1938 .ldsbankcount32,
1939 .mai_insts,
1940 .packed_fp32_ops,
1941 .packed_tid,
1942 .pk_fmac_f16_inst,
1943 .sramecc_support,
1944 }),
1945 };
1946 pub const gfx941 = CpuModel{
1947 .name = "gfx941",
1948 .llvm_name = "gfx941",
1949 .features = featureSet(&[_]Feature{
1950 .architected_flat_scratch,
1951 .atomic_buffer_global_pk_add_f16_insts,
1952 .atomic_ds_pk_add_16_insts,
1953 .atomic_fadd_no_rtn_insts,
1954 .atomic_fadd_rtn_insts,
1955 .atomic_flat_pk_add_16_insts,
1956 .atomic_global_pk_add_bf16_inst,
1957 .back_off_barrier,
1958 .dl_insts,
1959 .dot10_insts,
1960 .dot1_insts,
1961 .dot2_insts,
1962 .dot3_insts,
1963 .dot4_insts,
1964 .dot5_insts,
1965 .dot6_insts,
1966 .dot7_insts,
1967 .dpp_64bit,
1968 .flat_atomic_fadd_f32_inst,
1969 .fma_mix_insts,
1970 .fmacf64_inst,
1971 .force_store_sc0_sc1,
1972 .fp8_insts,
1973 .full_rate_64_ops,
1974 .gfx9,
1975 .gfx90a_insts,
1976 .gfx940_insts,
1977 .ldsbankcount32,
1978 .mai_insts,
1979 .packed_fp32_ops,
1980 .packed_tid,
1981 .pk_fmac_f16_inst,
1982 .sramecc_support,
1983 }),
1984 };
1985 pub const gfx942 = CpuModel{
1986 .name = "gfx942",
1987 .llvm_name = "gfx942",
1988 .features = featureSet(&[_]Feature{
1989 .architected_flat_scratch,
1990 .atomic_buffer_global_pk_add_f16_insts,
1991 .atomic_ds_pk_add_16_insts,
1992 .atomic_fadd_no_rtn_insts,
1993 .atomic_fadd_rtn_insts,
1994 .atomic_flat_pk_add_16_insts,
1995 .atomic_global_pk_add_bf16_inst,
1996 .back_off_barrier,
1997 .dl_insts,
1998 .dot10_insts,
1999 .dot1_insts,
2000 .dot2_insts,
2001 .dot3_insts,
2002 .dot4_insts,
2003 .dot5_insts,
2004 .dot6_insts,
2005 .dot7_insts,
2006 .dpp_64bit,
2007 .flat_atomic_fadd_f32_inst,
2008 .fma_mix_insts,
2009 .fmacf64_inst,
2010 .fp8_insts,
2011 .full_rate_64_ops,
2012 .gfx9,
2013 .gfx90a_insts,
2014 .gfx940_insts,
2015 .ldsbankcount32,
2016 .mai_insts,
2017 .packed_fp32_ops,
2018 .packed_tid,
2019 .pk_fmac_f16_inst,
2020 .sramecc_support,
2021 }),
2022 };
2023 pub const hainan = CpuModel{
2024 .name = "hainan",
2025 .llvm_name = "hainan",
2026 .features = featureSet(&[_]Feature{
2027 .southern_islands,
2028 }),
2029 };
2030 pub const hawaii = CpuModel{
2031 .name = "hawaii",
2032 .llvm_name = "hawaii",
2033 .features = featureSet(&[_]Feature{
2034 .fast_fmaf,
2035 .half_rate_64_ops,
2036 .ldsbankcount32,
2037 .sea_islands,
2038 }),
2039 };
2040 pub const iceland = CpuModel{
2041 .name = "iceland",
2042 .llvm_name = "iceland",
2043 .features = featureSet(&[_]Feature{
2044 .ldsbankcount32,
2045 .sgpr_init_bug,
2046 .unpacked_d16_vmem,
2047 .volcanic_islands,
2048 }),
2049 };
2050 pub const kabini = CpuModel{
2051 .name = "kabini",
2052 .llvm_name = "kabini",
2053 .features = featureSet(&[_]Feature{
2054 .ldsbankcount16,
2055 .sea_islands,
2056 }),
2057 };
2058 pub const kaveri = CpuModel{
2059 .name = "kaveri",
2060 .llvm_name = "kaveri",
2061 .features = featureSet(&[_]Feature{
2062 .ldsbankcount32,
2063 .sea_islands,
2064 }),
2065 };
2066 pub const mullins = CpuModel{
2067 .name = "mullins",
2068 .llvm_name = "mullins",
2069 .features = featureSet(&[_]Feature{
2070 .ldsbankcount16,
2071 .sea_islands,
2072 }),
2073 };
2074 pub const oland = CpuModel{
2075 .name = "oland",
2076 .llvm_name = "oland",
2077 .features = featureSet(&[_]Feature{
2078 .southern_islands,
2079 }),
2080 };
2081 pub const pitcairn = CpuModel{
2082 .name = "pitcairn",
2083 .llvm_name = "pitcairn",
2084 .features = featureSet(&[_]Feature{
2085 .southern_islands,
2086 }),
2087 };
2088 pub const polaris10 = CpuModel{
2089 .name = "polaris10",
2090 .llvm_name = "polaris10",
2091 .features = featureSet(&[_]Feature{
2092 .ldsbankcount32,
2093 .unpacked_d16_vmem,
2094 .volcanic_islands,
2095 }),
2096 };
2097 pub const polaris11 = CpuModel{
2098 .name = "polaris11",
2099 .llvm_name = "polaris11",
2100 .features = featureSet(&[_]Feature{
2101 .ldsbankcount32,
2102 .unpacked_d16_vmem,
2103 .volcanic_islands,
2104 }),
2105 };
2106 pub const stoney = CpuModel{
2107 .name = "stoney",
2108 .llvm_name = "stoney",
2109 .features = featureSet(&[_]Feature{
2110 .image_gather4_d16_bug,
2111 .image_store_d16_bug,
2112 .ldsbankcount16,
2113 .volcanic_islands,
2114 .xnack_support,
2115 }),
2116 };
2117 pub const tahiti = CpuModel{
2118 .name = "tahiti",
2119 .llvm_name = "tahiti",
2120 .features = featureSet(&[_]Feature{
2121 .fast_fmaf,
2122 .half_rate_64_ops,
2123 .southern_islands,
2124 }),
2125 };
2126 pub const tonga = CpuModel{
2127 .name = "tonga",
2128 .llvm_name = "tonga",
2129 .features = featureSet(&[_]Feature{
2130 .ldsbankcount32,
2131 .sgpr_init_bug,
2132 .unpacked_d16_vmem,
2133 .volcanic_islands,
2134 }),
2135 };
2136 pub const tongapro = CpuModel{
2137 .name = "tongapro",
2138 .llvm_name = "tongapro",
2139 .features = featureSet(&[_]Feature{
2140 .ldsbankcount32,
2141 .sgpr_init_bug,
2142 .unpacked_d16_vmem,
2143 .volcanic_islands,
2144 }),
2145 };
2146 pub const verde = CpuModel{
2147 .name = "verde",
2148 .llvm_name = "verde",
2149 .features = featureSet(&[_]Feature{
2150 .southern_islands,
2151 }),
2152 };
2153};
lib/std/Target/arc.zig created+39
......@@ -0,0 +1,39 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 norm,
9};
10
11pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
12pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
13pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
14pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
15
16pub const all_features = blk: {
17 const len = @typeInfo(Feature).Enum.fields.len;
18 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
19 var result: [len]CpuFeature = undefined;
20 result[@intFromEnum(Feature.norm)] = .{
21 .llvm_name = "norm",
22 .description = "Enable support for norm instruction.",
23 .dependencies = featureSet(&[_]Feature{}),
24 };
25 const ti = @typeInfo(Feature);
26 for (&result, 0..) |*elem, i| {
27 elem.index = i;
28 elem.name = ti.Enum.fields[i].name;
29 }
30 break :blk result;
31};
32
33pub const cpu = struct {
34 pub const generic = CpuModel{
35 .name = "generic",
36 .llvm_name = "generic",
37 .features = featureSet(&[_]Feature{}),
38 };
39};
lib/std/Target/arm.zig created+2604
......@@ -0,0 +1,2604 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"32bit",
9 @"8msecext",
10 a76,
11 aapcs_frame_chain,
12 aapcs_frame_chain_leaf,
13 aclass,
14 acquire_release,
15 aes,
16 atomics_32,
17 avoid_movs_shop,
18 avoid_partial_cpsr,
19 bf16,
20 big_endian_instructions,
21 cde,
22 cdecp0,
23 cdecp1,
24 cdecp2,
25 cdecp3,
26 cdecp4,
27 cdecp5,
28 cdecp6,
29 cdecp7,
30 cheap_predicable_cpsr,
31 clrbhb,
32 crc,
33 crypto,
34 d32,
35 db,
36 dfb,
37 disable_postra_scheduler,
38 dont_widen_vmovs,
39 dotprod,
40 dsp,
41 execute_only,
42 expand_fp_mlx,
43 exynos,
44 fix_cmse_cve_2021_35465,
45 fix_cortex_a57_aes_1742098,
46 fp16,
47 fp16fml,
48 fp64,
49 fp_armv8,
50 fp_armv8d16,
51 fp_armv8d16sp,
52 fp_armv8sp,
53 fpao,
54 fpregs,
55 fpregs16,
56 fpregs64,
57 fullfp16,
58 fuse_aes,
59 fuse_literals,
60 harden_sls_blr,
61 harden_sls_nocomdat,
62 harden_sls_retbr,
63 has_v4t,
64 has_v5t,
65 has_v5te,
66 has_v6,
67 has_v6k,
68 has_v6m,
69 has_v6t2,
70 has_v7,
71 has_v7clrex,
72 has_v8,
73 has_v8_1a,
74 has_v8_1m_main,
75 has_v8_2a,
76 has_v8_3a,
77 has_v8_4a,
78 has_v8_5a,
79 has_v8_6a,
80 has_v8_7a,
81 has_v8_8a,
82 has_v8_9a,
83 has_v8m,
84 has_v8m_main,
85 has_v9_1a,
86 has_v9_2a,
87 has_v9_3a,
88 has_v9_4a,
89 has_v9a,
90 hwdiv,
91 hwdiv_arm,
92 i8mm,
93 iwmmxt,
94 iwmmxt2,
95 lob,
96 long_calls,
97 loop_align,
98 m3,
99 mclass,
100 mp,
101 muxed_units,
102 mve,
103 mve1beat,
104 mve2beat,
105 mve4beat,
106 mve_fp,
107 nacl_trap,
108 neon,
109 neon_fpmovs,
110 neonfp,
111 no_branch_predictor,
112 no_bti_at_return_twice,
113 no_movt,
114 no_neg_immediates,
115 noarm,
116 nonpipelined_vfp,
117 pacbti,
118 perfmon,
119 prefer_ishst,
120 prefer_vmovsr,
121 prof_unpr,
122 r4,
123 ras,
124 rclass,
125 read_tp_tpidrprw,
126 read_tp_tpidruro,
127 read_tp_tpidrurw,
128 reserve_r9,
129 ret_addr_stack,
130 sb,
131 sha2,
132 slow_fp_brcc,
133 slow_load_D_subreg,
134 slow_odd_reg,
135 slow_vdup32,
136 slow_vgetlni32,
137 slowfpvfmx,
138 slowfpvmlx,
139 soft_float,
140 splat_vfp_neon,
141 strict_align,
142 swift,
143 thumb2,
144 thumb_mode,
145 trustzone,
146 use_mipipeliner,
147 use_misched,
148 v2,
149 v2a,
150 v3,
151 v3m,
152 v4,
153 v4t,
154 v5t,
155 v5te,
156 v5tej,
157 v6,
158 v6j,
159 v6k,
160 v6kz,
161 v6m,
162 v6sm,
163 v6t2,
164 v7a,
165 v7em,
166 v7k,
167 v7m,
168 v7r,
169 v7s,
170 v7ve,
171 v8_1a,
172 v8_1m_main,
173 v8_2a,
174 v8_3a,
175 v8_4a,
176 v8_5a,
177 v8_6a,
178 v8_7a,
179 v8_8a,
180 v8_9a,
181 v8a,
182 v8m,
183 v8m_main,
184 v8r,
185 v9_1a,
186 v9_2a,
187 v9_3a,
188 v9_4a,
189 v9a,
190 vfp2,
191 vfp2sp,
192 vfp3,
193 vfp3d16,
194 vfp3d16sp,
195 vfp3sp,
196 vfp4,
197 vfp4d16,
198 vfp4d16sp,
199 vfp4sp,
200 virtualization,
201 vldn_align,
202 vmlx_forwarding,
203 vmlx_hazards,
204 wide_stride_vfp,
205 xscale,
206 zcz,
207};
208
209pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
210pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
211pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
212pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
213
214pub const all_features = blk: {
215 @setEvalBranchQuota(10000);
216 const len = @typeInfo(Feature).Enum.fields.len;
217 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
218 var result: [len]CpuFeature = undefined;
219 result[@intFromEnum(Feature.@"32bit")] = .{
220 .llvm_name = "32bit",
221 .description = "Prefer 32-bit Thumb instrs",
222 .dependencies = featureSet(&[_]Feature{}),
223 };
224 result[@intFromEnum(Feature.@"8msecext")] = .{
225 .llvm_name = "8msecext",
226 .description = "Enable support for ARMv8-M Security Extensions",
227 .dependencies = featureSet(&[_]Feature{}),
228 };
229 result[@intFromEnum(Feature.a76)] = .{
230 .llvm_name = "a76",
231 .description = "Cortex-A76 ARM processors",
232 .dependencies = featureSet(&[_]Feature{}),
233 };
234 result[@intFromEnum(Feature.aapcs_frame_chain)] = .{
235 .llvm_name = "aapcs-frame-chain",
236 .description = "Create an AAPCS compliant frame chain",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.aapcs_frame_chain_leaf)] = .{
240 .llvm_name = "aapcs-frame-chain-leaf",
241 .description = "Create an AAPCS compliant frame chain for leaf functions",
242 .dependencies = featureSet(&[_]Feature{
243 .aapcs_frame_chain,
244 }),
245 };
246 result[@intFromEnum(Feature.aclass)] = .{
247 .llvm_name = "aclass",
248 .description = "Is application profile ('A' series)",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.acquire_release)] = .{
252 .llvm_name = "acquire-release",
253 .description = "Has v8 acquire/release (lda/ldaex etc) instructions",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.aes)] = .{
257 .llvm_name = "aes",
258 .description = "Enable AES support",
259 .dependencies = featureSet(&[_]Feature{
260 .neon,
261 }),
262 };
263 result[@intFromEnum(Feature.atomics_32)] = .{
264 .llvm_name = "atomics-32",
265 .description = "Assume that lock-free 32-bit atomics are available",
266 .dependencies = featureSet(&[_]Feature{}),
267 };
268 result[@intFromEnum(Feature.avoid_movs_shop)] = .{
269 .llvm_name = "avoid-movs-shop",
270 .description = "Avoid movs instructions with shifter operand",
271 .dependencies = featureSet(&[_]Feature{}),
272 };
273 result[@intFromEnum(Feature.avoid_partial_cpsr)] = .{
274 .llvm_name = "avoid-partial-cpsr",
275 .description = "Avoid CPSR partial update for OOO execution",
276 .dependencies = featureSet(&[_]Feature{}),
277 };
278 result[@intFromEnum(Feature.bf16)] = .{
279 .llvm_name = "bf16",
280 .description = "Enable support for BFloat16 instructions",
281 .dependencies = featureSet(&[_]Feature{
282 .neon,
283 }),
284 };
285 result[@intFromEnum(Feature.big_endian_instructions)] = .{
286 .llvm_name = "big-endian-instructions",
287 .description = "Expect instructions to be stored big-endian.",
288 .dependencies = featureSet(&[_]Feature{}),
289 };
290 result[@intFromEnum(Feature.cde)] = .{
291 .llvm_name = "cde",
292 .description = "Support CDE instructions",
293 .dependencies = featureSet(&[_]Feature{
294 .has_v8m_main,
295 }),
296 };
297 result[@intFromEnum(Feature.cdecp0)] = .{
298 .llvm_name = "cdecp0",
299 .description = "Coprocessor 0 ISA is CDEv1",
300 .dependencies = featureSet(&[_]Feature{
301 .cde,
302 }),
303 };
304 result[@intFromEnum(Feature.cdecp1)] = .{
305 .llvm_name = "cdecp1",
306 .description = "Coprocessor 1 ISA is CDEv1",
307 .dependencies = featureSet(&[_]Feature{
308 .cde,
309 }),
310 };
311 result[@intFromEnum(Feature.cdecp2)] = .{
312 .llvm_name = "cdecp2",
313 .description = "Coprocessor 2 ISA is CDEv1",
314 .dependencies = featureSet(&[_]Feature{
315 .cde,
316 }),
317 };
318 result[@intFromEnum(Feature.cdecp3)] = .{
319 .llvm_name = "cdecp3",
320 .description = "Coprocessor 3 ISA is CDEv1",
321 .dependencies = featureSet(&[_]Feature{
322 .cde,
323 }),
324 };
325 result[@intFromEnum(Feature.cdecp4)] = .{
326 .llvm_name = "cdecp4",
327 .description = "Coprocessor 4 ISA is CDEv1",
328 .dependencies = featureSet(&[_]Feature{
329 .cde,
330 }),
331 };
332 result[@intFromEnum(Feature.cdecp5)] = .{
333 .llvm_name = "cdecp5",
334 .description = "Coprocessor 5 ISA is CDEv1",
335 .dependencies = featureSet(&[_]Feature{
336 .cde,
337 }),
338 };
339 result[@intFromEnum(Feature.cdecp6)] = .{
340 .llvm_name = "cdecp6",
341 .description = "Coprocessor 6 ISA is CDEv1",
342 .dependencies = featureSet(&[_]Feature{
343 .cde,
344 }),
345 };
346 result[@intFromEnum(Feature.cdecp7)] = .{
347 .llvm_name = "cdecp7",
348 .description = "Coprocessor 7 ISA is CDEv1",
349 .dependencies = featureSet(&[_]Feature{
350 .cde,
351 }),
352 };
353 result[@intFromEnum(Feature.cheap_predicable_cpsr)] = .{
354 .llvm_name = "cheap-predicable-cpsr",
355 .description = "Disable +1 predication cost for instructions updating CPSR",
356 .dependencies = featureSet(&[_]Feature{}),
357 };
358 result[@intFromEnum(Feature.clrbhb)] = .{
359 .llvm_name = "clrbhb",
360 .description = "Enable Clear BHB instruction",
361 .dependencies = featureSet(&[_]Feature{}),
362 };
363 result[@intFromEnum(Feature.crc)] = .{
364 .llvm_name = "crc",
365 .description = "Enable support for CRC instructions",
366 .dependencies = featureSet(&[_]Feature{}),
367 };
368 result[@intFromEnum(Feature.crypto)] = .{
369 .llvm_name = "crypto",
370 .description = "Enable support for Cryptography extensions",
371 .dependencies = featureSet(&[_]Feature{
372 .aes,
373 .sha2,
374 }),
375 };
376 result[@intFromEnum(Feature.d32)] = .{
377 .llvm_name = "d32",
378 .description = "Extend FP to 32 double registers",
379 .dependencies = featureSet(&[_]Feature{}),
380 };
381 result[@intFromEnum(Feature.db)] = .{
382 .llvm_name = "db",
383 .description = "Has data barrier (dmb/dsb) instructions",
384 .dependencies = featureSet(&[_]Feature{}),
385 };
386 result[@intFromEnum(Feature.dfb)] = .{
387 .llvm_name = "dfb",
388 .description = "Has full data barrier (dfb) instruction",
389 .dependencies = featureSet(&[_]Feature{}),
390 };
391 result[@intFromEnum(Feature.disable_postra_scheduler)] = .{
392 .llvm_name = "disable-postra-scheduler",
393 .description = "Don't schedule again after register allocation",
394 .dependencies = featureSet(&[_]Feature{}),
395 };
396 result[@intFromEnum(Feature.dont_widen_vmovs)] = .{
397 .llvm_name = "dont-widen-vmovs",
398 .description = "Don't widen VMOVS to VMOVD",
399 .dependencies = featureSet(&[_]Feature{}),
400 };
401 result[@intFromEnum(Feature.dotprod)] = .{
402 .llvm_name = "dotprod",
403 .description = "Enable support for dot product instructions",
404 .dependencies = featureSet(&[_]Feature{
405 .neon,
406 }),
407 };
408 result[@intFromEnum(Feature.dsp)] = .{
409 .llvm_name = "dsp",
410 .description = "Supports DSP instructions in ARM and/or Thumb2",
411 .dependencies = featureSet(&[_]Feature{}),
412 };
413 result[@intFromEnum(Feature.execute_only)] = .{
414 .llvm_name = "execute-only",
415 .description = "Enable the generation of execute only code.",
416 .dependencies = featureSet(&[_]Feature{}),
417 };
418 result[@intFromEnum(Feature.expand_fp_mlx)] = .{
419 .llvm_name = "expand-fp-mlx",
420 .description = "Expand VFP/NEON MLA/MLS instructions",
421 .dependencies = featureSet(&[_]Feature{}),
422 };
423 result[@intFromEnum(Feature.exynos)] = .{
424 .llvm_name = "exynos",
425 .description = "Samsung Exynos processors",
426 .dependencies = featureSet(&[_]Feature{
427 .crc,
428 .crypto,
429 .expand_fp_mlx,
430 .fuse_aes,
431 .fuse_literals,
432 .hwdiv,
433 .hwdiv_arm,
434 .prof_unpr,
435 .ret_addr_stack,
436 .slow_fp_brcc,
437 .slow_vdup32,
438 .slow_vgetlni32,
439 .slowfpvfmx,
440 .slowfpvmlx,
441 .splat_vfp_neon,
442 .wide_stride_vfp,
443 .zcz,
444 }),
445 };
446 result[@intFromEnum(Feature.fix_cmse_cve_2021_35465)] = .{
447 .llvm_name = "fix-cmse-cve-2021-35465",
448 .description = "Mitigate against the cve-2021-35465 security vulnurability",
449 .dependencies = featureSet(&[_]Feature{}),
450 };
451 result[@intFromEnum(Feature.fix_cortex_a57_aes_1742098)] = .{
452 .llvm_name = "fix-cortex-a57-aes-1742098",
453 .description = "Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)",
454 .dependencies = featureSet(&[_]Feature{}),
455 };
456 result[@intFromEnum(Feature.fp16)] = .{
457 .llvm_name = "fp16",
458 .description = "Enable half-precision floating point",
459 .dependencies = featureSet(&[_]Feature{}),
460 };
461 result[@intFromEnum(Feature.fp16fml)] = .{
462 .llvm_name = "fp16fml",
463 .description = "Enable full half-precision floating point fml instructions",
464 .dependencies = featureSet(&[_]Feature{
465 .fullfp16,
466 }),
467 };
468 result[@intFromEnum(Feature.fp64)] = .{
469 .llvm_name = "fp64",
470 .description = "Floating point unit supports double precision",
471 .dependencies = featureSet(&[_]Feature{
472 .fpregs64,
473 }),
474 };
475 result[@intFromEnum(Feature.fp_armv8)] = .{
476 .llvm_name = "fp-armv8",
477 .description = "Enable ARMv8 FP",
478 .dependencies = featureSet(&[_]Feature{
479 .fp_armv8d16,
480 .fp_armv8sp,
481 .vfp4,
482 }),
483 };
484 result[@intFromEnum(Feature.fp_armv8d16)] = .{
485 .llvm_name = "fp-armv8d16",
486 .description = "Enable ARMv8 FP with only 16 d-registers",
487 .dependencies = featureSet(&[_]Feature{
488 .fp_armv8d16sp,
489 .vfp4d16,
490 }),
491 };
492 result[@intFromEnum(Feature.fp_armv8d16sp)] = .{
493 .llvm_name = "fp-armv8d16sp",
494 .description = "Enable ARMv8 FP with only 16 d-registers and no double precision",
495 .dependencies = featureSet(&[_]Feature{
496 .vfp4d16sp,
497 }),
498 };
499 result[@intFromEnum(Feature.fp_armv8sp)] = .{
500 .llvm_name = "fp-armv8sp",
501 .description = "Enable ARMv8 FP with no double precision",
502 .dependencies = featureSet(&[_]Feature{
503 .fp_armv8d16sp,
504 .vfp4sp,
505 }),
506 };
507 result[@intFromEnum(Feature.fpao)] = .{
508 .llvm_name = "fpao",
509 .description = "Enable fast computation of positive address offsets",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@intFromEnum(Feature.fpregs)] = .{
513 .llvm_name = "fpregs",
514 .description = "Enable FP registers",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@intFromEnum(Feature.fpregs16)] = .{
518 .llvm_name = "fpregs16",
519 .description = "Enable 16-bit FP registers",
520 .dependencies = featureSet(&[_]Feature{
521 .fpregs,
522 }),
523 };
524 result[@intFromEnum(Feature.fpregs64)] = .{
525 .llvm_name = "fpregs64",
526 .description = "Enable 64-bit FP registers",
527 .dependencies = featureSet(&[_]Feature{
528 .fpregs,
529 }),
530 };
531 result[@intFromEnum(Feature.fullfp16)] = .{
532 .llvm_name = "fullfp16",
533 .description = "Enable full half-precision floating point",
534 .dependencies = featureSet(&[_]Feature{
535 .fp_armv8d16sp,
536 .fpregs16,
537 }),
538 };
539 result[@intFromEnum(Feature.fuse_aes)] = .{
540 .llvm_name = "fuse-aes",
541 .description = "CPU fuses AES crypto operations",
542 .dependencies = featureSet(&[_]Feature{}),
543 };
544 result[@intFromEnum(Feature.fuse_literals)] = .{
545 .llvm_name = "fuse-literals",
546 .description = "CPU fuses literal generation operations",
547 .dependencies = featureSet(&[_]Feature{}),
548 };
549 result[@intFromEnum(Feature.harden_sls_blr)] = .{
550 .llvm_name = "harden-sls-blr",
551 .description = "Harden against straight line speculation across indirect calls",
552 .dependencies = featureSet(&[_]Feature{}),
553 };
554 result[@intFromEnum(Feature.harden_sls_nocomdat)] = .{
555 .llvm_name = "harden-sls-nocomdat",
556 .description = "Generate thunk code for SLS mitigation in the normal text section",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
559 result[@intFromEnum(Feature.harden_sls_retbr)] = .{
560 .llvm_name = "harden-sls-retbr",
561 .description = "Harden against straight line speculation across RETurn and BranchRegister instructions",
562 .dependencies = featureSet(&[_]Feature{}),
563 };
564 result[@intFromEnum(Feature.has_v4t)] = .{
565 .llvm_name = "v4t",
566 .description = "Support ARM v4T instructions",
567 .dependencies = featureSet(&[_]Feature{}),
568 };
569 result[@intFromEnum(Feature.has_v5t)] = .{
570 .llvm_name = "v5t",
571 .description = "Support ARM v5T instructions",
572 .dependencies = featureSet(&[_]Feature{
573 .has_v4t,
574 }),
575 };
576 result[@intFromEnum(Feature.has_v5te)] = .{
577 .llvm_name = "v5te",
578 .description = "Support ARM v5TE, v5TEj, and v5TExp instructions",
579 .dependencies = featureSet(&[_]Feature{
580 .has_v5t,
581 }),
582 };
583 result[@intFromEnum(Feature.has_v6)] = .{
584 .llvm_name = "v6",
585 .description = "Support ARM v6 instructions",
586 .dependencies = featureSet(&[_]Feature{
587 .has_v5te,
588 }),
589 };
590 result[@intFromEnum(Feature.has_v6k)] = .{
591 .llvm_name = "v6k",
592 .description = "Support ARM v6k instructions",
593 .dependencies = featureSet(&[_]Feature{
594 .has_v6,
595 }),
596 };
597 result[@intFromEnum(Feature.has_v6m)] = .{
598 .llvm_name = "v6m",
599 .description = "Support ARM v6M instructions",
600 .dependencies = featureSet(&[_]Feature{
601 .has_v6,
602 }),
603 };
604 result[@intFromEnum(Feature.has_v6t2)] = .{
605 .llvm_name = "v6t2",
606 .description = "Support ARM v6t2 instructions",
607 .dependencies = featureSet(&[_]Feature{
608 .has_v6k,
609 .has_v8m,
610 .thumb2,
611 }),
612 };
613 result[@intFromEnum(Feature.has_v7)] = .{
614 .llvm_name = "v7",
615 .description = "Support ARM v7 instructions",
616 .dependencies = featureSet(&[_]Feature{
617 .has_v6t2,
618 .has_v7clrex,
619 }),
620 };
621 result[@intFromEnum(Feature.has_v7clrex)] = .{
622 .llvm_name = "v7clrex",
623 .description = "Has v7 clrex instruction",
624 .dependencies = featureSet(&[_]Feature{}),
625 };
626 result[@intFromEnum(Feature.has_v8)] = .{
627 .llvm_name = "v8",
628 .description = "Support ARM v8 instructions",
629 .dependencies = featureSet(&[_]Feature{
630 .acquire_release,
631 .has_v7,
632 .perfmon,
633 }),
634 };
635 result[@intFromEnum(Feature.has_v8_1a)] = .{
636 .llvm_name = "v8.1a",
637 .description = "Support ARM v8.1a instructions",
638 .dependencies = featureSet(&[_]Feature{
639 .has_v8,
640 }),
641 };
642 result[@intFromEnum(Feature.has_v8_1m_main)] = .{
643 .llvm_name = "v8.1m.main",
644 .description = "Support ARM v8-1M Mainline instructions",
645 .dependencies = featureSet(&[_]Feature{
646 .has_v8m_main,
647 }),
648 };
649 result[@intFromEnum(Feature.has_v8_2a)] = .{
650 .llvm_name = "v8.2a",
651 .description = "Support ARM v8.2a instructions",
652 .dependencies = featureSet(&[_]Feature{
653 .has_v8_1a,
654 }),
655 };
656 result[@intFromEnum(Feature.has_v8_3a)] = .{
657 .llvm_name = "v8.3a",
658 .description = "Support ARM v8.3a instructions",
659 .dependencies = featureSet(&[_]Feature{
660 .has_v8_2a,
661 }),
662 };
663 result[@intFromEnum(Feature.has_v8_4a)] = .{
664 .llvm_name = "v8.4a",
665 .description = "Support ARM v8.4a instructions",
666 .dependencies = featureSet(&[_]Feature{
667 .dotprod,
668 .has_v8_3a,
669 }),
670 };
671 result[@intFromEnum(Feature.has_v8_5a)] = .{
672 .llvm_name = "v8.5a",
673 .description = "Support ARM v8.5a instructions",
674 .dependencies = featureSet(&[_]Feature{
675 .has_v8_4a,
676 .sb,
677 }),
678 };
679 result[@intFromEnum(Feature.has_v8_6a)] = .{
680 .llvm_name = "v8.6a",
681 .description = "Support ARM v8.6a instructions",
682 .dependencies = featureSet(&[_]Feature{
683 .bf16,
684 .has_v8_5a,
685 .i8mm,
686 }),
687 };
688 result[@intFromEnum(Feature.has_v8_7a)] = .{
689 .llvm_name = "v8.7a",
690 .description = "Support ARM v8.7a instructions",
691 .dependencies = featureSet(&[_]Feature{
692 .has_v8_6a,
693 }),
694 };
695 result[@intFromEnum(Feature.has_v8_8a)] = .{
696 .llvm_name = "v8.8a",
697 .description = "Support ARM v8.8a instructions",
698 .dependencies = featureSet(&[_]Feature{
699 .has_v8_7a,
700 }),
701 };
702 result[@intFromEnum(Feature.has_v8_9a)] = .{
703 .llvm_name = "v8.9a",
704 .description = "Support ARM v8.9a instructions",
705 .dependencies = featureSet(&[_]Feature{
706 .clrbhb,
707 .has_v8_8a,
708 }),
709 };
710 result[@intFromEnum(Feature.has_v8m)] = .{
711 .llvm_name = "v8m",
712 .description = "Support ARM v8M Baseline instructions",
713 .dependencies = featureSet(&[_]Feature{
714 .has_v6m,
715 }),
716 };
717 result[@intFromEnum(Feature.has_v8m_main)] = .{
718 .llvm_name = "v8m.main",
719 .description = "Support ARM v8M Mainline instructions",
720 .dependencies = featureSet(&[_]Feature{
721 .has_v7,
722 }),
723 };
724 result[@intFromEnum(Feature.has_v9_1a)] = .{
725 .llvm_name = "v9.1a",
726 .description = "Support ARM v9.1a instructions",
727 .dependencies = featureSet(&[_]Feature{
728 .has_v8_6a,
729 .has_v9a,
730 }),
731 };
732 result[@intFromEnum(Feature.has_v9_2a)] = .{
733 .llvm_name = "v9.2a",
734 .description = "Support ARM v9.2a instructions",
735 .dependencies = featureSet(&[_]Feature{
736 .has_v8_7a,
737 .has_v9_1a,
738 }),
739 };
740 result[@intFromEnum(Feature.has_v9_3a)] = .{
741 .llvm_name = "v9.3a",
742 .description = "Support ARM v9.3a instructions",
743 .dependencies = featureSet(&[_]Feature{
744 .has_v8_8a,
745 .has_v9_2a,
746 }),
747 };
748 result[@intFromEnum(Feature.has_v9_4a)] = .{
749 .llvm_name = "v9.4a",
750 .description = "Support ARM v9.4a instructions",
751 .dependencies = featureSet(&[_]Feature{
752 .has_v8_9a,
753 .has_v9_3a,
754 }),
755 };
756 result[@intFromEnum(Feature.has_v9a)] = .{
757 .llvm_name = "v9a",
758 .description = "Support ARM v9a instructions",
759 .dependencies = featureSet(&[_]Feature{
760 .has_v8_5a,
761 }),
762 };
763 result[@intFromEnum(Feature.hwdiv)] = .{
764 .llvm_name = "hwdiv",
765 .description = "Enable divide instructions in Thumb",
766 .dependencies = featureSet(&[_]Feature{}),
767 };
768 result[@intFromEnum(Feature.hwdiv_arm)] = .{
769 .llvm_name = "hwdiv-arm",
770 .description = "Enable divide instructions in ARM mode",
771 .dependencies = featureSet(&[_]Feature{}),
772 };
773 result[@intFromEnum(Feature.i8mm)] = .{
774 .llvm_name = "i8mm",
775 .description = "Enable Matrix Multiply Int8 Extension",
776 .dependencies = featureSet(&[_]Feature{
777 .neon,
778 }),
779 };
780 result[@intFromEnum(Feature.iwmmxt)] = .{
781 .llvm_name = "iwmmxt",
782 .description = "ARMv5te architecture",
783 .dependencies = featureSet(&[_]Feature{
784 .v5te,
785 }),
786 };
787 result[@intFromEnum(Feature.iwmmxt2)] = .{
788 .llvm_name = "iwmmxt2",
789 .description = "ARMv5te architecture",
790 .dependencies = featureSet(&[_]Feature{
791 .v5te,
792 }),
793 };
794 result[@intFromEnum(Feature.lob)] = .{
795 .llvm_name = "lob",
796 .description = "Enable Low Overhead Branch extensions",
797 .dependencies = featureSet(&[_]Feature{}),
798 };
799 result[@intFromEnum(Feature.long_calls)] = .{
800 .llvm_name = "long-calls",
801 .description = "Generate calls via indirect call instructions",
802 .dependencies = featureSet(&[_]Feature{}),
803 };
804 result[@intFromEnum(Feature.loop_align)] = .{
805 .llvm_name = "loop-align",
806 .description = "Prefer 32-bit alignment for loops",
807 .dependencies = featureSet(&[_]Feature{}),
808 };
809 result[@intFromEnum(Feature.m3)] = .{
810 .llvm_name = "m3",
811 .description = "Cortex-M3 ARM processors",
812 .dependencies = featureSet(&[_]Feature{}),
813 };
814 result[@intFromEnum(Feature.mclass)] = .{
815 .llvm_name = "mclass",
816 .description = "Is microcontroller profile ('M' series)",
817 .dependencies = featureSet(&[_]Feature{}),
818 };
819 result[@intFromEnum(Feature.mp)] = .{
820 .llvm_name = "mp",
821 .description = "Supports Multiprocessing extension",
822 .dependencies = featureSet(&[_]Feature{}),
823 };
824 result[@intFromEnum(Feature.muxed_units)] = .{
825 .llvm_name = "muxed-units",
826 .description = "Has muxed AGU and NEON/FPU",
827 .dependencies = featureSet(&[_]Feature{}),
828 };
829 result[@intFromEnum(Feature.mve)] = .{
830 .llvm_name = "mve",
831 .description = "Support M-Class Vector Extension with integer ops",
832 .dependencies = featureSet(&[_]Feature{
833 .dsp,
834 .fpregs16,
835 .fpregs64,
836 .has_v8_1m_main,
837 }),
838 };
839 result[@intFromEnum(Feature.mve1beat)] = .{
840 .llvm_name = "mve1beat",
841 .description = "Model MVE instructions as a 1 beat per tick architecture",
842 .dependencies = featureSet(&[_]Feature{}),
843 };
844 result[@intFromEnum(Feature.mve2beat)] = .{
845 .llvm_name = "mve2beat",
846 .description = "Model MVE instructions as a 2 beats per tick architecture",
847 .dependencies = featureSet(&[_]Feature{}),
848 };
849 result[@intFromEnum(Feature.mve4beat)] = .{
850 .llvm_name = "mve4beat",
851 .description = "Model MVE instructions as a 4 beats per tick architecture",
852 .dependencies = featureSet(&[_]Feature{}),
853 };
854 result[@intFromEnum(Feature.mve_fp)] = .{
855 .llvm_name = "mve.fp",
856 .description = "Support M-Class Vector Extension with integer and floating ops",
857 .dependencies = featureSet(&[_]Feature{
858 .fullfp16,
859 .mve,
860 }),
861 };
862 result[@intFromEnum(Feature.nacl_trap)] = .{
863 .llvm_name = "nacl-trap",
864 .description = "NaCl trap",
865 .dependencies = featureSet(&[_]Feature{}),
866 };
867 result[@intFromEnum(Feature.neon)] = .{
868 .llvm_name = "neon",
869 .description = "Enable NEON instructions",
870 .dependencies = featureSet(&[_]Feature{
871 .vfp3,
872 }),
873 };
874 result[@intFromEnum(Feature.neon_fpmovs)] = .{
875 .llvm_name = "neon-fpmovs",
876 .description = "Convert VMOVSR, VMOVRS, VMOVS to NEON",
877 .dependencies = featureSet(&[_]Feature{}),
878 };
879 result[@intFromEnum(Feature.neonfp)] = .{
880 .llvm_name = "neonfp",
881 .description = "Use NEON for single precision FP",
882 .dependencies = featureSet(&[_]Feature{}),
883 };
884 result[@intFromEnum(Feature.no_branch_predictor)] = .{
885 .llvm_name = "no-branch-predictor",
886 .description = "Has no branch predictor",
887 .dependencies = featureSet(&[_]Feature{}),
888 };
889 result[@intFromEnum(Feature.no_bti_at_return_twice)] = .{
890 .llvm_name = "no-bti-at-return-twice",
891 .description = "Don't place a BTI instruction after a return-twice",
892 .dependencies = featureSet(&[_]Feature{}),
893 };
894 result[@intFromEnum(Feature.no_movt)] = .{
895 .llvm_name = "no-movt",
896 .description = "Don't use movt/movw pairs for 32-bit imms",
897 .dependencies = featureSet(&[_]Feature{}),
898 };
899 result[@intFromEnum(Feature.no_neg_immediates)] = .{
900 .llvm_name = "no-neg-immediates",
901 .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
902 .dependencies = featureSet(&[_]Feature{}),
903 };
904 result[@intFromEnum(Feature.noarm)] = .{
905 .llvm_name = "noarm",
906 .description = "Does not support ARM mode execution",
907 .dependencies = featureSet(&[_]Feature{}),
908 };
909 result[@intFromEnum(Feature.nonpipelined_vfp)] = .{
910 .llvm_name = "nonpipelined-vfp",
911 .description = "VFP instructions are not pipelined",
912 .dependencies = featureSet(&[_]Feature{}),
913 };
914 result[@intFromEnum(Feature.pacbti)] = .{
915 .llvm_name = "pacbti",
916 .description = "Enable Pointer Authentication and Branch Target Identification",
917 .dependencies = featureSet(&[_]Feature{}),
918 };
919 result[@intFromEnum(Feature.perfmon)] = .{
920 .llvm_name = "perfmon",
921 .description = "Enable support for Performance Monitor extensions",
922 .dependencies = featureSet(&[_]Feature{}),
923 };
924 result[@intFromEnum(Feature.prefer_ishst)] = .{
925 .llvm_name = "prefer-ishst",
926 .description = "Prefer ISHST barriers",
927 .dependencies = featureSet(&[_]Feature{}),
928 };
929 result[@intFromEnum(Feature.prefer_vmovsr)] = .{
930 .llvm_name = "prefer-vmovsr",
931 .description = "Prefer VMOVSR",
932 .dependencies = featureSet(&[_]Feature{}),
933 };
934 result[@intFromEnum(Feature.prof_unpr)] = .{
935 .llvm_name = "prof-unpr",
936 .description = "Is profitable to unpredicate",
937 .dependencies = featureSet(&[_]Feature{}),
938 };
939 result[@intFromEnum(Feature.r4)] = .{
940 .llvm_name = "r4",
941 .description = "Cortex-R4 ARM processors",
942 .dependencies = featureSet(&[_]Feature{}),
943 };
944 result[@intFromEnum(Feature.ras)] = .{
945 .llvm_name = "ras",
946 .description = "Enable Reliability, Availability and Serviceability extensions",
947 .dependencies = featureSet(&[_]Feature{}),
948 };
949 result[@intFromEnum(Feature.rclass)] = .{
950 .llvm_name = "rclass",
951 .description = "Is realtime profile ('R' series)",
952 .dependencies = featureSet(&[_]Feature{}),
953 };
954 result[@intFromEnum(Feature.read_tp_tpidrprw)] = .{
955 .llvm_name = "read-tp-tpidrprw",
956 .description = "Reading thread pointer from TPIDRPRW register",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.read_tp_tpidruro)] = .{
960 .llvm_name = "read-tp-tpidruro",
961 .description = "Reading thread pointer from TPIDRURO register",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.read_tp_tpidrurw)] = .{
965 .llvm_name = "read-tp-tpidrurw",
966 .description = "Reading thread pointer from TPIDRURW register",
967 .dependencies = featureSet(&[_]Feature{}),
968 };
969 result[@intFromEnum(Feature.reserve_r9)] = .{
970 .llvm_name = "reserve-r9",
971 .description = "Reserve R9, making it unavailable as GPR",
972 .dependencies = featureSet(&[_]Feature{}),
973 };
974 result[@intFromEnum(Feature.ret_addr_stack)] = .{
975 .llvm_name = "ret-addr-stack",
976 .description = "Has return address stack",
977 .dependencies = featureSet(&[_]Feature{}),
978 };
979 result[@intFromEnum(Feature.sb)] = .{
980 .llvm_name = "sb",
981 .description = "Enable v8.5a Speculation Barrier",
982 .dependencies = featureSet(&[_]Feature{}),
983 };
984 result[@intFromEnum(Feature.sha2)] = .{
985 .llvm_name = "sha2",
986 .description = "Enable SHA1 and SHA256 support",
987 .dependencies = featureSet(&[_]Feature{
988 .neon,
989 }),
990 };
991 result[@intFromEnum(Feature.slow_fp_brcc)] = .{
992 .llvm_name = "slow-fp-brcc",
993 .description = "FP compare + branch is slow",
994 .dependencies = featureSet(&[_]Feature{}),
995 };
996 result[@intFromEnum(Feature.slow_load_D_subreg)] = .{
997 .llvm_name = "slow-load-D-subreg",
998 .description = "Loading into D subregs is slow",
999 .dependencies = featureSet(&[_]Feature{}),
1000 };
1001 result[@intFromEnum(Feature.slow_odd_reg)] = .{
1002 .llvm_name = "slow-odd-reg",
1003 .description = "VLDM/VSTM starting with an odd register is slow",
1004 .dependencies = featureSet(&[_]Feature{}),
1005 };
1006 result[@intFromEnum(Feature.slow_vdup32)] = .{
1007 .llvm_name = "slow-vdup32",
1008 .description = "Has slow VDUP32 - prefer VMOV",
1009 .dependencies = featureSet(&[_]Feature{}),
1010 };
1011 result[@intFromEnum(Feature.slow_vgetlni32)] = .{
1012 .llvm_name = "slow-vgetlni32",
1013 .description = "Has slow VGETLNi32 - prefer VMOV",
1014 .dependencies = featureSet(&[_]Feature{}),
1015 };
1016 result[@intFromEnum(Feature.slowfpvfmx)] = .{
1017 .llvm_name = "slowfpvfmx",
1018 .description = "Disable VFP / NEON FMA instructions",
1019 .dependencies = featureSet(&[_]Feature{}),
1020 };
1021 result[@intFromEnum(Feature.slowfpvmlx)] = .{
1022 .llvm_name = "slowfpvmlx",
1023 .description = "Disable VFP / NEON MAC instructions",
1024 .dependencies = featureSet(&[_]Feature{}),
1025 };
1026 result[@intFromEnum(Feature.soft_float)] = .{
1027 .llvm_name = "soft-float",
1028 .description = "Use software floating point features.",
1029 .dependencies = featureSet(&[_]Feature{}),
1030 };
1031 result[@intFromEnum(Feature.splat_vfp_neon)] = .{
1032 .llvm_name = "splat-vfp-neon",
1033 .description = "Splat register from VFP to NEON",
1034 .dependencies = featureSet(&[_]Feature{
1035 .dont_widen_vmovs,
1036 }),
1037 };
1038 result[@intFromEnum(Feature.strict_align)] = .{
1039 .llvm_name = "strict-align",
1040 .description = "Disallow all unaligned memory access",
1041 .dependencies = featureSet(&[_]Feature{}),
1042 };
1043 result[@intFromEnum(Feature.swift)] = .{
1044 .llvm_name = "swift",
1045 .description = "Swift ARM processors",
1046 .dependencies = featureSet(&[_]Feature{}),
1047 };
1048 result[@intFromEnum(Feature.thumb2)] = .{
1049 .llvm_name = "thumb2",
1050 .description = "Enable Thumb2 instructions",
1051 .dependencies = featureSet(&[_]Feature{}),
1052 };
1053 result[@intFromEnum(Feature.thumb_mode)] = .{
1054 .llvm_name = "thumb-mode",
1055 .description = "Thumb mode",
1056 .dependencies = featureSet(&[_]Feature{}),
1057 };
1058 result[@intFromEnum(Feature.trustzone)] = .{
1059 .llvm_name = "trustzone",
1060 .description = "Enable support for TrustZone security extensions",
1061 .dependencies = featureSet(&[_]Feature{}),
1062 };
1063 result[@intFromEnum(Feature.use_mipipeliner)] = .{
1064 .llvm_name = "use-mipipeliner",
1065 .description = "Use the MachinePipeliner",
1066 .dependencies = featureSet(&[_]Feature{}),
1067 };
1068 result[@intFromEnum(Feature.use_misched)] = .{
1069 .llvm_name = "use-misched",
1070 .description = "Use the MachineScheduler",
1071 .dependencies = featureSet(&[_]Feature{}),
1072 };
1073 result[@intFromEnum(Feature.v2)] = .{
1074 .llvm_name = null,
1075 .description = "ARMv2 architecture",
1076 .dependencies = featureSet(&[_]Feature{
1077 .strict_align,
1078 }),
1079 };
1080 result[@intFromEnum(Feature.v2a)] = .{
1081 .llvm_name = null,
1082 .description = "ARMv2a architecture",
1083 .dependencies = featureSet(&[_]Feature{
1084 .strict_align,
1085 }),
1086 };
1087 result[@intFromEnum(Feature.v3)] = .{
1088 .llvm_name = null,
1089 .description = "ARMv3 architecture",
1090 .dependencies = featureSet(&[_]Feature{
1091 .strict_align,
1092 }),
1093 };
1094 result[@intFromEnum(Feature.v3m)] = .{
1095 .llvm_name = null,
1096 .description = "ARMv3m architecture",
1097 .dependencies = featureSet(&[_]Feature{
1098 .strict_align,
1099 }),
1100 };
1101 result[@intFromEnum(Feature.v4)] = .{
1102 .llvm_name = "armv4",
1103 .description = "ARMv4 architecture",
1104 .dependencies = featureSet(&[_]Feature{
1105 .strict_align,
1106 }),
1107 };
1108 result[@intFromEnum(Feature.v4t)] = .{
1109 .llvm_name = "armv4t",
1110 .description = "ARMv4t architecture",
1111 .dependencies = featureSet(&[_]Feature{
1112 .has_v4t,
1113 .strict_align,
1114 }),
1115 };
1116 result[@intFromEnum(Feature.v5t)] = .{
1117 .llvm_name = "armv5t",
1118 .description = "ARMv5t architecture",
1119 .dependencies = featureSet(&[_]Feature{
1120 .has_v5t,
1121 .strict_align,
1122 }),
1123 };
1124 result[@intFromEnum(Feature.v5te)] = .{
1125 .llvm_name = "armv5te",
1126 .description = "ARMv5te architecture",
1127 .dependencies = featureSet(&[_]Feature{
1128 .has_v5te,
1129 .strict_align,
1130 }),
1131 };
1132 result[@intFromEnum(Feature.v5tej)] = .{
1133 .llvm_name = "armv5tej",
1134 .description = "ARMv5tej architecture",
1135 .dependencies = featureSet(&[_]Feature{
1136 .has_v5te,
1137 .strict_align,
1138 }),
1139 };
1140 result[@intFromEnum(Feature.v6)] = .{
1141 .llvm_name = "armv6",
1142 .description = "ARMv6 architecture",
1143 .dependencies = featureSet(&[_]Feature{
1144 .dsp,
1145 .has_v6,
1146 }),
1147 };
1148 result[@intFromEnum(Feature.v6j)] = .{
1149 .llvm_name = "armv6j",
1150 .description = "ARMv7a architecture",
1151 .dependencies = featureSet(&[_]Feature{
1152 .v6,
1153 }),
1154 };
1155 result[@intFromEnum(Feature.v6k)] = .{
1156 .llvm_name = "armv6k",
1157 .description = "ARMv6k architecture",
1158 .dependencies = featureSet(&[_]Feature{
1159 .has_v6k,
1160 }),
1161 };
1162 result[@intFromEnum(Feature.v6kz)] = .{
1163 .llvm_name = "armv6kz",
1164 .description = "ARMv6kz architecture",
1165 .dependencies = featureSet(&[_]Feature{
1166 .has_v6k,
1167 .trustzone,
1168 }),
1169 };
1170 result[@intFromEnum(Feature.v6m)] = .{
1171 .llvm_name = "armv6-m",
1172 .description = "ARMv6m architecture",
1173 .dependencies = featureSet(&[_]Feature{
1174 .db,
1175 .has_v6m,
1176 .mclass,
1177 .noarm,
1178 .strict_align,
1179 .thumb_mode,
1180 }),
1181 };
1182 result[@intFromEnum(Feature.v6sm)] = .{
1183 .llvm_name = "armv6s-m",
1184 .description = "ARMv6sm architecture",
1185 .dependencies = featureSet(&[_]Feature{
1186 .db,
1187 .has_v6m,
1188 .mclass,
1189 .noarm,
1190 .strict_align,
1191 .thumb_mode,
1192 }),
1193 };
1194 result[@intFromEnum(Feature.v6t2)] = .{
1195 .llvm_name = "armv6t2",
1196 .description = "ARMv6t2 architecture",
1197 .dependencies = featureSet(&[_]Feature{
1198 .dsp,
1199 .has_v6t2,
1200 }),
1201 };
1202 result[@intFromEnum(Feature.v7a)] = .{
1203 .llvm_name = "armv7-a",
1204 .description = "ARMv7a architecture",
1205 .dependencies = featureSet(&[_]Feature{
1206 .aclass,
1207 .db,
1208 .dsp,
1209 .has_v7,
1210 .neon,
1211 .perfmon,
1212 }),
1213 };
1214 result[@intFromEnum(Feature.v7em)] = .{
1215 .llvm_name = "armv7e-m",
1216 .description = "ARMv7em architecture",
1217 .dependencies = featureSet(&[_]Feature{
1218 .db,
1219 .dsp,
1220 .has_v7,
1221 .hwdiv,
1222 .mclass,
1223 .noarm,
1224 .thumb_mode,
1225 }),
1226 };
1227 result[@intFromEnum(Feature.v7k)] = .{
1228 .llvm_name = "armv7k",
1229 .description = "ARMv7a architecture",
1230 .dependencies = featureSet(&[_]Feature{
1231 .v7a,
1232 }),
1233 };
1234 result[@intFromEnum(Feature.v7m)] = .{
1235 .llvm_name = "armv7-m",
1236 .description = "ARMv7m architecture",
1237 .dependencies = featureSet(&[_]Feature{
1238 .db,
1239 .has_v7,
1240 .hwdiv,
1241 .mclass,
1242 .noarm,
1243 .thumb_mode,
1244 }),
1245 };
1246 result[@intFromEnum(Feature.v7r)] = .{
1247 .llvm_name = "armv7-r",
1248 .description = "ARMv7r architecture",
1249 .dependencies = featureSet(&[_]Feature{
1250 .db,
1251 .dsp,
1252 .has_v7,
1253 .hwdiv,
1254 .perfmon,
1255 .rclass,
1256 }),
1257 };
1258 result[@intFromEnum(Feature.v7s)] = .{
1259 .llvm_name = "armv7s",
1260 .description = "ARMv7a architecture",
1261 .dependencies = featureSet(&[_]Feature{
1262 .v7a,
1263 }),
1264 };
1265 result[@intFromEnum(Feature.v7ve)] = .{
1266 .llvm_name = "armv7ve",
1267 .description = "ARMv7ve architecture",
1268 .dependencies = featureSet(&[_]Feature{
1269 .aclass,
1270 .db,
1271 .dsp,
1272 .has_v7,
1273 .mp,
1274 .neon,
1275 .perfmon,
1276 .trustzone,
1277 .virtualization,
1278 }),
1279 };
1280 result[@intFromEnum(Feature.v8_1a)] = .{
1281 .llvm_name = "armv8.1-a",
1282 .description = "ARMv81a architecture",
1283 .dependencies = featureSet(&[_]Feature{
1284 .aclass,
1285 .crc,
1286 .crypto,
1287 .db,
1288 .dsp,
1289 .fp_armv8,
1290 .has_v8_1a,
1291 .mp,
1292 .trustzone,
1293 .virtualization,
1294 }),
1295 };
1296 result[@intFromEnum(Feature.v8_1m_main)] = .{
1297 .llvm_name = "armv8.1-m.main",
1298 .description = "ARMv81mMainline architecture",
1299 .dependencies = featureSet(&[_]Feature{
1300 .@"8msecext",
1301 .acquire_release,
1302 .db,
1303 .has_v8_1m_main,
1304 .hwdiv,
1305 .lob,
1306 .mclass,
1307 .noarm,
1308 .ras,
1309 .thumb_mode,
1310 }),
1311 };
1312 result[@intFromEnum(Feature.v8_2a)] = .{
1313 .llvm_name = "armv8.2-a",
1314 .description = "ARMv82a architecture",
1315 .dependencies = featureSet(&[_]Feature{
1316 .aclass,
1317 .crc,
1318 .crypto,
1319 .db,
1320 .dsp,
1321 .fp_armv8,
1322 .has_v8_2a,
1323 .mp,
1324 .ras,
1325 .trustzone,
1326 .virtualization,
1327 }),
1328 };
1329 result[@intFromEnum(Feature.v8_3a)] = .{
1330 .llvm_name = "armv8.3-a",
1331 .description = "ARMv83a architecture",
1332 .dependencies = featureSet(&[_]Feature{
1333 .aclass,
1334 .crc,
1335 .crypto,
1336 .db,
1337 .dsp,
1338 .fp_armv8,
1339 .has_v8_3a,
1340 .mp,
1341 .ras,
1342 .trustzone,
1343 .virtualization,
1344 }),
1345 };
1346 result[@intFromEnum(Feature.v8_4a)] = .{
1347 .llvm_name = "armv8.4-a",
1348 .description = "ARMv84a architecture",
1349 .dependencies = featureSet(&[_]Feature{
1350 .aclass,
1351 .crc,
1352 .crypto,
1353 .db,
1354 .dsp,
1355 .fp_armv8,
1356 .has_v8_4a,
1357 .mp,
1358 .ras,
1359 .trustzone,
1360 .virtualization,
1361 }),
1362 };
1363 result[@intFromEnum(Feature.v8_5a)] = .{
1364 .llvm_name = "armv8.5-a",
1365 .description = "ARMv85a architecture",
1366 .dependencies = featureSet(&[_]Feature{
1367 .aclass,
1368 .crc,
1369 .crypto,
1370 .db,
1371 .dsp,
1372 .fp_armv8,
1373 .has_v8_5a,
1374 .mp,
1375 .ras,
1376 .trustzone,
1377 .virtualization,
1378 }),
1379 };
1380 result[@intFromEnum(Feature.v8_6a)] = .{
1381 .llvm_name = "armv8.6-a",
1382 .description = "ARMv86a architecture",
1383 .dependencies = featureSet(&[_]Feature{
1384 .aclass,
1385 .crc,
1386 .crypto,
1387 .db,
1388 .dsp,
1389 .fp_armv8,
1390 .has_v8_6a,
1391 .mp,
1392 .ras,
1393 .trustzone,
1394 .virtualization,
1395 }),
1396 };
1397 result[@intFromEnum(Feature.v8_7a)] = .{
1398 .llvm_name = "armv8.7-a",
1399 .description = "ARMv87a architecture",
1400 .dependencies = featureSet(&[_]Feature{
1401 .aclass,
1402 .crc,
1403 .crypto,
1404 .db,
1405 .dsp,
1406 .fp_armv8,
1407 .has_v8_7a,
1408 .mp,
1409 .ras,
1410 .trustzone,
1411 .virtualization,
1412 }),
1413 };
1414 result[@intFromEnum(Feature.v8_8a)] = .{
1415 .llvm_name = "armv8.8-a",
1416 .description = "ARMv88a architecture",
1417 .dependencies = featureSet(&[_]Feature{
1418 .aclass,
1419 .crc,
1420 .crypto,
1421 .db,
1422 .dsp,
1423 .fp_armv8,
1424 .has_v8_8a,
1425 .mp,
1426 .ras,
1427 .trustzone,
1428 .virtualization,
1429 }),
1430 };
1431 result[@intFromEnum(Feature.v8_9a)] = .{
1432 .llvm_name = "armv8.9-a",
1433 .description = "ARMv89a architecture",
1434 .dependencies = featureSet(&[_]Feature{
1435 .aclass,
1436 .crc,
1437 .crypto,
1438 .db,
1439 .dsp,
1440 .fp_armv8,
1441 .has_v8_9a,
1442 .mp,
1443 .ras,
1444 .trustzone,
1445 .virtualization,
1446 }),
1447 };
1448 result[@intFromEnum(Feature.v8a)] = .{
1449 .llvm_name = "armv8-a",
1450 .description = "ARMv8a architecture",
1451 .dependencies = featureSet(&[_]Feature{
1452 .aclass,
1453 .crc,
1454 .crypto,
1455 .db,
1456 .dsp,
1457 .fp_armv8,
1458 .has_v8,
1459 .mp,
1460 .trustzone,
1461 .virtualization,
1462 }),
1463 };
1464 result[@intFromEnum(Feature.v8m)] = .{
1465 .llvm_name = "armv8-m.base",
1466 .description = "ARMv8mBaseline architecture",
1467 .dependencies = featureSet(&[_]Feature{
1468 .@"8msecext",
1469 .acquire_release,
1470 .db,
1471 .has_v7clrex,
1472 .has_v8m,
1473 .hwdiv,
1474 .mclass,
1475 .noarm,
1476 .strict_align,
1477 .thumb_mode,
1478 }),
1479 };
1480 result[@intFromEnum(Feature.v8m_main)] = .{
1481 .llvm_name = "armv8-m.main",
1482 .description = "ARMv8mMainline architecture",
1483 .dependencies = featureSet(&[_]Feature{
1484 .@"8msecext",
1485 .acquire_release,
1486 .db,
1487 .has_v8m_main,
1488 .hwdiv,
1489 .mclass,
1490 .noarm,
1491 .thumb_mode,
1492 }),
1493 };
1494 result[@intFromEnum(Feature.v8r)] = .{
1495 .llvm_name = "armv8-r",
1496 .description = "ARMv8r architecture",
1497 .dependencies = featureSet(&[_]Feature{
1498 .crc,
1499 .db,
1500 .dfb,
1501 .dsp,
1502 .fp_armv8,
1503 .has_v8,
1504 .mp,
1505 .neon,
1506 .rclass,
1507 .virtualization,
1508 }),
1509 };
1510 result[@intFromEnum(Feature.v9_1a)] = .{
1511 .llvm_name = "armv9.1-a",
1512 .description = "ARMv91a architecture",
1513 .dependencies = featureSet(&[_]Feature{
1514 .aclass,
1515 .crc,
1516 .db,
1517 .dsp,
1518 .fp_armv8,
1519 .has_v9_1a,
1520 .mp,
1521 .ras,
1522 .trustzone,
1523 .virtualization,
1524 }),
1525 };
1526 result[@intFromEnum(Feature.v9_2a)] = .{
1527 .llvm_name = "armv9.2-a",
1528 .description = "ARMv92a architecture",
1529 .dependencies = featureSet(&[_]Feature{
1530 .aclass,
1531 .crc,
1532 .db,
1533 .dsp,
1534 .fp_armv8,
1535 .has_v9_2a,
1536 .mp,
1537 .ras,
1538 .trustzone,
1539 .virtualization,
1540 }),
1541 };
1542 result[@intFromEnum(Feature.v9_3a)] = .{
1543 .llvm_name = "armv9.3-a",
1544 .description = "ARMv93a architecture",
1545 .dependencies = featureSet(&[_]Feature{
1546 .aclass,
1547 .crc,
1548 .crypto,
1549 .db,
1550 .dsp,
1551 .fp_armv8,
1552 .has_v9_3a,
1553 .mp,
1554 .ras,
1555 .trustzone,
1556 .virtualization,
1557 }),
1558 };
1559 result[@intFromEnum(Feature.v9_4a)] = .{
1560 .llvm_name = "armv9.4-a",
1561 .description = "ARMv94a architecture",
1562 .dependencies = featureSet(&[_]Feature{
1563 .aclass,
1564 .crc,
1565 .db,
1566 .dsp,
1567 .fp_armv8,
1568 .has_v9_4a,
1569 .mp,
1570 .ras,
1571 .trustzone,
1572 .virtualization,
1573 }),
1574 };
1575 result[@intFromEnum(Feature.v9a)] = .{
1576 .llvm_name = "armv9-a",
1577 .description = "ARMv9a architecture",
1578 .dependencies = featureSet(&[_]Feature{
1579 .aclass,
1580 .crc,
1581 .db,
1582 .dsp,
1583 .fp_armv8,
1584 .has_v9a,
1585 .mp,
1586 .ras,
1587 .trustzone,
1588 .virtualization,
1589 }),
1590 };
1591 result[@intFromEnum(Feature.vfp2)] = .{
1592 .llvm_name = "vfp2",
1593 .description = "Enable VFP2 instructions",
1594 .dependencies = featureSet(&[_]Feature{
1595 .fp64,
1596 .vfp2sp,
1597 }),
1598 };
1599 result[@intFromEnum(Feature.vfp2sp)] = .{
1600 .llvm_name = "vfp2sp",
1601 .description = "Enable VFP2 instructions with no double precision",
1602 .dependencies = featureSet(&[_]Feature{
1603 .fpregs,
1604 }),
1605 };
1606 result[@intFromEnum(Feature.vfp3)] = .{
1607 .llvm_name = "vfp3",
1608 .description = "Enable VFP3 instructions",
1609 .dependencies = featureSet(&[_]Feature{
1610 .vfp3d16,
1611 .vfp3sp,
1612 }),
1613 };
1614 result[@intFromEnum(Feature.vfp3d16)] = .{
1615 .llvm_name = "vfp3d16",
1616 .description = "Enable VFP3 instructions with only 16 d-registers",
1617 .dependencies = featureSet(&[_]Feature{
1618 .vfp2,
1619 .vfp3d16sp,
1620 }),
1621 };
1622 result[@intFromEnum(Feature.vfp3d16sp)] = .{
1623 .llvm_name = "vfp3d16sp",
1624 .description = "Enable VFP3 instructions with only 16 d-registers and no double precision",
1625 .dependencies = featureSet(&[_]Feature{
1626 .vfp2sp,
1627 }),
1628 };
1629 result[@intFromEnum(Feature.vfp3sp)] = .{
1630 .llvm_name = "vfp3sp",
1631 .description = "Enable VFP3 instructions with no double precision",
1632 .dependencies = featureSet(&[_]Feature{
1633 .d32,
1634 .vfp3d16sp,
1635 }),
1636 };
1637 result[@intFromEnum(Feature.vfp4)] = .{
1638 .llvm_name = "vfp4",
1639 .description = "Enable VFP4 instructions",
1640 .dependencies = featureSet(&[_]Feature{
1641 .vfp3,
1642 .vfp4d16,
1643 .vfp4sp,
1644 }),
1645 };
1646 result[@intFromEnum(Feature.vfp4d16)] = .{
1647 .llvm_name = "vfp4d16",
1648 .description = "Enable VFP4 instructions with only 16 d-registers",
1649 .dependencies = featureSet(&[_]Feature{
1650 .vfp3d16,
1651 .vfp4d16sp,
1652 }),
1653 };
1654 result[@intFromEnum(Feature.vfp4d16sp)] = .{
1655 .llvm_name = "vfp4d16sp",
1656 .description = "Enable VFP4 instructions with only 16 d-registers and no double precision",
1657 .dependencies = featureSet(&[_]Feature{
1658 .fp16,
1659 .vfp3d16sp,
1660 }),
1661 };
1662 result[@intFromEnum(Feature.vfp4sp)] = .{
1663 .llvm_name = "vfp4sp",
1664 .description = "Enable VFP4 instructions with no double precision",
1665 .dependencies = featureSet(&[_]Feature{
1666 .vfp3sp,
1667 .vfp4d16sp,
1668 }),
1669 };
1670 result[@intFromEnum(Feature.virtualization)] = .{
1671 .llvm_name = "virtualization",
1672 .description = "Supports Virtualization extension",
1673 .dependencies = featureSet(&[_]Feature{
1674 .hwdiv,
1675 .hwdiv_arm,
1676 }),
1677 };
1678 result[@intFromEnum(Feature.vldn_align)] = .{
1679 .llvm_name = "vldn-align",
1680 .description = "Check for VLDn unaligned access",
1681 .dependencies = featureSet(&[_]Feature{}),
1682 };
1683 result[@intFromEnum(Feature.vmlx_forwarding)] = .{
1684 .llvm_name = "vmlx-forwarding",
1685 .description = "Has multiplier accumulator forwarding",
1686 .dependencies = featureSet(&[_]Feature{}),
1687 };
1688 result[@intFromEnum(Feature.vmlx_hazards)] = .{
1689 .llvm_name = "vmlx-hazards",
1690 .description = "Has VMLx hazards",
1691 .dependencies = featureSet(&[_]Feature{}),
1692 };
1693 result[@intFromEnum(Feature.wide_stride_vfp)] = .{
1694 .llvm_name = "wide-stride-vfp",
1695 .description = "Use a wide stride when allocating VFP registers",
1696 .dependencies = featureSet(&[_]Feature{}),
1697 };
1698 result[@intFromEnum(Feature.xscale)] = .{
1699 .llvm_name = "xscale",
1700 .description = "ARMv5te architecture",
1701 .dependencies = featureSet(&[_]Feature{
1702 .v5te,
1703 }),
1704 };
1705 result[@intFromEnum(Feature.zcz)] = .{
1706 .llvm_name = "zcz",
1707 .description = "Has zero-cycle zeroing instructions",
1708 .dependencies = featureSet(&[_]Feature{}),
1709 };
1710 const ti = @typeInfo(Feature);
1711 for (&result, 0..) |*elem, i| {
1712 elem.index = i;
1713 elem.name = ti.Enum.fields[i].name;
1714 }
1715 break :blk result;
1716};
1717
1718pub const cpu = struct {
1719 pub const arm1020e = CpuModel{
1720 .name = "arm1020e",
1721 .llvm_name = "arm1020e",
1722 .features = featureSet(&[_]Feature{
1723 .v5te,
1724 }),
1725 };
1726 pub const arm1020t = CpuModel{
1727 .name = "arm1020t",
1728 .llvm_name = "arm1020t",
1729 .features = featureSet(&[_]Feature{
1730 .v5t,
1731 }),
1732 };
1733 pub const arm1022e = CpuModel{
1734 .name = "arm1022e",
1735 .llvm_name = "arm1022e",
1736 .features = featureSet(&[_]Feature{
1737 .v5te,
1738 }),
1739 };
1740 pub const arm10e = CpuModel{
1741 .name = "arm10e",
1742 .llvm_name = "arm10e",
1743 .features = featureSet(&[_]Feature{
1744 .v5te,
1745 }),
1746 };
1747 pub const arm10tdmi = CpuModel{
1748 .name = "arm10tdmi",
1749 .llvm_name = "arm10tdmi",
1750 .features = featureSet(&[_]Feature{
1751 .v5t,
1752 }),
1753 };
1754 pub const arm1136j_s = CpuModel{
1755 .name = "arm1136j_s",
1756 .llvm_name = "arm1136j-s",
1757 .features = featureSet(&[_]Feature{
1758 .v6,
1759 }),
1760 };
1761 pub const arm1136jf_s = CpuModel{
1762 .name = "arm1136jf_s",
1763 .llvm_name = "arm1136jf-s",
1764 .features = featureSet(&[_]Feature{
1765 .slowfpvmlx,
1766 .v6,
1767 .vfp2,
1768 }),
1769 };
1770 pub const arm1156t2_s = CpuModel{
1771 .name = "arm1156t2_s",
1772 .llvm_name = "arm1156t2-s",
1773 .features = featureSet(&[_]Feature{
1774 .v6t2,
1775 }),
1776 };
1777 pub const arm1156t2f_s = CpuModel{
1778 .name = "arm1156t2f_s",
1779 .llvm_name = "arm1156t2f-s",
1780 .features = featureSet(&[_]Feature{
1781 .slowfpvmlx,
1782 .v6t2,
1783 .vfp2,
1784 }),
1785 };
1786 pub const arm1176jz_s = CpuModel{
1787 .name = "arm1176jz_s",
1788 .llvm_name = "arm1176jz-s",
1789 .features = featureSet(&[_]Feature{
1790 .v6kz,
1791 }),
1792 };
1793 pub const arm1176jzf_s = CpuModel{
1794 .name = "arm1176jzf_s",
1795 .llvm_name = "arm1176jzf-s",
1796 .features = featureSet(&[_]Feature{
1797 .slowfpvmlx,
1798 .v6kz,
1799 .vfp2,
1800 }),
1801 };
1802 pub const arm710t = CpuModel{
1803 .name = "arm710t",
1804 .llvm_name = "arm710t",
1805 .features = featureSet(&[_]Feature{
1806 .v4t,
1807 }),
1808 };
1809 pub const arm720t = CpuModel{
1810 .name = "arm720t",
1811 .llvm_name = "arm720t",
1812 .features = featureSet(&[_]Feature{
1813 .v4t,
1814 }),
1815 };
1816 pub const arm7tdmi = CpuModel{
1817 .name = "arm7tdmi",
1818 .llvm_name = "arm7tdmi",
1819 .features = featureSet(&[_]Feature{
1820 .v4t,
1821 }),
1822 };
1823 pub const arm7tdmi_s = CpuModel{
1824 .name = "arm7tdmi_s",
1825 .llvm_name = "arm7tdmi-s",
1826 .features = featureSet(&[_]Feature{
1827 .v4t,
1828 }),
1829 };
1830 pub const arm8 = CpuModel{
1831 .name = "arm8",
1832 .llvm_name = "arm8",
1833 .features = featureSet(&[_]Feature{
1834 .v4,
1835 }),
1836 };
1837 pub const arm810 = CpuModel{
1838 .name = "arm810",
1839 .llvm_name = "arm810",
1840 .features = featureSet(&[_]Feature{
1841 .v4,
1842 }),
1843 };
1844 pub const arm9 = CpuModel{
1845 .name = "arm9",
1846 .llvm_name = "arm9",
1847 .features = featureSet(&[_]Feature{
1848 .v4t,
1849 }),
1850 };
1851 pub const arm920 = CpuModel{
1852 .name = "arm920",
1853 .llvm_name = "arm920",
1854 .features = featureSet(&[_]Feature{
1855 .v4t,
1856 }),
1857 };
1858 pub const arm920t = CpuModel{
1859 .name = "arm920t",
1860 .llvm_name = "arm920t",
1861 .features = featureSet(&[_]Feature{
1862 .v4t,
1863 }),
1864 };
1865 pub const arm922t = CpuModel{
1866 .name = "arm922t",
1867 .llvm_name = "arm922t",
1868 .features = featureSet(&[_]Feature{
1869 .v4t,
1870 }),
1871 };
1872 pub const arm926ej_s = CpuModel{
1873 .name = "arm926ej_s",
1874 .llvm_name = "arm926ej-s",
1875 .features = featureSet(&[_]Feature{
1876 .v5te,
1877 }),
1878 };
1879 pub const arm940t = CpuModel{
1880 .name = "arm940t",
1881 .llvm_name = "arm940t",
1882 .features = featureSet(&[_]Feature{
1883 .v4t,
1884 }),
1885 };
1886 pub const arm946e_s = CpuModel{
1887 .name = "arm946e_s",
1888 .llvm_name = "arm946e-s",
1889 .features = featureSet(&[_]Feature{
1890 .v5te,
1891 }),
1892 };
1893 pub const arm966e_s = CpuModel{
1894 .name = "arm966e_s",
1895 .llvm_name = "arm966e-s",
1896 .features = featureSet(&[_]Feature{
1897 .v5te,
1898 }),
1899 };
1900 pub const arm968e_s = CpuModel{
1901 .name = "arm968e_s",
1902 .llvm_name = "arm968e-s",
1903 .features = featureSet(&[_]Feature{
1904 .v5te,
1905 }),
1906 };
1907 pub const arm9e = CpuModel{
1908 .name = "arm9e",
1909 .llvm_name = "arm9e",
1910 .features = featureSet(&[_]Feature{
1911 .v5te,
1912 }),
1913 };
1914 pub const arm9tdmi = CpuModel{
1915 .name = "arm9tdmi",
1916 .llvm_name = "arm9tdmi",
1917 .features = featureSet(&[_]Feature{
1918 .v4t,
1919 }),
1920 };
1921 pub const baseline = CpuModel{
1922 .name = "baseline",
1923 .llvm_name = "generic",
1924 .features = featureSet(&[_]Feature{
1925 .v7a,
1926 }),
1927 };
1928 pub const cortex_a12 = CpuModel{
1929 .name = "cortex_a12",
1930 .llvm_name = "cortex-a12",
1931 .features = featureSet(&[_]Feature{
1932 .avoid_partial_cpsr,
1933 .mp,
1934 .ret_addr_stack,
1935 .trustzone,
1936 .v7a,
1937 .vfp4,
1938 .virtualization,
1939 .vmlx_forwarding,
1940 }),
1941 };
1942 pub const cortex_a15 = CpuModel{
1943 .name = "cortex_a15",
1944 .llvm_name = "cortex-a15",
1945 .features = featureSet(&[_]Feature{
1946 .avoid_partial_cpsr,
1947 .mp,
1948 .muxed_units,
1949 .ret_addr_stack,
1950 .splat_vfp_neon,
1951 .trustzone,
1952 .v7a,
1953 .vfp4,
1954 .virtualization,
1955 .vldn_align,
1956 }),
1957 };
1958 pub const cortex_a17 = CpuModel{
1959 .name = "cortex_a17",
1960 .llvm_name = "cortex-a17",
1961 .features = featureSet(&[_]Feature{
1962 .avoid_partial_cpsr,
1963 .mp,
1964 .ret_addr_stack,
1965 .trustzone,
1966 .v7a,
1967 .vfp4,
1968 .virtualization,
1969 .vmlx_forwarding,
1970 }),
1971 };
1972 pub const cortex_a32 = CpuModel{
1973 .name = "cortex_a32",
1974 .llvm_name = "cortex-a32",
1975 .features = featureSet(&[_]Feature{
1976 .v8a,
1977 }),
1978 };
1979 pub const cortex_a35 = CpuModel{
1980 .name = "cortex_a35",
1981 .llvm_name = "cortex-a35",
1982 .features = featureSet(&[_]Feature{
1983 .v8a,
1984 }),
1985 };
1986 pub const cortex_a5 = CpuModel{
1987 .name = "cortex_a5",
1988 .llvm_name = "cortex-a5",
1989 .features = featureSet(&[_]Feature{
1990 .mp,
1991 .ret_addr_stack,
1992 .slow_fp_brcc,
1993 .slowfpvfmx,
1994 .slowfpvmlx,
1995 .trustzone,
1996 .v7a,
1997 .vfp4,
1998 .vmlx_forwarding,
1999 }),
2000 };
2001 pub const cortex_a53 = CpuModel{
2002 .name = "cortex_a53",
2003 .llvm_name = "cortex-a53",
2004 .features = featureSet(&[_]Feature{
2005 .fpao,
2006 .v8a,
2007 }),
2008 };
2009 pub const cortex_a55 = CpuModel{
2010 .name = "cortex_a55",
2011 .llvm_name = "cortex-a55",
2012 .features = featureSet(&[_]Feature{
2013 .dotprod,
2014 .v8_2a,
2015 }),
2016 };
2017 pub const cortex_a57 = CpuModel{
2018 .name = "cortex_a57",
2019 .llvm_name = "cortex-a57",
2020 .features = featureSet(&[_]Feature{
2021 .avoid_partial_cpsr,
2022 .cheap_predicable_cpsr,
2023 .fix_cortex_a57_aes_1742098,
2024 .fpao,
2025 .v8a,
2026 }),
2027 };
2028 pub const cortex_a7 = CpuModel{
2029 .name = "cortex_a7",
2030 .llvm_name = "cortex-a7",
2031 .features = featureSet(&[_]Feature{
2032 .mp,
2033 .ret_addr_stack,
2034 .slow_fp_brcc,
2035 .slowfpvfmx,
2036 .slowfpvmlx,
2037 .trustzone,
2038 .v7a,
2039 .vfp4,
2040 .virtualization,
2041 .vmlx_forwarding,
2042 .vmlx_hazards,
2043 }),
2044 };
2045 pub const cortex_a710 = CpuModel{
2046 .name = "cortex_a710",
2047 .llvm_name = "cortex-a710",
2048 .features = featureSet(&[_]Feature{
2049 .bf16,
2050 .fp16fml,
2051 .i8mm,
2052 .v9a,
2053 }),
2054 };
2055 pub const cortex_a72 = CpuModel{
2056 .name = "cortex_a72",
2057 .llvm_name = "cortex-a72",
2058 .features = featureSet(&[_]Feature{
2059 .fix_cortex_a57_aes_1742098,
2060 .v8a,
2061 }),
2062 };
2063 pub const cortex_a73 = CpuModel{
2064 .name = "cortex_a73",
2065 .llvm_name = "cortex-a73",
2066 .features = featureSet(&[_]Feature{
2067 .v8a,
2068 }),
2069 };
2070 pub const cortex_a75 = CpuModel{
2071 .name = "cortex_a75",
2072 .llvm_name = "cortex-a75",
2073 .features = featureSet(&[_]Feature{
2074 .dotprod,
2075 .v8_2a,
2076 }),
2077 };
2078 pub const cortex_a76 = CpuModel{
2079 .name = "cortex_a76",
2080 .llvm_name = "cortex-a76",
2081 .features = featureSet(&[_]Feature{
2082 .a76,
2083 .dotprod,
2084 .fullfp16,
2085 .v8_2a,
2086 }),
2087 };
2088 pub const cortex_a76ae = CpuModel{
2089 .name = "cortex_a76ae",
2090 .llvm_name = "cortex-a76ae",
2091 .features = featureSet(&[_]Feature{
2092 .a76,
2093 .dotprod,
2094 .fullfp16,
2095 .v8_2a,
2096 }),
2097 };
2098 pub const cortex_a77 = CpuModel{
2099 .name = "cortex_a77",
2100 .llvm_name = "cortex-a77",
2101 .features = featureSet(&[_]Feature{
2102 .dotprod,
2103 .fullfp16,
2104 .v8_2a,
2105 }),
2106 };
2107 pub const cortex_a78 = CpuModel{
2108 .name = "cortex_a78",
2109 .llvm_name = "cortex-a78",
2110 .features = featureSet(&[_]Feature{
2111 .dotprod,
2112 .fullfp16,
2113 .v8_2a,
2114 }),
2115 };
2116 pub const cortex_a78c = CpuModel{
2117 .name = "cortex_a78c",
2118 .llvm_name = "cortex-a78c",
2119 .features = featureSet(&[_]Feature{
2120 .dotprod,
2121 .fullfp16,
2122 .v8_2a,
2123 }),
2124 };
2125 pub const cortex_a8 = CpuModel{
2126 .name = "cortex_a8",
2127 .llvm_name = "cortex-a8",
2128 .features = featureSet(&[_]Feature{
2129 .nonpipelined_vfp,
2130 .ret_addr_stack,
2131 .slow_fp_brcc,
2132 .slowfpvfmx,
2133 .slowfpvmlx,
2134 .trustzone,
2135 .v7a,
2136 .vmlx_forwarding,
2137 .vmlx_hazards,
2138 }),
2139 };
2140 pub const cortex_a9 = CpuModel{
2141 .name = "cortex_a9",
2142 .llvm_name = "cortex-a9",
2143 .features = featureSet(&[_]Feature{
2144 .avoid_partial_cpsr,
2145 .expand_fp_mlx,
2146 .fp16,
2147 .mp,
2148 .muxed_units,
2149 .neon_fpmovs,
2150 .prefer_vmovsr,
2151 .ret_addr_stack,
2152 .trustzone,
2153 .v7a,
2154 .vldn_align,
2155 .vmlx_forwarding,
2156 .vmlx_hazards,
2157 }),
2158 };
2159 pub const cortex_m0 = CpuModel{
2160 .name = "cortex_m0",
2161 .llvm_name = "cortex-m0",
2162 .features = featureSet(&[_]Feature{
2163 .no_branch_predictor,
2164 .v6m,
2165 }),
2166 };
2167 pub const cortex_m0plus = CpuModel{
2168 .name = "cortex_m0plus",
2169 .llvm_name = "cortex-m0plus",
2170 .features = featureSet(&[_]Feature{
2171 .no_branch_predictor,
2172 .v6m,
2173 }),
2174 };
2175 pub const cortex_m1 = CpuModel{
2176 .name = "cortex_m1",
2177 .llvm_name = "cortex-m1",
2178 .features = featureSet(&[_]Feature{
2179 .no_branch_predictor,
2180 .v6m,
2181 }),
2182 };
2183 pub const cortex_m23 = CpuModel{
2184 .name = "cortex_m23",
2185 .llvm_name = "cortex-m23",
2186 .features = featureSet(&[_]Feature{
2187 .no_branch_predictor,
2188 .no_movt,
2189 .v8m,
2190 }),
2191 };
2192 pub const cortex_m3 = CpuModel{
2193 .name = "cortex_m3",
2194 .llvm_name = "cortex-m3",
2195 .features = featureSet(&[_]Feature{
2196 .loop_align,
2197 .m3,
2198 .no_branch_predictor,
2199 .use_misched,
2200 .v7m,
2201 }),
2202 };
2203 pub const cortex_m33 = CpuModel{
2204 .name = "cortex_m33",
2205 .llvm_name = "cortex-m33",
2206 .features = featureSet(&[_]Feature{
2207 .dsp,
2208 .fix_cmse_cve_2021_35465,
2209 .fp_armv8d16sp,
2210 .loop_align,
2211 .no_branch_predictor,
2212 .slowfpvfmx,
2213 .slowfpvmlx,
2214 .use_misched,
2215 .v8m_main,
2216 }),
2217 };
2218 pub const cortex_m35p = CpuModel{
2219 .name = "cortex_m35p",
2220 .llvm_name = "cortex-m35p",
2221 .features = featureSet(&[_]Feature{
2222 .dsp,
2223 .fix_cmse_cve_2021_35465,
2224 .fp_armv8d16sp,
2225 .loop_align,
2226 .no_branch_predictor,
2227 .slowfpvfmx,
2228 .slowfpvmlx,
2229 .use_misched,
2230 .v8m_main,
2231 }),
2232 };
2233 pub const cortex_m4 = CpuModel{
2234 .name = "cortex_m4",
2235 .llvm_name = "cortex-m4",
2236 .features = featureSet(&[_]Feature{
2237 .loop_align,
2238 .no_branch_predictor,
2239 .slowfpvfmx,
2240 .slowfpvmlx,
2241 .use_misched,
2242 .v7em,
2243 .vfp4d16sp,
2244 }),
2245 };
2246 pub const cortex_m55 = CpuModel{
2247 .name = "cortex_m55",
2248 .llvm_name = "cortex-m55",
2249 .features = featureSet(&[_]Feature{
2250 .fix_cmse_cve_2021_35465,
2251 .fp_armv8d16,
2252 .loop_align,
2253 .mve_fp,
2254 .no_branch_predictor,
2255 .slowfpvmlx,
2256 .use_misched,
2257 .v8_1m_main,
2258 }),
2259 };
2260 pub const cortex_m7 = CpuModel{
2261 .name = "cortex_m7",
2262 .llvm_name = "cortex-m7",
2263 .features = featureSet(&[_]Feature{
2264 .fp_armv8d16,
2265 .use_mipipeliner,
2266 .use_misched,
2267 .v7em,
2268 }),
2269 };
2270 pub const cortex_m85 = CpuModel{
2271 .name = "cortex_m85",
2272 .llvm_name = "cortex-m85",
2273 .features = featureSet(&[_]Feature{
2274 .fp_armv8d16,
2275 .mve_fp,
2276 .pacbti,
2277 .use_misched,
2278 .v8_1m_main,
2279 }),
2280 };
2281 pub const cortex_r4 = CpuModel{
2282 .name = "cortex_r4",
2283 .llvm_name = "cortex-r4",
2284 .features = featureSet(&[_]Feature{
2285 .avoid_partial_cpsr,
2286 .r4,
2287 .ret_addr_stack,
2288 .v7r,
2289 }),
2290 };
2291 pub const cortex_r4f = CpuModel{
2292 .name = "cortex_r4f",
2293 .llvm_name = "cortex-r4f",
2294 .features = featureSet(&[_]Feature{
2295 .avoid_partial_cpsr,
2296 .r4,
2297 .ret_addr_stack,
2298 .slow_fp_brcc,
2299 .slowfpvfmx,
2300 .slowfpvmlx,
2301 .v7r,
2302 .vfp3d16,
2303 }),
2304 };
2305 pub const cortex_r5 = CpuModel{
2306 .name = "cortex_r5",
2307 .llvm_name = "cortex-r5",
2308 .features = featureSet(&[_]Feature{
2309 .avoid_partial_cpsr,
2310 .hwdiv_arm,
2311 .ret_addr_stack,
2312 .slow_fp_brcc,
2313 .slowfpvfmx,
2314 .slowfpvmlx,
2315 .v7r,
2316 .vfp3d16,
2317 }),
2318 };
2319 pub const cortex_r52 = CpuModel{
2320 .name = "cortex_r52",
2321 .llvm_name = "cortex-r52",
2322 .features = featureSet(&[_]Feature{
2323 .fpao,
2324 .use_misched,
2325 .v8r,
2326 }),
2327 };
2328 pub const cortex_r7 = CpuModel{
2329 .name = "cortex_r7",
2330 .llvm_name = "cortex-r7",
2331 .features = featureSet(&[_]Feature{
2332 .avoid_partial_cpsr,
2333 .fp16,
2334 .hwdiv_arm,
2335 .mp,
2336 .ret_addr_stack,
2337 .slow_fp_brcc,
2338 .slowfpvfmx,
2339 .slowfpvmlx,
2340 .v7r,
2341 .vfp3d16,
2342 }),
2343 };
2344 pub const cortex_r8 = CpuModel{
2345 .name = "cortex_r8",
2346 .llvm_name = "cortex-r8",
2347 .features = featureSet(&[_]Feature{
2348 .avoid_partial_cpsr,
2349 .fp16,
2350 .hwdiv_arm,
2351 .mp,
2352 .ret_addr_stack,
2353 .slow_fp_brcc,
2354 .slowfpvfmx,
2355 .slowfpvmlx,
2356 .v7r,
2357 .vfp3d16,
2358 }),
2359 };
2360 pub const cortex_x1 = CpuModel{
2361 .name = "cortex_x1",
2362 .llvm_name = "cortex-x1",
2363 .features = featureSet(&[_]Feature{
2364 .dotprod,
2365 .fullfp16,
2366 .v8_2a,
2367 }),
2368 };
2369 pub const cortex_x1c = CpuModel{
2370 .name = "cortex_x1c",
2371 .llvm_name = "cortex-x1c",
2372 .features = featureSet(&[_]Feature{
2373 .dotprod,
2374 .fullfp16,
2375 .v8_2a,
2376 }),
2377 };
2378 pub const cyclone = CpuModel{
2379 .name = "cyclone",
2380 .llvm_name = "cyclone",
2381 .features = featureSet(&[_]Feature{
2382 .avoid_movs_shop,
2383 .avoid_partial_cpsr,
2384 .disable_postra_scheduler,
2385 .neonfp,
2386 .ret_addr_stack,
2387 .slowfpvfmx,
2388 .slowfpvmlx,
2389 .swift,
2390 .use_misched,
2391 .v8a,
2392 .zcz,
2393 }),
2394 };
2395 pub const ep9312 = CpuModel{
2396 .name = "ep9312",
2397 .llvm_name = "ep9312",
2398 .features = featureSet(&[_]Feature{
2399 .v4t,
2400 }),
2401 };
2402 pub const exynos_m1 = CpuModel{
2403 .name = "exynos_m1",
2404 .llvm_name = null,
2405 .features = featureSet(&[_]Feature{
2406 .exynos,
2407 .v8a,
2408 }),
2409 };
2410 pub const exynos_m2 = CpuModel{
2411 .name = "exynos_m2",
2412 .llvm_name = null,
2413 .features = featureSet(&[_]Feature{
2414 .exynos,
2415 .v8a,
2416 }),
2417 };
2418 pub const exynos_m3 = CpuModel{
2419 .name = "exynos_m3",
2420 .llvm_name = "exynos-m3",
2421 .features = featureSet(&[_]Feature{
2422 .exynos,
2423 .v8a,
2424 }),
2425 };
2426 pub const exynos_m4 = CpuModel{
2427 .name = "exynos_m4",
2428 .llvm_name = "exynos-m4",
2429 .features = featureSet(&[_]Feature{
2430 .dotprod,
2431 .exynos,
2432 .fullfp16,
2433 .v8_2a,
2434 }),
2435 };
2436 pub const exynos_m5 = CpuModel{
2437 .name = "exynos_m5",
2438 .llvm_name = "exynos-m5",
2439 .features = featureSet(&[_]Feature{
2440 .dotprod,
2441 .exynos,
2442 .fullfp16,
2443 .v8_2a,
2444 }),
2445 };
2446 pub const generic = CpuModel{
2447 .name = "generic",
2448 .llvm_name = "generic",
2449 .features = featureSet(&[_]Feature{}),
2450 };
2451 pub const iwmmxt = CpuModel{
2452 .name = "iwmmxt",
2453 .llvm_name = "iwmmxt",
2454 .features = featureSet(&[_]Feature{
2455 .v5te,
2456 }),
2457 };
2458 pub const krait = CpuModel{
2459 .name = "krait",
2460 .llvm_name = "krait",
2461 .features = featureSet(&[_]Feature{
2462 .avoid_partial_cpsr,
2463 .hwdiv,
2464 .hwdiv_arm,
2465 .muxed_units,
2466 .ret_addr_stack,
2467 .v7a,
2468 .vfp4,
2469 .vldn_align,
2470 .vmlx_forwarding,
2471 }),
2472 };
2473 pub const kryo = CpuModel{
2474 .name = "kryo",
2475 .llvm_name = "kryo",
2476 .features = featureSet(&[_]Feature{
2477 .v8a,
2478 }),
2479 };
2480 pub const mpcore = CpuModel{
2481 .name = "mpcore",
2482 .llvm_name = "mpcore",
2483 .features = featureSet(&[_]Feature{
2484 .slowfpvmlx,
2485 .v6k,
2486 .vfp2,
2487 }),
2488 };
2489 pub const mpcorenovfp = CpuModel{
2490 .name = "mpcorenovfp",
2491 .llvm_name = "mpcorenovfp",
2492 .features = featureSet(&[_]Feature{
2493 .v6k,
2494 }),
2495 };
2496 pub const neoverse_n1 = CpuModel{
2497 .name = "neoverse_n1",
2498 .llvm_name = "neoverse-n1",
2499 .features = featureSet(&[_]Feature{
2500 .dotprod,
2501 .v8_2a,
2502 }),
2503 };
2504 pub const neoverse_n2 = CpuModel{
2505 .name = "neoverse_n2",
2506 .llvm_name = "neoverse-n2",
2507 .features = featureSet(&[_]Feature{
2508 .bf16,
2509 .i8mm,
2510 .v8_5a,
2511 }),
2512 };
2513 pub const neoverse_v1 = CpuModel{
2514 .name = "neoverse_v1",
2515 .llvm_name = "neoverse-v1",
2516 .features = featureSet(&[_]Feature{
2517 .bf16,
2518 .fullfp16,
2519 .i8mm,
2520 .v8_4a,
2521 }),
2522 };
2523 pub const sc000 = CpuModel{
2524 .name = "sc000",
2525 .llvm_name = "sc000",
2526 .features = featureSet(&[_]Feature{
2527 .no_branch_predictor,
2528 .v6m,
2529 }),
2530 };
2531 pub const sc300 = CpuModel{
2532 .name = "sc300",
2533 .llvm_name = "sc300",
2534 .features = featureSet(&[_]Feature{
2535 .m3,
2536 .no_branch_predictor,
2537 .use_misched,
2538 .v7m,
2539 }),
2540 };
2541 pub const strongarm = CpuModel{
2542 .name = "strongarm",
2543 .llvm_name = "strongarm",
2544 .features = featureSet(&[_]Feature{
2545 .v4,
2546 }),
2547 };
2548 pub const strongarm110 = CpuModel{
2549 .name = "strongarm110",
2550 .llvm_name = "strongarm110",
2551 .features = featureSet(&[_]Feature{
2552 .v4,
2553 }),
2554 };
2555 pub const strongarm1100 = CpuModel{
2556 .name = "strongarm1100",
2557 .llvm_name = "strongarm1100",
2558 .features = featureSet(&[_]Feature{
2559 .v4,
2560 }),
2561 };
2562 pub const strongarm1110 = CpuModel{
2563 .name = "strongarm1110",
2564 .llvm_name = "strongarm1110",
2565 .features = featureSet(&[_]Feature{
2566 .v4,
2567 }),
2568 };
2569 pub const swift = CpuModel{
2570 .name = "swift",
2571 .llvm_name = "swift",
2572 .features = featureSet(&[_]Feature{
2573 .avoid_movs_shop,
2574 .avoid_partial_cpsr,
2575 .disable_postra_scheduler,
2576 .hwdiv,
2577 .hwdiv_arm,
2578 .mp,
2579 .neonfp,
2580 .prefer_ishst,
2581 .prof_unpr,
2582 .ret_addr_stack,
2583 .slow_load_D_subreg,
2584 .slow_odd_reg,
2585 .slow_vdup32,
2586 .slow_vgetlni32,
2587 .slowfpvfmx,
2588 .slowfpvmlx,
2589 .swift,
2590 .use_misched,
2591 .v7a,
2592 .vfp4,
2593 .vmlx_hazards,
2594 .wide_stride_vfp,
2595 }),
2596 };
2597 pub const xscale = CpuModel{
2598 .name = "xscale",
2599 .llvm_name = "xscale",
2600 .features = featureSet(&[_]Feature{
2601 .v5te,
2602 }),
2603 };
2604};
lib/std/Target/avr.zig created+2607
......@@ -0,0 +1,2607 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 addsubiw,
9 avr0,
10 avr1,
11 avr2,
12 avr25,
13 avr3,
14 avr31,
15 avr35,
16 avr4,
17 avr5,
18 avr51,
19 avr6,
20 avrtiny,
21 @"break",
22 des,
23 eijmpcall,
24 elpm,
25 elpmx,
26 ijmpcall,
27 jmpcall,
28 lowbytefirst,
29 lpm,
30 lpmx,
31 memmappedregs,
32 movw,
33 mul,
34 rmw,
35 smallstack,
36 special,
37 spm,
38 spmx,
39 sram,
40 tinyencoding,
41 xmega,
42 xmega3,
43 xmegau,
44};
45
46pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
47pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
48pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
49pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
50
51pub const all_features = blk: {
52 const len = @typeInfo(Feature).Enum.fields.len;
53 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
54 var result: [len]CpuFeature = undefined;
55 result[@intFromEnum(Feature.addsubiw)] = .{
56 .llvm_name = "addsubiw",
57 .description = "Enable 16-bit register-immediate addition and subtraction instructions",
58 .dependencies = featureSet(&[_]Feature{}),
59 };
60 result[@intFromEnum(Feature.avr0)] = .{
61 .llvm_name = "avr0",
62 .description = "The device is a part of the avr0 family",
63 .dependencies = featureSet(&[_]Feature{}),
64 };
65 result[@intFromEnum(Feature.avr1)] = .{
66 .llvm_name = "avr1",
67 .description = "The device is a part of the avr1 family",
68 .dependencies = featureSet(&[_]Feature{
69 .avr0,
70 .lpm,
71 .memmappedregs,
72 }),
73 };
74 result[@intFromEnum(Feature.avr2)] = .{
75 .llvm_name = "avr2",
76 .description = "The device is a part of the avr2 family",
77 .dependencies = featureSet(&[_]Feature{
78 .addsubiw,
79 .avr1,
80 .ijmpcall,
81 .sram,
82 }),
83 };
84 result[@intFromEnum(Feature.avr25)] = .{
85 .llvm_name = "avr25",
86 .description = "The device is a part of the avr25 family",
87 .dependencies = featureSet(&[_]Feature{
88 .avr2,
89 .@"break",
90 .lpmx,
91 .movw,
92 .spm,
93 }),
94 };
95 result[@intFromEnum(Feature.avr3)] = .{
96 .llvm_name = "avr3",
97 .description = "The device is a part of the avr3 family",
98 .dependencies = featureSet(&[_]Feature{
99 .avr2,
100 .jmpcall,
101 }),
102 };
103 result[@intFromEnum(Feature.avr31)] = .{
104 .llvm_name = "avr31",
105 .description = "The device is a part of the avr31 family",
106 .dependencies = featureSet(&[_]Feature{
107 .avr3,
108 .elpm,
109 }),
110 };
111 result[@intFromEnum(Feature.avr35)] = .{
112 .llvm_name = "avr35",
113 .description = "The device is a part of the avr35 family",
114 .dependencies = featureSet(&[_]Feature{
115 .avr3,
116 .@"break",
117 .lpmx,
118 .movw,
119 .spm,
120 }),
121 };
122 result[@intFromEnum(Feature.avr4)] = .{
123 .llvm_name = "avr4",
124 .description = "The device is a part of the avr4 family",
125 .dependencies = featureSet(&[_]Feature{
126 .avr2,
127 .@"break",
128 .lpmx,
129 .movw,
130 .mul,
131 .spm,
132 }),
133 };
134 result[@intFromEnum(Feature.avr5)] = .{
135 .llvm_name = "avr5",
136 .description = "The device is a part of the avr5 family",
137 .dependencies = featureSet(&[_]Feature{
138 .avr3,
139 .@"break",
140 .lpmx,
141 .movw,
142 .mul,
143 .spm,
144 }),
145 };
146 result[@intFromEnum(Feature.avr51)] = .{
147 .llvm_name = "avr51",
148 .description = "The device is a part of the avr51 family",
149 .dependencies = featureSet(&[_]Feature{
150 .avr5,
151 .elpm,
152 .elpmx,
153 }),
154 };
155 result[@intFromEnum(Feature.avr6)] = .{
156 .llvm_name = "avr6",
157 .description = "The device is a part of the avr6 family",
158 .dependencies = featureSet(&[_]Feature{
159 .avr51,
160 .eijmpcall,
161 }),
162 };
163 result[@intFromEnum(Feature.avrtiny)] = .{
164 .llvm_name = "avrtiny",
165 .description = "The device is a part of the avrtiny family",
166 .dependencies = featureSet(&[_]Feature{
167 .avr0,
168 .@"break",
169 .smallstack,
170 .sram,
171 .tinyencoding,
172 }),
173 };
174 result[@intFromEnum(Feature.@"break")] = .{
175 .llvm_name = "break",
176 .description = "The device supports the `BREAK` debugging instruction",
177 .dependencies = featureSet(&[_]Feature{}),
178 };
179 result[@intFromEnum(Feature.des)] = .{
180 .llvm_name = "des",
181 .description = "The device supports the `DES k` encryption instruction",
182 .dependencies = featureSet(&[_]Feature{}),
183 };
184 result[@intFromEnum(Feature.eijmpcall)] = .{
185 .llvm_name = "eijmpcall",
186 .description = "The device supports the `EIJMP`/`EICALL` instructions",
187 .dependencies = featureSet(&[_]Feature{}),
188 };
189 result[@intFromEnum(Feature.elpm)] = .{
190 .llvm_name = "elpm",
191 .description = "The device supports the ELPM instruction",
192 .dependencies = featureSet(&[_]Feature{}),
193 };
194 result[@intFromEnum(Feature.elpmx)] = .{
195 .llvm_name = "elpmx",
196 .description = "The device supports the `ELPM Rd, Z[+]` instructions",
197 .dependencies = featureSet(&[_]Feature{}),
198 };
199 result[@intFromEnum(Feature.ijmpcall)] = .{
200 .llvm_name = "ijmpcall",
201 .description = "The device supports `IJMP`/`ICALL`instructions",
202 .dependencies = featureSet(&[_]Feature{}),
203 };
204 result[@intFromEnum(Feature.jmpcall)] = .{
205 .llvm_name = "jmpcall",
206 .description = "The device supports the `JMP` and `CALL` instructions",
207 .dependencies = featureSet(&[_]Feature{}),
208 };
209 result[@intFromEnum(Feature.lowbytefirst)] = .{
210 .llvm_name = "lowbytefirst",
211 .description = "Do the low byte first when writing a 16-bit port or storing a 16-bit word",
212 .dependencies = featureSet(&[_]Feature{}),
213 };
214 result[@intFromEnum(Feature.lpm)] = .{
215 .llvm_name = "lpm",
216 .description = "The device supports the `LPM` instruction",
217 .dependencies = featureSet(&[_]Feature{}),
218 };
219 result[@intFromEnum(Feature.lpmx)] = .{
220 .llvm_name = "lpmx",
221 .description = "The device supports the `LPM Rd, Z[+]` instruction",
222 .dependencies = featureSet(&[_]Feature{}),
223 };
224 result[@intFromEnum(Feature.memmappedregs)] = .{
225 .llvm_name = "memmappedregs",
226 .description = "The device has CPU registers mapped in data address space",
227 .dependencies = featureSet(&[_]Feature{}),
228 };
229 result[@intFromEnum(Feature.movw)] = .{
230 .llvm_name = "movw",
231 .description = "The device supports the 16-bit MOVW instruction",
232 .dependencies = featureSet(&[_]Feature{}),
233 };
234 result[@intFromEnum(Feature.mul)] = .{
235 .llvm_name = "mul",
236 .description = "The device supports the multiplication instructions",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.rmw)] = .{
240 .llvm_name = "rmw",
241 .description = "The device supports the read-write-modify instructions: XCH, LAS, LAC, LAT",
242 .dependencies = featureSet(&[_]Feature{}),
243 };
244 result[@intFromEnum(Feature.smallstack)] = .{
245 .llvm_name = "smallstack",
246 .description = "The device has an 8-bit stack pointer",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@intFromEnum(Feature.special)] = .{
250 .llvm_name = "special",
251 .description = "Enable use of the entire instruction set - used for debugging",
252 .dependencies = featureSet(&[_]Feature{
253 .addsubiw,
254 .@"break",
255 .des,
256 .eijmpcall,
257 .elpm,
258 .elpmx,
259 .ijmpcall,
260 .jmpcall,
261 .lpm,
262 .lpmx,
263 .memmappedregs,
264 .movw,
265 .mul,
266 .rmw,
267 .spm,
268 .spmx,
269 .sram,
270 }),
271 };
272 result[@intFromEnum(Feature.spm)] = .{
273 .llvm_name = "spm",
274 .description = "The device supports the `SPM` instruction",
275 .dependencies = featureSet(&[_]Feature{}),
276 };
277 result[@intFromEnum(Feature.spmx)] = .{
278 .llvm_name = "spmx",
279 .description = "The device supports the `SPM Z+` instruction",
280 .dependencies = featureSet(&[_]Feature{}),
281 };
282 result[@intFromEnum(Feature.sram)] = .{
283 .llvm_name = "sram",
284 .description = "The device has random access memory",
285 .dependencies = featureSet(&[_]Feature{}),
286 };
287 result[@intFromEnum(Feature.tinyencoding)] = .{
288 .llvm_name = "tinyencoding",
289 .description = "The device has Tiny core specific instruction encodings",
290 .dependencies = featureSet(&[_]Feature{}),
291 };
292 result[@intFromEnum(Feature.xmega)] = .{
293 .llvm_name = "xmega",
294 .description = "The device is a part of the xmega family",
295 .dependencies = featureSet(&[_]Feature{
296 .addsubiw,
297 .avr0,
298 .@"break",
299 .des,
300 .eijmpcall,
301 .elpm,
302 .elpmx,
303 .ijmpcall,
304 .jmpcall,
305 .lowbytefirst,
306 .lpm,
307 .lpmx,
308 .movw,
309 .mul,
310 .spm,
311 .spmx,
312 .sram,
313 }),
314 };
315 result[@intFromEnum(Feature.xmega3)] = .{
316 .llvm_name = "xmega3",
317 .description = "The device is a part of the xmega3 family",
318 .dependencies = featureSet(&[_]Feature{
319 .addsubiw,
320 .avr0,
321 .@"break",
322 .ijmpcall,
323 .jmpcall,
324 .lowbytefirst,
325 .lpm,
326 .lpmx,
327 .movw,
328 .mul,
329 .sram,
330 }),
331 };
332 result[@intFromEnum(Feature.xmegau)] = .{
333 .llvm_name = "xmegau",
334 .description = "The device is a part of the xmegau family",
335 .dependencies = featureSet(&[_]Feature{
336 .rmw,
337 .xmega,
338 }),
339 };
340 const ti = @typeInfo(Feature);
341 for (&result, 0..) |*elem, i| {
342 elem.index = i;
343 elem.name = ti.Enum.fields[i].name;
344 }
345 break :blk result;
346};
347
348pub const cpu = struct {
349 pub const at43usb320 = CpuModel{
350 .name = "at43usb320",
351 .llvm_name = "at43usb320",
352 .features = featureSet(&[_]Feature{
353 .avr31,
354 }),
355 };
356 pub const at43usb355 = CpuModel{
357 .name = "at43usb355",
358 .llvm_name = "at43usb355",
359 .features = featureSet(&[_]Feature{
360 .avr3,
361 }),
362 };
363 pub const at76c711 = CpuModel{
364 .name = "at76c711",
365 .llvm_name = "at76c711",
366 .features = featureSet(&[_]Feature{
367 .avr3,
368 }),
369 };
370 pub const at86rf401 = CpuModel{
371 .name = "at86rf401",
372 .llvm_name = "at86rf401",
373 .features = featureSet(&[_]Feature{
374 .avr2,
375 .lpmx,
376 .movw,
377 }),
378 };
379 pub const at90c8534 = CpuModel{
380 .name = "at90c8534",
381 .llvm_name = "at90c8534",
382 .features = featureSet(&[_]Feature{
383 .avr2,
384 }),
385 };
386 pub const at90can128 = CpuModel{
387 .name = "at90can128",
388 .llvm_name = "at90can128",
389 .features = featureSet(&[_]Feature{
390 .avr51,
391 }),
392 };
393 pub const at90can32 = CpuModel{
394 .name = "at90can32",
395 .llvm_name = "at90can32",
396 .features = featureSet(&[_]Feature{
397 .avr5,
398 }),
399 };
400 pub const at90can64 = CpuModel{
401 .name = "at90can64",
402 .llvm_name = "at90can64",
403 .features = featureSet(&[_]Feature{
404 .avr5,
405 }),
406 };
407 pub const at90pwm1 = CpuModel{
408 .name = "at90pwm1",
409 .llvm_name = "at90pwm1",
410 .features = featureSet(&[_]Feature{
411 .avr4,
412 }),
413 };
414 pub const at90pwm161 = CpuModel{
415 .name = "at90pwm161",
416 .llvm_name = "at90pwm161",
417 .features = featureSet(&[_]Feature{
418 .avr5,
419 }),
420 };
421 pub const at90pwm2 = CpuModel{
422 .name = "at90pwm2",
423 .llvm_name = "at90pwm2",
424 .features = featureSet(&[_]Feature{
425 .avr4,
426 }),
427 };
428 pub const at90pwm216 = CpuModel{
429 .name = "at90pwm216",
430 .llvm_name = "at90pwm216",
431 .features = featureSet(&[_]Feature{
432 .avr5,
433 }),
434 };
435 pub const at90pwm2b = CpuModel{
436 .name = "at90pwm2b",
437 .llvm_name = "at90pwm2b",
438 .features = featureSet(&[_]Feature{
439 .avr4,
440 }),
441 };
442 pub const at90pwm3 = CpuModel{
443 .name = "at90pwm3",
444 .llvm_name = "at90pwm3",
445 .features = featureSet(&[_]Feature{
446 .avr4,
447 }),
448 };
449 pub const at90pwm316 = CpuModel{
450 .name = "at90pwm316",
451 .llvm_name = "at90pwm316",
452 .features = featureSet(&[_]Feature{
453 .avr5,
454 }),
455 };
456 pub const at90pwm3b = CpuModel{
457 .name = "at90pwm3b",
458 .llvm_name = "at90pwm3b",
459 .features = featureSet(&[_]Feature{
460 .avr4,
461 }),
462 };
463 pub const at90pwm81 = CpuModel{
464 .name = "at90pwm81",
465 .llvm_name = "at90pwm81",
466 .features = featureSet(&[_]Feature{
467 .avr4,
468 }),
469 };
470 pub const at90s1200 = CpuModel{
471 .name = "at90s1200",
472 .llvm_name = "at90s1200",
473 .features = featureSet(&[_]Feature{
474 .avr0,
475 .smallstack,
476 }),
477 };
478 pub const at90s2313 = CpuModel{
479 .name = "at90s2313",
480 .llvm_name = "at90s2313",
481 .features = featureSet(&[_]Feature{
482 .avr2,
483 .smallstack,
484 }),
485 };
486 pub const at90s2323 = CpuModel{
487 .name = "at90s2323",
488 .llvm_name = "at90s2323",
489 .features = featureSet(&[_]Feature{
490 .avr2,
491 .smallstack,
492 }),
493 };
494 pub const at90s2333 = CpuModel{
495 .name = "at90s2333",
496 .llvm_name = "at90s2333",
497 .features = featureSet(&[_]Feature{
498 .avr2,
499 .smallstack,
500 }),
501 };
502 pub const at90s2343 = CpuModel{
503 .name = "at90s2343",
504 .llvm_name = "at90s2343",
505 .features = featureSet(&[_]Feature{
506 .avr2,
507 .smallstack,
508 }),
509 };
510 pub const at90s4414 = CpuModel{
511 .name = "at90s4414",
512 .llvm_name = "at90s4414",
513 .features = featureSet(&[_]Feature{
514 .avr2,
515 .smallstack,
516 }),
517 };
518 pub const at90s4433 = CpuModel{
519 .name = "at90s4433",
520 .llvm_name = "at90s4433",
521 .features = featureSet(&[_]Feature{
522 .avr2,
523 .smallstack,
524 }),
525 };
526 pub const at90s4434 = CpuModel{
527 .name = "at90s4434",
528 .llvm_name = "at90s4434",
529 .features = featureSet(&[_]Feature{
530 .avr2,
531 .smallstack,
532 }),
533 };
534 pub const at90s8515 = CpuModel{
535 .name = "at90s8515",
536 .llvm_name = "at90s8515",
537 .features = featureSet(&[_]Feature{
538 .avr2,
539 }),
540 };
541 pub const at90s8535 = CpuModel{
542 .name = "at90s8535",
543 .llvm_name = "at90s8535",
544 .features = featureSet(&[_]Feature{
545 .avr2,
546 }),
547 };
548 pub const at90scr100 = CpuModel{
549 .name = "at90scr100",
550 .llvm_name = "at90scr100",
551 .features = featureSet(&[_]Feature{
552 .avr5,
553 }),
554 };
555 pub const at90usb1286 = CpuModel{
556 .name = "at90usb1286",
557 .llvm_name = "at90usb1286",
558 .features = featureSet(&[_]Feature{
559 .avr51,
560 }),
561 };
562 pub const at90usb1287 = CpuModel{
563 .name = "at90usb1287",
564 .llvm_name = "at90usb1287",
565 .features = featureSet(&[_]Feature{
566 .avr51,
567 }),
568 };
569 pub const at90usb162 = CpuModel{
570 .name = "at90usb162",
571 .llvm_name = "at90usb162",
572 .features = featureSet(&[_]Feature{
573 .avr35,
574 }),
575 };
576 pub const at90usb646 = CpuModel{
577 .name = "at90usb646",
578 .llvm_name = "at90usb646",
579 .features = featureSet(&[_]Feature{
580 .avr5,
581 }),
582 };
583 pub const at90usb647 = CpuModel{
584 .name = "at90usb647",
585 .llvm_name = "at90usb647",
586 .features = featureSet(&[_]Feature{
587 .avr5,
588 }),
589 };
590 pub const at90usb82 = CpuModel{
591 .name = "at90usb82",
592 .llvm_name = "at90usb82",
593 .features = featureSet(&[_]Feature{
594 .avr35,
595 }),
596 };
597 pub const at94k = CpuModel{
598 .name = "at94k",
599 .llvm_name = "at94k",
600 .features = featureSet(&[_]Feature{
601 .avr3,
602 .lpmx,
603 .movw,
604 .mul,
605 }),
606 };
607 pub const ata5272 = CpuModel{
608 .name = "ata5272",
609 .llvm_name = "ata5272",
610 .features = featureSet(&[_]Feature{
611 .avr25,
612 }),
613 };
614 pub const ata5505 = CpuModel{
615 .name = "ata5505",
616 .llvm_name = "ata5505",
617 .features = featureSet(&[_]Feature{
618 .avr35,
619 }),
620 };
621 pub const ata5702m322 = CpuModel{
622 .name = "ata5702m322",
623 .llvm_name = "ata5702m322",
624 .features = featureSet(&[_]Feature{
625 .avr5,
626 }),
627 };
628 pub const ata5782 = CpuModel{
629 .name = "ata5782",
630 .llvm_name = "ata5782",
631 .features = featureSet(&[_]Feature{
632 .avr5,
633 }),
634 };
635 pub const ata5790 = CpuModel{
636 .name = "ata5790",
637 .llvm_name = "ata5790",
638 .features = featureSet(&[_]Feature{
639 .avr5,
640 }),
641 };
642 pub const ata5790n = CpuModel{
643 .name = "ata5790n",
644 .llvm_name = "ata5790n",
645 .features = featureSet(&[_]Feature{
646 .avr5,
647 }),
648 };
649 pub const ata5791 = CpuModel{
650 .name = "ata5791",
651 .llvm_name = "ata5791",
652 .features = featureSet(&[_]Feature{
653 .avr5,
654 }),
655 };
656 pub const ata5795 = CpuModel{
657 .name = "ata5795",
658 .llvm_name = "ata5795",
659 .features = featureSet(&[_]Feature{
660 .avr5,
661 }),
662 };
663 pub const ata5831 = CpuModel{
664 .name = "ata5831",
665 .llvm_name = "ata5831",
666 .features = featureSet(&[_]Feature{
667 .avr5,
668 }),
669 };
670 pub const ata6285 = CpuModel{
671 .name = "ata6285",
672 .llvm_name = "ata6285",
673 .features = featureSet(&[_]Feature{
674 .avr4,
675 }),
676 };
677 pub const ata6286 = CpuModel{
678 .name = "ata6286",
679 .llvm_name = "ata6286",
680 .features = featureSet(&[_]Feature{
681 .avr4,
682 }),
683 };
684 pub const ata6289 = CpuModel{
685 .name = "ata6289",
686 .llvm_name = "ata6289",
687 .features = featureSet(&[_]Feature{
688 .avr4,
689 }),
690 };
691 pub const ata6612c = CpuModel{
692 .name = "ata6612c",
693 .llvm_name = "ata6612c",
694 .features = featureSet(&[_]Feature{
695 .avr4,
696 }),
697 };
698 pub const ata6613c = CpuModel{
699 .name = "ata6613c",
700 .llvm_name = "ata6613c",
701 .features = featureSet(&[_]Feature{
702 .avr5,
703 }),
704 };
705 pub const ata6614q = CpuModel{
706 .name = "ata6614q",
707 .llvm_name = "ata6614q",
708 .features = featureSet(&[_]Feature{
709 .avr5,
710 }),
711 };
712 pub const ata6616c = CpuModel{
713 .name = "ata6616c",
714 .llvm_name = "ata6616c",
715 .features = featureSet(&[_]Feature{
716 .avr25,
717 }),
718 };
719 pub const ata6617c = CpuModel{
720 .name = "ata6617c",
721 .llvm_name = "ata6617c",
722 .features = featureSet(&[_]Feature{
723 .avr35,
724 }),
725 };
726 pub const ata664251 = CpuModel{
727 .name = "ata664251",
728 .llvm_name = "ata664251",
729 .features = featureSet(&[_]Feature{
730 .avr35,
731 }),
732 };
733 pub const ata8210 = CpuModel{
734 .name = "ata8210",
735 .llvm_name = "ata8210",
736 .features = featureSet(&[_]Feature{
737 .avr5,
738 }),
739 };
740 pub const ata8510 = CpuModel{
741 .name = "ata8510",
742 .llvm_name = "ata8510",
743 .features = featureSet(&[_]Feature{
744 .avr5,
745 }),
746 };
747 pub const atmega103 = CpuModel{
748 .name = "atmega103",
749 .llvm_name = "atmega103",
750 .features = featureSet(&[_]Feature{
751 .avr31,
752 }),
753 };
754 pub const atmega128 = CpuModel{
755 .name = "atmega128",
756 .llvm_name = "atmega128",
757 .features = featureSet(&[_]Feature{
758 .avr51,
759 }),
760 };
761 pub const atmega1280 = CpuModel{
762 .name = "atmega1280",
763 .llvm_name = "atmega1280",
764 .features = featureSet(&[_]Feature{
765 .avr51,
766 }),
767 };
768 pub const atmega1281 = CpuModel{
769 .name = "atmega1281",
770 .llvm_name = "atmega1281",
771 .features = featureSet(&[_]Feature{
772 .avr51,
773 }),
774 };
775 pub const atmega1284 = CpuModel{
776 .name = "atmega1284",
777 .llvm_name = "atmega1284",
778 .features = featureSet(&[_]Feature{
779 .avr51,
780 }),
781 };
782 pub const atmega1284p = CpuModel{
783 .name = "atmega1284p",
784 .llvm_name = "atmega1284p",
785 .features = featureSet(&[_]Feature{
786 .avr51,
787 }),
788 };
789 pub const atmega1284rfr2 = CpuModel{
790 .name = "atmega1284rfr2",
791 .llvm_name = "atmega1284rfr2",
792 .features = featureSet(&[_]Feature{
793 .avr51,
794 }),
795 };
796 pub const atmega128a = CpuModel{
797 .name = "atmega128a",
798 .llvm_name = "atmega128a",
799 .features = featureSet(&[_]Feature{
800 .avr51,
801 }),
802 };
803 pub const atmega128rfa1 = CpuModel{
804 .name = "atmega128rfa1",
805 .llvm_name = "atmega128rfa1",
806 .features = featureSet(&[_]Feature{
807 .avr51,
808 }),
809 };
810 pub const atmega128rfr2 = CpuModel{
811 .name = "atmega128rfr2",
812 .llvm_name = "atmega128rfr2",
813 .features = featureSet(&[_]Feature{
814 .avr51,
815 }),
816 };
817 pub const atmega16 = CpuModel{
818 .name = "atmega16",
819 .llvm_name = "atmega16",
820 .features = featureSet(&[_]Feature{
821 .avr5,
822 }),
823 };
824 pub const atmega1608 = CpuModel{
825 .name = "atmega1608",
826 .llvm_name = "atmega1608",
827 .features = featureSet(&[_]Feature{
828 .xmega3,
829 }),
830 };
831 pub const atmega1609 = CpuModel{
832 .name = "atmega1609",
833 .llvm_name = "atmega1609",
834 .features = featureSet(&[_]Feature{
835 .xmega3,
836 }),
837 };
838 pub const atmega161 = CpuModel{
839 .name = "atmega161",
840 .llvm_name = "atmega161",
841 .features = featureSet(&[_]Feature{
842 .avr3,
843 .lpmx,
844 .movw,
845 .mul,
846 .spm,
847 }),
848 };
849 pub const atmega162 = CpuModel{
850 .name = "atmega162",
851 .llvm_name = "atmega162",
852 .features = featureSet(&[_]Feature{
853 .avr5,
854 }),
855 };
856 pub const atmega163 = CpuModel{
857 .name = "atmega163",
858 .llvm_name = "atmega163",
859 .features = featureSet(&[_]Feature{
860 .avr3,
861 .lpmx,
862 .movw,
863 .mul,
864 .spm,
865 }),
866 };
867 pub const atmega164a = CpuModel{
868 .name = "atmega164a",
869 .llvm_name = "atmega164a",
870 .features = featureSet(&[_]Feature{
871 .avr5,
872 }),
873 };
874 pub const atmega164p = CpuModel{
875 .name = "atmega164p",
876 .llvm_name = "atmega164p",
877 .features = featureSet(&[_]Feature{
878 .avr5,
879 }),
880 };
881 pub const atmega164pa = CpuModel{
882 .name = "atmega164pa",
883 .llvm_name = "atmega164pa",
884 .features = featureSet(&[_]Feature{
885 .avr5,
886 }),
887 };
888 pub const atmega165 = CpuModel{
889 .name = "atmega165",
890 .llvm_name = "atmega165",
891 .features = featureSet(&[_]Feature{
892 .avr5,
893 }),
894 };
895 pub const atmega165a = CpuModel{
896 .name = "atmega165a",
897 .llvm_name = "atmega165a",
898 .features = featureSet(&[_]Feature{
899 .avr5,
900 }),
901 };
902 pub const atmega165p = CpuModel{
903 .name = "atmega165p",
904 .llvm_name = "atmega165p",
905 .features = featureSet(&[_]Feature{
906 .avr5,
907 }),
908 };
909 pub const atmega165pa = CpuModel{
910 .name = "atmega165pa",
911 .llvm_name = "atmega165pa",
912 .features = featureSet(&[_]Feature{
913 .avr5,
914 }),
915 };
916 pub const atmega168 = CpuModel{
917 .name = "atmega168",
918 .llvm_name = "atmega168",
919 .features = featureSet(&[_]Feature{
920 .avr5,
921 }),
922 };
923 pub const atmega168a = CpuModel{
924 .name = "atmega168a",
925 .llvm_name = "atmega168a",
926 .features = featureSet(&[_]Feature{
927 .avr5,
928 }),
929 };
930 pub const atmega168p = CpuModel{
931 .name = "atmega168p",
932 .llvm_name = "atmega168p",
933 .features = featureSet(&[_]Feature{
934 .avr5,
935 }),
936 };
937 pub const atmega168pa = CpuModel{
938 .name = "atmega168pa",
939 .llvm_name = "atmega168pa",
940 .features = featureSet(&[_]Feature{
941 .avr5,
942 }),
943 };
944 pub const atmega168pb = CpuModel{
945 .name = "atmega168pb",
946 .llvm_name = "atmega168pb",
947 .features = featureSet(&[_]Feature{
948 .avr5,
949 }),
950 };
951 pub const atmega169 = CpuModel{
952 .name = "atmega169",
953 .llvm_name = "atmega169",
954 .features = featureSet(&[_]Feature{
955 .avr5,
956 }),
957 };
958 pub const atmega169a = CpuModel{
959 .name = "atmega169a",
960 .llvm_name = "atmega169a",
961 .features = featureSet(&[_]Feature{
962 .avr5,
963 }),
964 };
965 pub const atmega169p = CpuModel{
966 .name = "atmega169p",
967 .llvm_name = "atmega169p",
968 .features = featureSet(&[_]Feature{
969 .avr5,
970 }),
971 };
972 pub const atmega169pa = CpuModel{
973 .name = "atmega169pa",
974 .llvm_name = "atmega169pa",
975 .features = featureSet(&[_]Feature{
976 .avr5,
977 }),
978 };
979 pub const atmega16a = CpuModel{
980 .name = "atmega16a",
981 .llvm_name = "atmega16a",
982 .features = featureSet(&[_]Feature{
983 .avr5,
984 }),
985 };
986 pub const atmega16hva = CpuModel{
987 .name = "atmega16hva",
988 .llvm_name = "atmega16hva",
989 .features = featureSet(&[_]Feature{
990 .avr5,
991 }),
992 };
993 pub const atmega16hva2 = CpuModel{
994 .name = "atmega16hva2",
995 .llvm_name = "atmega16hva2",
996 .features = featureSet(&[_]Feature{
997 .avr5,
998 }),
999 };
1000 pub const atmega16hvb = CpuModel{
1001 .name = "atmega16hvb",
1002 .llvm_name = "atmega16hvb",
1003 .features = featureSet(&[_]Feature{
1004 .avr5,
1005 }),
1006 };
1007 pub const atmega16hvbrevb = CpuModel{
1008 .name = "atmega16hvbrevb",
1009 .llvm_name = "atmega16hvbrevb",
1010 .features = featureSet(&[_]Feature{
1011 .avr5,
1012 }),
1013 };
1014 pub const atmega16m1 = CpuModel{
1015 .name = "atmega16m1",
1016 .llvm_name = "atmega16m1",
1017 .features = featureSet(&[_]Feature{
1018 .avr5,
1019 }),
1020 };
1021 pub const atmega16u2 = CpuModel{
1022 .name = "atmega16u2",
1023 .llvm_name = "atmega16u2",
1024 .features = featureSet(&[_]Feature{
1025 .avr35,
1026 }),
1027 };
1028 pub const atmega16u4 = CpuModel{
1029 .name = "atmega16u4",
1030 .llvm_name = "atmega16u4",
1031 .features = featureSet(&[_]Feature{
1032 .avr5,
1033 }),
1034 };
1035 pub const atmega2560 = CpuModel{
1036 .name = "atmega2560",
1037 .llvm_name = "atmega2560",
1038 .features = featureSet(&[_]Feature{
1039 .avr6,
1040 }),
1041 };
1042 pub const atmega2561 = CpuModel{
1043 .name = "atmega2561",
1044 .llvm_name = "atmega2561",
1045 .features = featureSet(&[_]Feature{
1046 .avr6,
1047 }),
1048 };
1049 pub const atmega2564rfr2 = CpuModel{
1050 .name = "atmega2564rfr2",
1051 .llvm_name = "atmega2564rfr2",
1052 .features = featureSet(&[_]Feature{
1053 .avr6,
1054 }),
1055 };
1056 pub const atmega256rfr2 = CpuModel{
1057 .name = "atmega256rfr2",
1058 .llvm_name = "atmega256rfr2",
1059 .features = featureSet(&[_]Feature{
1060 .avr6,
1061 }),
1062 };
1063 pub const atmega32 = CpuModel{
1064 .name = "atmega32",
1065 .llvm_name = "atmega32",
1066 .features = featureSet(&[_]Feature{
1067 .avr5,
1068 }),
1069 };
1070 pub const atmega3208 = CpuModel{
1071 .name = "atmega3208",
1072 .llvm_name = "atmega3208",
1073 .features = featureSet(&[_]Feature{
1074 .xmega3,
1075 }),
1076 };
1077 pub const atmega3209 = CpuModel{
1078 .name = "atmega3209",
1079 .llvm_name = "atmega3209",
1080 .features = featureSet(&[_]Feature{
1081 .xmega3,
1082 }),
1083 };
1084 pub const atmega323 = CpuModel{
1085 .name = "atmega323",
1086 .llvm_name = "atmega323",
1087 .features = featureSet(&[_]Feature{
1088 .avr5,
1089 }),
1090 };
1091 pub const atmega324a = CpuModel{
1092 .name = "atmega324a",
1093 .llvm_name = "atmega324a",
1094 .features = featureSet(&[_]Feature{
1095 .avr5,
1096 }),
1097 };
1098 pub const atmega324p = CpuModel{
1099 .name = "atmega324p",
1100 .llvm_name = "atmega324p",
1101 .features = featureSet(&[_]Feature{
1102 .avr5,
1103 }),
1104 };
1105 pub const atmega324pa = CpuModel{
1106 .name = "atmega324pa",
1107 .llvm_name = "atmega324pa",
1108 .features = featureSet(&[_]Feature{
1109 .avr5,
1110 }),
1111 };
1112 pub const atmega324pb = CpuModel{
1113 .name = "atmega324pb",
1114 .llvm_name = "atmega324pb",
1115 .features = featureSet(&[_]Feature{
1116 .avr5,
1117 }),
1118 };
1119 pub const atmega325 = CpuModel{
1120 .name = "atmega325",
1121 .llvm_name = "atmega325",
1122 .features = featureSet(&[_]Feature{
1123 .avr5,
1124 }),
1125 };
1126 pub const atmega3250 = CpuModel{
1127 .name = "atmega3250",
1128 .llvm_name = "atmega3250",
1129 .features = featureSet(&[_]Feature{
1130 .avr5,
1131 }),
1132 };
1133 pub const atmega3250a = CpuModel{
1134 .name = "atmega3250a",
1135 .llvm_name = "atmega3250a",
1136 .features = featureSet(&[_]Feature{
1137 .avr5,
1138 }),
1139 };
1140 pub const atmega3250p = CpuModel{
1141 .name = "atmega3250p",
1142 .llvm_name = "atmega3250p",
1143 .features = featureSet(&[_]Feature{
1144 .avr5,
1145 }),
1146 };
1147 pub const atmega3250pa = CpuModel{
1148 .name = "atmega3250pa",
1149 .llvm_name = "atmega3250pa",
1150 .features = featureSet(&[_]Feature{
1151 .avr5,
1152 }),
1153 };
1154 pub const atmega325a = CpuModel{
1155 .name = "atmega325a",
1156 .llvm_name = "atmega325a",
1157 .features = featureSet(&[_]Feature{
1158 .avr5,
1159 }),
1160 };
1161 pub const atmega325p = CpuModel{
1162 .name = "atmega325p",
1163 .llvm_name = "atmega325p",
1164 .features = featureSet(&[_]Feature{
1165 .avr5,
1166 }),
1167 };
1168 pub const atmega325pa = CpuModel{
1169 .name = "atmega325pa",
1170 .llvm_name = "atmega325pa",
1171 .features = featureSet(&[_]Feature{
1172 .avr5,
1173 }),
1174 };
1175 pub const atmega328 = CpuModel{
1176 .name = "atmega328",
1177 .llvm_name = "atmega328",
1178 .features = featureSet(&[_]Feature{
1179 .avr5,
1180 }),
1181 };
1182 pub const atmega328p = CpuModel{
1183 .name = "atmega328p",
1184 .llvm_name = "atmega328p",
1185 .features = featureSet(&[_]Feature{
1186 .avr5,
1187 }),
1188 };
1189 pub const atmega328pb = CpuModel{
1190 .name = "atmega328pb",
1191 .llvm_name = "atmega328pb",
1192 .features = featureSet(&[_]Feature{
1193 .avr5,
1194 }),
1195 };
1196 pub const atmega329 = CpuModel{
1197 .name = "atmega329",
1198 .llvm_name = "atmega329",
1199 .features = featureSet(&[_]Feature{
1200 .avr5,
1201 }),
1202 };
1203 pub const atmega3290 = CpuModel{
1204 .name = "atmega3290",
1205 .llvm_name = "atmega3290",
1206 .features = featureSet(&[_]Feature{
1207 .avr5,
1208 }),
1209 };
1210 pub const atmega3290a = CpuModel{
1211 .name = "atmega3290a",
1212 .llvm_name = "atmega3290a",
1213 .features = featureSet(&[_]Feature{
1214 .avr5,
1215 }),
1216 };
1217 pub const atmega3290p = CpuModel{
1218 .name = "atmega3290p",
1219 .llvm_name = "atmega3290p",
1220 .features = featureSet(&[_]Feature{
1221 .avr5,
1222 }),
1223 };
1224 pub const atmega3290pa = CpuModel{
1225 .name = "atmega3290pa",
1226 .llvm_name = "atmega3290pa",
1227 .features = featureSet(&[_]Feature{
1228 .avr5,
1229 }),
1230 };
1231 pub const atmega329a = CpuModel{
1232 .name = "atmega329a",
1233 .llvm_name = "atmega329a",
1234 .features = featureSet(&[_]Feature{
1235 .avr5,
1236 }),
1237 };
1238 pub const atmega329p = CpuModel{
1239 .name = "atmega329p",
1240 .llvm_name = "atmega329p",
1241 .features = featureSet(&[_]Feature{
1242 .avr5,
1243 }),
1244 };
1245 pub const atmega329pa = CpuModel{
1246 .name = "atmega329pa",
1247 .llvm_name = "atmega329pa",
1248 .features = featureSet(&[_]Feature{
1249 .avr5,
1250 }),
1251 };
1252 pub const atmega32a = CpuModel{
1253 .name = "atmega32a",
1254 .llvm_name = "atmega32a",
1255 .features = featureSet(&[_]Feature{
1256 .avr5,
1257 }),
1258 };
1259 pub const atmega32c1 = CpuModel{
1260 .name = "atmega32c1",
1261 .llvm_name = "atmega32c1",
1262 .features = featureSet(&[_]Feature{
1263 .avr5,
1264 }),
1265 };
1266 pub const atmega32hvb = CpuModel{
1267 .name = "atmega32hvb",
1268 .llvm_name = "atmega32hvb",
1269 .features = featureSet(&[_]Feature{
1270 .avr5,
1271 }),
1272 };
1273 pub const atmega32hvbrevb = CpuModel{
1274 .name = "atmega32hvbrevb",
1275 .llvm_name = "atmega32hvbrevb",
1276 .features = featureSet(&[_]Feature{
1277 .avr5,
1278 }),
1279 };
1280 pub const atmega32m1 = CpuModel{
1281 .name = "atmega32m1",
1282 .llvm_name = "atmega32m1",
1283 .features = featureSet(&[_]Feature{
1284 .avr5,
1285 }),
1286 };
1287 pub const atmega32u2 = CpuModel{
1288 .name = "atmega32u2",
1289 .llvm_name = "atmega32u2",
1290 .features = featureSet(&[_]Feature{
1291 .avr35,
1292 }),
1293 };
1294 pub const atmega32u4 = CpuModel{
1295 .name = "atmega32u4",
1296 .llvm_name = "atmega32u4",
1297 .features = featureSet(&[_]Feature{
1298 .avr5,
1299 }),
1300 };
1301 pub const atmega32u6 = CpuModel{
1302 .name = "atmega32u6",
1303 .llvm_name = "atmega32u6",
1304 .features = featureSet(&[_]Feature{
1305 .avr5,
1306 }),
1307 };
1308 pub const atmega406 = CpuModel{
1309 .name = "atmega406",
1310 .llvm_name = "atmega406",
1311 .features = featureSet(&[_]Feature{
1312 .avr5,
1313 }),
1314 };
1315 pub const atmega48 = CpuModel{
1316 .name = "atmega48",
1317 .llvm_name = "atmega48",
1318 .features = featureSet(&[_]Feature{
1319 .avr4,
1320 }),
1321 };
1322 pub const atmega4808 = CpuModel{
1323 .name = "atmega4808",
1324 .llvm_name = "atmega4808",
1325 .features = featureSet(&[_]Feature{
1326 .xmega3,
1327 }),
1328 };
1329 pub const atmega4809 = CpuModel{
1330 .name = "atmega4809",
1331 .llvm_name = "atmega4809",
1332 .features = featureSet(&[_]Feature{
1333 .xmega3,
1334 }),
1335 };
1336 pub const atmega48a = CpuModel{
1337 .name = "atmega48a",
1338 .llvm_name = "atmega48a",
1339 .features = featureSet(&[_]Feature{
1340 .avr4,
1341 }),
1342 };
1343 pub const atmega48p = CpuModel{
1344 .name = "atmega48p",
1345 .llvm_name = "atmega48p",
1346 .features = featureSet(&[_]Feature{
1347 .avr4,
1348 }),
1349 };
1350 pub const atmega48pa = CpuModel{
1351 .name = "atmega48pa",
1352 .llvm_name = "atmega48pa",
1353 .features = featureSet(&[_]Feature{
1354 .avr4,
1355 }),
1356 };
1357 pub const atmega48pb = CpuModel{
1358 .name = "atmega48pb",
1359 .llvm_name = "atmega48pb",
1360 .features = featureSet(&[_]Feature{
1361 .avr4,
1362 }),
1363 };
1364 pub const atmega64 = CpuModel{
1365 .name = "atmega64",
1366 .llvm_name = "atmega64",
1367 .features = featureSet(&[_]Feature{
1368 .avr5,
1369 }),
1370 };
1371 pub const atmega640 = CpuModel{
1372 .name = "atmega640",
1373 .llvm_name = "atmega640",
1374 .features = featureSet(&[_]Feature{
1375 .avr5,
1376 }),
1377 };
1378 pub const atmega644 = CpuModel{
1379 .name = "atmega644",
1380 .llvm_name = "atmega644",
1381 .features = featureSet(&[_]Feature{
1382 .avr5,
1383 }),
1384 };
1385 pub const atmega644a = CpuModel{
1386 .name = "atmega644a",
1387 .llvm_name = "atmega644a",
1388 .features = featureSet(&[_]Feature{
1389 .avr5,
1390 }),
1391 };
1392 pub const atmega644p = CpuModel{
1393 .name = "atmega644p",
1394 .llvm_name = "atmega644p",
1395 .features = featureSet(&[_]Feature{
1396 .avr5,
1397 }),
1398 };
1399 pub const atmega644pa = CpuModel{
1400 .name = "atmega644pa",
1401 .llvm_name = "atmega644pa",
1402 .features = featureSet(&[_]Feature{
1403 .avr5,
1404 }),
1405 };
1406 pub const atmega644rfr2 = CpuModel{
1407 .name = "atmega644rfr2",
1408 .llvm_name = "atmega644rfr2",
1409 .features = featureSet(&[_]Feature{
1410 .avr5,
1411 }),
1412 };
1413 pub const atmega645 = CpuModel{
1414 .name = "atmega645",
1415 .llvm_name = "atmega645",
1416 .features = featureSet(&[_]Feature{
1417 .avr5,
1418 }),
1419 };
1420 pub const atmega6450 = CpuModel{
1421 .name = "atmega6450",
1422 .llvm_name = "atmega6450",
1423 .features = featureSet(&[_]Feature{
1424 .avr5,
1425 }),
1426 };
1427 pub const atmega6450a = CpuModel{
1428 .name = "atmega6450a",
1429 .llvm_name = "atmega6450a",
1430 .features = featureSet(&[_]Feature{
1431 .avr5,
1432 }),
1433 };
1434 pub const atmega6450p = CpuModel{
1435 .name = "atmega6450p",
1436 .llvm_name = "atmega6450p",
1437 .features = featureSet(&[_]Feature{
1438 .avr5,
1439 }),
1440 };
1441 pub const atmega645a = CpuModel{
1442 .name = "atmega645a",
1443 .llvm_name = "atmega645a",
1444 .features = featureSet(&[_]Feature{
1445 .avr5,
1446 }),
1447 };
1448 pub const atmega645p = CpuModel{
1449 .name = "atmega645p",
1450 .llvm_name = "atmega645p",
1451 .features = featureSet(&[_]Feature{
1452 .avr5,
1453 }),
1454 };
1455 pub const atmega649 = CpuModel{
1456 .name = "atmega649",
1457 .llvm_name = "atmega649",
1458 .features = featureSet(&[_]Feature{
1459 .avr5,
1460 }),
1461 };
1462 pub const atmega6490 = CpuModel{
1463 .name = "atmega6490",
1464 .llvm_name = "atmega6490",
1465 .features = featureSet(&[_]Feature{
1466 .avr5,
1467 }),
1468 };
1469 pub const atmega6490a = CpuModel{
1470 .name = "atmega6490a",
1471 .llvm_name = "atmega6490a",
1472 .features = featureSet(&[_]Feature{
1473 .avr5,
1474 }),
1475 };
1476 pub const atmega6490p = CpuModel{
1477 .name = "atmega6490p",
1478 .llvm_name = "atmega6490p",
1479 .features = featureSet(&[_]Feature{
1480 .avr5,
1481 }),
1482 };
1483 pub const atmega649a = CpuModel{
1484 .name = "atmega649a",
1485 .llvm_name = "atmega649a",
1486 .features = featureSet(&[_]Feature{
1487 .avr5,
1488 }),
1489 };
1490 pub const atmega649p = CpuModel{
1491 .name = "atmega649p",
1492 .llvm_name = "atmega649p",
1493 .features = featureSet(&[_]Feature{
1494 .avr5,
1495 }),
1496 };
1497 pub const atmega64a = CpuModel{
1498 .name = "atmega64a",
1499 .llvm_name = "atmega64a",
1500 .features = featureSet(&[_]Feature{
1501 .avr5,
1502 }),
1503 };
1504 pub const atmega64c1 = CpuModel{
1505 .name = "atmega64c1",
1506 .llvm_name = "atmega64c1",
1507 .features = featureSet(&[_]Feature{
1508 .avr5,
1509 }),
1510 };
1511 pub const atmega64hve = CpuModel{
1512 .name = "atmega64hve",
1513 .llvm_name = "atmega64hve",
1514 .features = featureSet(&[_]Feature{
1515 .avr5,
1516 }),
1517 };
1518 pub const atmega64hve2 = CpuModel{
1519 .name = "atmega64hve2",
1520 .llvm_name = "atmega64hve2",
1521 .features = featureSet(&[_]Feature{
1522 .avr5,
1523 }),
1524 };
1525 pub const atmega64m1 = CpuModel{
1526 .name = "atmega64m1",
1527 .llvm_name = "atmega64m1",
1528 .features = featureSet(&[_]Feature{
1529 .avr5,
1530 }),
1531 };
1532 pub const atmega64rfr2 = CpuModel{
1533 .name = "atmega64rfr2",
1534 .llvm_name = "atmega64rfr2",
1535 .features = featureSet(&[_]Feature{
1536 .avr5,
1537 }),
1538 };
1539 pub const atmega8 = CpuModel{
1540 .name = "atmega8",
1541 .llvm_name = "atmega8",
1542 .features = featureSet(&[_]Feature{
1543 .avr2,
1544 .lpmx,
1545 .movw,
1546 .mul,
1547 .spm,
1548 }),
1549 };
1550 pub const atmega808 = CpuModel{
1551 .name = "atmega808",
1552 .llvm_name = "atmega808",
1553 .features = featureSet(&[_]Feature{
1554 .xmega3,
1555 }),
1556 };
1557 pub const atmega809 = CpuModel{
1558 .name = "atmega809",
1559 .llvm_name = "atmega809",
1560 .features = featureSet(&[_]Feature{
1561 .xmega3,
1562 }),
1563 };
1564 pub const atmega8515 = CpuModel{
1565 .name = "atmega8515",
1566 .llvm_name = "atmega8515",
1567 .features = featureSet(&[_]Feature{
1568 .avr2,
1569 .lpmx,
1570 .movw,
1571 .mul,
1572 .spm,
1573 }),
1574 };
1575 pub const atmega8535 = CpuModel{
1576 .name = "atmega8535",
1577 .llvm_name = "atmega8535",
1578 .features = featureSet(&[_]Feature{
1579 .avr2,
1580 .lpmx,
1581 .movw,
1582 .mul,
1583 .spm,
1584 }),
1585 };
1586 pub const atmega88 = CpuModel{
1587 .name = "atmega88",
1588 .llvm_name = "atmega88",
1589 .features = featureSet(&[_]Feature{
1590 .avr4,
1591 }),
1592 };
1593 pub const atmega88a = CpuModel{
1594 .name = "atmega88a",
1595 .llvm_name = "atmega88a",
1596 .features = featureSet(&[_]Feature{
1597 .avr4,
1598 }),
1599 };
1600 pub const atmega88p = CpuModel{
1601 .name = "atmega88p",
1602 .llvm_name = "atmega88p",
1603 .features = featureSet(&[_]Feature{
1604 .avr4,
1605 }),
1606 };
1607 pub const atmega88pa = CpuModel{
1608 .name = "atmega88pa",
1609 .llvm_name = "atmega88pa",
1610 .features = featureSet(&[_]Feature{
1611 .avr4,
1612 }),
1613 };
1614 pub const atmega88pb = CpuModel{
1615 .name = "atmega88pb",
1616 .llvm_name = "atmega88pb",
1617 .features = featureSet(&[_]Feature{
1618 .avr4,
1619 }),
1620 };
1621 pub const atmega8a = CpuModel{
1622 .name = "atmega8a",
1623 .llvm_name = "atmega8a",
1624 .features = featureSet(&[_]Feature{
1625 .avr2,
1626 .lpmx,
1627 .movw,
1628 .mul,
1629 .spm,
1630 }),
1631 };
1632 pub const atmega8hva = CpuModel{
1633 .name = "atmega8hva",
1634 .llvm_name = "atmega8hva",
1635 .features = featureSet(&[_]Feature{
1636 .avr4,
1637 }),
1638 };
1639 pub const atmega8u2 = CpuModel{
1640 .name = "atmega8u2",
1641 .llvm_name = "atmega8u2",
1642 .features = featureSet(&[_]Feature{
1643 .avr35,
1644 }),
1645 };
1646 pub const attiny10 = CpuModel{
1647 .name = "attiny10",
1648 .llvm_name = "attiny10",
1649 .features = featureSet(&[_]Feature{
1650 .avrtiny,
1651 }),
1652 };
1653 pub const attiny102 = CpuModel{
1654 .name = "attiny102",
1655 .llvm_name = "attiny102",
1656 .features = featureSet(&[_]Feature{
1657 .avrtiny,
1658 }),
1659 };
1660 pub const attiny104 = CpuModel{
1661 .name = "attiny104",
1662 .llvm_name = "attiny104",
1663 .features = featureSet(&[_]Feature{
1664 .avrtiny,
1665 }),
1666 };
1667 pub const attiny11 = CpuModel{
1668 .name = "attiny11",
1669 .llvm_name = "attiny11",
1670 .features = featureSet(&[_]Feature{
1671 .avr1,
1672 .smallstack,
1673 }),
1674 };
1675 pub const attiny12 = CpuModel{
1676 .name = "attiny12",
1677 .llvm_name = "attiny12",
1678 .features = featureSet(&[_]Feature{
1679 .avr1,
1680 .smallstack,
1681 }),
1682 };
1683 pub const attiny13 = CpuModel{
1684 .name = "attiny13",
1685 .llvm_name = "attiny13",
1686 .features = featureSet(&[_]Feature{
1687 .avr25,
1688 .smallstack,
1689 }),
1690 };
1691 pub const attiny13a = CpuModel{
1692 .name = "attiny13a",
1693 .llvm_name = "attiny13a",
1694 .features = featureSet(&[_]Feature{
1695 .avr25,
1696 .smallstack,
1697 }),
1698 };
1699 pub const attiny15 = CpuModel{
1700 .name = "attiny15",
1701 .llvm_name = "attiny15",
1702 .features = featureSet(&[_]Feature{
1703 .avr1,
1704 .smallstack,
1705 }),
1706 };
1707 pub const attiny1604 = CpuModel{
1708 .name = "attiny1604",
1709 .llvm_name = "attiny1604",
1710 .features = featureSet(&[_]Feature{
1711 .xmega3,
1712 }),
1713 };
1714 pub const attiny1606 = CpuModel{
1715 .name = "attiny1606",
1716 .llvm_name = "attiny1606",
1717 .features = featureSet(&[_]Feature{
1718 .xmega3,
1719 }),
1720 };
1721 pub const attiny1607 = CpuModel{
1722 .name = "attiny1607",
1723 .llvm_name = "attiny1607",
1724 .features = featureSet(&[_]Feature{
1725 .xmega3,
1726 }),
1727 };
1728 pub const attiny1614 = CpuModel{
1729 .name = "attiny1614",
1730 .llvm_name = "attiny1614",
1731 .features = featureSet(&[_]Feature{
1732 .xmega3,
1733 }),
1734 };
1735 pub const attiny1616 = CpuModel{
1736 .name = "attiny1616",
1737 .llvm_name = "attiny1616",
1738 .features = featureSet(&[_]Feature{
1739 .xmega3,
1740 }),
1741 };
1742 pub const attiny1617 = CpuModel{
1743 .name = "attiny1617",
1744 .llvm_name = "attiny1617",
1745 .features = featureSet(&[_]Feature{
1746 .xmega3,
1747 }),
1748 };
1749 pub const attiny1624 = CpuModel{
1750 .name = "attiny1624",
1751 .llvm_name = "attiny1624",
1752 .features = featureSet(&[_]Feature{
1753 .xmega3,
1754 }),
1755 };
1756 pub const attiny1626 = CpuModel{
1757 .name = "attiny1626",
1758 .llvm_name = "attiny1626",
1759 .features = featureSet(&[_]Feature{
1760 .xmega3,
1761 }),
1762 };
1763 pub const attiny1627 = CpuModel{
1764 .name = "attiny1627",
1765 .llvm_name = "attiny1627",
1766 .features = featureSet(&[_]Feature{
1767 .xmega3,
1768 }),
1769 };
1770 pub const attiny1634 = CpuModel{
1771 .name = "attiny1634",
1772 .llvm_name = "attiny1634",
1773 .features = featureSet(&[_]Feature{
1774 .avr35,
1775 }),
1776 };
1777 pub const attiny167 = CpuModel{
1778 .name = "attiny167",
1779 .llvm_name = "attiny167",
1780 .features = featureSet(&[_]Feature{
1781 .avr35,
1782 }),
1783 };
1784 pub const attiny20 = CpuModel{
1785 .name = "attiny20",
1786 .llvm_name = "attiny20",
1787 .features = featureSet(&[_]Feature{
1788 .avrtiny,
1789 }),
1790 };
1791 pub const attiny202 = CpuModel{
1792 .name = "attiny202",
1793 .llvm_name = "attiny202",
1794 .features = featureSet(&[_]Feature{
1795 .xmega3,
1796 }),
1797 };
1798 pub const attiny204 = CpuModel{
1799 .name = "attiny204",
1800 .llvm_name = "attiny204",
1801 .features = featureSet(&[_]Feature{
1802 .xmega3,
1803 }),
1804 };
1805 pub const attiny212 = CpuModel{
1806 .name = "attiny212",
1807 .llvm_name = "attiny212",
1808 .features = featureSet(&[_]Feature{
1809 .xmega3,
1810 }),
1811 };
1812 pub const attiny214 = CpuModel{
1813 .name = "attiny214",
1814 .llvm_name = "attiny214",
1815 .features = featureSet(&[_]Feature{
1816 .xmega3,
1817 }),
1818 };
1819 pub const attiny22 = CpuModel{
1820 .name = "attiny22",
1821 .llvm_name = "attiny22",
1822 .features = featureSet(&[_]Feature{
1823 .avr2,
1824 .smallstack,
1825 }),
1826 };
1827 pub const attiny2313 = CpuModel{
1828 .name = "attiny2313",
1829 .llvm_name = "attiny2313",
1830 .features = featureSet(&[_]Feature{
1831 .avr25,
1832 .smallstack,
1833 }),
1834 };
1835 pub const attiny2313a = CpuModel{
1836 .name = "attiny2313a",
1837 .llvm_name = "attiny2313a",
1838 .features = featureSet(&[_]Feature{
1839 .avr25,
1840 .smallstack,
1841 }),
1842 };
1843 pub const attiny24 = CpuModel{
1844 .name = "attiny24",
1845 .llvm_name = "attiny24",
1846 .features = featureSet(&[_]Feature{
1847 .avr25,
1848 .smallstack,
1849 }),
1850 };
1851 pub const attiny24a = CpuModel{
1852 .name = "attiny24a",
1853 .llvm_name = "attiny24a",
1854 .features = featureSet(&[_]Feature{
1855 .avr25,
1856 .smallstack,
1857 }),
1858 };
1859 pub const attiny25 = CpuModel{
1860 .name = "attiny25",
1861 .llvm_name = "attiny25",
1862 .features = featureSet(&[_]Feature{
1863 .avr25,
1864 .smallstack,
1865 }),
1866 };
1867 pub const attiny26 = CpuModel{
1868 .name = "attiny26",
1869 .llvm_name = "attiny26",
1870 .features = featureSet(&[_]Feature{
1871 .avr2,
1872 .lpmx,
1873 .smallstack,
1874 }),
1875 };
1876 pub const attiny261 = CpuModel{
1877 .name = "attiny261",
1878 .llvm_name = "attiny261",
1879 .features = featureSet(&[_]Feature{
1880 .avr25,
1881 .smallstack,
1882 }),
1883 };
1884 pub const attiny261a = CpuModel{
1885 .name = "attiny261a",
1886 .llvm_name = "attiny261a",
1887 .features = featureSet(&[_]Feature{
1888 .avr25,
1889 .smallstack,
1890 }),
1891 };
1892 pub const attiny28 = CpuModel{
1893 .name = "attiny28",
1894 .llvm_name = "attiny28",
1895 .features = featureSet(&[_]Feature{
1896 .avr1,
1897 .smallstack,
1898 }),
1899 };
1900 pub const attiny3216 = CpuModel{
1901 .name = "attiny3216",
1902 .llvm_name = "attiny3216",
1903 .features = featureSet(&[_]Feature{
1904 .xmega3,
1905 }),
1906 };
1907 pub const attiny3217 = CpuModel{
1908 .name = "attiny3217",
1909 .llvm_name = "attiny3217",
1910 .features = featureSet(&[_]Feature{
1911 .xmega3,
1912 }),
1913 };
1914 pub const attiny4 = CpuModel{
1915 .name = "attiny4",
1916 .llvm_name = "attiny4",
1917 .features = featureSet(&[_]Feature{
1918 .avrtiny,
1919 }),
1920 };
1921 pub const attiny40 = CpuModel{
1922 .name = "attiny40",
1923 .llvm_name = "attiny40",
1924 .features = featureSet(&[_]Feature{
1925 .avrtiny,
1926 }),
1927 };
1928 pub const attiny402 = CpuModel{
1929 .name = "attiny402",
1930 .llvm_name = "attiny402",
1931 .features = featureSet(&[_]Feature{
1932 .xmega3,
1933 }),
1934 };
1935 pub const attiny404 = CpuModel{
1936 .name = "attiny404",
1937 .llvm_name = "attiny404",
1938 .features = featureSet(&[_]Feature{
1939 .xmega3,
1940 }),
1941 };
1942 pub const attiny406 = CpuModel{
1943 .name = "attiny406",
1944 .llvm_name = "attiny406",
1945 .features = featureSet(&[_]Feature{
1946 .xmega3,
1947 }),
1948 };
1949 pub const attiny412 = CpuModel{
1950 .name = "attiny412",
1951 .llvm_name = "attiny412",
1952 .features = featureSet(&[_]Feature{
1953 .xmega3,
1954 }),
1955 };
1956 pub const attiny414 = CpuModel{
1957 .name = "attiny414",
1958 .llvm_name = "attiny414",
1959 .features = featureSet(&[_]Feature{
1960 .xmega3,
1961 }),
1962 };
1963 pub const attiny416 = CpuModel{
1964 .name = "attiny416",
1965 .llvm_name = "attiny416",
1966 .features = featureSet(&[_]Feature{
1967 .xmega3,
1968 }),
1969 };
1970 pub const attiny417 = CpuModel{
1971 .name = "attiny417",
1972 .llvm_name = "attiny417",
1973 .features = featureSet(&[_]Feature{
1974 .xmega3,
1975 }),
1976 };
1977 pub const attiny4313 = CpuModel{
1978 .name = "attiny4313",
1979 .llvm_name = "attiny4313",
1980 .features = featureSet(&[_]Feature{
1981 .avr25,
1982 }),
1983 };
1984 pub const attiny43u = CpuModel{
1985 .name = "attiny43u",
1986 .llvm_name = "attiny43u",
1987 .features = featureSet(&[_]Feature{
1988 .avr25,
1989 }),
1990 };
1991 pub const attiny44 = CpuModel{
1992 .name = "attiny44",
1993 .llvm_name = "attiny44",
1994 .features = featureSet(&[_]Feature{
1995 .avr25,
1996 }),
1997 };
1998 pub const attiny441 = CpuModel{
1999 .name = "attiny441",
2000 .llvm_name = "attiny441",
2001 .features = featureSet(&[_]Feature{
2002 .avr25,
2003 }),
2004 };
2005 pub const attiny44a = CpuModel{
2006 .name = "attiny44a",
2007 .llvm_name = "attiny44a",
2008 .features = featureSet(&[_]Feature{
2009 .avr25,
2010 }),
2011 };
2012 pub const attiny45 = CpuModel{
2013 .name = "attiny45",
2014 .llvm_name = "attiny45",
2015 .features = featureSet(&[_]Feature{
2016 .avr25,
2017 }),
2018 };
2019 pub const attiny461 = CpuModel{
2020 .name = "attiny461",
2021 .llvm_name = "attiny461",
2022 .features = featureSet(&[_]Feature{
2023 .avr25,
2024 }),
2025 };
2026 pub const attiny461a = CpuModel{
2027 .name = "attiny461a",
2028 .llvm_name = "attiny461a",
2029 .features = featureSet(&[_]Feature{
2030 .avr25,
2031 }),
2032 };
2033 pub const attiny48 = CpuModel{
2034 .name = "attiny48",
2035 .llvm_name = "attiny48",
2036 .features = featureSet(&[_]Feature{
2037 .avr25,
2038 }),
2039 };
2040 pub const attiny5 = CpuModel{
2041 .name = "attiny5",
2042 .llvm_name = "attiny5",
2043 .features = featureSet(&[_]Feature{
2044 .avrtiny,
2045 }),
2046 };
2047 pub const attiny804 = CpuModel{
2048 .name = "attiny804",
2049 .llvm_name = "attiny804",
2050 .features = featureSet(&[_]Feature{
2051 .xmega3,
2052 }),
2053 };
2054 pub const attiny806 = CpuModel{
2055 .name = "attiny806",
2056 .llvm_name = "attiny806",
2057 .features = featureSet(&[_]Feature{
2058 .xmega3,
2059 }),
2060 };
2061 pub const attiny807 = CpuModel{
2062 .name = "attiny807",
2063 .llvm_name = "attiny807",
2064 .features = featureSet(&[_]Feature{
2065 .xmega3,
2066 }),
2067 };
2068 pub const attiny814 = CpuModel{
2069 .name = "attiny814",
2070 .llvm_name = "attiny814",
2071 .features = featureSet(&[_]Feature{
2072 .xmega3,
2073 }),
2074 };
2075 pub const attiny816 = CpuModel{
2076 .name = "attiny816",
2077 .llvm_name = "attiny816",
2078 .features = featureSet(&[_]Feature{
2079 .xmega3,
2080 }),
2081 };
2082 pub const attiny817 = CpuModel{
2083 .name = "attiny817",
2084 .llvm_name = "attiny817",
2085 .features = featureSet(&[_]Feature{
2086 .xmega3,
2087 }),
2088 };
2089 pub const attiny828 = CpuModel{
2090 .name = "attiny828",
2091 .llvm_name = "attiny828",
2092 .features = featureSet(&[_]Feature{
2093 .avr25,
2094 }),
2095 };
2096 pub const attiny84 = CpuModel{
2097 .name = "attiny84",
2098 .llvm_name = "attiny84",
2099 .features = featureSet(&[_]Feature{
2100 .avr25,
2101 }),
2102 };
2103 pub const attiny841 = CpuModel{
2104 .name = "attiny841",
2105 .llvm_name = "attiny841",
2106 .features = featureSet(&[_]Feature{
2107 .avr25,
2108 }),
2109 };
2110 pub const attiny84a = CpuModel{
2111 .name = "attiny84a",
2112 .llvm_name = "attiny84a",
2113 .features = featureSet(&[_]Feature{
2114 .avr25,
2115 }),
2116 };
2117 pub const attiny85 = CpuModel{
2118 .name = "attiny85",
2119 .llvm_name = "attiny85",
2120 .features = featureSet(&[_]Feature{
2121 .avr25,
2122 }),
2123 };
2124 pub const attiny861 = CpuModel{
2125 .name = "attiny861",
2126 .llvm_name = "attiny861",
2127 .features = featureSet(&[_]Feature{
2128 .avr25,
2129 }),
2130 };
2131 pub const attiny861a = CpuModel{
2132 .name = "attiny861a",
2133 .llvm_name = "attiny861a",
2134 .features = featureSet(&[_]Feature{
2135 .avr25,
2136 }),
2137 };
2138 pub const attiny87 = CpuModel{
2139 .name = "attiny87",
2140 .llvm_name = "attiny87",
2141 .features = featureSet(&[_]Feature{
2142 .avr25,
2143 }),
2144 };
2145 pub const attiny88 = CpuModel{
2146 .name = "attiny88",
2147 .llvm_name = "attiny88",
2148 .features = featureSet(&[_]Feature{
2149 .avr25,
2150 }),
2151 };
2152 pub const attiny9 = CpuModel{
2153 .name = "attiny9",
2154 .llvm_name = "attiny9",
2155 .features = featureSet(&[_]Feature{
2156 .avrtiny,
2157 }),
2158 };
2159 pub const atxmega128a1 = CpuModel{
2160 .name = "atxmega128a1",
2161 .llvm_name = "atxmega128a1",
2162 .features = featureSet(&[_]Feature{
2163 .xmega,
2164 }),
2165 };
2166 pub const atxmega128a1u = CpuModel{
2167 .name = "atxmega128a1u",
2168 .llvm_name = "atxmega128a1u",
2169 .features = featureSet(&[_]Feature{
2170 .xmegau,
2171 }),
2172 };
2173 pub const atxmega128a3 = CpuModel{
2174 .name = "atxmega128a3",
2175 .llvm_name = "atxmega128a3",
2176 .features = featureSet(&[_]Feature{
2177 .xmega,
2178 }),
2179 };
2180 pub const atxmega128a3u = CpuModel{
2181 .name = "atxmega128a3u",
2182 .llvm_name = "atxmega128a3u",
2183 .features = featureSet(&[_]Feature{
2184 .xmegau,
2185 }),
2186 };
2187 pub const atxmega128a4u = CpuModel{
2188 .name = "atxmega128a4u",
2189 .llvm_name = "atxmega128a4u",
2190 .features = featureSet(&[_]Feature{
2191 .xmegau,
2192 }),
2193 };
2194 pub const atxmega128b1 = CpuModel{
2195 .name = "atxmega128b1",
2196 .llvm_name = "atxmega128b1",
2197 .features = featureSet(&[_]Feature{
2198 .xmegau,
2199 }),
2200 };
2201 pub const atxmega128b3 = CpuModel{
2202 .name = "atxmega128b3",
2203 .llvm_name = "atxmega128b3",
2204 .features = featureSet(&[_]Feature{
2205 .xmegau,
2206 }),
2207 };
2208 pub const atxmega128c3 = CpuModel{
2209 .name = "atxmega128c3",
2210 .llvm_name = "atxmega128c3",
2211 .features = featureSet(&[_]Feature{
2212 .xmegau,
2213 }),
2214 };
2215 pub const atxmega128d3 = CpuModel{
2216 .name = "atxmega128d3",
2217 .llvm_name = "atxmega128d3",
2218 .features = featureSet(&[_]Feature{
2219 .xmega,
2220 }),
2221 };
2222 pub const atxmega128d4 = CpuModel{
2223 .name = "atxmega128d4",
2224 .llvm_name = "atxmega128d4",
2225 .features = featureSet(&[_]Feature{
2226 .xmega,
2227 }),
2228 };
2229 pub const atxmega16a4 = CpuModel{
2230 .name = "atxmega16a4",
2231 .llvm_name = "atxmega16a4",
2232 .features = featureSet(&[_]Feature{
2233 .xmega,
2234 }),
2235 };
2236 pub const atxmega16a4u = CpuModel{
2237 .name = "atxmega16a4u",
2238 .llvm_name = "atxmega16a4u",
2239 .features = featureSet(&[_]Feature{
2240 .xmegau,
2241 }),
2242 };
2243 pub const atxmega16c4 = CpuModel{
2244 .name = "atxmega16c4",
2245 .llvm_name = "atxmega16c4",
2246 .features = featureSet(&[_]Feature{
2247 .xmegau,
2248 }),
2249 };
2250 pub const atxmega16d4 = CpuModel{
2251 .name = "atxmega16d4",
2252 .llvm_name = "atxmega16d4",
2253 .features = featureSet(&[_]Feature{
2254 .xmega,
2255 }),
2256 };
2257 pub const atxmega16e5 = CpuModel{
2258 .name = "atxmega16e5",
2259 .llvm_name = "atxmega16e5",
2260 .features = featureSet(&[_]Feature{
2261 .xmegau,
2262 }),
2263 };
2264 pub const atxmega192a3 = CpuModel{
2265 .name = "atxmega192a3",
2266 .llvm_name = "atxmega192a3",
2267 .features = featureSet(&[_]Feature{
2268 .xmega,
2269 }),
2270 };
2271 pub const atxmega192a3u = CpuModel{
2272 .name = "atxmega192a3u",
2273 .llvm_name = "atxmega192a3u",
2274 .features = featureSet(&[_]Feature{
2275 .xmegau,
2276 }),
2277 };
2278 pub const atxmega192c3 = CpuModel{
2279 .name = "atxmega192c3",
2280 .llvm_name = "atxmega192c3",
2281 .features = featureSet(&[_]Feature{
2282 .xmegau,
2283 }),
2284 };
2285 pub const atxmega192d3 = CpuModel{
2286 .name = "atxmega192d3",
2287 .llvm_name = "atxmega192d3",
2288 .features = featureSet(&[_]Feature{
2289 .xmega,
2290 }),
2291 };
2292 pub const atxmega256a3 = CpuModel{
2293 .name = "atxmega256a3",
2294 .llvm_name = "atxmega256a3",
2295 .features = featureSet(&[_]Feature{
2296 .xmega,
2297 }),
2298 };
2299 pub const atxmega256a3b = CpuModel{
2300 .name = "atxmega256a3b",
2301 .llvm_name = "atxmega256a3b",
2302 .features = featureSet(&[_]Feature{
2303 .xmega,
2304 }),
2305 };
2306 pub const atxmega256a3bu = CpuModel{
2307 .name = "atxmega256a3bu",
2308 .llvm_name = "atxmega256a3bu",
2309 .features = featureSet(&[_]Feature{
2310 .xmegau,
2311 }),
2312 };
2313 pub const atxmega256a3u = CpuModel{
2314 .name = "atxmega256a3u",
2315 .llvm_name = "atxmega256a3u",
2316 .features = featureSet(&[_]Feature{
2317 .xmegau,
2318 }),
2319 };
2320 pub const atxmega256c3 = CpuModel{
2321 .name = "atxmega256c3",
2322 .llvm_name = "atxmega256c3",
2323 .features = featureSet(&[_]Feature{
2324 .xmegau,
2325 }),
2326 };
2327 pub const atxmega256d3 = CpuModel{
2328 .name = "atxmega256d3",
2329 .llvm_name = "atxmega256d3",
2330 .features = featureSet(&[_]Feature{
2331 .xmega,
2332 }),
2333 };
2334 pub const atxmega32a4 = CpuModel{
2335 .name = "atxmega32a4",
2336 .llvm_name = "atxmega32a4",
2337 .features = featureSet(&[_]Feature{
2338 .xmega,
2339 }),
2340 };
2341 pub const atxmega32a4u = CpuModel{
2342 .name = "atxmega32a4u",
2343 .llvm_name = "atxmega32a4u",
2344 .features = featureSet(&[_]Feature{
2345 .xmegau,
2346 }),
2347 };
2348 pub const atxmega32c3 = CpuModel{
2349 .name = "atxmega32c3",
2350 .llvm_name = "atxmega32c3",
2351 .features = featureSet(&[_]Feature{
2352 .xmegau,
2353 }),
2354 };
2355 pub const atxmega32c4 = CpuModel{
2356 .name = "atxmega32c4",
2357 .llvm_name = "atxmega32c4",
2358 .features = featureSet(&[_]Feature{
2359 .xmegau,
2360 }),
2361 };
2362 pub const atxmega32d3 = CpuModel{
2363 .name = "atxmega32d3",
2364 .llvm_name = "atxmega32d3",
2365 .features = featureSet(&[_]Feature{
2366 .xmega,
2367 }),
2368 };
2369 pub const atxmega32d4 = CpuModel{
2370 .name = "atxmega32d4",
2371 .llvm_name = "atxmega32d4",
2372 .features = featureSet(&[_]Feature{
2373 .xmega,
2374 }),
2375 };
2376 pub const atxmega32e5 = CpuModel{
2377 .name = "atxmega32e5",
2378 .llvm_name = "atxmega32e5",
2379 .features = featureSet(&[_]Feature{
2380 .xmegau,
2381 }),
2382 };
2383 pub const atxmega384c3 = CpuModel{
2384 .name = "atxmega384c3",
2385 .llvm_name = "atxmega384c3",
2386 .features = featureSet(&[_]Feature{
2387 .xmegau,
2388 }),
2389 };
2390 pub const atxmega384d3 = CpuModel{
2391 .name = "atxmega384d3",
2392 .llvm_name = "atxmega384d3",
2393 .features = featureSet(&[_]Feature{
2394 .xmega,
2395 }),
2396 };
2397 pub const atxmega64a1 = CpuModel{
2398 .name = "atxmega64a1",
2399 .llvm_name = "atxmega64a1",
2400 .features = featureSet(&[_]Feature{
2401 .xmega,
2402 }),
2403 };
2404 pub const atxmega64a1u = CpuModel{
2405 .name = "atxmega64a1u",
2406 .llvm_name = "atxmega64a1u",
2407 .features = featureSet(&[_]Feature{
2408 .xmegau,
2409 }),
2410 };
2411 pub const atxmega64a3 = CpuModel{
2412 .name = "atxmega64a3",
2413 .llvm_name = "atxmega64a3",
2414 .features = featureSet(&[_]Feature{
2415 .xmega,
2416 }),
2417 };
2418 pub const atxmega64a3u = CpuModel{
2419 .name = "atxmega64a3u",
2420 .llvm_name = "atxmega64a3u",
2421 .features = featureSet(&[_]Feature{
2422 .xmegau,
2423 }),
2424 };
2425 pub const atxmega64a4u = CpuModel{
2426 .name = "atxmega64a4u",
2427 .llvm_name = "atxmega64a4u",
2428 .features = featureSet(&[_]Feature{
2429 .xmegau,
2430 }),
2431 };
2432 pub const atxmega64b1 = CpuModel{
2433 .name = "atxmega64b1",
2434 .llvm_name = "atxmega64b1",
2435 .features = featureSet(&[_]Feature{
2436 .xmegau,
2437 }),
2438 };
2439 pub const atxmega64b3 = CpuModel{
2440 .name = "atxmega64b3",
2441 .llvm_name = "atxmega64b3",
2442 .features = featureSet(&[_]Feature{
2443 .xmegau,
2444 }),
2445 };
2446 pub const atxmega64c3 = CpuModel{
2447 .name = "atxmega64c3",
2448 .llvm_name = "atxmega64c3",
2449 .features = featureSet(&[_]Feature{
2450 .xmegau,
2451 }),
2452 };
2453 pub const atxmega64d3 = CpuModel{
2454 .name = "atxmega64d3",
2455 .llvm_name = "atxmega64d3",
2456 .features = featureSet(&[_]Feature{
2457 .xmega,
2458 }),
2459 };
2460 pub const atxmega64d4 = CpuModel{
2461 .name = "atxmega64d4",
2462 .llvm_name = "atxmega64d4",
2463 .features = featureSet(&[_]Feature{
2464 .xmega,
2465 }),
2466 };
2467 pub const atxmega8e5 = CpuModel{
2468 .name = "atxmega8e5",
2469 .llvm_name = "atxmega8e5",
2470 .features = featureSet(&[_]Feature{
2471 .xmegau,
2472 }),
2473 };
2474 pub const avr1 = CpuModel{
2475 .name = "avr1",
2476 .llvm_name = "avr1",
2477 .features = featureSet(&[_]Feature{
2478 .avr1,
2479 }),
2480 };
2481 pub const avr2 = CpuModel{
2482 .name = "avr2",
2483 .llvm_name = "avr2",
2484 .features = featureSet(&[_]Feature{
2485 .avr2,
2486 }),
2487 };
2488 pub const avr25 = CpuModel{
2489 .name = "avr25",
2490 .llvm_name = "avr25",
2491 .features = featureSet(&[_]Feature{
2492 .avr25,
2493 }),
2494 };
2495 pub const avr3 = CpuModel{
2496 .name = "avr3",
2497 .llvm_name = "avr3",
2498 .features = featureSet(&[_]Feature{
2499 .avr3,
2500 }),
2501 };
2502 pub const avr31 = CpuModel{
2503 .name = "avr31",
2504 .llvm_name = "avr31",
2505 .features = featureSet(&[_]Feature{
2506 .avr31,
2507 }),
2508 };
2509 pub const avr35 = CpuModel{
2510 .name = "avr35",
2511 .llvm_name = "avr35",
2512 .features = featureSet(&[_]Feature{
2513 .avr35,
2514 }),
2515 };
2516 pub const avr4 = CpuModel{
2517 .name = "avr4",
2518 .llvm_name = "avr4",
2519 .features = featureSet(&[_]Feature{
2520 .avr4,
2521 }),
2522 };
2523 pub const avr5 = CpuModel{
2524 .name = "avr5",
2525 .llvm_name = "avr5",
2526 .features = featureSet(&[_]Feature{
2527 .avr5,
2528 }),
2529 };
2530 pub const avr51 = CpuModel{
2531 .name = "avr51",
2532 .llvm_name = "avr51",
2533 .features = featureSet(&[_]Feature{
2534 .avr51,
2535 }),
2536 };
2537 pub const avr6 = CpuModel{
2538 .name = "avr6",
2539 .llvm_name = "avr6",
2540 .features = featureSet(&[_]Feature{
2541 .avr6,
2542 }),
2543 };
2544 pub const avrtiny = CpuModel{
2545 .name = "avrtiny",
2546 .llvm_name = "avrtiny",
2547 .features = featureSet(&[_]Feature{
2548 .avrtiny,
2549 }),
2550 };
2551 pub const avrxmega1 = CpuModel{
2552 .name = "avrxmega1",
2553 .llvm_name = "avrxmega1",
2554 .features = featureSet(&[_]Feature{
2555 .xmega,
2556 }),
2557 };
2558 pub const avrxmega2 = CpuModel{
2559 .name = "avrxmega2",
2560 .llvm_name = "avrxmega2",
2561 .features = featureSet(&[_]Feature{
2562 .xmega,
2563 }),
2564 };
2565 pub const avrxmega3 = CpuModel{
2566 .name = "avrxmega3",
2567 .llvm_name = "avrxmega3",
2568 .features = featureSet(&[_]Feature{
2569 .xmega3,
2570 }),
2571 };
2572 pub const avrxmega4 = CpuModel{
2573 .name = "avrxmega4",
2574 .llvm_name = "avrxmega4",
2575 .features = featureSet(&[_]Feature{
2576 .xmega,
2577 }),
2578 };
2579 pub const avrxmega5 = CpuModel{
2580 .name = "avrxmega5",
2581 .llvm_name = "avrxmega5",
2582 .features = featureSet(&[_]Feature{
2583 .xmega,
2584 }),
2585 };
2586 pub const avrxmega6 = CpuModel{
2587 .name = "avrxmega6",
2588 .llvm_name = "avrxmega6",
2589 .features = featureSet(&[_]Feature{
2590 .xmega,
2591 }),
2592 };
2593 pub const avrxmega7 = CpuModel{
2594 .name = "avrxmega7",
2595 .llvm_name = "avrxmega7",
2596 .features = featureSet(&[_]Feature{
2597 .xmega,
2598 }),
2599 };
2600 pub const m3000 = CpuModel{
2601 .name = "m3000",
2602 .llvm_name = "m3000",
2603 .features = featureSet(&[_]Feature{
2604 .avr5,
2605 }),
2606 };
2607};
lib/std/Target/bpf.zig created+73
......@@ -0,0 +1,73 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 alu32,
9 dummy,
10 dwarfris,
11};
12
13pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
14pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
15pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
16pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
17
18pub const all_features = blk: {
19 const len = @typeInfo(Feature).Enum.fields.len;
20 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
21 var result: [len]CpuFeature = undefined;
22 result[@intFromEnum(Feature.alu32)] = .{
23 .llvm_name = "alu32",
24 .description = "Enable ALU32 instructions",
25 .dependencies = featureSet(&[_]Feature{}),
26 };
27 result[@intFromEnum(Feature.dummy)] = .{
28 .llvm_name = "dummy",
29 .description = "unused feature",
30 .dependencies = featureSet(&[_]Feature{}),
31 };
32 result[@intFromEnum(Feature.dwarfris)] = .{
33 .llvm_name = "dwarfris",
34 .description = "Disable MCAsmInfo DwarfUsesRelocationsAcrossSections",
35 .dependencies = featureSet(&[_]Feature{}),
36 };
37 const ti = @typeInfo(Feature);
38 for (&result, 0..) |*elem, i| {
39 elem.index = i;
40 elem.name = ti.Enum.fields[i].name;
41 }
42 break :blk result;
43};
44
45pub const cpu = struct {
46 pub const generic = CpuModel{
47 .name = "generic",
48 .llvm_name = "generic",
49 .features = featureSet(&[_]Feature{}),
50 };
51 pub const probe = CpuModel{
52 .name = "probe",
53 .llvm_name = "probe",
54 .features = featureSet(&[_]Feature{}),
55 };
56 pub const v1 = CpuModel{
57 .name = "v1",
58 .llvm_name = "v1",
59 .features = featureSet(&[_]Feature{}),
60 };
61 pub const v2 = CpuModel{
62 .name = "v2",
63 .llvm_name = "v2",
64 .features = featureSet(&[_]Feature{}),
65 };
66 pub const v3 = CpuModel{
67 .name = "v3",
68 .llvm_name = "v3",
69 .features = featureSet(&[_]Feature{
70 .alu32,
71 }),
72 };
73};
lib/std/Target/csky.zig created+3214
......@@ -0,0 +1,3214 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"10e60",
9 @"2e3",
10 @"3e3r1",
11 @"3e3r2",
12 @"3e3r3",
13 @"3e7",
14 @"7e10",
15 btst16,
16 cache,
17 ccrt,
18 ck801,
19 ck802,
20 ck803,
21 ck803s,
22 ck804,
23 ck805,
24 ck807,
25 ck810,
26 ck810v,
27 ck860,
28 ck860v,
29 constpool,
30 doloop,
31 dsp1e2,
32 dsp_silan,
33 dspe60,
34 dspv2,
35 e1,
36 e2,
37 edsp,
38 elrw,
39 fdivdu,
40 float1e2,
41 float1e3,
42 float3e4,
43 float7e60,
44 floate1,
45 fpuv2_df,
46 fpuv2_sf,
47 fpuv3_df,
48 fpuv3_hf,
49 fpuv3_hi,
50 fpuv3_sf,
51 hard_float,
52 hard_float_abi,
53 hard_tp,
54 high_registers,
55 hwdiv,
56 istack,
57 java,
58 mp,
59 mp1e2,
60 multiple_stld,
61 nvic,
62 pushpop,
63 smart,
64 soft_tp,
65 stack_size,
66 trust,
67 vdsp2e3,
68 vdsp2e60f,
69 vdspv1,
70 vdspv2,
71};
72
73pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
74pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
75pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
76pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
77
78pub const all_features = blk: {
79 const len = @typeInfo(Feature).Enum.fields.len;
80 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
81 var result: [len]CpuFeature = undefined;
82 result[@intFromEnum(Feature.@"10e60")] = .{
83 .llvm_name = "10e60",
84 .description = "Support CSKY 10e60 instructions",
85 .dependencies = featureSet(&[_]Feature{
86 .@"7e10",
87 }),
88 };
89 result[@intFromEnum(Feature.@"2e3")] = .{
90 .llvm_name = "2e3",
91 .description = "Support CSKY 2e3 instructions",
92 .dependencies = featureSet(&[_]Feature{
93 .e2,
94 }),
95 };
96 result[@intFromEnum(Feature.@"3e3r1")] = .{
97 .llvm_name = "3e3r1",
98 .description = "Support CSKY 3e3r1 instructions",
99 .dependencies = featureSet(&[_]Feature{}),
100 };
101 result[@intFromEnum(Feature.@"3e3r2")] = .{
102 .llvm_name = "3e3r2",
103 .description = "Support CSKY 3e3r2 instructions",
104 .dependencies = featureSet(&[_]Feature{
105 .@"3e3r1",
106 .doloop,
107 }),
108 };
109 result[@intFromEnum(Feature.@"3e3r3")] = .{
110 .llvm_name = "3e3r3",
111 .description = "Support CSKY 3e3r3 instructions",
112 .dependencies = featureSet(&[_]Feature{
113 .doloop,
114 }),
115 };
116 result[@intFromEnum(Feature.@"3e7")] = .{
117 .llvm_name = "3e7",
118 .description = "Support CSKY 3e7 instructions",
119 .dependencies = featureSet(&[_]Feature{
120 .@"2e3",
121 }),
122 };
123 result[@intFromEnum(Feature.@"7e10")] = .{
124 .llvm_name = "7e10",
125 .description = "Support CSKY 7e10 instructions",
126 .dependencies = featureSet(&[_]Feature{
127 .@"3e7",
128 }),
129 };
130 result[@intFromEnum(Feature.btst16)] = .{
131 .llvm_name = "btst16",
132 .description = "Use the 16-bit btsti instruction",
133 .dependencies = featureSet(&[_]Feature{}),
134 };
135 result[@intFromEnum(Feature.cache)] = .{
136 .llvm_name = "cache",
137 .description = "Enable cache",
138 .dependencies = featureSet(&[_]Feature{}),
139 };
140 result[@intFromEnum(Feature.ccrt)] = .{
141 .llvm_name = "ccrt",
142 .description = "Use CSKY compiler runtime",
143 .dependencies = featureSet(&[_]Feature{}),
144 };
145 result[@intFromEnum(Feature.ck801)] = .{
146 .llvm_name = "ck801",
147 .description = "CSKY ck801 processors",
148 .dependencies = featureSet(&[_]Feature{}),
149 };
150 result[@intFromEnum(Feature.ck802)] = .{
151 .llvm_name = "ck802",
152 .description = "CSKY ck802 processors",
153 .dependencies = featureSet(&[_]Feature{}),
154 };
155 result[@intFromEnum(Feature.ck803)] = .{
156 .llvm_name = "ck803",
157 .description = "CSKY ck803 processors",
158 .dependencies = featureSet(&[_]Feature{}),
159 };
160 result[@intFromEnum(Feature.ck803s)] = .{
161 .llvm_name = "ck803s",
162 .description = "CSKY ck803s processors",
163 .dependencies = featureSet(&[_]Feature{}),
164 };
165 result[@intFromEnum(Feature.ck804)] = .{
166 .llvm_name = "ck804",
167 .description = "CSKY ck804 processors",
168 .dependencies = featureSet(&[_]Feature{}),
169 };
170 result[@intFromEnum(Feature.ck805)] = .{
171 .llvm_name = "ck805",
172 .description = "CSKY ck805 processors",
173 .dependencies = featureSet(&[_]Feature{}),
174 };
175 result[@intFromEnum(Feature.ck807)] = .{
176 .llvm_name = "ck807",
177 .description = "CSKY ck807 processors",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.ck810)] = .{
181 .llvm_name = "ck810",
182 .description = "CSKY ck810 processors",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.ck810v)] = .{
186 .llvm_name = "ck810v",
187 .description = "CSKY ck810v processors",
188 .dependencies = featureSet(&[_]Feature{}),
189 };
190 result[@intFromEnum(Feature.ck860)] = .{
191 .llvm_name = "ck860",
192 .description = "CSKY ck860 processors",
193 .dependencies = featureSet(&[_]Feature{}),
194 };
195 result[@intFromEnum(Feature.ck860v)] = .{
196 .llvm_name = "ck860v",
197 .description = "CSKY ck860v processors",
198 .dependencies = featureSet(&[_]Feature{}),
199 };
200 result[@intFromEnum(Feature.constpool)] = .{
201 .llvm_name = "constpool",
202 .description = "Dump the constant pool by compiler",
203 .dependencies = featureSet(&[_]Feature{}),
204 };
205 result[@intFromEnum(Feature.doloop)] = .{
206 .llvm_name = "doloop",
207 .description = "Enable doloop instructions",
208 .dependencies = featureSet(&[_]Feature{}),
209 };
210 result[@intFromEnum(Feature.dsp1e2)] = .{
211 .llvm_name = "dsp1e2",
212 .description = "Support CSKY dsp1e2 instructions",
213 .dependencies = featureSet(&[_]Feature{}),
214 };
215 result[@intFromEnum(Feature.dsp_silan)] = .{
216 .llvm_name = "dsp_silan",
217 .description = "Enable DSP Silan instrutions",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
220 result[@intFromEnum(Feature.dspe60)] = .{
221 .llvm_name = "dspe60",
222 .description = "Support CSKY dspe60 instructions",
223 .dependencies = featureSet(&[_]Feature{}),
224 };
225 result[@intFromEnum(Feature.dspv2)] = .{
226 .llvm_name = "dspv2",
227 .description = "Enable DSP V2.0 instrutions",
228 .dependencies = featureSet(&[_]Feature{}),
229 };
230 result[@intFromEnum(Feature.e1)] = .{
231 .llvm_name = "e1",
232 .description = "Support CSKY e1 instructions",
233 .dependencies = featureSet(&[_]Feature{
234 .elrw,
235 }),
236 };
237 result[@intFromEnum(Feature.e2)] = .{
238 .llvm_name = "e2",
239 .description = "Support CSKY e2 instructions",
240 .dependencies = featureSet(&[_]Feature{
241 .e1,
242 }),
243 };
244 result[@intFromEnum(Feature.edsp)] = .{
245 .llvm_name = "edsp",
246 .description = "Enable DSP instrutions",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@intFromEnum(Feature.elrw)] = .{
250 .llvm_name = "elrw",
251 .description = "Use the extend LRW instruction",
252 .dependencies = featureSet(&[_]Feature{}),
253 };
254 result[@intFromEnum(Feature.fdivdu)] = .{
255 .llvm_name = "fdivdu",
256 .description = "Enable float divide instructions",
257 .dependencies = featureSet(&[_]Feature{}),
258 };
259 result[@intFromEnum(Feature.float1e2)] = .{
260 .llvm_name = "float1e2",
261 .description = "Support CSKY float1e2 instructions",
262 .dependencies = featureSet(&[_]Feature{}),
263 };
264 result[@intFromEnum(Feature.float1e3)] = .{
265 .llvm_name = "float1e3",
266 .description = "Support CSKY float1e3 instructions",
267 .dependencies = featureSet(&[_]Feature{}),
268 };
269 result[@intFromEnum(Feature.float3e4)] = .{
270 .llvm_name = "float3e4",
271 .description = "Support CSKY float3e4 instructions",
272 .dependencies = featureSet(&[_]Feature{}),
273 };
274 result[@intFromEnum(Feature.float7e60)] = .{
275 .llvm_name = "float7e60",
276 .description = "Support CSKY float7e60 instructions",
277 .dependencies = featureSet(&[_]Feature{}),
278 };
279 result[@intFromEnum(Feature.floate1)] = .{
280 .llvm_name = "floate1",
281 .description = "Support CSKY floate1 instructions",
282 .dependencies = featureSet(&[_]Feature{}),
283 };
284 result[@intFromEnum(Feature.fpuv2_df)] = .{
285 .llvm_name = "fpuv2_df",
286 .description = "Enable FPUv2 double float instructions",
287 .dependencies = featureSet(&[_]Feature{}),
288 };
289 result[@intFromEnum(Feature.fpuv2_sf)] = .{
290 .llvm_name = "fpuv2_sf",
291 .description = "Enable FPUv2 single float instructions",
292 .dependencies = featureSet(&[_]Feature{}),
293 };
294 result[@intFromEnum(Feature.fpuv3_df)] = .{
295 .llvm_name = "fpuv3_df",
296 .description = "Enable FPUv3 double float instructions",
297 .dependencies = featureSet(&[_]Feature{}),
298 };
299 result[@intFromEnum(Feature.fpuv3_hf)] = .{
300 .llvm_name = "fpuv3_hf",
301 .description = "Enable FPUv3 half precision operate instructions",
302 .dependencies = featureSet(&[_]Feature{}),
303 };
304 result[@intFromEnum(Feature.fpuv3_hi)] = .{
305 .llvm_name = "fpuv3_hi",
306 .description = "Enable FPUv3 half word converting instructions",
307 .dependencies = featureSet(&[_]Feature{}),
308 };
309 result[@intFromEnum(Feature.fpuv3_sf)] = .{
310 .llvm_name = "fpuv3_sf",
311 .description = "Enable FPUv3 single float instructions",
312 .dependencies = featureSet(&[_]Feature{}),
313 };
314 result[@intFromEnum(Feature.hard_float)] = .{
315 .llvm_name = "hard-float",
316 .description = "Use hard floating point features",
317 .dependencies = featureSet(&[_]Feature{}),
318 };
319 result[@intFromEnum(Feature.hard_float_abi)] = .{
320 .llvm_name = "hard-float-abi",
321 .description = "Use hard floating point ABI to pass args",
322 .dependencies = featureSet(&[_]Feature{}),
323 };
324 result[@intFromEnum(Feature.hard_tp)] = .{
325 .llvm_name = "hard-tp",
326 .description = "Enable TLS Pointer register",
327 .dependencies = featureSet(&[_]Feature{}),
328 };
329 result[@intFromEnum(Feature.high_registers)] = .{
330 .llvm_name = "high-registers",
331 .description = "Enable r16-r31 registers",
332 .dependencies = featureSet(&[_]Feature{}),
333 };
334 result[@intFromEnum(Feature.hwdiv)] = .{
335 .llvm_name = "hwdiv",
336 .description = "Enable divide instrutions",
337 .dependencies = featureSet(&[_]Feature{}),
338 };
339 result[@intFromEnum(Feature.istack)] = .{
340 .llvm_name = "istack",
341 .description = "Enable interrput attribute",
342 .dependencies = featureSet(&[_]Feature{}),
343 };
344 result[@intFromEnum(Feature.java)] = .{
345 .llvm_name = "java",
346 .description = "Enable java instructions",
347 .dependencies = featureSet(&[_]Feature{}),
348 };
349 result[@intFromEnum(Feature.mp)] = .{
350 .llvm_name = "mp",
351 .description = "Support CSKY mp instructions",
352 .dependencies = featureSet(&[_]Feature{
353 .@"2e3",
354 }),
355 };
356 result[@intFromEnum(Feature.mp1e2)] = .{
357 .llvm_name = "mp1e2",
358 .description = "Support CSKY mp1e2 instructions",
359 .dependencies = featureSet(&[_]Feature{
360 .@"3e7",
361 }),
362 };
363 result[@intFromEnum(Feature.multiple_stld)] = .{
364 .llvm_name = "multiple_stld",
365 .description = "Enable multiple load/store instrutions",
366 .dependencies = featureSet(&[_]Feature{}),
367 };
368 result[@intFromEnum(Feature.nvic)] = .{
369 .llvm_name = "nvic",
370 .description = "Enable NVIC",
371 .dependencies = featureSet(&[_]Feature{}),
372 };
373 result[@intFromEnum(Feature.pushpop)] = .{
374 .llvm_name = "pushpop",
375 .description = "Enable push/pop instrutions",
376 .dependencies = featureSet(&[_]Feature{}),
377 };
378 result[@intFromEnum(Feature.smart)] = .{
379 .llvm_name = "smart",
380 .description = "Let CPU work in Smart Mode",
381 .dependencies = featureSet(&[_]Feature{}),
382 };
383 result[@intFromEnum(Feature.soft_tp)] = .{
384 .llvm_name = "soft-tp",
385 .description = "Disable TLS Pointer register",
386 .dependencies = featureSet(&[_]Feature{}),
387 };
388 result[@intFromEnum(Feature.stack_size)] = .{
389 .llvm_name = "stack-size",
390 .description = "Output stack size information",
391 .dependencies = featureSet(&[_]Feature{}),
392 };
393 result[@intFromEnum(Feature.trust)] = .{
394 .llvm_name = "trust",
395 .description = "Enable trust instructions",
396 .dependencies = featureSet(&[_]Feature{}),
397 };
398 result[@intFromEnum(Feature.vdsp2e3)] = .{
399 .llvm_name = "vdsp2e3",
400 .description = "Support CSKY vdsp2e3 instructions",
401 .dependencies = featureSet(&[_]Feature{}),
402 };
403 result[@intFromEnum(Feature.vdsp2e60f)] = .{
404 .llvm_name = "vdsp2e60f",
405 .description = "Support CSKY vdsp2e60f instructions",
406 .dependencies = featureSet(&[_]Feature{}),
407 };
408 result[@intFromEnum(Feature.vdspv1)] = .{
409 .llvm_name = "vdspv1",
410 .description = "Enable 128bit vdsp-v1 instructions",
411 .dependencies = featureSet(&[_]Feature{}),
412 };
413 result[@intFromEnum(Feature.vdspv2)] = .{
414 .llvm_name = "vdspv2",
415 .description = "Enable vdsp-v2 instructions",
416 .dependencies = featureSet(&[_]Feature{}),
417 };
418 const ti = @typeInfo(Feature);
419 for (&result, 0..) |*elem, i| {
420 elem.index = i;
421 elem.name = ti.Enum.fields[i].name;
422 }
423 break :blk result;
424};
425
426pub const cpu = struct {
427 pub const c807 = CpuModel{
428 .name = "c807",
429 .llvm_name = "c807",
430 .features = featureSet(&[_]Feature{
431 .cache,
432 .ck807,
433 .dsp1e2,
434 .dspe60,
435 .edsp,
436 .hard_tp,
437 .high_registers,
438 .hwdiv,
439 .mp,
440 .mp1e2,
441 .nvic,
442 .trust,
443 }),
444 };
445 pub const c807f = CpuModel{
446 .name = "c807f",
447 .llvm_name = "c807f",
448 .features = featureSet(&[_]Feature{
449 .cache,
450 .ck807,
451 .dsp1e2,
452 .dspe60,
453 .edsp,
454 .fdivdu,
455 .float1e2,
456 .float1e3,
457 .float3e4,
458 .floate1,
459 .fpuv2_df,
460 .fpuv2_sf,
461 .hard_tp,
462 .high_registers,
463 .hwdiv,
464 .mp,
465 .mp1e2,
466 .nvic,
467 .trust,
468 }),
469 };
470 pub const c810 = CpuModel{
471 .name = "c810",
472 .llvm_name = "c810",
473 .features = featureSet(&[_]Feature{
474 .@"7e10",
475 .cache,
476 .ck810,
477 .dsp1e2,
478 .dspe60,
479 .edsp,
480 .fdivdu,
481 .float1e2,
482 .floate1,
483 .fpuv2_df,
484 .fpuv2_sf,
485 .hard_tp,
486 .high_registers,
487 .hwdiv,
488 .mp,
489 .mp1e2,
490 .nvic,
491 .trust,
492 }),
493 };
494 pub const c810t = CpuModel{
495 .name = "c810t",
496 .llvm_name = "c810t",
497 .features = featureSet(&[_]Feature{
498 .@"7e10",
499 .cache,
500 .ck810,
501 .dsp1e2,
502 .dspe60,
503 .edsp,
504 .fdivdu,
505 .float1e2,
506 .floate1,
507 .fpuv2_df,
508 .fpuv2_sf,
509 .hard_tp,
510 .high_registers,
511 .hwdiv,
512 .mp,
513 .mp1e2,
514 .nvic,
515 .trust,
516 }),
517 };
518 pub const c810tv = CpuModel{
519 .name = "c810tv",
520 .llvm_name = "c810tv",
521 .features = featureSet(&[_]Feature{
522 .@"7e10",
523 .cache,
524 .ck810,
525 .ck810v,
526 .dsp1e2,
527 .dspe60,
528 .edsp,
529 .fdivdu,
530 .float1e2,
531 .floate1,
532 .fpuv2_df,
533 .fpuv2_sf,
534 .hard_tp,
535 .high_registers,
536 .hwdiv,
537 .mp,
538 .mp1e2,
539 .nvic,
540 .trust,
541 .vdspv1,
542 }),
543 };
544 pub const c810v = CpuModel{
545 .name = "c810v",
546 .llvm_name = "c810v",
547 .features = featureSet(&[_]Feature{
548 .@"7e10",
549 .cache,
550 .ck810,
551 .ck810v,
552 .dsp1e2,
553 .dspe60,
554 .edsp,
555 .fdivdu,
556 .float1e2,
557 .floate1,
558 .fpuv2_df,
559 .fpuv2_sf,
560 .hard_tp,
561 .high_registers,
562 .hwdiv,
563 .mp,
564 .mp1e2,
565 .nvic,
566 .trust,
567 .vdspv1,
568 }),
569 };
570 pub const c860 = CpuModel{
571 .name = "c860",
572 .llvm_name = "c860",
573 .features = featureSet(&[_]Feature{
574 .@"10e60",
575 .@"3e3r2",
576 .@"3e3r3",
577 .btst16,
578 .cache,
579 .ck860,
580 .dspe60,
581 .float7e60,
582 .fpuv3_df,
583 .fpuv3_hf,
584 .fpuv3_hi,
585 .fpuv3_sf,
586 .hard_tp,
587 .high_registers,
588 .hwdiv,
589 .mp,
590 .mp1e2,
591 .nvic,
592 .trust,
593 }),
594 };
595 pub const c860v = CpuModel{
596 .name = "c860v",
597 .llvm_name = "c860v",
598 .features = featureSet(&[_]Feature{
599 .@"10e60",
600 .@"3e3r2",
601 .@"3e3r3",
602 .btst16,
603 .cache,
604 .ck860,
605 .ck860v,
606 .dspe60,
607 .float7e60,
608 .fpuv3_df,
609 .fpuv3_hf,
610 .fpuv3_hi,
611 .fpuv3_sf,
612 .hard_tp,
613 .high_registers,
614 .hwdiv,
615 .mp,
616 .mp1e2,
617 .nvic,
618 .trust,
619 .vdsp2e60f,
620 .vdspv2,
621 }),
622 };
623 pub const ck801 = CpuModel{
624 .name = "ck801",
625 .llvm_name = "ck801",
626 .features = featureSet(&[_]Feature{
627 .btst16,
628 .ck801,
629 .e1,
630 .trust,
631 }),
632 };
633 pub const ck801t = CpuModel{
634 .name = "ck801t",
635 .llvm_name = "ck801t",
636 .features = featureSet(&[_]Feature{
637 .btst16,
638 .ck801,
639 .e1,
640 .trust,
641 }),
642 };
643 pub const ck802 = CpuModel{
644 .name = "ck802",
645 .llvm_name = "ck802",
646 .features = featureSet(&[_]Feature{
647 .btst16,
648 .ck802,
649 .e2,
650 .nvic,
651 .trust,
652 }),
653 };
654 pub const ck802j = CpuModel{
655 .name = "ck802j",
656 .llvm_name = "ck802j",
657 .features = featureSet(&[_]Feature{
658 .btst16,
659 .ck802,
660 .e2,
661 .java,
662 .nvic,
663 .trust,
664 }),
665 };
666 pub const ck802t = CpuModel{
667 .name = "ck802t",
668 .llvm_name = "ck802t",
669 .features = featureSet(&[_]Feature{
670 .btst16,
671 .ck802,
672 .e2,
673 .nvic,
674 .trust,
675 }),
676 };
677 pub const ck803 = CpuModel{
678 .name = "ck803",
679 .llvm_name = "ck803",
680 .features = featureSet(&[_]Feature{
681 .btst16,
682 .ck803,
683 .hwdiv,
684 .mp,
685 .nvic,
686 .trust,
687 }),
688 };
689 pub const ck803e = CpuModel{
690 .name = "ck803e",
691 .llvm_name = "ck803e",
692 .features = featureSet(&[_]Feature{
693 .btst16,
694 .ck803,
695 .dsp1e2,
696 .dspe60,
697 .edsp,
698 .hwdiv,
699 .mp,
700 .nvic,
701 .trust,
702 }),
703 };
704 pub const ck803ef = CpuModel{
705 .name = "ck803ef",
706 .llvm_name = "ck803ef",
707 .features = featureSet(&[_]Feature{
708 .btst16,
709 .ck803,
710 .dsp1e2,
711 .dspe60,
712 .edsp,
713 .float1e3,
714 .floate1,
715 .fpuv2_sf,
716 .hwdiv,
717 .mp,
718 .nvic,
719 .trust,
720 }),
721 };
722 pub const ck803efh = CpuModel{
723 .name = "ck803efh",
724 .llvm_name = "ck803efh",
725 .features = featureSet(&[_]Feature{
726 .btst16,
727 .ck803,
728 .dsp1e2,
729 .dspe60,
730 .edsp,
731 .float1e3,
732 .floate1,
733 .fpuv2_sf,
734 .hwdiv,
735 .mp,
736 .nvic,
737 .trust,
738 }),
739 };
740 pub const ck803efhr1 = CpuModel{
741 .name = "ck803efhr1",
742 .llvm_name = "ck803efhr1",
743 .features = featureSet(&[_]Feature{
744 .@"3e3r1",
745 .btst16,
746 .ck803,
747 .dsp1e2,
748 .dspe60,
749 .dspv2,
750 .edsp,
751 .float1e3,
752 .floate1,
753 .fpuv2_sf,
754 .high_registers,
755 .hwdiv,
756 .mp,
757 .nvic,
758 .trust,
759 }),
760 };
761 pub const ck803efhr2 = CpuModel{
762 .name = "ck803efhr2",
763 .llvm_name = "ck803efhr2",
764 .features = featureSet(&[_]Feature{
765 .@"3e3r2",
766 .@"3e3r3",
767 .btst16,
768 .ck803,
769 .dsp1e2,
770 .dspe60,
771 .dspv2,
772 .edsp,
773 .float1e3,
774 .floate1,
775 .fpuv2_sf,
776 .high_registers,
777 .hwdiv,
778 .mp,
779 .nvic,
780 .trust,
781 }),
782 };
783 pub const ck803efhr3 = CpuModel{
784 .name = "ck803efhr3",
785 .llvm_name = "ck803efhr3",
786 .features = featureSet(&[_]Feature{
787 .@"3e3r2",
788 .@"3e3r3",
789 .btst16,
790 .ck803,
791 .dsp1e2,
792 .dspe60,
793 .dspv2,
794 .edsp,
795 .float1e3,
796 .floate1,
797 .fpuv2_sf,
798 .high_registers,
799 .hwdiv,
800 .mp,
801 .nvic,
802 .trust,
803 }),
804 };
805 pub const ck803efht = CpuModel{
806 .name = "ck803efht",
807 .llvm_name = "ck803efht",
808 .features = featureSet(&[_]Feature{
809 .btst16,
810 .ck803,
811 .dsp1e2,
812 .dspe60,
813 .edsp,
814 .float1e3,
815 .floate1,
816 .fpuv2_sf,
817 .hwdiv,
818 .mp,
819 .nvic,
820 .trust,
821 }),
822 };
823 pub const ck803efhtr1 = CpuModel{
824 .name = "ck803efhtr1",
825 .llvm_name = "ck803efhtr1",
826 .features = featureSet(&[_]Feature{
827 .@"3e3r1",
828 .btst16,
829 .ck803,
830 .dsp1e2,
831 .dspe60,
832 .dspv2,
833 .edsp,
834 .float1e3,
835 .floate1,
836 .fpuv2_sf,
837 .high_registers,
838 .hwdiv,
839 .mp,
840 .nvic,
841 .trust,
842 }),
843 };
844 pub const ck803efhtr2 = CpuModel{
845 .name = "ck803efhtr2",
846 .llvm_name = "ck803efhtr2",
847 .features = featureSet(&[_]Feature{
848 .@"3e3r2",
849 .@"3e3r3",
850 .btst16,
851 .ck803,
852 .dsp1e2,
853 .dspe60,
854 .dspv2,
855 .edsp,
856 .float1e3,
857 .floate1,
858 .fpuv2_sf,
859 .high_registers,
860 .hwdiv,
861 .mp,
862 .nvic,
863 .trust,
864 }),
865 };
866 pub const ck803efhtr3 = CpuModel{
867 .name = "ck803efhtr3",
868 .llvm_name = "ck803efhtr3",
869 .features = featureSet(&[_]Feature{
870 .@"3e3r2",
871 .@"3e3r3",
872 .btst16,
873 .ck803,
874 .dsp1e2,
875 .dspe60,
876 .dspv2,
877 .edsp,
878 .float1e3,
879 .floate1,
880 .fpuv2_sf,
881 .high_registers,
882 .hwdiv,
883 .mp,
884 .nvic,
885 .trust,
886 }),
887 };
888 pub const ck803efr1 = CpuModel{
889 .name = "ck803efr1",
890 .llvm_name = "ck803efr1",
891 .features = featureSet(&[_]Feature{
892 .@"3e3r1",
893 .btst16,
894 .ck803,
895 .dsp1e2,
896 .dspe60,
897 .dspv2,
898 .edsp,
899 .float1e3,
900 .floate1,
901 .fpuv2_sf,
902 .high_registers,
903 .hwdiv,
904 .mp,
905 .nvic,
906 .trust,
907 }),
908 };
909 pub const ck803efr2 = CpuModel{
910 .name = "ck803efr2",
911 .llvm_name = "ck803efr2",
912 .features = featureSet(&[_]Feature{
913 .@"3e3r2",
914 .@"3e3r3",
915 .btst16,
916 .ck803,
917 .dsp1e2,
918 .dspe60,
919 .dspv2,
920 .edsp,
921 .float1e3,
922 .floate1,
923 .fpuv2_sf,
924 .high_registers,
925 .hwdiv,
926 .mp,
927 .nvic,
928 .trust,
929 }),
930 };
931 pub const ck803efr3 = CpuModel{
932 .name = "ck803efr3",
933 .llvm_name = "ck803efr3",
934 .features = featureSet(&[_]Feature{
935 .@"3e3r2",
936 .@"3e3r3",
937 .btst16,
938 .ck803,
939 .dsp1e2,
940 .dspe60,
941 .dspv2,
942 .edsp,
943 .float1e3,
944 .floate1,
945 .fpuv2_sf,
946 .high_registers,
947 .hwdiv,
948 .mp,
949 .nvic,
950 .trust,
951 }),
952 };
953 pub const ck803eft = CpuModel{
954 .name = "ck803eft",
955 .llvm_name = "ck803eft",
956 .features = featureSet(&[_]Feature{
957 .btst16,
958 .ck803,
959 .dsp1e2,
960 .dspe60,
961 .edsp,
962 .float1e3,
963 .floate1,
964 .fpuv2_sf,
965 .hwdiv,
966 .mp,
967 .nvic,
968 .trust,
969 }),
970 };
971 pub const ck803eftr1 = CpuModel{
972 .name = "ck803eftr1",
973 .llvm_name = "ck803eftr1",
974 .features = featureSet(&[_]Feature{
975 .@"3e3r1",
976 .btst16,
977 .ck803,
978 .dsp1e2,
979 .dspe60,
980 .dspv2,
981 .edsp,
982 .float1e3,
983 .floate1,
984 .fpuv2_sf,
985 .high_registers,
986 .hwdiv,
987 .mp,
988 .nvic,
989 .trust,
990 }),
991 };
992 pub const ck803eftr2 = CpuModel{
993 .name = "ck803eftr2",
994 .llvm_name = "ck803eftr2",
995 .features = featureSet(&[_]Feature{
996 .@"3e3r2",
997 .@"3e3r3",
998 .btst16,
999 .ck803,
1000 .dsp1e2,
1001 .dspe60,
1002 .dspv2,
1003 .edsp,
1004 .float1e3,
1005 .floate1,
1006 .fpuv2_sf,
1007 .high_registers,
1008 .hwdiv,
1009 .mp,
1010 .nvic,
1011 .trust,
1012 }),
1013 };
1014 pub const ck803eftr3 = CpuModel{
1015 .name = "ck803eftr3",
1016 .llvm_name = "ck803eftr3",
1017 .features = featureSet(&[_]Feature{
1018 .@"3e3r2",
1019 .@"3e3r3",
1020 .btst16,
1021 .ck803,
1022 .dsp1e2,
1023 .dspe60,
1024 .dspv2,
1025 .edsp,
1026 .float1e3,
1027 .floate1,
1028 .fpuv2_sf,
1029 .high_registers,
1030 .hwdiv,
1031 .mp,
1032 .nvic,
1033 .trust,
1034 }),
1035 };
1036 pub const ck803eh = CpuModel{
1037 .name = "ck803eh",
1038 .llvm_name = "ck803eh",
1039 .features = featureSet(&[_]Feature{
1040 .btst16,
1041 .ck803,
1042 .dsp1e2,
1043 .dspe60,
1044 .edsp,
1045 .hwdiv,
1046 .mp,
1047 .nvic,
1048 .trust,
1049 }),
1050 };
1051 pub const ck803ehr1 = CpuModel{
1052 .name = "ck803ehr1",
1053 .llvm_name = "ck803ehr1",
1054 .features = featureSet(&[_]Feature{
1055 .@"3e3r1",
1056 .@"3e3r3",
1057 .btst16,
1058 .ck803,
1059 .dsp1e2,
1060 .dspe60,
1061 .dspv2,
1062 .edsp,
1063 .high_registers,
1064 .hwdiv,
1065 .mp,
1066 .nvic,
1067 .trust,
1068 }),
1069 };
1070 pub const ck803ehr2 = CpuModel{
1071 .name = "ck803ehr2",
1072 .llvm_name = "ck803ehr2",
1073 .features = featureSet(&[_]Feature{
1074 .@"3e3r2",
1075 .@"3e3r3",
1076 .btst16,
1077 .ck803,
1078 .dsp1e2,
1079 .dspe60,
1080 .dspv2,
1081 .edsp,
1082 .high_registers,
1083 .hwdiv,
1084 .mp,
1085 .nvic,
1086 .trust,
1087 }),
1088 };
1089 pub const ck803ehr3 = CpuModel{
1090 .name = "ck803ehr3",
1091 .llvm_name = "ck803ehr3",
1092 .features = featureSet(&[_]Feature{
1093 .@"3e3r2",
1094 .@"3e3r3",
1095 .btst16,
1096 .ck803,
1097 .dsp1e2,
1098 .dspe60,
1099 .dspv2,
1100 .edsp,
1101 .high_registers,
1102 .hwdiv,
1103 .mp,
1104 .nvic,
1105 .trust,
1106 }),
1107 };
1108 pub const ck803eht = CpuModel{
1109 .name = "ck803eht",
1110 .llvm_name = "ck803eht",
1111 .features = featureSet(&[_]Feature{
1112 .btst16,
1113 .ck803,
1114 .dsp1e2,
1115 .dspe60,
1116 .edsp,
1117 .hwdiv,
1118 .mp,
1119 .nvic,
1120 .trust,
1121 }),
1122 };
1123 pub const ck803ehtr1 = CpuModel{
1124 .name = "ck803ehtr1",
1125 .llvm_name = "ck803ehtr1",
1126 .features = featureSet(&[_]Feature{
1127 .@"3e3r1",
1128 .@"3e3r3",
1129 .btst16,
1130 .ck803,
1131 .dsp1e2,
1132 .dspe60,
1133 .dspv2,
1134 .edsp,
1135 .high_registers,
1136 .hwdiv,
1137 .mp,
1138 .nvic,
1139 .trust,
1140 }),
1141 };
1142 pub const ck803ehtr2 = CpuModel{
1143 .name = "ck803ehtr2",
1144 .llvm_name = "ck803ehtr2",
1145 .features = featureSet(&[_]Feature{
1146 .@"3e3r2",
1147 .@"3e3r3",
1148 .btst16,
1149 .ck803,
1150 .dsp1e2,
1151 .dspe60,
1152 .dspv2,
1153 .edsp,
1154 .high_registers,
1155 .hwdiv,
1156 .mp,
1157 .nvic,
1158 .trust,
1159 }),
1160 };
1161 pub const ck803ehtr3 = CpuModel{
1162 .name = "ck803ehtr3",
1163 .llvm_name = "ck803ehtr3",
1164 .features = featureSet(&[_]Feature{
1165 .@"3e3r2",
1166 .@"3e3r3",
1167 .btst16,
1168 .ck803,
1169 .dsp1e2,
1170 .dspe60,
1171 .dspv2,
1172 .edsp,
1173 .high_registers,
1174 .hwdiv,
1175 .mp,
1176 .nvic,
1177 .trust,
1178 }),
1179 };
1180 pub const ck803er1 = CpuModel{
1181 .name = "ck803er1",
1182 .llvm_name = "ck803er1",
1183 .features = featureSet(&[_]Feature{
1184 .@"3e3r1",
1185 .@"3e3r3",
1186 .btst16,
1187 .ck803,
1188 .dsp1e2,
1189 .dspe60,
1190 .dspv2,
1191 .edsp,
1192 .high_registers,
1193 .hwdiv,
1194 .mp,
1195 .nvic,
1196 .trust,
1197 }),
1198 };
1199 pub const ck803er2 = CpuModel{
1200 .name = "ck803er2",
1201 .llvm_name = "ck803er2",
1202 .features = featureSet(&[_]Feature{
1203 .@"3e3r2",
1204 .@"3e3r3",
1205 .btst16,
1206 .ck803,
1207 .dsp1e2,
1208 .dspe60,
1209 .dspv2,
1210 .edsp,
1211 .high_registers,
1212 .hwdiv,
1213 .mp,
1214 .nvic,
1215 .trust,
1216 }),
1217 };
1218 pub const ck803er3 = CpuModel{
1219 .name = "ck803er3",
1220 .llvm_name = "ck803er3",
1221 .features = featureSet(&[_]Feature{
1222 .@"3e3r2",
1223 .@"3e3r3",
1224 .btst16,
1225 .ck803,
1226 .dsp1e2,
1227 .dspe60,
1228 .dspv2,
1229 .edsp,
1230 .high_registers,
1231 .hwdiv,
1232 .mp,
1233 .nvic,
1234 .trust,
1235 }),
1236 };
1237 pub const ck803et = CpuModel{
1238 .name = "ck803et",
1239 .llvm_name = "ck803et",
1240 .features = featureSet(&[_]Feature{
1241 .btst16,
1242 .ck803,
1243 .dsp1e2,
1244 .dspe60,
1245 .edsp,
1246 .hwdiv,
1247 .mp,
1248 .nvic,
1249 .trust,
1250 }),
1251 };
1252 pub const ck803etr1 = CpuModel{
1253 .name = "ck803etr1",
1254 .llvm_name = "ck803etr1",
1255 .features = featureSet(&[_]Feature{
1256 .@"3e3r1",
1257 .@"3e3r3",
1258 .btst16,
1259 .ck803,
1260 .dsp1e2,
1261 .dspe60,
1262 .dspv2,
1263 .edsp,
1264 .high_registers,
1265 .hwdiv,
1266 .mp,
1267 .nvic,
1268 .trust,
1269 }),
1270 };
1271 pub const ck803etr2 = CpuModel{
1272 .name = "ck803etr2",
1273 .llvm_name = "ck803etr2",
1274 .features = featureSet(&[_]Feature{
1275 .@"3e3r2",
1276 .@"3e3r3",
1277 .btst16,
1278 .ck803,
1279 .dsp1e2,
1280 .dspe60,
1281 .dspv2,
1282 .edsp,
1283 .high_registers,
1284 .hwdiv,
1285 .mp,
1286 .nvic,
1287 .trust,
1288 }),
1289 };
1290 pub const ck803etr3 = CpuModel{
1291 .name = "ck803etr3",
1292 .llvm_name = "ck803etr3",
1293 .features = featureSet(&[_]Feature{
1294 .@"3e3r2",
1295 .@"3e3r3",
1296 .btst16,
1297 .ck803,
1298 .dsp1e2,
1299 .dspe60,
1300 .dspv2,
1301 .edsp,
1302 .high_registers,
1303 .hwdiv,
1304 .mp,
1305 .nvic,
1306 .trust,
1307 }),
1308 };
1309 pub const ck803f = CpuModel{
1310 .name = "ck803f",
1311 .llvm_name = "ck803f",
1312 .features = featureSet(&[_]Feature{
1313 .btst16,
1314 .ck803,
1315 .float1e3,
1316 .floate1,
1317 .fpuv2_sf,
1318 .hwdiv,
1319 .mp,
1320 .nvic,
1321 .trust,
1322 }),
1323 };
1324 pub const ck803fh = CpuModel{
1325 .name = "ck803fh",
1326 .llvm_name = "ck803fh",
1327 .features = featureSet(&[_]Feature{
1328 .btst16,
1329 .ck803,
1330 .float1e3,
1331 .floate1,
1332 .fpuv2_sf,
1333 .hwdiv,
1334 .mp,
1335 .nvic,
1336 .trust,
1337 }),
1338 };
1339 pub const ck803fhr1 = CpuModel{
1340 .name = "ck803fhr1",
1341 .llvm_name = "ck803fhr1",
1342 .features = featureSet(&[_]Feature{
1343 .@"3e3r1",
1344 .@"3e3r3",
1345 .btst16,
1346 .ck803,
1347 .dspv2,
1348 .float1e3,
1349 .floate1,
1350 .fpuv2_sf,
1351 .hwdiv,
1352 .mp,
1353 .nvic,
1354 .trust,
1355 }),
1356 };
1357 pub const ck803fhr2 = CpuModel{
1358 .name = "ck803fhr2",
1359 .llvm_name = "ck803fhr2",
1360 .features = featureSet(&[_]Feature{
1361 .@"3e3r2",
1362 .@"3e3r3",
1363 .btst16,
1364 .ck803,
1365 .dspv2,
1366 .float1e3,
1367 .floate1,
1368 .fpuv2_sf,
1369 .hwdiv,
1370 .mp,
1371 .nvic,
1372 .trust,
1373 }),
1374 };
1375 pub const ck803fhr3 = CpuModel{
1376 .name = "ck803fhr3",
1377 .llvm_name = "ck803fhr3",
1378 .features = featureSet(&[_]Feature{
1379 .@"3e3r2",
1380 .@"3e3r3",
1381 .btst16,
1382 .ck803,
1383 .dspv2,
1384 .float1e3,
1385 .floate1,
1386 .fpuv2_sf,
1387 .hwdiv,
1388 .mp,
1389 .nvic,
1390 .trust,
1391 }),
1392 };
1393 pub const ck803fr1 = CpuModel{
1394 .name = "ck803fr1",
1395 .llvm_name = "ck803fr1",
1396 .features = featureSet(&[_]Feature{
1397 .@"3e3r1",
1398 .@"3e3r3",
1399 .btst16,
1400 .ck803,
1401 .dspv2,
1402 .float1e3,
1403 .floate1,
1404 .fpuv2_sf,
1405 .hwdiv,
1406 .mp,
1407 .nvic,
1408 .trust,
1409 }),
1410 };
1411 pub const ck803fr2 = CpuModel{
1412 .name = "ck803fr2",
1413 .llvm_name = "ck803fr2",
1414 .features = featureSet(&[_]Feature{
1415 .@"3e3r2",
1416 .@"3e3r3",
1417 .btst16,
1418 .ck803,
1419 .dspv2,
1420 .float1e3,
1421 .floate1,
1422 .fpuv2_sf,
1423 .hwdiv,
1424 .mp,
1425 .nvic,
1426 .trust,
1427 }),
1428 };
1429 pub const ck803fr3 = CpuModel{
1430 .name = "ck803fr3",
1431 .llvm_name = "ck803fr3",
1432 .features = featureSet(&[_]Feature{
1433 .@"3e3r2",
1434 .@"3e3r3",
1435 .btst16,
1436 .ck803,
1437 .dspv2,
1438 .float1e3,
1439 .floate1,
1440 .fpuv2_sf,
1441 .hwdiv,
1442 .mp,
1443 .nvic,
1444 .trust,
1445 }),
1446 };
1447 pub const ck803ft = CpuModel{
1448 .name = "ck803ft",
1449 .llvm_name = "ck803ft",
1450 .features = featureSet(&[_]Feature{
1451 .btst16,
1452 .ck803,
1453 .float1e3,
1454 .floate1,
1455 .fpuv2_sf,
1456 .hwdiv,
1457 .mp,
1458 .nvic,
1459 .trust,
1460 }),
1461 };
1462 pub const ck803ftr1 = CpuModel{
1463 .name = "ck803ftr1",
1464 .llvm_name = "ck803ftr1",
1465 .features = featureSet(&[_]Feature{
1466 .@"3e3r1",
1467 .btst16,
1468 .ck803,
1469 .dspv2,
1470 .float1e3,
1471 .floate1,
1472 .fpuv2_sf,
1473 .hwdiv,
1474 .mp,
1475 .nvic,
1476 .trust,
1477 }),
1478 };
1479 pub const ck803ftr2 = CpuModel{
1480 .name = "ck803ftr2",
1481 .llvm_name = "ck803ftr2",
1482 .features = featureSet(&[_]Feature{
1483 .@"3e3r2",
1484 .@"3e3r3",
1485 .btst16,
1486 .ck803,
1487 .dspv2,
1488 .float1e3,
1489 .floate1,
1490 .fpuv2_sf,
1491 .hwdiv,
1492 .mp,
1493 .nvic,
1494 .trust,
1495 }),
1496 };
1497 pub const ck803ftr3 = CpuModel{
1498 .name = "ck803ftr3",
1499 .llvm_name = "ck803ftr3",
1500 .features = featureSet(&[_]Feature{
1501 .@"3e3r2",
1502 .@"3e3r3",
1503 .btst16,
1504 .ck803,
1505 .dspv2,
1506 .float1e3,
1507 .floate1,
1508 .fpuv2_sf,
1509 .hwdiv,
1510 .mp,
1511 .nvic,
1512 .trust,
1513 }),
1514 };
1515 pub const ck803h = CpuModel{
1516 .name = "ck803h",
1517 .llvm_name = "ck803h",
1518 .features = featureSet(&[_]Feature{
1519 .btst16,
1520 .ck803,
1521 .hwdiv,
1522 .mp,
1523 .nvic,
1524 .trust,
1525 }),
1526 };
1527 pub const ck803hr1 = CpuModel{
1528 .name = "ck803hr1",
1529 .llvm_name = "ck803hr1",
1530 .features = featureSet(&[_]Feature{
1531 .@"3e3r1",
1532 .@"3e3r3",
1533 .btst16,
1534 .ck803,
1535 .dspv2,
1536 .hwdiv,
1537 .mp,
1538 .nvic,
1539 .trust,
1540 }),
1541 };
1542 pub const ck803hr2 = CpuModel{
1543 .name = "ck803hr2",
1544 .llvm_name = "ck803hr2",
1545 .features = featureSet(&[_]Feature{
1546 .@"3e3r2",
1547 .@"3e3r3",
1548 .btst16,
1549 .ck803,
1550 .dspv2,
1551 .hwdiv,
1552 .mp,
1553 .nvic,
1554 .trust,
1555 }),
1556 };
1557 pub const ck803hr3 = CpuModel{
1558 .name = "ck803hr3",
1559 .llvm_name = "ck803hr3",
1560 .features = featureSet(&[_]Feature{
1561 .@"3e3r2",
1562 .@"3e3r3",
1563 .btst16,
1564 .ck803,
1565 .dspv2,
1566 .hwdiv,
1567 .mp,
1568 .nvic,
1569 .trust,
1570 }),
1571 };
1572 pub const ck803ht = CpuModel{
1573 .name = "ck803ht",
1574 .llvm_name = "ck803ht",
1575 .features = featureSet(&[_]Feature{
1576 .btst16,
1577 .ck803,
1578 .hwdiv,
1579 .mp,
1580 .nvic,
1581 .trust,
1582 }),
1583 };
1584 pub const ck803htr1 = CpuModel{
1585 .name = "ck803htr1",
1586 .llvm_name = "ck803htr1",
1587 .features = featureSet(&[_]Feature{
1588 .@"3e3r1",
1589 .@"3e3r3",
1590 .btst16,
1591 .ck803,
1592 .dspv2,
1593 .hwdiv,
1594 .mp,
1595 .nvic,
1596 .trust,
1597 }),
1598 };
1599 pub const ck803htr2 = CpuModel{
1600 .name = "ck803htr2",
1601 .llvm_name = "ck803htr2",
1602 .features = featureSet(&[_]Feature{
1603 .@"3e3r2",
1604 .@"3e3r3",
1605 .btst16,
1606 .ck803,
1607 .dspv2,
1608 .hwdiv,
1609 .mp,
1610 .nvic,
1611 .trust,
1612 }),
1613 };
1614 pub const ck803htr3 = CpuModel{
1615 .name = "ck803htr3",
1616 .llvm_name = "ck803htr3",
1617 .features = featureSet(&[_]Feature{
1618 .@"3e3r2",
1619 .@"3e3r3",
1620 .btst16,
1621 .ck803,
1622 .dspv2,
1623 .hwdiv,
1624 .mp,
1625 .nvic,
1626 .trust,
1627 }),
1628 };
1629 pub const ck803r1 = CpuModel{
1630 .name = "ck803r1",
1631 .llvm_name = "ck803r1",
1632 .features = featureSet(&[_]Feature{
1633 .@"3e3r1",
1634 .@"3e3r3",
1635 .btst16,
1636 .ck803,
1637 .dspv2,
1638 .hwdiv,
1639 .mp,
1640 .nvic,
1641 .trust,
1642 }),
1643 };
1644 pub const ck803r2 = CpuModel{
1645 .name = "ck803r2",
1646 .llvm_name = "ck803r2",
1647 .features = featureSet(&[_]Feature{
1648 .@"3e3r2",
1649 .@"3e3r3",
1650 .btst16,
1651 .ck803,
1652 .dspv2,
1653 .hwdiv,
1654 .mp,
1655 .nvic,
1656 .trust,
1657 }),
1658 };
1659 pub const ck803r3 = CpuModel{
1660 .name = "ck803r3",
1661 .llvm_name = "ck803r3",
1662 .features = featureSet(&[_]Feature{
1663 .@"3e3r2",
1664 .@"3e3r3",
1665 .btst16,
1666 .ck803,
1667 .dspv2,
1668 .hwdiv,
1669 .mp,
1670 .nvic,
1671 .trust,
1672 }),
1673 };
1674 pub const ck803s = CpuModel{
1675 .name = "ck803s",
1676 .llvm_name = "ck803s",
1677 .features = featureSet(&[_]Feature{
1678 .@"3e3r1",
1679 .btst16,
1680 .ck803,
1681 .ck803s,
1682 .hwdiv,
1683 .mp,
1684 .nvic,
1685 .trust,
1686 }),
1687 };
1688 pub const ck803se = CpuModel{
1689 .name = "ck803se",
1690 .llvm_name = "ck803se",
1691 .features = featureSet(&[_]Feature{
1692 .@"3e3r1",
1693 .btst16,
1694 .ck803,
1695 .ck803s,
1696 .dsp1e2,
1697 .dspe60,
1698 .edsp,
1699 .hwdiv,
1700 .mp,
1701 .nvic,
1702 .trust,
1703 }),
1704 };
1705 pub const ck803sef = CpuModel{
1706 .name = "ck803sef",
1707 .llvm_name = "ck803sef",
1708 .features = featureSet(&[_]Feature{
1709 .@"3e3r1",
1710 .btst16,
1711 .ck803,
1712 .ck803s,
1713 .dsp1e2,
1714 .dspe60,
1715 .edsp,
1716 .float1e3,
1717 .floate1,
1718 .fpuv2_sf,
1719 .hwdiv,
1720 .mp,
1721 .nvic,
1722 .trust,
1723 }),
1724 };
1725 pub const ck803sefn = CpuModel{
1726 .name = "ck803sefn",
1727 .llvm_name = "ck803sefn",
1728 .features = featureSet(&[_]Feature{
1729 .@"3e3r1",
1730 .btst16,
1731 .ck803,
1732 .ck803s,
1733 .dsp1e2,
1734 .dsp_silan,
1735 .dspe60,
1736 .edsp,
1737 .float1e3,
1738 .floate1,
1739 .fpuv2_sf,
1740 .hwdiv,
1741 .mp,
1742 .nvic,
1743 .trust,
1744 }),
1745 };
1746 pub const ck803sefnt = CpuModel{
1747 .name = "ck803sefnt",
1748 .llvm_name = "ck803sefnt",
1749 .features = featureSet(&[_]Feature{
1750 .@"3e3r1",
1751 .btst16,
1752 .ck803,
1753 .ck803s,
1754 .dsp1e2,
1755 .dsp_silan,
1756 .dspe60,
1757 .edsp,
1758 .float1e3,
1759 .floate1,
1760 .fpuv2_sf,
1761 .hwdiv,
1762 .mp,
1763 .nvic,
1764 .trust,
1765 }),
1766 };
1767 pub const ck803seft = CpuModel{
1768 .name = "ck803seft",
1769 .llvm_name = "ck803seft",
1770 .features = featureSet(&[_]Feature{
1771 .@"3e3r1",
1772 .btst16,
1773 .ck803,
1774 .ck803s,
1775 .dsp1e2,
1776 .dspe60,
1777 .edsp,
1778 .float1e3,
1779 .floate1,
1780 .fpuv2_sf,
1781 .hwdiv,
1782 .mp,
1783 .nvic,
1784 .trust,
1785 }),
1786 };
1787 pub const ck803sen = CpuModel{
1788 .name = "ck803sen",
1789 .llvm_name = "ck803sen",
1790 .features = featureSet(&[_]Feature{
1791 .@"3e3r1",
1792 .btst16,
1793 .ck803,
1794 .ck803s,
1795 .dsp1e2,
1796 .dsp_silan,
1797 .dspe60,
1798 .edsp,
1799 .hwdiv,
1800 .mp,
1801 .nvic,
1802 .trust,
1803 }),
1804 };
1805 pub const ck803sf = CpuModel{
1806 .name = "ck803sf",
1807 .llvm_name = "ck803sf",
1808 .features = featureSet(&[_]Feature{
1809 .@"3e3r1",
1810 .btst16,
1811 .ck803,
1812 .ck803s,
1813 .float1e3,
1814 .floate1,
1815 .fpuv2_sf,
1816 .hwdiv,
1817 .mp,
1818 .nvic,
1819 .trust,
1820 }),
1821 };
1822 pub const ck803sfn = CpuModel{
1823 .name = "ck803sfn",
1824 .llvm_name = "ck803sfn",
1825 .features = featureSet(&[_]Feature{
1826 .@"3e3r1",
1827 .btst16,
1828 .ck803,
1829 .ck803s,
1830 .dsp_silan,
1831 .float1e3,
1832 .floate1,
1833 .fpuv2_sf,
1834 .hwdiv,
1835 .mp,
1836 .nvic,
1837 .trust,
1838 }),
1839 };
1840 pub const ck803sn = CpuModel{
1841 .name = "ck803sn",
1842 .llvm_name = "ck803sn",
1843 .features = featureSet(&[_]Feature{
1844 .@"3e3r1",
1845 .btst16,
1846 .ck803,
1847 .ck803s,
1848 .dsp_silan,
1849 .hwdiv,
1850 .mp,
1851 .nvic,
1852 .trust,
1853 }),
1854 };
1855 pub const ck803snt = CpuModel{
1856 .name = "ck803snt",
1857 .llvm_name = "ck803snt",
1858 .features = featureSet(&[_]Feature{
1859 .@"3e3r1",
1860 .btst16,
1861 .ck803,
1862 .ck803s,
1863 .dsp_silan,
1864 .hwdiv,
1865 .mp,
1866 .nvic,
1867 .trust,
1868 }),
1869 };
1870 pub const ck803st = CpuModel{
1871 .name = "ck803st",
1872 .llvm_name = "ck803st",
1873 .features = featureSet(&[_]Feature{
1874 .@"3e3r1",
1875 .btst16,
1876 .ck803,
1877 .ck803s,
1878 .hwdiv,
1879 .mp,
1880 .nvic,
1881 .trust,
1882 }),
1883 };
1884 pub const ck803t = CpuModel{
1885 .name = "ck803t",
1886 .llvm_name = "ck803t",
1887 .features = featureSet(&[_]Feature{
1888 .btst16,
1889 .ck803,
1890 .hwdiv,
1891 .mp,
1892 .nvic,
1893 .trust,
1894 }),
1895 };
1896 pub const ck803tr1 = CpuModel{
1897 .name = "ck803tr1",
1898 .llvm_name = "ck803tr1",
1899 .features = featureSet(&[_]Feature{
1900 .@"3e3r1",
1901 .@"3e3r3",
1902 .btst16,
1903 .ck803,
1904 .dspv2,
1905 .hwdiv,
1906 .mp,
1907 .nvic,
1908 .trust,
1909 }),
1910 };
1911 pub const ck803tr2 = CpuModel{
1912 .name = "ck803tr2",
1913 .llvm_name = "ck803tr2",
1914 .features = featureSet(&[_]Feature{
1915 .@"3e3r2",
1916 .@"3e3r3",
1917 .btst16,
1918 .ck803,
1919 .dspv2,
1920 .hwdiv,
1921 .mp,
1922 .nvic,
1923 .trust,
1924 }),
1925 };
1926 pub const ck803tr3 = CpuModel{
1927 .name = "ck803tr3",
1928 .llvm_name = "ck803tr3",
1929 .features = featureSet(&[_]Feature{
1930 .@"3e3r2",
1931 .@"3e3r3",
1932 .btst16,
1933 .ck803,
1934 .dspv2,
1935 .hwdiv,
1936 .mp,
1937 .nvic,
1938 .trust,
1939 }),
1940 };
1941 pub const ck804 = CpuModel{
1942 .name = "ck804",
1943 .llvm_name = "ck804",
1944 .features = featureSet(&[_]Feature{
1945 .@"3e3r2",
1946 .@"3e3r3",
1947 .btst16,
1948 .ck803,
1949 .ck804,
1950 .hwdiv,
1951 .mp,
1952 .nvic,
1953 .trust,
1954 }),
1955 };
1956 pub const ck804e = CpuModel{
1957 .name = "ck804e",
1958 .llvm_name = "ck804e",
1959 .features = featureSet(&[_]Feature{
1960 .@"3e3r2",
1961 .@"3e3r3",
1962 .btst16,
1963 .ck803,
1964 .ck804,
1965 .dspv2,
1966 .high_registers,
1967 .hwdiv,
1968 .mp,
1969 .nvic,
1970 .trust,
1971 }),
1972 };
1973 pub const ck804ef = CpuModel{
1974 .name = "ck804ef",
1975 .llvm_name = "ck804ef",
1976 .features = featureSet(&[_]Feature{
1977 .@"3e3r2",
1978 .@"3e3r3",
1979 .btst16,
1980 .ck803,
1981 .ck804,
1982 .dspv2,
1983 .float1e3,
1984 .floate1,
1985 .fpuv2_sf,
1986 .high_registers,
1987 .hwdiv,
1988 .mp,
1989 .nvic,
1990 .trust,
1991 }),
1992 };
1993 pub const ck804efh = CpuModel{
1994 .name = "ck804efh",
1995 .llvm_name = "ck804efh",
1996 .features = featureSet(&[_]Feature{
1997 .@"3e3r2",
1998 .@"3e3r3",
1999 .btst16,
2000 .ck803,
2001 .ck804,
2002 .dspv2,
2003 .float1e3,
2004 .floate1,
2005 .fpuv2_sf,
2006 .high_registers,
2007 .hwdiv,
2008 .mp,
2009 .nvic,
2010 .trust,
2011 }),
2012 };
2013 pub const ck804efht = CpuModel{
2014 .name = "ck804efht",
2015 .llvm_name = "ck804efht",
2016 .features = featureSet(&[_]Feature{
2017 .@"3e3r2",
2018 .@"3e3r3",
2019 .btst16,
2020 .ck803,
2021 .ck804,
2022 .dspv2,
2023 .float1e3,
2024 .floate1,
2025 .fpuv2_sf,
2026 .high_registers,
2027 .hwdiv,
2028 .mp,
2029 .nvic,
2030 .trust,
2031 }),
2032 };
2033 pub const ck804eft = CpuModel{
2034 .name = "ck804eft",
2035 .llvm_name = "ck804eft",
2036 .features = featureSet(&[_]Feature{
2037 .@"3e3r2",
2038 .@"3e3r3",
2039 .btst16,
2040 .ck803,
2041 .ck804,
2042 .dspv2,
2043 .float1e3,
2044 .floate1,
2045 .fpuv2_sf,
2046 .high_registers,
2047 .hwdiv,
2048 .mp,
2049 .nvic,
2050 .trust,
2051 }),
2052 };
2053 pub const ck804eh = CpuModel{
2054 .name = "ck804eh",
2055 .llvm_name = "ck804eh",
2056 .features = featureSet(&[_]Feature{
2057 .@"3e3r2",
2058 .@"3e3r3",
2059 .btst16,
2060 .ck803,
2061 .ck804,
2062 .dspv2,
2063 .high_registers,
2064 .hwdiv,
2065 .mp,
2066 .nvic,
2067 .trust,
2068 }),
2069 };
2070 pub const ck804eht = CpuModel{
2071 .name = "ck804eht",
2072 .llvm_name = "ck804eht",
2073 .features = featureSet(&[_]Feature{
2074 .@"3e3r2",
2075 .@"3e3r3",
2076 .btst16,
2077 .ck803,
2078 .ck804,
2079 .dspv2,
2080 .high_registers,
2081 .hwdiv,
2082 .mp,
2083 .nvic,
2084 .trust,
2085 }),
2086 };
2087 pub const ck804et = CpuModel{
2088 .name = "ck804et",
2089 .llvm_name = "ck804et",
2090 .features = featureSet(&[_]Feature{
2091 .@"3e3r2",
2092 .@"3e3r3",
2093 .btst16,
2094 .ck803,
2095 .ck804,
2096 .dspv2,
2097 .high_registers,
2098 .hwdiv,
2099 .mp,
2100 .nvic,
2101 .trust,
2102 }),
2103 };
2104 pub const ck804f = CpuModel{
2105 .name = "ck804f",
2106 .llvm_name = "ck804f",
2107 .features = featureSet(&[_]Feature{
2108 .@"3e3r2",
2109 .@"3e3r3",
2110 .btst16,
2111 .ck803,
2112 .ck804,
2113 .float1e3,
2114 .floate1,
2115 .fpuv2_sf,
2116 .hwdiv,
2117 .mp,
2118 .nvic,
2119 .trust,
2120 }),
2121 };
2122 pub const ck804fh = CpuModel{
2123 .name = "ck804fh",
2124 .llvm_name = "ck804fh",
2125 .features = featureSet(&[_]Feature{
2126 .@"3e3r2",
2127 .@"3e3r3",
2128 .btst16,
2129 .ck803,
2130 .ck804,
2131 .float1e3,
2132 .floate1,
2133 .fpuv2_sf,
2134 .hwdiv,
2135 .mp,
2136 .nvic,
2137 .trust,
2138 }),
2139 };
2140 pub const ck804ft = CpuModel{
2141 .name = "ck804ft",
2142 .llvm_name = "ck804ft",
2143 .features = featureSet(&[_]Feature{
2144 .@"3e3r2",
2145 .@"3e3r3",
2146 .btst16,
2147 .ck803,
2148 .ck804,
2149 .float1e3,
2150 .floate1,
2151 .fpuv2_sf,
2152 .hwdiv,
2153 .mp,
2154 .nvic,
2155 .trust,
2156 }),
2157 };
2158 pub const ck804h = CpuModel{
2159 .name = "ck804h",
2160 .llvm_name = "ck804h",
2161 .features = featureSet(&[_]Feature{
2162 .@"3e3r2",
2163 .@"3e3r3",
2164 .btst16,
2165 .ck803,
2166 .ck804,
2167 .hwdiv,
2168 .mp,
2169 .nvic,
2170 .trust,
2171 }),
2172 };
2173 pub const ck804ht = CpuModel{
2174 .name = "ck804ht",
2175 .llvm_name = "ck804ht",
2176 .features = featureSet(&[_]Feature{
2177 .@"3e3r2",
2178 .@"3e3r3",
2179 .btst16,
2180 .ck803,
2181 .ck804,
2182 .hwdiv,
2183 .mp,
2184 .nvic,
2185 .trust,
2186 }),
2187 };
2188 pub const ck804t = CpuModel{
2189 .name = "ck804t",
2190 .llvm_name = "ck804t",
2191 .features = featureSet(&[_]Feature{
2192 .@"3e3r2",
2193 .@"3e3r3",
2194 .btst16,
2195 .ck803,
2196 .ck804,
2197 .hwdiv,
2198 .mp,
2199 .nvic,
2200 .trust,
2201 }),
2202 };
2203 pub const ck805 = CpuModel{
2204 .name = "ck805",
2205 .llvm_name = "ck805",
2206 .features = featureSet(&[_]Feature{
2207 .@"3e3r2",
2208 .@"3e3r3",
2209 .btst16,
2210 .ck803,
2211 .ck805,
2212 .high_registers,
2213 .hwdiv,
2214 .mp,
2215 .nvic,
2216 .trust,
2217 .vdsp2e3,
2218 .vdspv2,
2219 }),
2220 };
2221 pub const ck805e = CpuModel{
2222 .name = "ck805e",
2223 .llvm_name = "ck805e",
2224 .features = featureSet(&[_]Feature{
2225 .@"3e3r2",
2226 .@"3e3r3",
2227 .btst16,
2228 .ck803,
2229 .ck805,
2230 .dspv2,
2231 .high_registers,
2232 .hwdiv,
2233 .mp,
2234 .nvic,
2235 .trust,
2236 .vdsp2e3,
2237 .vdspv2,
2238 }),
2239 };
2240 pub const ck805ef = CpuModel{
2241 .name = "ck805ef",
2242 .llvm_name = "ck805ef",
2243 .features = featureSet(&[_]Feature{
2244 .@"3e3r2",
2245 .@"3e3r3",
2246 .btst16,
2247 .ck803,
2248 .ck805,
2249 .dspv2,
2250 .float1e3,
2251 .floate1,
2252 .fpuv2_sf,
2253 .high_registers,
2254 .hwdiv,
2255 .mp,
2256 .nvic,
2257 .trust,
2258 .vdsp2e3,
2259 .vdspv2,
2260 }),
2261 };
2262 pub const ck805eft = CpuModel{
2263 .name = "ck805eft",
2264 .llvm_name = "ck805eft",
2265 .features = featureSet(&[_]Feature{
2266 .@"3e3r2",
2267 .@"3e3r3",
2268 .btst16,
2269 .ck803,
2270 .ck805,
2271 .dspv2,
2272 .float1e3,
2273 .floate1,
2274 .fpuv2_sf,
2275 .high_registers,
2276 .hwdiv,
2277 .mp,
2278 .nvic,
2279 .trust,
2280 .vdsp2e3,
2281 .vdspv2,
2282 }),
2283 };
2284 pub const ck805et = CpuModel{
2285 .name = "ck805et",
2286 .llvm_name = "ck805et",
2287 .features = featureSet(&[_]Feature{
2288 .@"3e3r2",
2289 .@"3e3r3",
2290 .btst16,
2291 .ck803,
2292 .ck805,
2293 .dspv2,
2294 .high_registers,
2295 .hwdiv,
2296 .mp,
2297 .nvic,
2298 .trust,
2299 .vdsp2e3,
2300 .vdspv2,
2301 }),
2302 };
2303 pub const ck805f = CpuModel{
2304 .name = "ck805f",
2305 .llvm_name = "ck805f",
2306 .features = featureSet(&[_]Feature{
2307 .@"3e3r2",
2308 .@"3e3r3",
2309 .btst16,
2310 .ck803,
2311 .ck805,
2312 .float1e3,
2313 .floate1,
2314 .fpuv2_sf,
2315 .high_registers,
2316 .hwdiv,
2317 .mp,
2318 .nvic,
2319 .trust,
2320 .vdsp2e3,
2321 .vdspv2,
2322 }),
2323 };
2324 pub const ck805ft = CpuModel{
2325 .name = "ck805ft",
2326 .llvm_name = "ck805ft",
2327 .features = featureSet(&[_]Feature{
2328 .@"3e3r2",
2329 .@"3e3r3",
2330 .btst16,
2331 .ck803,
2332 .ck805,
2333 .float1e3,
2334 .floate1,
2335 .fpuv2_sf,
2336 .high_registers,
2337 .hwdiv,
2338 .mp,
2339 .nvic,
2340 .trust,
2341 .vdsp2e3,
2342 .vdspv2,
2343 }),
2344 };
2345 pub const ck805t = CpuModel{
2346 .name = "ck805t",
2347 .llvm_name = "ck805t",
2348 .features = featureSet(&[_]Feature{
2349 .@"3e3r2",
2350 .@"3e3r3",
2351 .btst16,
2352 .ck803,
2353 .ck805,
2354 .high_registers,
2355 .hwdiv,
2356 .mp,
2357 .nvic,
2358 .trust,
2359 .vdsp2e3,
2360 .vdspv2,
2361 }),
2362 };
2363 pub const ck807 = CpuModel{
2364 .name = "ck807",
2365 .llvm_name = "ck807",
2366 .features = featureSet(&[_]Feature{
2367 .cache,
2368 .ck807,
2369 .dsp1e2,
2370 .dspe60,
2371 .edsp,
2372 .hard_tp,
2373 .high_registers,
2374 .hwdiv,
2375 .mp,
2376 .mp1e2,
2377 .nvic,
2378 .trust,
2379 }),
2380 };
2381 pub const ck807e = CpuModel{
2382 .name = "ck807e",
2383 .llvm_name = "ck807e",
2384 .features = featureSet(&[_]Feature{
2385 .cache,
2386 .ck807,
2387 .dsp1e2,
2388 .dspe60,
2389 .edsp,
2390 .hard_tp,
2391 .high_registers,
2392 .hwdiv,
2393 .mp,
2394 .mp1e2,
2395 .nvic,
2396 .trust,
2397 }),
2398 };
2399 pub const ck807ef = CpuModel{
2400 .name = "ck807ef",
2401 .llvm_name = "ck807ef",
2402 .features = featureSet(&[_]Feature{
2403 .cache,
2404 .ck807,
2405 .dsp1e2,
2406 .dspe60,
2407 .edsp,
2408 .fdivdu,
2409 .float1e2,
2410 .float1e3,
2411 .float3e4,
2412 .floate1,
2413 .fpuv2_df,
2414 .fpuv2_sf,
2415 .hard_tp,
2416 .high_registers,
2417 .hwdiv,
2418 .mp,
2419 .mp1e2,
2420 .nvic,
2421 .trust,
2422 }),
2423 };
2424 pub const ck807f = CpuModel{
2425 .name = "ck807f",
2426 .llvm_name = "ck807f",
2427 .features = featureSet(&[_]Feature{
2428 .cache,
2429 .ck807,
2430 .dsp1e2,
2431 .dspe60,
2432 .edsp,
2433 .fdivdu,
2434 .float1e2,
2435 .float1e3,
2436 .float3e4,
2437 .floate1,
2438 .fpuv2_df,
2439 .fpuv2_sf,
2440 .hard_tp,
2441 .high_registers,
2442 .hwdiv,
2443 .mp,
2444 .mp1e2,
2445 .nvic,
2446 .trust,
2447 }),
2448 };
2449 pub const ck810 = CpuModel{
2450 .name = "ck810",
2451 .llvm_name = "ck810",
2452 .features = featureSet(&[_]Feature{
2453 .@"7e10",
2454 .cache,
2455 .ck810,
2456 .dsp1e2,
2457 .dspe60,
2458 .edsp,
2459 .hard_tp,
2460 .high_registers,
2461 .hwdiv,
2462 .mp,
2463 .mp1e2,
2464 .nvic,
2465 .trust,
2466 }),
2467 };
2468 pub const ck810e = CpuModel{
2469 .name = "ck810e",
2470 .llvm_name = "ck810e",
2471 .features = featureSet(&[_]Feature{
2472 .@"7e10",
2473 .cache,
2474 .ck810,
2475 .dsp1e2,
2476 .dspe60,
2477 .edsp,
2478 .hard_tp,
2479 .high_registers,
2480 .hwdiv,
2481 .mp,
2482 .mp1e2,
2483 .nvic,
2484 .trust,
2485 }),
2486 };
2487 pub const ck810ef = CpuModel{
2488 .name = "ck810ef",
2489 .llvm_name = "ck810ef",
2490 .features = featureSet(&[_]Feature{
2491 .@"7e10",
2492 .cache,
2493 .ck810,
2494 .dsp1e2,
2495 .dspe60,
2496 .edsp,
2497 .fdivdu,
2498 .float1e2,
2499 .floate1,
2500 .fpuv2_df,
2501 .fpuv2_sf,
2502 .hard_tp,
2503 .high_registers,
2504 .hwdiv,
2505 .mp,
2506 .mp1e2,
2507 .nvic,
2508 .trust,
2509 }),
2510 };
2511 pub const ck810eft = CpuModel{
2512 .name = "ck810eft",
2513 .llvm_name = "ck810eft",
2514 .features = featureSet(&[_]Feature{
2515 .@"7e10",
2516 .cache,
2517 .ck810,
2518 .dsp1e2,
2519 .dspe60,
2520 .edsp,
2521 .fdivdu,
2522 .float1e2,
2523 .floate1,
2524 .fpuv2_df,
2525 .fpuv2_sf,
2526 .hard_tp,
2527 .high_registers,
2528 .hwdiv,
2529 .mp,
2530 .mp1e2,
2531 .nvic,
2532 .trust,
2533 }),
2534 };
2535 pub const ck810eftv = CpuModel{
2536 .name = "ck810eftv",
2537 .llvm_name = "ck810eftv",
2538 .features = featureSet(&[_]Feature{
2539 .@"7e10",
2540 .cache,
2541 .ck810,
2542 .ck810v,
2543 .dsp1e2,
2544 .dspe60,
2545 .edsp,
2546 .fdivdu,
2547 .float1e2,
2548 .floate1,
2549 .fpuv2_df,
2550 .fpuv2_sf,
2551 .hard_tp,
2552 .high_registers,
2553 .hwdiv,
2554 .mp,
2555 .mp1e2,
2556 .nvic,
2557 .trust,
2558 .vdspv1,
2559 }),
2560 };
2561 pub const ck810efv = CpuModel{
2562 .name = "ck810efv",
2563 .llvm_name = "ck810efv",
2564 .features = featureSet(&[_]Feature{
2565 .@"7e10",
2566 .cache,
2567 .ck810,
2568 .ck810v,
2569 .dsp1e2,
2570 .dspe60,
2571 .edsp,
2572 .fdivdu,
2573 .float1e2,
2574 .floate1,
2575 .fpuv2_df,
2576 .fpuv2_sf,
2577 .hard_tp,
2578 .high_registers,
2579 .hwdiv,
2580 .mp,
2581 .mp1e2,
2582 .nvic,
2583 .trust,
2584 .vdspv1,
2585 }),
2586 };
2587 pub const ck810et = CpuModel{
2588 .name = "ck810et",
2589 .llvm_name = "ck810et",
2590 .features = featureSet(&[_]Feature{
2591 .@"7e10",
2592 .cache,
2593 .ck810,
2594 .dsp1e2,
2595 .dspe60,
2596 .edsp,
2597 .hard_tp,
2598 .high_registers,
2599 .hwdiv,
2600 .mp,
2601 .mp1e2,
2602 .nvic,
2603 .trust,
2604 }),
2605 };
2606 pub const ck810etv = CpuModel{
2607 .name = "ck810etv",
2608 .llvm_name = "ck810etv",
2609 .features = featureSet(&[_]Feature{
2610 .@"7e10",
2611 .cache,
2612 .ck810,
2613 .ck810v,
2614 .dsp1e2,
2615 .dspe60,
2616 .edsp,
2617 .hard_tp,
2618 .high_registers,
2619 .hwdiv,
2620 .mp,
2621 .mp1e2,
2622 .nvic,
2623 .trust,
2624 .vdspv1,
2625 }),
2626 };
2627 pub const ck810ev = CpuModel{
2628 .name = "ck810ev",
2629 .llvm_name = "ck810ev",
2630 .features = featureSet(&[_]Feature{
2631 .@"7e10",
2632 .cache,
2633 .ck810,
2634 .ck810v,
2635 .dsp1e2,
2636 .dspe60,
2637 .edsp,
2638 .hard_tp,
2639 .high_registers,
2640 .hwdiv,
2641 .mp,
2642 .mp1e2,
2643 .nvic,
2644 .trust,
2645 .vdspv1,
2646 }),
2647 };
2648 pub const ck810f = CpuModel{
2649 .name = "ck810f",
2650 .llvm_name = "ck810f",
2651 .features = featureSet(&[_]Feature{
2652 .@"7e10",
2653 .cache,
2654 .ck810,
2655 .dsp1e2,
2656 .dspe60,
2657 .edsp,
2658 .fdivdu,
2659 .float1e2,
2660 .floate1,
2661 .fpuv2_df,
2662 .fpuv2_sf,
2663 .hard_tp,
2664 .high_registers,
2665 .hwdiv,
2666 .mp,
2667 .mp1e2,
2668 .nvic,
2669 .trust,
2670 }),
2671 };
2672 pub const ck810ft = CpuModel{
2673 .name = "ck810ft",
2674 .llvm_name = "ck810ft",
2675 .features = featureSet(&[_]Feature{
2676 .@"7e10",
2677 .cache,
2678 .ck810,
2679 .dsp1e2,
2680 .dspe60,
2681 .edsp,
2682 .fdivdu,
2683 .float1e2,
2684 .floate1,
2685 .fpuv2_df,
2686 .fpuv2_sf,
2687 .hard_tp,
2688 .high_registers,
2689 .hwdiv,
2690 .mp,
2691 .mp1e2,
2692 .nvic,
2693 .trust,
2694 }),
2695 };
2696 pub const ck810ftv = CpuModel{
2697 .name = "ck810ftv",
2698 .llvm_name = "ck810ftv",
2699 .features = featureSet(&[_]Feature{
2700 .@"7e10",
2701 .cache,
2702 .ck810,
2703 .ck810v,
2704 .dsp1e2,
2705 .dspe60,
2706 .edsp,
2707 .fdivdu,
2708 .float1e2,
2709 .floate1,
2710 .fpuv2_df,
2711 .fpuv2_sf,
2712 .hard_tp,
2713 .high_registers,
2714 .hwdiv,
2715 .mp,
2716 .mp1e2,
2717 .nvic,
2718 .trust,
2719 .vdspv1,
2720 }),
2721 };
2722 pub const ck810fv = CpuModel{
2723 .name = "ck810fv",
2724 .llvm_name = "ck810fv",
2725 .features = featureSet(&[_]Feature{
2726 .@"7e10",
2727 .cache,
2728 .ck810,
2729 .ck810v,
2730 .dsp1e2,
2731 .dspe60,
2732 .edsp,
2733 .fdivdu,
2734 .float1e2,
2735 .floate1,
2736 .fpuv2_df,
2737 .fpuv2_sf,
2738 .hard_tp,
2739 .high_registers,
2740 .hwdiv,
2741 .mp,
2742 .mp1e2,
2743 .nvic,
2744 .trust,
2745 .vdspv1,
2746 }),
2747 };
2748 pub const ck810t = CpuModel{
2749 .name = "ck810t",
2750 .llvm_name = "ck810t",
2751 .features = featureSet(&[_]Feature{
2752 .@"7e10",
2753 .cache,
2754 .ck810,
2755 .dsp1e2,
2756 .dspe60,
2757 .edsp,
2758 .hard_tp,
2759 .high_registers,
2760 .hwdiv,
2761 .mp,
2762 .mp1e2,
2763 .nvic,
2764 .trust,
2765 }),
2766 };
2767 pub const ck810tv = CpuModel{
2768 .name = "ck810tv",
2769 .llvm_name = "ck810tv",
2770 .features = featureSet(&[_]Feature{
2771 .@"7e10",
2772 .cache,
2773 .ck810,
2774 .ck810v,
2775 .dsp1e2,
2776 .dspe60,
2777 .edsp,
2778 .hard_tp,
2779 .high_registers,
2780 .hwdiv,
2781 .mp,
2782 .mp1e2,
2783 .nvic,
2784 .trust,
2785 .vdspv1,
2786 }),
2787 };
2788 pub const ck810v = CpuModel{
2789 .name = "ck810v",
2790 .llvm_name = "ck810v",
2791 .features = featureSet(&[_]Feature{
2792 .@"7e10",
2793 .cache,
2794 .ck810,
2795 .ck810v,
2796 .dsp1e2,
2797 .dspe60,
2798 .edsp,
2799 .hard_tp,
2800 .high_registers,
2801 .hwdiv,
2802 .mp,
2803 .mp1e2,
2804 .nvic,
2805 .trust,
2806 .vdspv1,
2807 }),
2808 };
2809 pub const ck860 = CpuModel{
2810 .name = "ck860",
2811 .llvm_name = "ck860",
2812 .features = featureSet(&[_]Feature{
2813 .@"10e60",
2814 .@"3e3r2",
2815 .@"3e3r3",
2816 .btst16,
2817 .cache,
2818 .ck860,
2819 .dspe60,
2820 .hard_tp,
2821 .high_registers,
2822 .hwdiv,
2823 .mp,
2824 .mp1e2,
2825 .nvic,
2826 .trust,
2827 }),
2828 };
2829 pub const ck860f = CpuModel{
2830 .name = "ck860f",
2831 .llvm_name = "ck860f",
2832 .features = featureSet(&[_]Feature{
2833 .@"10e60",
2834 .@"3e3r2",
2835 .@"3e3r3",
2836 .btst16,
2837 .cache,
2838 .ck860,
2839 .dspe60,
2840 .float7e60,
2841 .fpuv3_df,
2842 .fpuv3_hf,
2843 .fpuv3_hi,
2844 .fpuv3_sf,
2845 .hard_tp,
2846 .high_registers,
2847 .hwdiv,
2848 .mp,
2849 .mp1e2,
2850 .nvic,
2851 .trust,
2852 }),
2853 };
2854 pub const ck860fv = CpuModel{
2855 .name = "ck860fv",
2856 .llvm_name = "ck860fv",
2857 .features = featureSet(&[_]Feature{
2858 .@"10e60",
2859 .@"3e3r2",
2860 .@"3e3r3",
2861 .btst16,
2862 .cache,
2863 .ck860,
2864 .ck860v,
2865 .dspe60,
2866 .float7e60,
2867 .fpuv3_df,
2868 .fpuv3_hf,
2869 .fpuv3_hi,
2870 .fpuv3_sf,
2871 .hard_tp,
2872 .high_registers,
2873 .hwdiv,
2874 .mp,
2875 .mp1e2,
2876 .nvic,
2877 .trust,
2878 .vdsp2e60f,
2879 .vdspv2,
2880 }),
2881 };
2882 pub const ck860v = CpuModel{
2883 .name = "ck860v",
2884 .llvm_name = "ck860v",
2885 .features = featureSet(&[_]Feature{
2886 .@"10e60",
2887 .@"3e3r2",
2888 .@"3e3r3",
2889 .btst16,
2890 .cache,
2891 .ck860,
2892 .ck860v,
2893 .dspe60,
2894 .hard_tp,
2895 .high_registers,
2896 .hwdiv,
2897 .mp,
2898 .mp1e2,
2899 .nvic,
2900 .trust,
2901 .vdsp2e60f,
2902 .vdspv2,
2903 }),
2904 };
2905 pub const e801 = CpuModel{
2906 .name = "e801",
2907 .llvm_name = "e801",
2908 .features = featureSet(&[_]Feature{
2909 .btst16,
2910 .ck801,
2911 .e1,
2912 .trust,
2913 }),
2914 };
2915 pub const e802 = CpuModel{
2916 .name = "e802",
2917 .llvm_name = "e802",
2918 .features = featureSet(&[_]Feature{
2919 .btst16,
2920 .ck802,
2921 .e2,
2922 .nvic,
2923 .trust,
2924 }),
2925 };
2926 pub const e802t = CpuModel{
2927 .name = "e802t",
2928 .llvm_name = "e802t",
2929 .features = featureSet(&[_]Feature{
2930 .btst16,
2931 .ck802,
2932 .e2,
2933 .nvic,
2934 .trust,
2935 }),
2936 };
2937 pub const e803 = CpuModel{
2938 .name = "e803",
2939 .llvm_name = "e803",
2940 .features = featureSet(&[_]Feature{
2941 .@"3e3r2",
2942 .@"3e3r3",
2943 .btst16,
2944 .ck803,
2945 .hwdiv,
2946 .mp,
2947 .nvic,
2948 .trust,
2949 }),
2950 };
2951 pub const e803t = CpuModel{
2952 .name = "e803t",
2953 .llvm_name = "e803t",
2954 .features = featureSet(&[_]Feature{
2955 .@"3e3r2",
2956 .@"3e3r3",
2957 .btst16,
2958 .ck803,
2959 .hwdiv,
2960 .mp,
2961 .nvic,
2962 .trust,
2963 }),
2964 };
2965 pub const e804d = CpuModel{
2966 .name = "e804d",
2967 .llvm_name = "e804d",
2968 .features = featureSet(&[_]Feature{
2969 .@"3e3r2",
2970 .@"3e3r3",
2971 .btst16,
2972 .ck803,
2973 .ck804,
2974 .dspv2,
2975 .high_registers,
2976 .hwdiv,
2977 .mp,
2978 .nvic,
2979 .trust,
2980 }),
2981 };
2982 pub const e804df = CpuModel{
2983 .name = "e804df",
2984 .llvm_name = "e804df",
2985 .features = featureSet(&[_]Feature{
2986 .@"3e3r2",
2987 .@"3e3r3",
2988 .btst16,
2989 .ck803,
2990 .ck804,
2991 .dspv2,
2992 .float1e3,
2993 .floate1,
2994 .fpuv2_sf,
2995 .high_registers,
2996 .hwdiv,
2997 .mp,
2998 .nvic,
2999 .trust,
3000 }),
3001 };
3002 pub const e804dft = CpuModel{
3003 .name = "e804dft",
3004 .llvm_name = "e804dft",
3005 .features = featureSet(&[_]Feature{
3006 .@"3e3r2",
3007 .@"3e3r3",
3008 .btst16,
3009 .ck803,
3010 .ck804,
3011 .dspv2,
3012 .float1e3,
3013 .floate1,
3014 .fpuv2_sf,
3015 .high_registers,
3016 .hwdiv,
3017 .mp,
3018 .nvic,
3019 .trust,
3020 }),
3021 };
3022 pub const e804dt = CpuModel{
3023 .name = "e804dt",
3024 .llvm_name = "e804dt",
3025 .features = featureSet(&[_]Feature{
3026 .@"3e3r2",
3027 .@"3e3r3",
3028 .btst16,
3029 .ck803,
3030 .ck804,
3031 .dspv2,
3032 .high_registers,
3033 .hwdiv,
3034 .mp,
3035 .nvic,
3036 .trust,
3037 }),
3038 };
3039 pub const e804f = CpuModel{
3040 .name = "e804f",
3041 .llvm_name = "e804f",
3042 .features = featureSet(&[_]Feature{
3043 .@"3e3r2",
3044 .@"3e3r3",
3045 .btst16,
3046 .ck803,
3047 .ck804,
3048 .float1e3,
3049 .floate1,
3050 .fpuv2_sf,
3051 .hwdiv,
3052 .mp,
3053 .nvic,
3054 .trust,
3055 }),
3056 };
3057 pub const e804ft = CpuModel{
3058 .name = "e804ft",
3059 .llvm_name = "e804ft",
3060 .features = featureSet(&[_]Feature{
3061 .@"3e3r2",
3062 .@"3e3r3",
3063 .btst16,
3064 .ck803,
3065 .ck804,
3066 .float1e3,
3067 .floate1,
3068 .fpuv2_sf,
3069 .hwdiv,
3070 .mp,
3071 .nvic,
3072 .trust,
3073 }),
3074 };
3075 pub const generic = CpuModel{
3076 .name = "generic",
3077 .llvm_name = "generic",
3078 .features = featureSet(&[_]Feature{
3079 .btst16,
3080 }),
3081 };
3082 pub const @"i805" = CpuModel{
3083 .name = "i805",
3084 .llvm_name = "i805",
3085 .features = featureSet(&[_]Feature{
3086 .@"3e3r2",
3087 .@"3e3r3",
3088 .btst16,
3089 .ck803,
3090 .ck805,
3091 .high_registers,
3092 .hwdiv,
3093 .mp,
3094 .nvic,
3095 .trust,
3096 .vdsp2e3,
3097 .vdspv2,
3098 }),
3099 };
3100 pub const i805f = CpuModel{
3101 .name = "i805f",
3102 .llvm_name = "i805f",
3103 .features = featureSet(&[_]Feature{
3104 .@"3e3r2",
3105 .@"3e3r3",
3106 .btst16,
3107 .ck803,
3108 .ck805,
3109 .float1e3,
3110 .floate1,
3111 .fpuv2_sf,
3112 .high_registers,
3113 .hwdiv,
3114 .mp,
3115 .nvic,
3116 .trust,
3117 .vdsp2e3,
3118 .vdspv2,
3119 }),
3120 };
3121 pub const r807 = CpuModel{
3122 .name = "r807",
3123 .llvm_name = "r807",
3124 .features = featureSet(&[_]Feature{
3125 .cache,
3126 .ck807,
3127 .dsp1e2,
3128 .dspe60,
3129 .edsp,
3130 .hard_tp,
3131 .high_registers,
3132 .hwdiv,
3133 .mp,
3134 .mp1e2,
3135 .nvic,
3136 .trust,
3137 }),
3138 };
3139 pub const r807f = CpuModel{
3140 .name = "r807f",
3141 .llvm_name = "r807f",
3142 .features = featureSet(&[_]Feature{
3143 .cache,
3144 .ck807,
3145 .dsp1e2,
3146 .dspe60,
3147 .edsp,
3148 .fdivdu,
3149 .float1e2,
3150 .float1e3,
3151 .float3e4,
3152 .floate1,
3153 .fpuv2_df,
3154 .fpuv2_sf,
3155 .hard_tp,
3156 .high_registers,
3157 .hwdiv,
3158 .mp,
3159 .mp1e2,
3160 .nvic,
3161 .trust,
3162 }),
3163 };
3164 pub const s802 = CpuModel{
3165 .name = "s802",
3166 .llvm_name = "s802",
3167 .features = featureSet(&[_]Feature{
3168 .btst16,
3169 .ck802,
3170 .e2,
3171 .nvic,
3172 .trust,
3173 }),
3174 };
3175 pub const s802t = CpuModel{
3176 .name = "s802t",
3177 .llvm_name = "s802t",
3178 .features = featureSet(&[_]Feature{
3179 .btst16,
3180 .ck802,
3181 .e2,
3182 .nvic,
3183 .trust,
3184 }),
3185 };
3186 pub const s803 = CpuModel{
3187 .name = "s803",
3188 .llvm_name = "s803",
3189 .features = featureSet(&[_]Feature{
3190 .@"3e3r2",
3191 .@"3e3r3",
3192 .btst16,
3193 .ck803,
3194 .hwdiv,
3195 .mp,
3196 .nvic,
3197 .trust,
3198 }),
3199 };
3200 pub const s803t = CpuModel{
3201 .name = "s803t",
3202 .llvm_name = "s803t",
3203 .features = featureSet(&[_]Feature{
3204 .@"3e3r2",
3205 .@"3e3r3",
3206 .btst16,
3207 .ck803,
3208 .hwdiv,
3209 .mp,
3210 .nvic,
3211 .trust,
3212 }),
3213 };
3214};
lib/std/Target/hexagon.zig created+586
......@@ -0,0 +1,586 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 audio,
9 cabac,
10 compound,
11 duplex,
12 hvx,
13 hvx_ieee_fp,
14 hvx_length128b,
15 hvx_length64b,
16 hvx_qfloat,
17 hvxv60,
18 hvxv62,
19 hvxv65,
20 hvxv66,
21 hvxv67,
22 hvxv68,
23 hvxv69,
24 hvxv71,
25 hvxv73,
26 long_calls,
27 mem_noshuf,
28 memops,
29 noreturn_stack_elim,
30 nvj,
31 nvs,
32 packets,
33 prev65,
34 reserved_r19,
35 small_data,
36 tinycore,
37 unsafe_fp,
38 v5,
39 v55,
40 v60,
41 v62,
42 v65,
43 v66,
44 v67,
45 v68,
46 v69,
47 v71,
48 v73,
49 zreg,
50};
51
52pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
53pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
54pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
55pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
56
57pub const all_features = blk: {
58 const len = @typeInfo(Feature).Enum.fields.len;
59 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
60 var result: [len]CpuFeature = undefined;
61 result[@intFromEnum(Feature.audio)] = .{
62 .llvm_name = "audio",
63 .description = "Hexagon Audio extension instructions",
64 .dependencies = featureSet(&[_]Feature{}),
65 };
66 result[@intFromEnum(Feature.cabac)] = .{
67 .llvm_name = "cabac",
68 .description = "Emit the CABAC instruction",
69 .dependencies = featureSet(&[_]Feature{}),
70 };
71 result[@intFromEnum(Feature.compound)] = .{
72 .llvm_name = "compound",
73 .description = "Use compound instructions",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.duplex)] = .{
77 .llvm_name = "duplex",
78 .description = "Enable generation of duplex instruction",
79 .dependencies = featureSet(&[_]Feature{}),
80 };
81 result[@intFromEnum(Feature.hvx)] = .{
82 .llvm_name = "hvx",
83 .description = "Hexagon HVX instructions",
84 .dependencies = featureSet(&[_]Feature{}),
85 };
86 result[@intFromEnum(Feature.hvx_ieee_fp)] = .{
87 .llvm_name = "hvx-ieee-fp",
88 .description = "Hexagon HVX IEEE floating point instructions",
89 .dependencies = featureSet(&[_]Feature{}),
90 };
91 result[@intFromEnum(Feature.hvx_length128b)] = .{
92 .llvm_name = "hvx-length128b",
93 .description = "Hexagon HVX 128B instructions",
94 .dependencies = featureSet(&[_]Feature{
95 .hvx,
96 }),
97 };
98 result[@intFromEnum(Feature.hvx_length64b)] = .{
99 .llvm_name = "hvx-length64b",
100 .description = "Hexagon HVX 64B instructions",
101 .dependencies = featureSet(&[_]Feature{
102 .hvx,
103 }),
104 };
105 result[@intFromEnum(Feature.hvx_qfloat)] = .{
106 .llvm_name = "hvx-qfloat",
107 .description = "Hexagon HVX QFloating point instructions",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.hvxv60)] = .{
111 .llvm_name = "hvxv60",
112 .description = "Hexagon HVX instructions",
113 .dependencies = featureSet(&[_]Feature{
114 .hvx,
115 }),
116 };
117 result[@intFromEnum(Feature.hvxv62)] = .{
118 .llvm_name = "hvxv62",
119 .description = "Hexagon HVX instructions",
120 .dependencies = featureSet(&[_]Feature{
121 .hvxv60,
122 }),
123 };
124 result[@intFromEnum(Feature.hvxv65)] = .{
125 .llvm_name = "hvxv65",
126 .description = "Hexagon HVX instructions",
127 .dependencies = featureSet(&[_]Feature{
128 .hvxv62,
129 }),
130 };
131 result[@intFromEnum(Feature.hvxv66)] = .{
132 .llvm_name = "hvxv66",
133 .description = "Hexagon HVX instructions",
134 .dependencies = featureSet(&[_]Feature{
135 .hvxv65,
136 .zreg,
137 }),
138 };
139 result[@intFromEnum(Feature.hvxv67)] = .{
140 .llvm_name = "hvxv67",
141 .description = "Hexagon HVX instructions",
142 .dependencies = featureSet(&[_]Feature{
143 .hvxv66,
144 }),
145 };
146 result[@intFromEnum(Feature.hvxv68)] = .{
147 .llvm_name = "hvxv68",
148 .description = "Hexagon HVX instructions",
149 .dependencies = featureSet(&[_]Feature{
150 .hvxv67,
151 }),
152 };
153 result[@intFromEnum(Feature.hvxv69)] = .{
154 .llvm_name = "hvxv69",
155 .description = "Hexagon HVX instructions",
156 .dependencies = featureSet(&[_]Feature{
157 .hvxv68,
158 }),
159 };
160 result[@intFromEnum(Feature.hvxv71)] = .{
161 .llvm_name = "hvxv71",
162 .description = "Hexagon HVX instructions",
163 .dependencies = featureSet(&[_]Feature{
164 .hvxv69,
165 }),
166 };
167 result[@intFromEnum(Feature.hvxv73)] = .{
168 .llvm_name = "hvxv73",
169 .description = "Hexagon HVX instructions",
170 .dependencies = featureSet(&[_]Feature{
171 .hvxv71,
172 }),
173 };
174 result[@intFromEnum(Feature.long_calls)] = .{
175 .llvm_name = "long-calls",
176 .description = "Use constant-extended calls",
177 .dependencies = featureSet(&[_]Feature{}),
178 };
179 result[@intFromEnum(Feature.mem_noshuf)] = .{
180 .llvm_name = "mem_noshuf",
181 .description = "Supports mem_noshuf feature",
182 .dependencies = featureSet(&[_]Feature{}),
183 };
184 result[@intFromEnum(Feature.memops)] = .{
185 .llvm_name = "memops",
186 .description = "Use memop instructions",
187 .dependencies = featureSet(&[_]Feature{}),
188 };
189 result[@intFromEnum(Feature.noreturn_stack_elim)] = .{
190 .llvm_name = "noreturn-stack-elim",
191 .description = "Eliminate stack allocation in a noreturn function when possible",
192 .dependencies = featureSet(&[_]Feature{}),
193 };
194 result[@intFromEnum(Feature.nvj)] = .{
195 .llvm_name = "nvj",
196 .description = "Support for new-value jumps",
197 .dependencies = featureSet(&[_]Feature{
198 .packets,
199 }),
200 };
201 result[@intFromEnum(Feature.nvs)] = .{
202 .llvm_name = "nvs",
203 .description = "Support for new-value stores",
204 .dependencies = featureSet(&[_]Feature{
205 .packets,
206 }),
207 };
208 result[@intFromEnum(Feature.packets)] = .{
209 .llvm_name = "packets",
210 .description = "Support for instruction packets",
211 .dependencies = featureSet(&[_]Feature{}),
212 };
213 result[@intFromEnum(Feature.prev65)] = .{
214 .llvm_name = "prev65",
215 .description = "Support features deprecated in v65",
216 .dependencies = featureSet(&[_]Feature{}),
217 };
218 result[@intFromEnum(Feature.reserved_r19)] = .{
219 .llvm_name = "reserved-r19",
220 .description = "Reserve register R19",
221 .dependencies = featureSet(&[_]Feature{}),
222 };
223 result[@intFromEnum(Feature.small_data)] = .{
224 .llvm_name = "small-data",
225 .description = "Allow GP-relative addressing of global variables",
226 .dependencies = featureSet(&[_]Feature{}),
227 };
228 result[@intFromEnum(Feature.tinycore)] = .{
229 .llvm_name = "tinycore",
230 .description = "Hexagon Tiny Core",
231 .dependencies = featureSet(&[_]Feature{}),
232 };
233 result[@intFromEnum(Feature.unsafe_fp)] = .{
234 .llvm_name = "unsafe-fp",
235 .description = "Use unsafe FP math",
236 .dependencies = featureSet(&[_]Feature{}),
237 };
238 result[@intFromEnum(Feature.v5)] = .{
239 .llvm_name = "v5",
240 .description = "Enable Hexagon V5 architecture",
241 .dependencies = featureSet(&[_]Feature{}),
242 };
243 result[@intFromEnum(Feature.v55)] = .{
244 .llvm_name = "v55",
245 .description = "Enable Hexagon V55 architecture",
246 .dependencies = featureSet(&[_]Feature{}),
247 };
248 result[@intFromEnum(Feature.v60)] = .{
249 .llvm_name = "v60",
250 .description = "Enable Hexagon V60 architecture",
251 .dependencies = featureSet(&[_]Feature{}),
252 };
253 result[@intFromEnum(Feature.v62)] = .{
254 .llvm_name = "v62",
255 .description = "Enable Hexagon V62 architecture",
256 .dependencies = featureSet(&[_]Feature{}),
257 };
258 result[@intFromEnum(Feature.v65)] = .{
259 .llvm_name = "v65",
260 .description = "Enable Hexagon V65 architecture",
261 .dependencies = featureSet(&[_]Feature{}),
262 };
263 result[@intFromEnum(Feature.v66)] = .{
264 .llvm_name = "v66",
265 .description = "Enable Hexagon V66 architecture",
266 .dependencies = featureSet(&[_]Feature{}),
267 };
268 result[@intFromEnum(Feature.v67)] = .{
269 .llvm_name = "v67",
270 .description = "Enable Hexagon V67 architecture",
271 .dependencies = featureSet(&[_]Feature{}),
272 };
273 result[@intFromEnum(Feature.v68)] = .{
274 .llvm_name = "v68",
275 .description = "Enable Hexagon V68 architecture",
276 .dependencies = featureSet(&[_]Feature{}),
277 };
278 result[@intFromEnum(Feature.v69)] = .{
279 .llvm_name = "v69",
280 .description = "Enable Hexagon V69 architecture",
281 .dependencies = featureSet(&[_]Feature{}),
282 };
283 result[@intFromEnum(Feature.v71)] = .{
284 .llvm_name = "v71",
285 .description = "Enable Hexagon V71 architecture",
286 .dependencies = featureSet(&[_]Feature{}),
287 };
288 result[@intFromEnum(Feature.v73)] = .{
289 .llvm_name = "v73",
290 .description = "Enable Hexagon V73 architecture",
291 .dependencies = featureSet(&[_]Feature{}),
292 };
293 result[@intFromEnum(Feature.zreg)] = .{
294 .llvm_name = "zreg",
295 .description = "Hexagon ZReg extension instructions",
296 .dependencies = featureSet(&[_]Feature{}),
297 };
298 const ti = @typeInfo(Feature);
299 for (&result, 0..) |*elem, i| {
300 elem.index = i;
301 elem.name = ti.Enum.fields[i].name;
302 }
303 break :blk result;
304};
305
306pub const cpu = struct {
307 pub const generic = CpuModel{
308 .name = "generic",
309 .llvm_name = "generic",
310 .features = featureSet(&[_]Feature{
311 .cabac,
312 .compound,
313 .duplex,
314 .memops,
315 .nvj,
316 .nvs,
317 .prev65,
318 .small_data,
319 .v5,
320 .v55,
321 .v60,
322 }),
323 };
324 pub const hexagonv5 = CpuModel{
325 .name = "hexagonv5",
326 .llvm_name = "hexagonv5",
327 .features = featureSet(&[_]Feature{
328 .cabac,
329 .compound,
330 .duplex,
331 .memops,
332 .nvj,
333 .nvs,
334 .prev65,
335 .small_data,
336 .v5,
337 }),
338 };
339 pub const hexagonv55 = CpuModel{
340 .name = "hexagonv55",
341 .llvm_name = "hexagonv55",
342 .features = featureSet(&[_]Feature{
343 .cabac,
344 .compound,
345 .duplex,
346 .memops,
347 .nvj,
348 .nvs,
349 .prev65,
350 .small_data,
351 .v5,
352 .v55,
353 }),
354 };
355 pub const hexagonv60 = CpuModel{
356 .name = "hexagonv60",
357 .llvm_name = "hexagonv60",
358 .features = featureSet(&[_]Feature{
359 .cabac,
360 .compound,
361 .duplex,
362 .memops,
363 .nvj,
364 .nvs,
365 .prev65,
366 .small_data,
367 .v5,
368 .v55,
369 .v60,
370 }),
371 };
372 pub const hexagonv62 = CpuModel{
373 .name = "hexagonv62",
374 .llvm_name = "hexagonv62",
375 .features = featureSet(&[_]Feature{
376 .cabac,
377 .compound,
378 .duplex,
379 .memops,
380 .nvj,
381 .nvs,
382 .prev65,
383 .small_data,
384 .v5,
385 .v55,
386 .v60,
387 .v62,
388 }),
389 };
390 pub const hexagonv65 = CpuModel{
391 .name = "hexagonv65",
392 .llvm_name = "hexagonv65",
393 .features = featureSet(&[_]Feature{
394 .cabac,
395 .compound,
396 .duplex,
397 .mem_noshuf,
398 .memops,
399 .nvj,
400 .nvs,
401 .small_data,
402 .v5,
403 .v55,
404 .v60,
405 .v62,
406 .v65,
407 }),
408 };
409 pub const hexagonv66 = CpuModel{
410 .name = "hexagonv66",
411 .llvm_name = "hexagonv66",
412 .features = featureSet(&[_]Feature{
413 .cabac,
414 .compound,
415 .duplex,
416 .mem_noshuf,
417 .memops,
418 .nvj,
419 .nvs,
420 .small_data,
421 .v5,
422 .v55,
423 .v60,
424 .v62,
425 .v65,
426 .v66,
427 }),
428 };
429 pub const hexagonv67 = CpuModel{
430 .name = "hexagonv67",
431 .llvm_name = "hexagonv67",
432 .features = featureSet(&[_]Feature{
433 .cabac,
434 .compound,
435 .duplex,
436 .mem_noshuf,
437 .memops,
438 .nvj,
439 .nvs,
440 .small_data,
441 .v5,
442 .v55,
443 .v60,
444 .v62,
445 .v65,
446 .v66,
447 .v67,
448 }),
449 };
450 pub const hexagonv67t = CpuModel{
451 .name = "hexagonv67t",
452 .llvm_name = "hexagonv67t",
453 .features = featureSet(&[_]Feature{
454 .audio,
455 .compound,
456 .mem_noshuf,
457 .memops,
458 .nvs,
459 .small_data,
460 .tinycore,
461 .v5,
462 .v55,
463 .v60,
464 .v62,
465 .v65,
466 .v66,
467 .v67,
468 }),
469 };
470 pub const hexagonv68 = CpuModel{
471 .name = "hexagonv68",
472 .llvm_name = "hexagonv68",
473 .features = featureSet(&[_]Feature{
474 .cabac,
475 .compound,
476 .duplex,
477 .mem_noshuf,
478 .memops,
479 .nvj,
480 .nvs,
481 .small_data,
482 .v5,
483 .v55,
484 .v60,
485 .v62,
486 .v65,
487 .v66,
488 .v67,
489 .v68,
490 }),
491 };
492 pub const hexagonv69 = CpuModel{
493 .name = "hexagonv69",
494 .llvm_name = "hexagonv69",
495 .features = featureSet(&[_]Feature{
496 .cabac,
497 .compound,
498 .duplex,
499 .mem_noshuf,
500 .memops,
501 .nvj,
502 .nvs,
503 .small_data,
504 .v5,
505 .v55,
506 .v60,
507 .v62,
508 .v65,
509 .v66,
510 .v67,
511 .v68,
512 .v69,
513 }),
514 };
515 pub const hexagonv71 = CpuModel{
516 .name = "hexagonv71",
517 .llvm_name = "hexagonv71",
518 .features = featureSet(&[_]Feature{
519 .cabac,
520 .compound,
521 .duplex,
522 .mem_noshuf,
523 .memops,
524 .nvj,
525 .nvs,
526 .small_data,
527 .v5,
528 .v55,
529 .v60,
530 .v62,
531 .v65,
532 .v66,
533 .v67,
534 .v68,
535 .v69,
536 .v71,
537 }),
538 };
539 pub const hexagonv71t = CpuModel{
540 .name = "hexagonv71t",
541 .llvm_name = "hexagonv71t",
542 .features = featureSet(&[_]Feature{
543 .audio,
544 .compound,
545 .mem_noshuf,
546 .memops,
547 .nvs,
548 .small_data,
549 .tinycore,
550 .v5,
551 .v55,
552 .v60,
553 .v62,
554 .v65,
555 .v66,
556 .v67,
557 .v68,
558 .v69,
559 .v71,
560 }),
561 };
562 pub const hexagonv73 = CpuModel{
563 .name = "hexagonv73",
564 .llvm_name = "hexagonv73",
565 .features = featureSet(&[_]Feature{
566 .compound,
567 .duplex,
568 .mem_noshuf,
569 .memops,
570 .nvj,
571 .nvs,
572 .small_data,
573 .v5,
574 .v55,
575 .v60,
576 .v62,
577 .v65,
578 .v66,
579 .v67,
580 .v68,
581 .v69,
582 .v71,
583 .v73,
584 }),
585 };
586};
lib/std/Target/loongarch.zig created+146
......@@ -0,0 +1,146 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"32bit",
9 @"64bit",
10 d,
11 f,
12 la_global_with_abs,
13 la_global_with_pcrel,
14 la_local_with_abs,
15 lasx,
16 lbt,
17 lsx,
18 lvz,
19 ual,
20};
21
22pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
23pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
24pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
25pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
26
27pub const all_features = blk: {
28 const len = @typeInfo(Feature).Enum.fields.len;
29 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
30 var result: [len]CpuFeature = undefined;
31 result[@intFromEnum(Feature.@"32bit")] = .{
32 .llvm_name = "32bit",
33 .description = "LA32 Basic Integer and Privilege Instruction Set",
34 .dependencies = featureSet(&[_]Feature{}),
35 };
36 result[@intFromEnum(Feature.@"64bit")] = .{
37 .llvm_name = "64bit",
38 .description = "LA64 Basic Integer and Privilege Instruction Set",
39 .dependencies = featureSet(&[_]Feature{}),
40 };
41 result[@intFromEnum(Feature.d)] = .{
42 .llvm_name = "d",
43 .description = "'D' (Double-Precision Floating-Point)",
44 .dependencies = featureSet(&[_]Feature{
45 .f,
46 }),
47 };
48 result[@intFromEnum(Feature.f)] = .{
49 .llvm_name = "f",
50 .description = "'F' (Single-Precision Floating-Point)",
51 .dependencies = featureSet(&[_]Feature{}),
52 };
53 result[@intFromEnum(Feature.la_global_with_abs)] = .{
54 .llvm_name = "la-global-with-abs",
55 .description = "Expand la.global as la.abs",
56 .dependencies = featureSet(&[_]Feature{}),
57 };
58 result[@intFromEnum(Feature.la_global_with_pcrel)] = .{
59 .llvm_name = "la-global-with-pcrel",
60 .description = "Expand la.global as la.pcrel",
61 .dependencies = featureSet(&[_]Feature{}),
62 };
63 result[@intFromEnum(Feature.la_local_with_abs)] = .{
64 .llvm_name = "la-local-with-abs",
65 .description = "Expand la.local as la.abs",
66 .dependencies = featureSet(&[_]Feature{}),
67 };
68 result[@intFromEnum(Feature.lasx)] = .{
69 .llvm_name = "lasx",
70 .description = "'LASX' (Loongson Advanced SIMD Extension)",
71 .dependencies = featureSet(&[_]Feature{
72 .lsx,
73 }),
74 };
75 result[@intFromEnum(Feature.lbt)] = .{
76 .llvm_name = "lbt",
77 .description = "'LBT' (Loongson Binary Translation Extension)",
78 .dependencies = featureSet(&[_]Feature{}),
79 };
80 result[@intFromEnum(Feature.lsx)] = .{
81 .llvm_name = "lsx",
82 .description = "'LSX' (Loongson SIMD Extension)",
83 .dependencies = featureSet(&[_]Feature{
84 .d,
85 }),
86 };
87 result[@intFromEnum(Feature.lvz)] = .{
88 .llvm_name = "lvz",
89 .description = "'LVZ' (Loongson Virtualization Extension)",
90 .dependencies = featureSet(&[_]Feature{}),
91 };
92 result[@intFromEnum(Feature.ual)] = .{
93 .llvm_name = "ual",
94 .description = "Allow memory accesses to be unaligned",
95 .dependencies = featureSet(&[_]Feature{}),
96 };
97 const ti = @typeInfo(Feature);
98 for (&result, 0..) |*elem, i| {
99 elem.index = i;
100 elem.name = ti.Enum.fields[i].name;
101 }
102 break :blk result;
103};
104
105pub const cpu = struct {
106 pub const generic = CpuModel{
107 .name = "generic",
108 .llvm_name = "generic",
109 .features = featureSet(&[_]Feature{}),
110 };
111 pub const generic_la32 = CpuModel{
112 .name = "generic_la32",
113 .llvm_name = "generic-la32",
114 .features = featureSet(&[_]Feature{
115 .@"32bit",
116 }),
117 };
118 pub const generic_la64 = CpuModel{
119 .name = "generic_la64",
120 .llvm_name = "generic-la64",
121 .features = featureSet(&[_]Feature{
122 .@"64bit",
123 .ual,
124 }),
125 };
126 pub const la464 = CpuModel{
127 .name = "la464",
128 .llvm_name = "la464",
129 .features = featureSet(&[_]Feature{
130 .@"64bit",
131 .lasx,
132 .lbt,
133 .lvz,
134 .ual,
135 }),
136 };
137 pub const loongarch64 = CpuModel{
138 .name = "loongarch64",
139 .llvm_name = "loongarch64",
140 .features = featureSet(&[_]Feature{
141 .@"64bit",
142 .d,
143 .ual,
144 }),
145 };
146};
lib/std/Target/m68k.zig created+228
......@@ -0,0 +1,228 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 isa_68000,
9 isa_68010,
10 isa_68020,
11 isa_68030,
12 isa_68040,
13 isa_68060,
14 isa_68881,
15 isa_68882,
16 reserve_a0,
17 reserve_a1,
18 reserve_a2,
19 reserve_a3,
20 reserve_a4,
21 reserve_a5,
22 reserve_a6,
23 reserve_d0,
24 reserve_d1,
25 reserve_d2,
26 reserve_d3,
27 reserve_d4,
28 reserve_d5,
29 reserve_d6,
30 reserve_d7,
31};
32
33pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
34pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
35pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
36pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
37
38pub const all_features = blk: {
39 const len = @typeInfo(Feature).Enum.fields.len;
40 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
41 var result: [len]CpuFeature = undefined;
42 result[@intFromEnum(Feature.isa_68000)] = .{
43 .llvm_name = "isa-68000",
44 .description = "Is M68000 ISA supported",
45 .dependencies = featureSet(&[_]Feature{}),
46 };
47 result[@intFromEnum(Feature.isa_68010)] = .{
48 .llvm_name = "isa-68010",
49 .description = "Is M68010 ISA supported",
50 .dependencies = featureSet(&[_]Feature{
51 .isa_68000,
52 }),
53 };
54 result[@intFromEnum(Feature.isa_68020)] = .{
55 .llvm_name = "isa-68020",
56 .description = "Is M68020 ISA supported",
57 .dependencies = featureSet(&[_]Feature{
58 .isa_68010,
59 }),
60 };
61 result[@intFromEnum(Feature.isa_68030)] = .{
62 .llvm_name = "isa-68030",
63 .description = "Is M68030 ISA supported",
64 .dependencies = featureSet(&[_]Feature{
65 .isa_68020,
66 }),
67 };
68 result[@intFromEnum(Feature.isa_68040)] = .{
69 .llvm_name = "isa-68040",
70 .description = "Is M68040 ISA supported",
71 .dependencies = featureSet(&[_]Feature{
72 .isa_68030,
73 .isa_68882,
74 }),
75 };
76 result[@intFromEnum(Feature.isa_68060)] = .{
77 .llvm_name = "isa-68060",
78 .description = "Is M68060 ISA supported",
79 .dependencies = featureSet(&[_]Feature{
80 .isa_68040,
81 }),
82 };
83 result[@intFromEnum(Feature.isa_68881)] = .{
84 .llvm_name = "isa-68881",
85 .description = "Is M68881 (FPU) ISA supported",
86 .dependencies = featureSet(&[_]Feature{}),
87 };
88 result[@intFromEnum(Feature.isa_68882)] = .{
89 .llvm_name = "isa-68882",
90 .description = "Is M68882 (FPU) ISA supported",
91 .dependencies = featureSet(&[_]Feature{
92 .isa_68881,
93 }),
94 };
95 result[@intFromEnum(Feature.reserve_a0)] = .{
96 .llvm_name = "reserve-a0",
97 .description = "Reserve A0 register",
98 .dependencies = featureSet(&[_]Feature{}),
99 };
100 result[@intFromEnum(Feature.reserve_a1)] = .{
101 .llvm_name = "reserve-a1",
102 .description = "Reserve A1 register",
103 .dependencies = featureSet(&[_]Feature{}),
104 };
105 result[@intFromEnum(Feature.reserve_a2)] = .{
106 .llvm_name = "reserve-a2",
107 .description = "Reserve A2 register",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.reserve_a3)] = .{
111 .llvm_name = "reserve-a3",
112 .description = "Reserve A3 register",
113 .dependencies = featureSet(&[_]Feature{}),
114 };
115 result[@intFromEnum(Feature.reserve_a4)] = .{
116 .llvm_name = "reserve-a4",
117 .description = "Reserve A4 register",
118 .dependencies = featureSet(&[_]Feature{}),
119 };
120 result[@intFromEnum(Feature.reserve_a5)] = .{
121 .llvm_name = "reserve-a5",
122 .description = "Reserve A5 register",
123 .dependencies = featureSet(&[_]Feature{}),
124 };
125 result[@intFromEnum(Feature.reserve_a6)] = .{
126 .llvm_name = "reserve-a6",
127 .description = "Reserve A6 register",
128 .dependencies = featureSet(&[_]Feature{}),
129 };
130 result[@intFromEnum(Feature.reserve_d0)] = .{
131 .llvm_name = "reserve-d0",
132 .description = "Reserve D0 register",
133 .dependencies = featureSet(&[_]Feature{}),
134 };
135 result[@intFromEnum(Feature.reserve_d1)] = .{
136 .llvm_name = "reserve-d1",
137 .description = "Reserve D1 register",
138 .dependencies = featureSet(&[_]Feature{}),
139 };
140 result[@intFromEnum(Feature.reserve_d2)] = .{
141 .llvm_name = "reserve-d2",
142 .description = "Reserve D2 register",
143 .dependencies = featureSet(&[_]Feature{}),
144 };
145 result[@intFromEnum(Feature.reserve_d3)] = .{
146 .llvm_name = "reserve-d3",
147 .description = "Reserve D3 register",
148 .dependencies = featureSet(&[_]Feature{}),
149 };
150 result[@intFromEnum(Feature.reserve_d4)] = .{
151 .llvm_name = "reserve-d4",
152 .description = "Reserve D4 register",
153 .dependencies = featureSet(&[_]Feature{}),
154 };
155 result[@intFromEnum(Feature.reserve_d5)] = .{
156 .llvm_name = "reserve-d5",
157 .description = "Reserve D5 register",
158 .dependencies = featureSet(&[_]Feature{}),
159 };
160 result[@intFromEnum(Feature.reserve_d6)] = .{
161 .llvm_name = "reserve-d6",
162 .description = "Reserve D6 register",
163 .dependencies = featureSet(&[_]Feature{}),
164 };
165 result[@intFromEnum(Feature.reserve_d7)] = .{
166 .llvm_name = "reserve-d7",
167 .description = "Reserve D7 register",
168 .dependencies = featureSet(&[_]Feature{}),
169 };
170 const ti = @typeInfo(Feature);
171 for (&result, 0..) |*elem, i| {
172 elem.index = i;
173 elem.name = ti.Enum.fields[i].name;
174 }
175 break :blk result;
176};
177
178pub const cpu = struct {
179 pub const generic = CpuModel{
180 .name = "generic",
181 .llvm_name = "generic",
182 .features = featureSet(&[_]Feature{
183 .isa_68000,
184 }),
185 };
186 pub const M68000 = CpuModel{
187 .name = "M68000",
188 .llvm_name = "M68000",
189 .features = featureSet(&[_]Feature{
190 .isa_68000,
191 }),
192 };
193 pub const M68010 = CpuModel{
194 .name = "M68010",
195 .llvm_name = "M68010",
196 .features = featureSet(&[_]Feature{
197 .isa_68010,
198 }),
199 };
200 pub const M68020 = CpuModel{
201 .name = "M68020",
202 .llvm_name = "M68020",
203 .features = featureSet(&[_]Feature{
204 .isa_68020,
205 }),
206 };
207 pub const M68030 = CpuModel{
208 .name = "M68030",
209 .llvm_name = "M68030",
210 .features = featureSet(&[_]Feature{
211 .isa_68030,
212 }),
213 };
214 pub const M68040 = CpuModel{
215 .name = "M68040",
216 .llvm_name = "M68040",
217 .features = featureSet(&[_]Feature{
218 .isa_68040,
219 }),
220 };
221 pub const M68060 = CpuModel{
222 .name = "M68060",
223 .llvm_name = "M68060",
224 .features = featureSet(&[_]Feature{
225 .isa_68060,
226 }),
227 };
228};
lib/std/Target/mips.zig created+531
......@@ -0,0 +1,531 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 abs2008,
9 cnmips,
10 cnmipsp,
11 crc,
12 dsp,
13 dspr2,
14 dspr3,
15 eva,
16 fp64,
17 fpxx,
18 ginv,
19 gp64,
20 long_calls,
21 micromips,
22 mips1,
23 mips16,
24 mips2,
25 mips3,
26 mips32,
27 mips32r2,
28 mips32r3,
29 mips32r5,
30 mips32r6,
31 mips3_32,
32 mips3_32r2,
33 mips3d,
34 mips4,
35 mips4_32,
36 mips4_32r2,
37 mips5,
38 mips5_32r2,
39 mips64,
40 mips64r2,
41 mips64r3,
42 mips64r5,
43 mips64r6,
44 msa,
45 mt,
46 nan2008,
47 noabicalls,
48 nomadd4,
49 nooddspreg,
50 p5600,
51 ptr64,
52 single_float,
53 soft_float,
54 sym32,
55 use_indirect_jump_hazard,
56 use_tcc_in_div,
57 vfpu,
58 virt,
59 xgot,
60};
61
62pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
63pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
64pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
65pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
66
67pub const all_features = blk: {
68 const len = @typeInfo(Feature).Enum.fields.len;
69 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
70 var result: [len]CpuFeature = undefined;
71 result[@intFromEnum(Feature.abs2008)] = .{
72 .llvm_name = "abs2008",
73 .description = "Disable IEEE 754-2008 abs.fmt mode",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.cnmips)] = .{
77 .llvm_name = "cnmips",
78 .description = "Octeon cnMIPS Support",
79 .dependencies = featureSet(&[_]Feature{
80 .mips64r2,
81 }),
82 };
83 result[@intFromEnum(Feature.cnmipsp)] = .{
84 .llvm_name = "cnmipsp",
85 .description = "Octeon+ cnMIPS Support",
86 .dependencies = featureSet(&[_]Feature{
87 .cnmips,
88 }),
89 };
90 result[@intFromEnum(Feature.crc)] = .{
91 .llvm_name = "crc",
92 .description = "Mips R6 CRC ASE",
93 .dependencies = featureSet(&[_]Feature{}),
94 };
95 result[@intFromEnum(Feature.dsp)] = .{
96 .llvm_name = "dsp",
97 .description = "Mips DSP ASE",
98 .dependencies = featureSet(&[_]Feature{}),
99 };
100 result[@intFromEnum(Feature.dspr2)] = .{
101 .llvm_name = "dspr2",
102 .description = "Mips DSP-R2 ASE",
103 .dependencies = featureSet(&[_]Feature{
104 .dsp,
105 }),
106 };
107 result[@intFromEnum(Feature.dspr3)] = .{
108 .llvm_name = "dspr3",
109 .description = "Mips DSP-R3 ASE",
110 .dependencies = featureSet(&[_]Feature{
111 .dspr2,
112 }),
113 };
114 result[@intFromEnum(Feature.eva)] = .{
115 .llvm_name = "eva",
116 .description = "Mips EVA ASE",
117 .dependencies = featureSet(&[_]Feature{}),
118 };
119 result[@intFromEnum(Feature.fp64)] = .{
120 .llvm_name = "fp64",
121 .description = "Support 64-bit FP registers",
122 .dependencies = featureSet(&[_]Feature{}),
123 };
124 result[@intFromEnum(Feature.fpxx)] = .{
125 .llvm_name = "fpxx",
126 .description = "Support for FPXX",
127 .dependencies = featureSet(&[_]Feature{}),
128 };
129 result[@intFromEnum(Feature.ginv)] = .{
130 .llvm_name = "ginv",
131 .description = "Mips Global Invalidate ASE",
132 .dependencies = featureSet(&[_]Feature{}),
133 };
134 result[@intFromEnum(Feature.gp64)] = .{
135 .llvm_name = "gp64",
136 .description = "General Purpose Registers are 64-bit wide",
137 .dependencies = featureSet(&[_]Feature{}),
138 };
139 result[@intFromEnum(Feature.long_calls)] = .{
140 .llvm_name = "long-calls",
141 .description = "Disable use of the jal instruction",
142 .dependencies = featureSet(&[_]Feature{}),
143 };
144 result[@intFromEnum(Feature.micromips)] = .{
145 .llvm_name = "micromips",
146 .description = "microMips mode",
147 .dependencies = featureSet(&[_]Feature{}),
148 };
149 result[@intFromEnum(Feature.mips1)] = .{
150 .llvm_name = "mips1",
151 .description = "Mips I ISA Support [highly experimental]",
152 .dependencies = featureSet(&[_]Feature{}),
153 };
154 result[@intFromEnum(Feature.mips16)] = .{
155 .llvm_name = "mips16",
156 .description = "Mips16 mode",
157 .dependencies = featureSet(&[_]Feature{}),
158 };
159 result[@intFromEnum(Feature.mips2)] = .{
160 .llvm_name = "mips2",
161 .description = "Mips II ISA Support [highly experimental]",
162 .dependencies = featureSet(&[_]Feature{
163 .mips1,
164 }),
165 };
166 result[@intFromEnum(Feature.mips3)] = .{
167 .llvm_name = "mips3",
168 .description = "MIPS III ISA Support [highly experimental]",
169 .dependencies = featureSet(&[_]Feature{
170 .fp64,
171 .gp64,
172 .mips2,
173 .mips3_32,
174 .mips3_32r2,
175 }),
176 };
177 result[@intFromEnum(Feature.mips32)] = .{
178 .llvm_name = "mips32",
179 .description = "Mips32 ISA Support",
180 .dependencies = featureSet(&[_]Feature{
181 .mips2,
182 .mips3_32,
183 .mips4_32,
184 }),
185 };
186 result[@intFromEnum(Feature.mips32r2)] = .{
187 .llvm_name = "mips32r2",
188 .description = "Mips32r2 ISA Support",
189 .dependencies = featureSet(&[_]Feature{
190 .mips32,
191 .mips3_32r2,
192 .mips4_32r2,
193 .mips5_32r2,
194 }),
195 };
196 result[@intFromEnum(Feature.mips32r3)] = .{
197 .llvm_name = "mips32r3",
198 .description = "Mips32r3 ISA Support",
199 .dependencies = featureSet(&[_]Feature{
200 .mips32r2,
201 }),
202 };
203 result[@intFromEnum(Feature.mips32r5)] = .{
204 .llvm_name = "mips32r5",
205 .description = "Mips32r5 ISA Support",
206 .dependencies = featureSet(&[_]Feature{
207 .mips32r3,
208 }),
209 };
210 result[@intFromEnum(Feature.mips32r6)] = .{
211 .llvm_name = "mips32r6",
212 .description = "Mips32r6 ISA Support [experimental]",
213 .dependencies = featureSet(&[_]Feature{
214 .abs2008,
215 .fp64,
216 .mips32r5,
217 .nan2008,
218 }),
219 };
220 result[@intFromEnum(Feature.mips3_32)] = .{
221 .llvm_name = "mips3_32",
222 .description = "Subset of MIPS-III that is also in MIPS32 [highly experimental]",
223 .dependencies = featureSet(&[_]Feature{}),
224 };
225 result[@intFromEnum(Feature.mips3_32r2)] = .{
226 .llvm_name = "mips3_32r2",
227 .description = "Subset of MIPS-III that is also in MIPS32r2 [highly experimental]",
228 .dependencies = featureSet(&[_]Feature{}),
229 };
230 result[@intFromEnum(Feature.mips3d)] = .{
231 .llvm_name = "mips3d",
232 .description = "Mips 3D ASE",
233 .dependencies = featureSet(&[_]Feature{}),
234 };
235 result[@intFromEnum(Feature.mips4)] = .{
236 .llvm_name = "mips4",
237 .description = "MIPS IV ISA Support",
238 .dependencies = featureSet(&[_]Feature{
239 .mips3,
240 .mips4_32,
241 .mips4_32r2,
242 }),
243 };
244 result[@intFromEnum(Feature.mips4_32)] = .{
245 .llvm_name = "mips4_32",
246 .description = "Subset of MIPS-IV that is also in MIPS32 [highly experimental]",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@intFromEnum(Feature.mips4_32r2)] = .{
250 .llvm_name = "mips4_32r2",
251 .description = "Subset of MIPS-IV that is also in MIPS32r2 [highly experimental]",
252 .dependencies = featureSet(&[_]Feature{}),
253 };
254 result[@intFromEnum(Feature.mips5)] = .{
255 .llvm_name = "mips5",
256 .description = "MIPS V ISA Support [highly experimental]",
257 .dependencies = featureSet(&[_]Feature{
258 .mips4,
259 .mips5_32r2,
260 }),
261 };
262 result[@intFromEnum(Feature.mips5_32r2)] = .{
263 .llvm_name = "mips5_32r2",
264 .description = "Subset of MIPS-V that is also in MIPS32r2 [highly experimental]",
265 .dependencies = featureSet(&[_]Feature{}),
266 };
267 result[@intFromEnum(Feature.mips64)] = .{
268 .llvm_name = "mips64",
269 .description = "Mips64 ISA Support",
270 .dependencies = featureSet(&[_]Feature{
271 .mips32,
272 .mips5,
273 }),
274 };
275 result[@intFromEnum(Feature.mips64r2)] = .{
276 .llvm_name = "mips64r2",
277 .description = "Mips64r2 ISA Support",
278 .dependencies = featureSet(&[_]Feature{
279 .mips32r2,
280 .mips64,
281 }),
282 };
283 result[@intFromEnum(Feature.mips64r3)] = .{
284 .llvm_name = "mips64r3",
285 .description = "Mips64r3 ISA Support",
286 .dependencies = featureSet(&[_]Feature{
287 .mips32r3,
288 .mips64r2,
289 }),
290 };
291 result[@intFromEnum(Feature.mips64r5)] = .{
292 .llvm_name = "mips64r5",
293 .description = "Mips64r5 ISA Support",
294 .dependencies = featureSet(&[_]Feature{
295 .mips32r5,
296 .mips64r3,
297 }),
298 };
299 result[@intFromEnum(Feature.mips64r6)] = .{
300 .llvm_name = "mips64r6",
301 .description = "Mips64r6 ISA Support [experimental]",
302 .dependencies = featureSet(&[_]Feature{
303 .mips32r6,
304 .mips64r5,
305 }),
306 };
307 result[@intFromEnum(Feature.msa)] = .{
308 .llvm_name = "msa",
309 .description = "Mips MSA ASE",
310 .dependencies = featureSet(&[_]Feature{}),
311 };
312 result[@intFromEnum(Feature.mt)] = .{
313 .llvm_name = "mt",
314 .description = "Mips MT ASE",
315 .dependencies = featureSet(&[_]Feature{}),
316 };
317 result[@intFromEnum(Feature.nan2008)] = .{
318 .llvm_name = "nan2008",
319 .description = "IEEE 754-2008 NaN encoding",
320 .dependencies = featureSet(&[_]Feature{}),
321 };
322 result[@intFromEnum(Feature.noabicalls)] = .{
323 .llvm_name = "noabicalls",
324 .description = "Disable SVR4-style position-independent code",
325 .dependencies = featureSet(&[_]Feature{}),
326 };
327 result[@intFromEnum(Feature.nomadd4)] = .{
328 .llvm_name = "nomadd4",
329 .description = "Disable 4-operand madd.fmt and related instructions",
330 .dependencies = featureSet(&[_]Feature{}),
331 };
332 result[@intFromEnum(Feature.nooddspreg)] = .{
333 .llvm_name = "nooddspreg",
334 .description = "Disable odd numbered single-precision registers",
335 .dependencies = featureSet(&[_]Feature{}),
336 };
337 result[@intFromEnum(Feature.p5600)] = .{
338 .llvm_name = "p5600",
339 .description = "The P5600 Processor",
340 .dependencies = featureSet(&[_]Feature{
341 .mips32r5,
342 }),
343 };
344 result[@intFromEnum(Feature.ptr64)] = .{
345 .llvm_name = "ptr64",
346 .description = "Pointers are 64-bit wide",
347 .dependencies = featureSet(&[_]Feature{}),
348 };
349 result[@intFromEnum(Feature.single_float)] = .{
350 .llvm_name = "single-float",
351 .description = "Only supports single precision float",
352 .dependencies = featureSet(&[_]Feature{}),
353 };
354 result[@intFromEnum(Feature.soft_float)] = .{
355 .llvm_name = "soft-float",
356 .description = "Does not support floating point instructions",
357 .dependencies = featureSet(&[_]Feature{}),
358 };
359 result[@intFromEnum(Feature.sym32)] = .{
360 .llvm_name = "sym32",
361 .description = "Symbols are 32 bit on Mips64",
362 .dependencies = featureSet(&[_]Feature{}),
363 };
364 result[@intFromEnum(Feature.use_indirect_jump_hazard)] = .{
365 .llvm_name = "use-indirect-jump-hazard",
366 .description = "Use indirect jump guards to prevent certain speculation based attacks",
367 .dependencies = featureSet(&[_]Feature{}),
368 };
369 result[@intFromEnum(Feature.use_tcc_in_div)] = .{
370 .llvm_name = "use-tcc-in-div",
371 .description = "Force the assembler to use trapping",
372 .dependencies = featureSet(&[_]Feature{}),
373 };
374 result[@intFromEnum(Feature.vfpu)] = .{
375 .llvm_name = "vfpu",
376 .description = "Enable vector FPU instructions",
377 .dependencies = featureSet(&[_]Feature{}),
378 };
379 result[@intFromEnum(Feature.virt)] = .{
380 .llvm_name = "virt",
381 .description = "Mips Virtualization ASE",
382 .dependencies = featureSet(&[_]Feature{}),
383 };
384 result[@intFromEnum(Feature.xgot)] = .{
385 .llvm_name = "xgot",
386 .description = "Assume 32-bit GOT",
387 .dependencies = featureSet(&[_]Feature{}),
388 };
389 const ti = @typeInfo(Feature);
390 for (&result, 0..) |*elem, i| {
391 elem.index = i;
392 elem.name = ti.Enum.fields[i].name;
393 }
394 break :blk result;
395};
396
397pub const cpu = struct {
398 pub const generic = CpuModel{
399 .name = "generic",
400 .llvm_name = "generic",
401 .features = featureSet(&[_]Feature{
402 .mips32,
403 }),
404 };
405 pub const mips1 = CpuModel{
406 .name = "mips1",
407 .llvm_name = "mips1",
408 .features = featureSet(&[_]Feature{
409 .mips1,
410 }),
411 };
412 pub const mips2 = CpuModel{
413 .name = "mips2",
414 .llvm_name = "mips2",
415 .features = featureSet(&[_]Feature{
416 .mips2,
417 }),
418 };
419 pub const mips3 = CpuModel{
420 .name = "mips3",
421 .llvm_name = "mips3",
422 .features = featureSet(&[_]Feature{
423 .mips3,
424 }),
425 };
426 pub const mips32 = CpuModel{
427 .name = "mips32",
428 .llvm_name = "mips32",
429 .features = featureSet(&[_]Feature{
430 .mips32,
431 }),
432 };
433 pub const mips32r2 = CpuModel{
434 .name = "mips32r2",
435 .llvm_name = "mips32r2",
436 .features = featureSet(&[_]Feature{
437 .mips32r2,
438 }),
439 };
440 pub const mips32r3 = CpuModel{
441 .name = "mips32r3",
442 .llvm_name = "mips32r3",
443 .features = featureSet(&[_]Feature{
444 .mips32r3,
445 }),
446 };
447 pub const mips32r5 = CpuModel{
448 .name = "mips32r5",
449 .llvm_name = "mips32r5",
450 .features = featureSet(&[_]Feature{
451 .mips32r5,
452 }),
453 };
454 pub const mips32r6 = CpuModel{
455 .name = "mips32r6",
456 .llvm_name = "mips32r6",
457 .features = featureSet(&[_]Feature{
458 .mips32r6,
459 }),
460 };
461 pub const mips4 = CpuModel{
462 .name = "mips4",
463 .llvm_name = "mips4",
464 .features = featureSet(&[_]Feature{
465 .mips4,
466 }),
467 };
468 pub const mips5 = CpuModel{
469 .name = "mips5",
470 .llvm_name = "mips5",
471 .features = featureSet(&[_]Feature{
472 .mips5,
473 }),
474 };
475 pub const mips64 = CpuModel{
476 .name = "mips64",
477 .llvm_name = "mips64",
478 .features = featureSet(&[_]Feature{
479 .mips64,
480 }),
481 };
482 pub const mips64r2 = CpuModel{
483 .name = "mips64r2",
484 .llvm_name = "mips64r2",
485 .features = featureSet(&[_]Feature{
486 .mips64r2,
487 }),
488 };
489 pub const mips64r3 = CpuModel{
490 .name = "mips64r3",
491 .llvm_name = "mips64r3",
492 .features = featureSet(&[_]Feature{
493 .mips64r3,
494 }),
495 };
496 pub const mips64r5 = CpuModel{
497 .name = "mips64r5",
498 .llvm_name = "mips64r5",
499 .features = featureSet(&[_]Feature{
500 .mips64r5,
501 }),
502 };
503 pub const mips64r6 = CpuModel{
504 .name = "mips64r6",
505 .llvm_name = "mips64r6",
506 .features = featureSet(&[_]Feature{
507 .mips64r6,
508 }),
509 };
510 pub const octeon = CpuModel{
511 .name = "octeon",
512 .llvm_name = "octeon",
513 .features = featureSet(&[_]Feature{
514 .cnmips,
515 }),
516 };
517 pub const @"octeon+" = CpuModel{
518 .name = "octeon+",
519 .llvm_name = "octeon+",
520 .features = featureSet(&[_]Feature{
521 .cnmipsp,
522 }),
523 };
524 pub const p5600 = CpuModel{
525 .name = "p5600",
526 .llvm_name = "p5600",
527 .features = featureSet(&[_]Feature{
528 .p5600,
529 }),
530 };
531};
lib/std/Target/msp430.zig created+69
......@@ -0,0 +1,69 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 ext,
9 hwmult16,
10 hwmult32,
11 hwmultf5,
12};
13
14pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
15pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
16pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
17pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
18
19pub const all_features = blk: {
20 const len = @typeInfo(Feature).Enum.fields.len;
21 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
22 var result: [len]CpuFeature = undefined;
23 result[@intFromEnum(Feature.ext)] = .{
24 .llvm_name = "ext",
25 .description = "Enable MSP430-X extensions",
26 .dependencies = featureSet(&[_]Feature{}),
27 };
28 result[@intFromEnum(Feature.hwmult16)] = .{
29 .llvm_name = "hwmult16",
30 .description = "Enable 16-bit hardware multiplier",
31 .dependencies = featureSet(&[_]Feature{}),
32 };
33 result[@intFromEnum(Feature.hwmult32)] = .{
34 .llvm_name = "hwmult32",
35 .description = "Enable 32-bit hardware multiplier",
36 .dependencies = featureSet(&[_]Feature{}),
37 };
38 result[@intFromEnum(Feature.hwmultf5)] = .{
39 .llvm_name = "hwmultf5",
40 .description = "Enable F5 series hardware multiplier",
41 .dependencies = featureSet(&[_]Feature{}),
42 };
43 const ti = @typeInfo(Feature);
44 for (&result, 0..) |*elem, i| {
45 elem.index = i;
46 elem.name = ti.Enum.fields[i].name;
47 }
48 break :blk result;
49};
50
51pub const cpu = struct {
52 pub const generic = CpuModel{
53 .name = "generic",
54 .llvm_name = "generic",
55 .features = featureSet(&[_]Feature{}),
56 };
57 pub const msp430 = CpuModel{
58 .name = "msp430",
59 .llvm_name = "msp430",
60 .features = featureSet(&[_]Feature{}),
61 };
62 pub const msp430x = CpuModel{
63 .name = "msp430x",
64 .llvm_name = "msp430x",
65 .features = featureSet(&[_]Feature{
66 .ext,
67 }),
68 };
69};
lib/std/Target/nvptx.zig created+439
......@@ -0,0 +1,439 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 ptx32,
9 ptx40,
10 ptx41,
11 ptx42,
12 ptx43,
13 ptx50,
14 ptx60,
15 ptx61,
16 ptx63,
17 ptx64,
18 ptx65,
19 ptx70,
20 ptx71,
21 ptx72,
22 ptx73,
23 ptx74,
24 ptx75,
25 ptx76,
26 ptx77,
27 ptx78,
28 ptx80,
29 ptx81,
30 sm_20,
31 sm_21,
32 sm_30,
33 sm_32,
34 sm_35,
35 sm_37,
36 sm_50,
37 sm_52,
38 sm_53,
39 sm_60,
40 sm_61,
41 sm_62,
42 sm_70,
43 sm_72,
44 sm_75,
45 sm_80,
46 sm_86,
47 sm_87,
48 sm_89,
49 sm_90,
50};
51
52pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
53pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
54pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
55pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
56
57pub const all_features = blk: {
58 const len = @typeInfo(Feature).Enum.fields.len;
59 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
60 var result: [len]CpuFeature = undefined;
61 result[@intFromEnum(Feature.ptx32)] = .{
62 .llvm_name = "ptx32",
63 .description = "Use PTX version 32",
64 .dependencies = featureSet(&[_]Feature{}),
65 };
66 result[@intFromEnum(Feature.ptx40)] = .{
67 .llvm_name = "ptx40",
68 .description = "Use PTX version 40",
69 .dependencies = featureSet(&[_]Feature{}),
70 };
71 result[@intFromEnum(Feature.ptx41)] = .{
72 .llvm_name = "ptx41",
73 .description = "Use PTX version 41",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.ptx42)] = .{
77 .llvm_name = "ptx42",
78 .description = "Use PTX version 42",
79 .dependencies = featureSet(&[_]Feature{}),
80 };
81 result[@intFromEnum(Feature.ptx43)] = .{
82 .llvm_name = "ptx43",
83 .description = "Use PTX version 43",
84 .dependencies = featureSet(&[_]Feature{}),
85 };
86 result[@intFromEnum(Feature.ptx50)] = .{
87 .llvm_name = "ptx50",
88 .description = "Use PTX version 50",
89 .dependencies = featureSet(&[_]Feature{}),
90 };
91 result[@intFromEnum(Feature.ptx60)] = .{
92 .llvm_name = "ptx60",
93 .description = "Use PTX version 60",
94 .dependencies = featureSet(&[_]Feature{}),
95 };
96 result[@intFromEnum(Feature.ptx61)] = .{
97 .llvm_name = "ptx61",
98 .description = "Use PTX version 61",
99 .dependencies = featureSet(&[_]Feature{}),
100 };
101 result[@intFromEnum(Feature.ptx63)] = .{
102 .llvm_name = "ptx63",
103 .description = "Use PTX version 63",
104 .dependencies = featureSet(&[_]Feature{}),
105 };
106 result[@intFromEnum(Feature.ptx64)] = .{
107 .llvm_name = "ptx64",
108 .description = "Use PTX version 64",
109 .dependencies = featureSet(&[_]Feature{}),
110 };
111 result[@intFromEnum(Feature.ptx65)] = .{
112 .llvm_name = "ptx65",
113 .description = "Use PTX version 65",
114 .dependencies = featureSet(&[_]Feature{}),
115 };
116 result[@intFromEnum(Feature.ptx70)] = .{
117 .llvm_name = "ptx70",
118 .description = "Use PTX version 70",
119 .dependencies = featureSet(&[_]Feature{}),
120 };
121 result[@intFromEnum(Feature.ptx71)] = .{
122 .llvm_name = "ptx71",
123 .description = "Use PTX version 71",
124 .dependencies = featureSet(&[_]Feature{}),
125 };
126 result[@intFromEnum(Feature.ptx72)] = .{
127 .llvm_name = "ptx72",
128 .description = "Use PTX version 72",
129 .dependencies = featureSet(&[_]Feature{}),
130 };
131 result[@intFromEnum(Feature.ptx73)] = .{
132 .llvm_name = "ptx73",
133 .description = "Use PTX version 73",
134 .dependencies = featureSet(&[_]Feature{}),
135 };
136 result[@intFromEnum(Feature.ptx74)] = .{
137 .llvm_name = "ptx74",
138 .description = "Use PTX version 74",
139 .dependencies = featureSet(&[_]Feature{}),
140 };
141 result[@intFromEnum(Feature.ptx75)] = .{
142 .llvm_name = "ptx75",
143 .description = "Use PTX version 75",
144 .dependencies = featureSet(&[_]Feature{}),
145 };
146 result[@intFromEnum(Feature.ptx76)] = .{
147 .llvm_name = "ptx76",
148 .description = "Use PTX version 76",
149 .dependencies = featureSet(&[_]Feature{}),
150 };
151 result[@intFromEnum(Feature.ptx77)] = .{
152 .llvm_name = "ptx77",
153 .description = "Use PTX version 77",
154 .dependencies = featureSet(&[_]Feature{}),
155 };
156 result[@intFromEnum(Feature.ptx78)] = .{
157 .llvm_name = "ptx78",
158 .description = "Use PTX version 78",
159 .dependencies = featureSet(&[_]Feature{}),
160 };
161 result[@intFromEnum(Feature.ptx80)] = .{
162 .llvm_name = "ptx80",
163 .description = "Use PTX version 80",
164 .dependencies = featureSet(&[_]Feature{}),
165 };
166 result[@intFromEnum(Feature.ptx81)] = .{
167 .llvm_name = "ptx81",
168 .description = "Use PTX version 81",
169 .dependencies = featureSet(&[_]Feature{}),
170 };
171 result[@intFromEnum(Feature.sm_20)] = .{
172 .llvm_name = "sm_20",
173 .description = "Target SM 20",
174 .dependencies = featureSet(&[_]Feature{}),
175 };
176 result[@intFromEnum(Feature.sm_21)] = .{
177 .llvm_name = "sm_21",
178 .description = "Target SM 21",
179 .dependencies = featureSet(&[_]Feature{}),
180 };
181 result[@intFromEnum(Feature.sm_30)] = .{
182 .llvm_name = "sm_30",
183 .description = "Target SM 30",
184 .dependencies = featureSet(&[_]Feature{}),
185 };
186 result[@intFromEnum(Feature.sm_32)] = .{
187 .llvm_name = "sm_32",
188 .description = "Target SM 32",
189 .dependencies = featureSet(&[_]Feature{}),
190 };
191 result[@intFromEnum(Feature.sm_35)] = .{
192 .llvm_name = "sm_35",
193 .description = "Target SM 35",
194 .dependencies = featureSet(&[_]Feature{}),
195 };
196 result[@intFromEnum(Feature.sm_37)] = .{
197 .llvm_name = "sm_37",
198 .description = "Target SM 37",
199 .dependencies = featureSet(&[_]Feature{}),
200 };
201 result[@intFromEnum(Feature.sm_50)] = .{
202 .llvm_name = "sm_50",
203 .description = "Target SM 50",
204 .dependencies = featureSet(&[_]Feature{}),
205 };
206 result[@intFromEnum(Feature.sm_52)] = .{
207 .llvm_name = "sm_52",
208 .description = "Target SM 52",
209 .dependencies = featureSet(&[_]Feature{}),
210 };
211 result[@intFromEnum(Feature.sm_53)] = .{
212 .llvm_name = "sm_53",
213 .description = "Target SM 53",
214 .dependencies = featureSet(&[_]Feature{}),
215 };
216 result[@intFromEnum(Feature.sm_60)] = .{
217 .llvm_name = "sm_60",
218 .description = "Target SM 60",
219 .dependencies = featureSet(&[_]Feature{}),
220 };
221 result[@intFromEnum(Feature.sm_61)] = .{
222 .llvm_name = "sm_61",
223 .description = "Target SM 61",
224 .dependencies = featureSet(&[_]Feature{}),
225 };
226 result[@intFromEnum(Feature.sm_62)] = .{
227 .llvm_name = "sm_62",
228 .description = "Target SM 62",
229 .dependencies = featureSet(&[_]Feature{}),
230 };
231 result[@intFromEnum(Feature.sm_70)] = .{
232 .llvm_name = "sm_70",
233 .description = "Target SM 70",
234 .dependencies = featureSet(&[_]Feature{}),
235 };
236 result[@intFromEnum(Feature.sm_72)] = .{
237 .llvm_name = "sm_72",
238 .description = "Target SM 72",
239 .dependencies = featureSet(&[_]Feature{}),
240 };
241 result[@intFromEnum(Feature.sm_75)] = .{
242 .llvm_name = "sm_75",
243 .description = "Target SM 75",
244 .dependencies = featureSet(&[_]Feature{}),
245 };
246 result[@intFromEnum(Feature.sm_80)] = .{
247 .llvm_name = "sm_80",
248 .description = "Target SM 80",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.sm_86)] = .{
252 .llvm_name = "sm_86",
253 .description = "Target SM 86",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.sm_87)] = .{
257 .llvm_name = "sm_87",
258 .description = "Target SM 87",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.sm_89)] = .{
262 .llvm_name = "sm_89",
263 .description = "Target SM 89",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.sm_90)] = .{
267 .llvm_name = "sm_90",
268 .description = "Target SM 90",
269 .dependencies = featureSet(&[_]Feature{}),
270 };
271 const ti = @typeInfo(Feature);
272 for (&result, 0..) |*elem, i| {
273 elem.index = i;
274 elem.name = ti.Enum.fields[i].name;
275 }
276 break :blk result;
277};
278
279pub const cpu = struct {
280 pub const sm_20 = CpuModel{
281 .name = "sm_20",
282 .llvm_name = "sm_20",
283 .features = featureSet(&[_]Feature{
284 .ptx32,
285 .sm_20,
286 }),
287 };
288 pub const sm_21 = CpuModel{
289 .name = "sm_21",
290 .llvm_name = "sm_21",
291 .features = featureSet(&[_]Feature{
292 .ptx32,
293 .sm_21,
294 }),
295 };
296 pub const sm_30 = CpuModel{
297 .name = "sm_30",
298 .llvm_name = "sm_30",
299 .features = featureSet(&[_]Feature{
300 .sm_30,
301 }),
302 };
303 pub const sm_32 = CpuModel{
304 .name = "sm_32",
305 .llvm_name = "sm_32",
306 .features = featureSet(&[_]Feature{
307 .ptx40,
308 .sm_32,
309 }),
310 };
311 pub const sm_35 = CpuModel{
312 .name = "sm_35",
313 .llvm_name = "sm_35",
314 .features = featureSet(&[_]Feature{
315 .ptx32,
316 .sm_35,
317 }),
318 };
319 pub const sm_37 = CpuModel{
320 .name = "sm_37",
321 .llvm_name = "sm_37",
322 .features = featureSet(&[_]Feature{
323 .ptx41,
324 .sm_37,
325 }),
326 };
327 pub const sm_50 = CpuModel{
328 .name = "sm_50",
329 .llvm_name = "sm_50",
330 .features = featureSet(&[_]Feature{
331 .ptx40,
332 .sm_50,
333 }),
334 };
335 pub const sm_52 = CpuModel{
336 .name = "sm_52",
337 .llvm_name = "sm_52",
338 .features = featureSet(&[_]Feature{
339 .ptx41,
340 .sm_52,
341 }),
342 };
343 pub const sm_53 = CpuModel{
344 .name = "sm_53",
345 .llvm_name = "sm_53",
346 .features = featureSet(&[_]Feature{
347 .ptx42,
348 .sm_53,
349 }),
350 };
351 pub const sm_60 = CpuModel{
352 .name = "sm_60",
353 .llvm_name = "sm_60",
354 .features = featureSet(&[_]Feature{
355 .ptx50,
356 .sm_60,
357 }),
358 };
359 pub const sm_61 = CpuModel{
360 .name = "sm_61",
361 .llvm_name = "sm_61",
362 .features = featureSet(&[_]Feature{
363 .ptx50,
364 .sm_61,
365 }),
366 };
367 pub const sm_62 = CpuModel{
368 .name = "sm_62",
369 .llvm_name = "sm_62",
370 .features = featureSet(&[_]Feature{
371 .ptx50,
372 .sm_62,
373 }),
374 };
375 pub const sm_70 = CpuModel{
376 .name = "sm_70",
377 .llvm_name = "sm_70",
378 .features = featureSet(&[_]Feature{
379 .ptx60,
380 .sm_70,
381 }),
382 };
383 pub const sm_72 = CpuModel{
384 .name = "sm_72",
385 .llvm_name = "sm_72",
386 .features = featureSet(&[_]Feature{
387 .ptx61,
388 .sm_72,
389 }),
390 };
391 pub const sm_75 = CpuModel{
392 .name = "sm_75",
393 .llvm_name = "sm_75",
394 .features = featureSet(&[_]Feature{
395 .ptx63,
396 .sm_75,
397 }),
398 };
399 pub const sm_80 = CpuModel{
400 .name = "sm_80",
401 .llvm_name = "sm_80",
402 .features = featureSet(&[_]Feature{
403 .ptx70,
404 .sm_80,
405 }),
406 };
407 pub const sm_86 = CpuModel{
408 .name = "sm_86",
409 .llvm_name = "sm_86",
410 .features = featureSet(&[_]Feature{
411 .ptx71,
412 .sm_86,
413 }),
414 };
415 pub const sm_87 = CpuModel{
416 .name = "sm_87",
417 .llvm_name = "sm_87",
418 .features = featureSet(&[_]Feature{
419 .ptx74,
420 .sm_87,
421 }),
422 };
423 pub const sm_89 = CpuModel{
424 .name = "sm_89",
425 .llvm_name = "sm_89",
426 .features = featureSet(&[_]Feature{
427 .ptx78,
428 .sm_89,
429 }),
430 };
431 pub const sm_90 = CpuModel{
432 .name = "sm_90",
433 .llvm_name = "sm_90",
434 .features = featureSet(&[_]Feature{
435 .ptx78,
436 .sm_90,
437 }),
438 };
439};
lib/std/Target/powerpc.zig created+1192
......@@ -0,0 +1,1192 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"64bit",
9 @"64bitregs",
10 aix,
11 allow_unaligned_fp_access,
12 altivec,
13 booke,
14 bpermd,
15 cmpb,
16 crbits,
17 crypto,
18 direct_move,
19 e500,
20 efpu2,
21 extdiv,
22 fast_MFLR,
23 fcpsgn,
24 float128,
25 fpcvt,
26 fprnd,
27 fpu,
28 fre,
29 fres,
30 frsqrte,
31 frsqrtes,
32 fsqrt,
33 fuse_add_logical,
34 fuse_addi_load,
35 fuse_addis_load,
36 fuse_arith_add,
37 fuse_back2back,
38 fuse_cmp,
39 fuse_logical,
40 fuse_logical_add,
41 fuse_sha3,
42 fuse_store,
43 fuse_wideimm,
44 fuse_zeromove,
45 fusion,
46 hard_float,
47 htm,
48 icbt,
49 invariant_function_descriptors,
50 isa_future_instructions,
51 isa_v206_instructions,
52 isa_v207_instructions,
53 isa_v30_instructions,
54 isa_v31_instructions,
55 isel,
56 ldbrx,
57 lfiwax,
58 longcall,
59 mfocrf,
60 mma,
61 modern_aix_as,
62 msync,
63 paired_vector_memops,
64 partword_atomics,
65 pcrelative_memops,
66 popcntd,
67 power10_vector,
68 power8_altivec,
69 power8_vector,
70 power9_altivec,
71 power9_vector,
72 ppc4xx,
73 ppc6xx,
74 ppc_postra_sched,
75 ppc_prera_sched,
76 predictable_select_expensive,
77 prefix_instrs,
78 privileged,
79 quadword_atomics,
80 recipprec,
81 rop_protect,
82 secure_plt,
83 slow_popcntd,
84 spe,
85 stfiwx,
86 two_const_nr,
87 vectors_use_two_units,
88 vsx,
89};
90
91pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
92pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
93pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
94pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
95
96pub const all_features = blk: {
97 const len = @typeInfo(Feature).Enum.fields.len;
98 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
99 var result: [len]CpuFeature = undefined;
100 result[@intFromEnum(Feature.@"64bit")] = .{
101 .llvm_name = "64bit",
102 .description = "Enable 64-bit instructions",
103 .dependencies = featureSet(&[_]Feature{}),
104 };
105 result[@intFromEnum(Feature.@"64bitregs")] = .{
106 .llvm_name = "64bitregs",
107 .description = "Enable 64-bit registers usage for ppc32 [beta]",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.aix)] = .{
111 .llvm_name = "aix",
112 .description = "AIX OS",
113 .dependencies = featureSet(&[_]Feature{}),
114 };
115 result[@intFromEnum(Feature.allow_unaligned_fp_access)] = .{
116 .llvm_name = "allow-unaligned-fp-access",
117 .description = "CPU does not trap on unaligned FP access",
118 .dependencies = featureSet(&[_]Feature{}),
119 };
120 result[@intFromEnum(Feature.altivec)] = .{
121 .llvm_name = "altivec",
122 .description = "Enable Altivec instructions",
123 .dependencies = featureSet(&[_]Feature{
124 .fpu,
125 }),
126 };
127 result[@intFromEnum(Feature.booke)] = .{
128 .llvm_name = "booke",
129 .description = "Enable Book E instructions",
130 .dependencies = featureSet(&[_]Feature{
131 .icbt,
132 }),
133 };
134 result[@intFromEnum(Feature.bpermd)] = .{
135 .llvm_name = "bpermd",
136 .description = "Enable the bpermd instruction",
137 .dependencies = featureSet(&[_]Feature{}),
138 };
139 result[@intFromEnum(Feature.cmpb)] = .{
140 .llvm_name = "cmpb",
141 .description = "Enable the cmpb instruction",
142 .dependencies = featureSet(&[_]Feature{}),
143 };
144 result[@intFromEnum(Feature.crbits)] = .{
145 .llvm_name = "crbits",
146 .description = "Use condition-register bits individually",
147 .dependencies = featureSet(&[_]Feature{}),
148 };
149 result[@intFromEnum(Feature.crypto)] = .{
150 .llvm_name = "crypto",
151 .description = "Enable POWER8 Crypto instructions",
152 .dependencies = featureSet(&[_]Feature{
153 .power8_altivec,
154 }),
155 };
156 result[@intFromEnum(Feature.direct_move)] = .{
157 .llvm_name = "direct-move",
158 .description = "Enable Power8 direct move instructions",
159 .dependencies = featureSet(&[_]Feature{
160 .vsx,
161 }),
162 };
163 result[@intFromEnum(Feature.e500)] = .{
164 .llvm_name = "e500",
165 .description = "Enable E500/E500mc instructions",
166 .dependencies = featureSet(&[_]Feature{}),
167 };
168 result[@intFromEnum(Feature.efpu2)] = .{
169 .llvm_name = "efpu2",
170 .description = "Enable Embedded Floating-Point APU 2 instructions",
171 .dependencies = featureSet(&[_]Feature{
172 .spe,
173 }),
174 };
175 result[@intFromEnum(Feature.extdiv)] = .{
176 .llvm_name = "extdiv",
177 .description = "Enable extended divide instructions",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.fast_MFLR)] = .{
181 .llvm_name = "fast-MFLR",
182 .description = "MFLR is a fast instruction",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.fcpsgn)] = .{
186 .llvm_name = "fcpsgn",
187 .description = "Enable the fcpsgn instruction",
188 .dependencies = featureSet(&[_]Feature{
189 .fpu,
190 }),
191 };
192 result[@intFromEnum(Feature.float128)] = .{
193 .llvm_name = "float128",
194 .description = "Enable the __float128 data type for IEEE-754R Binary128.",
195 .dependencies = featureSet(&[_]Feature{
196 .vsx,
197 }),
198 };
199 result[@intFromEnum(Feature.fpcvt)] = .{
200 .llvm_name = "fpcvt",
201 .description = "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions",
202 .dependencies = featureSet(&[_]Feature{
203 .fpu,
204 }),
205 };
206 result[@intFromEnum(Feature.fprnd)] = .{
207 .llvm_name = "fprnd",
208 .description = "Enable the fri[mnpz] instructions",
209 .dependencies = featureSet(&[_]Feature{
210 .fpu,
211 }),
212 };
213 result[@intFromEnum(Feature.fpu)] = .{
214 .llvm_name = "fpu",
215 .description = "Enable classic FPU instructions",
216 .dependencies = featureSet(&[_]Feature{
217 .hard_float,
218 }),
219 };
220 result[@intFromEnum(Feature.fre)] = .{
221 .llvm_name = "fre",
222 .description = "Enable the fre instruction",
223 .dependencies = featureSet(&[_]Feature{
224 .fpu,
225 }),
226 };
227 result[@intFromEnum(Feature.fres)] = .{
228 .llvm_name = "fres",
229 .description = "Enable the fres instruction",
230 .dependencies = featureSet(&[_]Feature{
231 .fpu,
232 }),
233 };
234 result[@intFromEnum(Feature.frsqrte)] = .{
235 .llvm_name = "frsqrte",
236 .description = "Enable the frsqrte instruction",
237 .dependencies = featureSet(&[_]Feature{
238 .fpu,
239 }),
240 };
241 result[@intFromEnum(Feature.frsqrtes)] = .{
242 .llvm_name = "frsqrtes",
243 .description = "Enable the frsqrtes instruction",
244 .dependencies = featureSet(&[_]Feature{
245 .fpu,
246 }),
247 };
248 result[@intFromEnum(Feature.fsqrt)] = .{
249 .llvm_name = "fsqrt",
250 .description = "Enable the fsqrt instruction",
251 .dependencies = featureSet(&[_]Feature{
252 .fpu,
253 }),
254 };
255 result[@intFromEnum(Feature.fuse_add_logical)] = .{
256 .llvm_name = "fuse-add-logical",
257 .description = "Target supports Add with Logical Operations fusion",
258 .dependencies = featureSet(&[_]Feature{
259 .fusion,
260 }),
261 };
262 result[@intFromEnum(Feature.fuse_addi_load)] = .{
263 .llvm_name = "fuse-addi-load",
264 .description = "Power8 Addi-Load fusion",
265 .dependencies = featureSet(&[_]Feature{
266 .fusion,
267 }),
268 };
269 result[@intFromEnum(Feature.fuse_addis_load)] = .{
270 .llvm_name = "fuse-addis-load",
271 .description = "Power8 Addis-Load fusion",
272 .dependencies = featureSet(&[_]Feature{
273 .fusion,
274 }),
275 };
276 result[@intFromEnum(Feature.fuse_arith_add)] = .{
277 .llvm_name = "fuse-arith-add",
278 .description = "Target supports Arithmetic Operations with Add fusion",
279 .dependencies = featureSet(&[_]Feature{
280 .fusion,
281 }),
282 };
283 result[@intFromEnum(Feature.fuse_back2back)] = .{
284 .llvm_name = "fuse-back2back",
285 .description = "Target supports general back to back fusion",
286 .dependencies = featureSet(&[_]Feature{
287 .fusion,
288 }),
289 };
290 result[@intFromEnum(Feature.fuse_cmp)] = .{
291 .llvm_name = "fuse-cmp",
292 .description = "Target supports Comparison Operations fusion",
293 .dependencies = featureSet(&[_]Feature{
294 .fusion,
295 }),
296 };
297 result[@intFromEnum(Feature.fuse_logical)] = .{
298 .llvm_name = "fuse-logical",
299 .description = "Target supports Logical Operations fusion",
300 .dependencies = featureSet(&[_]Feature{
301 .fusion,
302 }),
303 };
304 result[@intFromEnum(Feature.fuse_logical_add)] = .{
305 .llvm_name = "fuse-logical-add",
306 .description = "Target supports Logical with Add Operations fusion",
307 .dependencies = featureSet(&[_]Feature{
308 .fusion,
309 }),
310 };
311 result[@intFromEnum(Feature.fuse_sha3)] = .{
312 .llvm_name = "fuse-sha3",
313 .description = "Target supports SHA3 assist fusion",
314 .dependencies = featureSet(&[_]Feature{
315 .fusion,
316 }),
317 };
318 result[@intFromEnum(Feature.fuse_store)] = .{
319 .llvm_name = "fuse-store",
320 .description = "Target supports store clustering",
321 .dependencies = featureSet(&[_]Feature{
322 .fusion,
323 }),
324 };
325 result[@intFromEnum(Feature.fuse_wideimm)] = .{
326 .llvm_name = "fuse-wideimm",
327 .description = "Target supports Wide-Immediate fusion",
328 .dependencies = featureSet(&[_]Feature{
329 .fusion,
330 }),
331 };
332 result[@intFromEnum(Feature.fuse_zeromove)] = .{
333 .llvm_name = "fuse-zeromove",
334 .description = "Target supports move to SPR with branch fusion",
335 .dependencies = featureSet(&[_]Feature{
336 .fusion,
337 }),
338 };
339 result[@intFromEnum(Feature.fusion)] = .{
340 .llvm_name = "fusion",
341 .description = "Target supports instruction fusion",
342 .dependencies = featureSet(&[_]Feature{}),
343 };
344 result[@intFromEnum(Feature.hard_float)] = .{
345 .llvm_name = "hard-float",
346 .description = "Enable floating-point instructions",
347 .dependencies = featureSet(&[_]Feature{}),
348 };
349 result[@intFromEnum(Feature.htm)] = .{
350 .llvm_name = "htm",
351 .description = "Enable Hardware Transactional Memory instructions",
352 .dependencies = featureSet(&[_]Feature{}),
353 };
354 result[@intFromEnum(Feature.icbt)] = .{
355 .llvm_name = "icbt",
356 .description = "Enable icbt instruction",
357 .dependencies = featureSet(&[_]Feature{}),
358 };
359 result[@intFromEnum(Feature.invariant_function_descriptors)] = .{
360 .llvm_name = "invariant-function-descriptors",
361 .description = "Assume function descriptors are invariant",
362 .dependencies = featureSet(&[_]Feature{}),
363 };
364 result[@intFromEnum(Feature.isa_future_instructions)] = .{
365 .llvm_name = "isa-future-instructions",
366 .description = "Enable instructions for Future ISA.",
367 .dependencies = featureSet(&[_]Feature{
368 .isa_v31_instructions,
369 }),
370 };
371 result[@intFromEnum(Feature.isa_v206_instructions)] = .{
372 .llvm_name = "isa-v206-instructions",
373 .description = "Enable instructions in ISA 2.06.",
374 .dependencies = featureSet(&[_]Feature{}),
375 };
376 result[@intFromEnum(Feature.isa_v207_instructions)] = .{
377 .llvm_name = "isa-v207-instructions",
378 .description = "Enable instructions in ISA 2.07.",
379 .dependencies = featureSet(&[_]Feature{}),
380 };
381 result[@intFromEnum(Feature.isa_v30_instructions)] = .{
382 .llvm_name = "isa-v30-instructions",
383 .description = "Enable instructions in ISA 3.0.",
384 .dependencies = featureSet(&[_]Feature{
385 .isa_v207_instructions,
386 }),
387 };
388 result[@intFromEnum(Feature.isa_v31_instructions)] = .{
389 .llvm_name = "isa-v31-instructions",
390 .description = "Enable instructions in ISA 3.1.",
391 .dependencies = featureSet(&[_]Feature{
392 .isa_v30_instructions,
393 }),
394 };
395 result[@intFromEnum(Feature.isel)] = .{
396 .llvm_name = "isel",
397 .description = "Enable the isel instruction",
398 .dependencies = featureSet(&[_]Feature{}),
399 };
400 result[@intFromEnum(Feature.ldbrx)] = .{
401 .llvm_name = "ldbrx",
402 .description = "Enable the ldbrx instruction",
403 .dependencies = featureSet(&[_]Feature{}),
404 };
405 result[@intFromEnum(Feature.lfiwax)] = .{
406 .llvm_name = "lfiwax",
407 .description = "Enable the lfiwax instruction",
408 .dependencies = featureSet(&[_]Feature{
409 .fpu,
410 }),
411 };
412 result[@intFromEnum(Feature.longcall)] = .{
413 .llvm_name = "longcall",
414 .description = "Always use indirect calls",
415 .dependencies = featureSet(&[_]Feature{}),
416 };
417 result[@intFromEnum(Feature.mfocrf)] = .{
418 .llvm_name = "mfocrf",
419 .description = "Enable the MFOCRF instruction",
420 .dependencies = featureSet(&[_]Feature{}),
421 };
422 result[@intFromEnum(Feature.mma)] = .{
423 .llvm_name = "mma",
424 .description = "Enable MMA instructions",
425 .dependencies = featureSet(&[_]Feature{
426 .paired_vector_memops,
427 .power8_vector,
428 .power9_altivec,
429 }),
430 };
431 result[@intFromEnum(Feature.modern_aix_as)] = .{
432 .llvm_name = "modern-aix-as",
433 .description = "AIX system assembler is modern enough to support new mnes",
434 .dependencies = featureSet(&[_]Feature{}),
435 };
436 result[@intFromEnum(Feature.msync)] = .{
437 .llvm_name = "msync",
438 .description = "Has only the msync instruction instead of sync",
439 .dependencies = featureSet(&[_]Feature{
440 .booke,
441 }),
442 };
443 result[@intFromEnum(Feature.paired_vector_memops)] = .{
444 .llvm_name = "paired-vector-memops",
445 .description = "32Byte load and store instructions",
446 .dependencies = featureSet(&[_]Feature{
447 .isa_v30_instructions,
448 }),
449 };
450 result[@intFromEnum(Feature.partword_atomics)] = .{
451 .llvm_name = "partword-atomics",
452 .description = "Enable l[bh]arx and st[bh]cx.",
453 .dependencies = featureSet(&[_]Feature{}),
454 };
455 result[@intFromEnum(Feature.pcrelative_memops)] = .{
456 .llvm_name = "pcrelative-memops",
457 .description = "Enable PC relative Memory Ops",
458 .dependencies = featureSet(&[_]Feature{
459 .prefix_instrs,
460 }),
461 };
462 result[@intFromEnum(Feature.popcntd)] = .{
463 .llvm_name = "popcntd",
464 .description = "Enable the popcnt[dw] instructions",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@intFromEnum(Feature.power10_vector)] = .{
468 .llvm_name = "power10-vector",
469 .description = "Enable POWER10 vector instructions",
470 .dependencies = featureSet(&[_]Feature{
471 .isa_v31_instructions,
472 .power9_vector,
473 }),
474 };
475 result[@intFromEnum(Feature.power8_altivec)] = .{
476 .llvm_name = "power8-altivec",
477 .description = "Enable POWER8 Altivec instructions",
478 .dependencies = featureSet(&[_]Feature{
479 .altivec,
480 }),
481 };
482 result[@intFromEnum(Feature.power8_vector)] = .{
483 .llvm_name = "power8-vector",
484 .description = "Enable POWER8 vector instructions",
485 .dependencies = featureSet(&[_]Feature{
486 .power8_altivec,
487 .vsx,
488 }),
489 };
490 result[@intFromEnum(Feature.power9_altivec)] = .{
491 .llvm_name = "power9-altivec",
492 .description = "Enable POWER9 Altivec instructions",
493 .dependencies = featureSet(&[_]Feature{
494 .isa_v30_instructions,
495 .power8_altivec,
496 }),
497 };
498 result[@intFromEnum(Feature.power9_vector)] = .{
499 .llvm_name = "power9-vector",
500 .description = "Enable POWER9 vector instructions",
501 .dependencies = featureSet(&[_]Feature{
502 .power8_vector,
503 .power9_altivec,
504 }),
505 };
506 result[@intFromEnum(Feature.ppc4xx)] = .{
507 .llvm_name = "ppc4xx",
508 .description = "Enable PPC 4xx instructions",
509 .dependencies = featureSet(&[_]Feature{}),
510 };
511 result[@intFromEnum(Feature.ppc6xx)] = .{
512 .llvm_name = "ppc6xx",
513 .description = "Enable PPC 6xx instructions",
514 .dependencies = featureSet(&[_]Feature{}),
515 };
516 result[@intFromEnum(Feature.ppc_postra_sched)] = .{
517 .llvm_name = "ppc-postra-sched",
518 .description = "Use PowerPC post-RA scheduling strategy",
519 .dependencies = featureSet(&[_]Feature{}),
520 };
521 result[@intFromEnum(Feature.ppc_prera_sched)] = .{
522 .llvm_name = "ppc-prera-sched",
523 .description = "Use PowerPC pre-RA scheduling strategy",
524 .dependencies = featureSet(&[_]Feature{}),
525 };
526 result[@intFromEnum(Feature.predictable_select_expensive)] = .{
527 .llvm_name = "predictable-select-expensive",
528 .description = "Prefer likely predicted branches over selects",
529 .dependencies = featureSet(&[_]Feature{}),
530 };
531 result[@intFromEnum(Feature.prefix_instrs)] = .{
532 .llvm_name = "prefix-instrs",
533 .description = "Enable prefixed instructions",
534 .dependencies = featureSet(&[_]Feature{
535 .power8_vector,
536 .power9_altivec,
537 }),
538 };
539 result[@intFromEnum(Feature.privileged)] = .{
540 .llvm_name = "privileged",
541 .description = "Add privileged instructions",
542 .dependencies = featureSet(&[_]Feature{}),
543 };
544 result[@intFromEnum(Feature.quadword_atomics)] = .{
545 .llvm_name = "quadword-atomics",
546 .description = "Enable lqarx and stqcx.",
547 .dependencies = featureSet(&[_]Feature{}),
548 };
549 result[@intFromEnum(Feature.recipprec)] = .{
550 .llvm_name = "recipprec",
551 .description = "Assume higher precision reciprocal estimates",
552 .dependencies = featureSet(&[_]Feature{}),
553 };
554 result[@intFromEnum(Feature.rop_protect)] = .{
555 .llvm_name = "rop-protect",
556 .description = "Add ROP protect",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
559 result[@intFromEnum(Feature.secure_plt)] = .{
560 .llvm_name = "secure-plt",
561 .description = "Enable secure plt mode",
562 .dependencies = featureSet(&[_]Feature{}),
563 };
564 result[@intFromEnum(Feature.slow_popcntd)] = .{
565 .llvm_name = "slow-popcntd",
566 .description = "Has slow popcnt[dw] instructions",
567 .dependencies = featureSet(&[_]Feature{}),
568 };
569 result[@intFromEnum(Feature.spe)] = .{
570 .llvm_name = "spe",
571 .description = "Enable SPE instructions",
572 .dependencies = featureSet(&[_]Feature{
573 .hard_float,
574 }),
575 };
576 result[@intFromEnum(Feature.stfiwx)] = .{
577 .llvm_name = "stfiwx",
578 .description = "Enable the stfiwx instruction",
579 .dependencies = featureSet(&[_]Feature{
580 .fpu,
581 }),
582 };
583 result[@intFromEnum(Feature.two_const_nr)] = .{
584 .llvm_name = "two-const-nr",
585 .description = "Requires two constant Newton-Raphson computation",
586 .dependencies = featureSet(&[_]Feature{}),
587 };
588 result[@intFromEnum(Feature.vectors_use_two_units)] = .{
589 .llvm_name = "vectors-use-two-units",
590 .description = "Vectors use two units",
591 .dependencies = featureSet(&[_]Feature{}),
592 };
593 result[@intFromEnum(Feature.vsx)] = .{
594 .llvm_name = "vsx",
595 .description = "Enable VSX instructions",
596 .dependencies = featureSet(&[_]Feature{
597 .altivec,
598 }),
599 };
600 const ti = @typeInfo(Feature);
601 for (&result, 0..) |*elem, i| {
602 elem.index = i;
603 elem.name = ti.Enum.fields[i].name;
604 }
605 break :blk result;
606};
607
608pub const cpu = struct {
609 pub const @"440" = CpuModel{
610 .name = "440",
611 .llvm_name = "440",
612 .features = featureSet(&[_]Feature{
613 .fres,
614 .frsqrte,
615 .isel,
616 .msync,
617 }),
618 };
619 pub const @"450" = CpuModel{
620 .name = "450",
621 .llvm_name = "450",
622 .features = featureSet(&[_]Feature{
623 .fres,
624 .frsqrte,
625 .isel,
626 .msync,
627 }),
628 };
629 pub const @"601" = CpuModel{
630 .name = "601",
631 .llvm_name = "601",
632 .features = featureSet(&[_]Feature{
633 .fpu,
634 }),
635 };
636 pub const @"602" = CpuModel{
637 .name = "602",
638 .llvm_name = "602",
639 .features = featureSet(&[_]Feature{
640 .fpu,
641 }),
642 };
643 pub const @"603" = CpuModel{
644 .name = "603",
645 .llvm_name = "603",
646 .features = featureSet(&[_]Feature{
647 .fres,
648 .frsqrte,
649 }),
650 };
651 pub const @"603e" = CpuModel{
652 .name = "603e",
653 .llvm_name = "603e",
654 .features = featureSet(&[_]Feature{
655 .fres,
656 .frsqrte,
657 }),
658 };
659 pub const @"603ev" = CpuModel{
660 .name = "603ev",
661 .llvm_name = "603ev",
662 .features = featureSet(&[_]Feature{
663 .fres,
664 .frsqrte,
665 }),
666 };
667 pub const @"604" = CpuModel{
668 .name = "604",
669 .llvm_name = "604",
670 .features = featureSet(&[_]Feature{
671 .fres,
672 .frsqrte,
673 }),
674 };
675 pub const @"604e" = CpuModel{
676 .name = "604e",
677 .llvm_name = "604e",
678 .features = featureSet(&[_]Feature{
679 .fres,
680 .frsqrte,
681 }),
682 };
683 pub const @"620" = CpuModel{
684 .name = "620",
685 .llvm_name = "620",
686 .features = featureSet(&[_]Feature{
687 .fres,
688 .frsqrte,
689 }),
690 };
691 pub const @"7400" = CpuModel{
692 .name = "7400",
693 .llvm_name = "7400",
694 .features = featureSet(&[_]Feature{
695 .altivec,
696 .fres,
697 .frsqrte,
698 }),
699 };
700 pub const @"7450" = CpuModel{
701 .name = "7450",
702 .llvm_name = "7450",
703 .features = featureSet(&[_]Feature{
704 .altivec,
705 .fres,
706 .frsqrte,
707 }),
708 };
709 pub const @"750" = CpuModel{
710 .name = "750",
711 .llvm_name = "750",
712 .features = featureSet(&[_]Feature{
713 .fres,
714 .frsqrte,
715 }),
716 };
717 pub const @"970" = CpuModel{
718 .name = "970",
719 .llvm_name = "970",
720 .features = featureSet(&[_]Feature{
721 .@"64bit",
722 .altivec,
723 .fres,
724 .frsqrte,
725 .fsqrt,
726 .mfocrf,
727 .stfiwx,
728 }),
729 };
730 pub const a2 = CpuModel{
731 .name = "a2",
732 .llvm_name = "a2",
733 .features = featureSet(&[_]Feature{
734 .@"64bit",
735 .booke,
736 .cmpb,
737 .fcpsgn,
738 .fpcvt,
739 .fprnd,
740 .fre,
741 .fres,
742 .frsqrte,
743 .frsqrtes,
744 .fsqrt,
745 .isa_v206_instructions,
746 .isel,
747 .ldbrx,
748 .lfiwax,
749 .mfocrf,
750 .recipprec,
751 .slow_popcntd,
752 .stfiwx,
753 }),
754 };
755 pub const e500 = CpuModel{
756 .name = "e500",
757 .llvm_name = "e500",
758 .features = featureSet(&[_]Feature{
759 .isel,
760 .msync,
761 .spe,
762 }),
763 };
764 pub const e500mc = CpuModel{
765 .name = "e500mc",
766 .llvm_name = "e500mc",
767 .features = featureSet(&[_]Feature{
768 .booke,
769 .isel,
770 .stfiwx,
771 }),
772 };
773 pub const e5500 = CpuModel{
774 .name = "e5500",
775 .llvm_name = "e5500",
776 .features = featureSet(&[_]Feature{
777 .@"64bit",
778 .booke,
779 .isel,
780 .mfocrf,
781 .stfiwx,
782 }),
783 };
784 pub const future = CpuModel{
785 .name = "future",
786 .llvm_name = "future",
787 .features = featureSet(&[_]Feature{
788 .@"64bit",
789 .allow_unaligned_fp_access,
790 .bpermd,
791 .cmpb,
792 .crbits,
793 .crypto,
794 .direct_move,
795 .extdiv,
796 .fast_MFLR,
797 .fcpsgn,
798 .fpcvt,
799 .fprnd,
800 .fre,
801 .fres,
802 .frsqrte,
803 .frsqrtes,
804 .fsqrt,
805 .fuse_add_logical,
806 .fuse_arith_add,
807 .fuse_logical,
808 .fuse_logical_add,
809 .fuse_sha3,
810 .fuse_store,
811 .htm,
812 .icbt,
813 .isa_future_instructions,
814 .isa_v206_instructions,
815 .isel,
816 .ldbrx,
817 .lfiwax,
818 .mfocrf,
819 .mma,
820 .partword_atomics,
821 .pcrelative_memops,
822 .popcntd,
823 .power10_vector,
824 .ppc_postra_sched,
825 .ppc_prera_sched,
826 .predictable_select_expensive,
827 .quadword_atomics,
828 .recipprec,
829 .stfiwx,
830 .two_const_nr,
831 }),
832 };
833 pub const g3 = CpuModel{
834 .name = "g3",
835 .llvm_name = "g3",
836 .features = featureSet(&[_]Feature{
837 .fres,
838 .frsqrte,
839 }),
840 };
841 pub const g4 = CpuModel{
842 .name = "g4",
843 .llvm_name = "g4",
844 .features = featureSet(&[_]Feature{
845 .altivec,
846 .fres,
847 .frsqrte,
848 }),
849 };
850 pub const @"g4+" = CpuModel{
851 .name = "g4+",
852 .llvm_name = "g4+",
853 .features = featureSet(&[_]Feature{
854 .altivec,
855 .fres,
856 .frsqrte,
857 }),
858 };
859 pub const g5 = CpuModel{
860 .name = "g5",
861 .llvm_name = "g5",
862 .features = featureSet(&[_]Feature{
863 .@"64bit",
864 .altivec,
865 .fres,
866 .frsqrte,
867 .fsqrt,
868 .mfocrf,
869 .stfiwx,
870 }),
871 };
872 pub const generic = CpuModel{
873 .name = "generic",
874 .llvm_name = "generic",
875 .features = featureSet(&[_]Feature{
876 .hard_float,
877 }),
878 };
879 pub const ppc = CpuModel{
880 .name = "ppc",
881 .llvm_name = "ppc",
882 .features = featureSet(&[_]Feature{
883 .hard_float,
884 }),
885 };
886 pub const ppc64 = CpuModel{
887 .name = "ppc64",
888 .llvm_name = "ppc64",
889 .features = featureSet(&[_]Feature{
890 .@"64bit",
891 .altivec,
892 .fres,
893 .frsqrte,
894 .fsqrt,
895 .mfocrf,
896 .stfiwx,
897 }),
898 };
899 pub const ppc64le = CpuModel{
900 .name = "ppc64le",
901 .llvm_name = "ppc64le",
902 .features = featureSet(&[_]Feature{
903 .@"64bit",
904 .allow_unaligned_fp_access,
905 .bpermd,
906 .cmpb,
907 .crbits,
908 .crypto,
909 .direct_move,
910 .extdiv,
911 .fcpsgn,
912 .fpcvt,
913 .fprnd,
914 .fre,
915 .fres,
916 .frsqrte,
917 .frsqrtes,
918 .fsqrt,
919 .fuse_addi_load,
920 .fuse_addis_load,
921 .htm,
922 .icbt,
923 .isa_v206_instructions,
924 .isa_v207_instructions,
925 .isel,
926 .ldbrx,
927 .lfiwax,
928 .mfocrf,
929 .partword_atomics,
930 .popcntd,
931 .power8_vector,
932 .predictable_select_expensive,
933 .quadword_atomics,
934 .recipprec,
935 .stfiwx,
936 .two_const_nr,
937 }),
938 };
939 pub const pwr10 = CpuModel{
940 .name = "pwr10",
941 .llvm_name = "pwr10",
942 .features = featureSet(&[_]Feature{
943 .@"64bit",
944 .allow_unaligned_fp_access,
945 .bpermd,
946 .cmpb,
947 .crbits,
948 .crypto,
949 .direct_move,
950 .extdiv,
951 .fast_MFLR,
952 .fcpsgn,
953 .fpcvt,
954 .fprnd,
955 .fre,
956 .fres,
957 .frsqrte,
958 .frsqrtes,
959 .fsqrt,
960 .fuse_add_logical,
961 .fuse_arith_add,
962 .fuse_logical,
963 .fuse_logical_add,
964 .fuse_sha3,
965 .fuse_store,
966 .htm,
967 .icbt,
968 .isa_v206_instructions,
969 .isel,
970 .ldbrx,
971 .lfiwax,
972 .mfocrf,
973 .mma,
974 .partword_atomics,
975 .pcrelative_memops,
976 .popcntd,
977 .power10_vector,
978 .ppc_postra_sched,
979 .ppc_prera_sched,
980 .predictable_select_expensive,
981 .quadword_atomics,
982 .recipprec,
983 .stfiwx,
984 .two_const_nr,
985 }),
986 };
987 pub const pwr3 = CpuModel{
988 .name = "pwr3",
989 .llvm_name = "pwr3",
990 .features = featureSet(&[_]Feature{
991 .@"64bit",
992 .altivec,
993 .fres,
994 .frsqrte,
995 .mfocrf,
996 .stfiwx,
997 }),
998 };
999 pub const pwr4 = CpuModel{
1000 .name = "pwr4",
1001 .llvm_name = "pwr4",
1002 .features = featureSet(&[_]Feature{
1003 .@"64bit",
1004 .altivec,
1005 .fres,
1006 .frsqrte,
1007 .fsqrt,
1008 .mfocrf,
1009 .stfiwx,
1010 }),
1011 };
1012 pub const pwr5 = CpuModel{
1013 .name = "pwr5",
1014 .llvm_name = "pwr5",
1015 .features = featureSet(&[_]Feature{
1016 .@"64bit",
1017 .altivec,
1018 .fre,
1019 .fres,
1020 .frsqrte,
1021 .frsqrtes,
1022 .fsqrt,
1023 .mfocrf,
1024 .stfiwx,
1025 }),
1026 };
1027 pub const pwr5x = CpuModel{
1028 .name = "pwr5x",
1029 .llvm_name = "pwr5x",
1030 .features = featureSet(&[_]Feature{
1031 .@"64bit",
1032 .altivec,
1033 .fprnd,
1034 .fre,
1035 .fres,
1036 .frsqrte,
1037 .frsqrtes,
1038 .fsqrt,
1039 .mfocrf,
1040 .stfiwx,
1041 }),
1042 };
1043 pub const pwr6 = CpuModel{
1044 .name = "pwr6",
1045 .llvm_name = "pwr6",
1046 .features = featureSet(&[_]Feature{
1047 .@"64bit",
1048 .altivec,
1049 .cmpb,
1050 .fcpsgn,
1051 .fprnd,
1052 .fre,
1053 .fres,
1054 .frsqrte,
1055 .frsqrtes,
1056 .fsqrt,
1057 .lfiwax,
1058 .mfocrf,
1059 .recipprec,
1060 .stfiwx,
1061 }),
1062 };
1063 pub const pwr6x = CpuModel{
1064 .name = "pwr6x",
1065 .llvm_name = "pwr6x",
1066 .features = featureSet(&[_]Feature{
1067 .@"64bit",
1068 .altivec,
1069 .cmpb,
1070 .fcpsgn,
1071 .fprnd,
1072 .fre,
1073 .fres,
1074 .frsqrte,
1075 .frsqrtes,
1076 .fsqrt,
1077 .lfiwax,
1078 .mfocrf,
1079 .recipprec,
1080 .stfiwx,
1081 }),
1082 };
1083 pub const pwr7 = CpuModel{
1084 .name = "pwr7",
1085 .llvm_name = "pwr7",
1086 .features = featureSet(&[_]Feature{
1087 .@"64bit",
1088 .allow_unaligned_fp_access,
1089 .bpermd,
1090 .cmpb,
1091 .extdiv,
1092 .fcpsgn,
1093 .fpcvt,
1094 .fprnd,
1095 .fre,
1096 .fres,
1097 .frsqrte,
1098 .frsqrtes,
1099 .fsqrt,
1100 .isa_v206_instructions,
1101 .isel,
1102 .ldbrx,
1103 .lfiwax,
1104 .mfocrf,
1105 .popcntd,
1106 .recipprec,
1107 .stfiwx,
1108 .two_const_nr,
1109 .vsx,
1110 }),
1111 };
1112 pub const pwr8 = CpuModel{
1113 .name = "pwr8",
1114 .llvm_name = "pwr8",
1115 .features = featureSet(&[_]Feature{
1116 .@"64bit",
1117 .allow_unaligned_fp_access,
1118 .bpermd,
1119 .cmpb,
1120 .crbits,
1121 .crypto,
1122 .direct_move,
1123 .extdiv,
1124 .fcpsgn,
1125 .fpcvt,
1126 .fprnd,
1127 .fre,
1128 .fres,
1129 .frsqrte,
1130 .frsqrtes,
1131 .fsqrt,
1132 .fuse_addi_load,
1133 .fuse_addis_load,
1134 .htm,
1135 .icbt,
1136 .isa_v206_instructions,
1137 .isa_v207_instructions,
1138 .isel,
1139 .ldbrx,
1140 .lfiwax,
1141 .mfocrf,
1142 .partword_atomics,
1143 .popcntd,
1144 .power8_vector,
1145 .predictable_select_expensive,
1146 .quadword_atomics,
1147 .recipprec,
1148 .stfiwx,
1149 .two_const_nr,
1150 }),
1151 };
1152 pub const pwr9 = CpuModel{
1153 .name = "pwr9",
1154 .llvm_name = "pwr9",
1155 .features = featureSet(&[_]Feature{
1156 .@"64bit",
1157 .allow_unaligned_fp_access,
1158 .bpermd,
1159 .cmpb,
1160 .crbits,
1161 .crypto,
1162 .direct_move,
1163 .extdiv,
1164 .fcpsgn,
1165 .fpcvt,
1166 .fprnd,
1167 .fre,
1168 .fres,
1169 .frsqrte,
1170 .frsqrtes,
1171 .fsqrt,
1172 .htm,
1173 .icbt,
1174 .isa_v206_instructions,
1175 .isel,
1176 .ldbrx,
1177 .lfiwax,
1178 .mfocrf,
1179 .partword_atomics,
1180 .popcntd,
1181 .power9_vector,
1182 .ppc_postra_sched,
1183 .ppc_prera_sched,
1184 .predictable_select_expensive,
1185 .quadword_atomics,
1186 .recipprec,
1187 .stfiwx,
1188 .two_const_nr,
1189 .vectors_use_two_units,
1190 }),
1191 };
1192};
lib/std/Target/riscv.zig created+1341
......@@ -0,0 +1,1341 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"32bit",
9 @"64bit",
10 a,
11 c,
12 d,
13 dlen_factor_2,
14 e,
15 experimental_smaia,
16 experimental_ssaia,
17 experimental_zacas,
18 experimental_zfa,
19 experimental_zfbfmin,
20 experimental_zicond,
21 experimental_zihintntl,
22 experimental_ztso,
23 experimental_zvbb,
24 experimental_zvbc,
25 experimental_zvfbfmin,
26 experimental_zvfbfwma,
27 experimental_zvkg,
28 experimental_zvkn,
29 experimental_zvknc,
30 experimental_zvkned,
31 experimental_zvkng,
32 experimental_zvknha,
33 experimental_zvknhb,
34 experimental_zvks,
35 experimental_zvksc,
36 experimental_zvksed,
37 experimental_zvksg,
38 experimental_zvksh,
39 experimental_zvkt,
40 f,
41 forced_atomics,
42 h,
43 lui_addi_fusion,
44 m,
45 no_default_unroll,
46 no_optimized_zero_stride_load,
47 no_rvc_hints,
48 relax,
49 reserve_x1,
50 reserve_x10,
51 reserve_x11,
52 reserve_x12,
53 reserve_x13,
54 reserve_x14,
55 reserve_x15,
56 reserve_x16,
57 reserve_x17,
58 reserve_x18,
59 reserve_x19,
60 reserve_x2,
61 reserve_x20,
62 reserve_x21,
63 reserve_x22,
64 reserve_x23,
65 reserve_x24,
66 reserve_x25,
67 reserve_x26,
68 reserve_x27,
69 reserve_x28,
70 reserve_x29,
71 reserve_x3,
72 reserve_x30,
73 reserve_x31,
74 reserve_x4,
75 reserve_x5,
76 reserve_x6,
77 reserve_x7,
78 reserve_x8,
79 reserve_x9,
80 save_restore,
81 seq_cst_trailing_fence,
82 short_forward_branch_opt,
83 svinval,
84 svnapot,
85 svpbmt,
86 tagged_globals,
87 unaligned_scalar_mem,
88 unaligned_vector_mem,
89 v,
90 xcvbitmanip,
91 xcvmac,
92 xsfcie,
93 xsfvcp,
94 xtheadba,
95 xtheadbb,
96 xtheadbs,
97 xtheadcmo,
98 xtheadcondmov,
99 xtheadfmemidx,
100 xtheadmac,
101 xtheadmemidx,
102 xtheadmempair,
103 xtheadsync,
104 xtheadvdot,
105 xventanacondops,
106 zawrs,
107 zba,
108 zbb,
109 zbc,
110 zbkb,
111 zbkc,
112 zbkx,
113 zbs,
114 zca,
115 zcb,
116 zcd,
117 zce,
118 zcf,
119 zcmp,
120 zcmt,
121 zdinx,
122 zfh,
123 zfhmin,
124 zfinx,
125 zhinx,
126 zhinxmin,
127 zicbom,
128 zicbop,
129 zicboz,
130 zicntr,
131 zicsr,
132 zifencei,
133 zihintpause,
134 zihpm,
135 zk,
136 zkn,
137 zknd,
138 zkne,
139 zknh,
140 zkr,
141 zks,
142 zksed,
143 zksh,
144 zkt,
145 zmmul,
146 zve32f,
147 zve32x,
148 zve64d,
149 zve64f,
150 zve64x,
151 zvfh,
152 zvl1024b,
153 zvl128b,
154 zvl16384b,
155 zvl2048b,
156 zvl256b,
157 zvl32768b,
158 zvl32b,
159 zvl4096b,
160 zvl512b,
161 zvl64b,
162 zvl65536b,
163 zvl8192b,
164};
165
166pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
167pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
168pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
169pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
170
171pub const all_features = blk: {
172 const len = @typeInfo(Feature).Enum.fields.len;
173 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
174 var result: [len]CpuFeature = undefined;
175 result[@intFromEnum(Feature.@"32bit")] = .{
176 .llvm_name = "32bit",
177 .description = "Implements RV32",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.@"64bit")] = .{
181 .llvm_name = "64bit",
182 .description = "Implements RV64",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.a)] = .{
186 .llvm_name = "a",
187 .description = "'A' (Atomic Instructions)",
188 .dependencies = featureSet(&[_]Feature{}),
189 };
190 result[@intFromEnum(Feature.c)] = .{
191 .llvm_name = "c",
192 .description = "'C' (Compressed Instructions)",
193 .dependencies = featureSet(&[_]Feature{}),
194 };
195 result[@intFromEnum(Feature.d)] = .{
196 .llvm_name = "d",
197 .description = "'D' (Double-Precision Floating-Point)",
198 .dependencies = featureSet(&[_]Feature{
199 .f,
200 }),
201 };
202 result[@intFromEnum(Feature.dlen_factor_2)] = .{
203 .llvm_name = "dlen-factor-2",
204 .description = "Vector unit DLEN(data path width) is half of VLEN",
205 .dependencies = featureSet(&[_]Feature{}),
206 };
207 result[@intFromEnum(Feature.e)] = .{
208 .llvm_name = "e",
209 .description = "Implements RV{32,64}E (provides 16 rather than 32 GPRs)",
210 .dependencies = featureSet(&[_]Feature{}),
211 };
212 result[@intFromEnum(Feature.experimental_smaia)] = .{
213 .llvm_name = "experimental-smaia",
214 .description = "'Smaia' (Smaia encompasses all added CSRs and all modifications to interrupt response behavior that the AIA specifies for a hart, over all privilege levels.)",
215 .dependencies = featureSet(&[_]Feature{}),
216 };
217 result[@intFromEnum(Feature.experimental_ssaia)] = .{
218 .llvm_name = "experimental-ssaia",
219 .description = "'Ssaia' (Ssaia is essentially the same as Smaia except excluding the machine-level CSRs and behavior not directly visible to supervisor level.)",
220 .dependencies = featureSet(&[_]Feature{}),
221 };
222 result[@intFromEnum(Feature.experimental_zacas)] = .{
223 .llvm_name = "experimental-zacas",
224 .description = "'Zacas' (Atomic Compare-And-Swap Instructions)",
225 .dependencies = featureSet(&[_]Feature{}),
226 };
227 result[@intFromEnum(Feature.experimental_zfa)] = .{
228 .llvm_name = "experimental-zfa",
229 .description = "'Zfa' (Additional Floating-Point)",
230 .dependencies = featureSet(&[_]Feature{
231 .f,
232 }),
233 };
234 result[@intFromEnum(Feature.experimental_zfbfmin)] = .{
235 .llvm_name = "experimental-zfbfmin",
236 .description = "'Zfbfmin' (Scalar BF16 Converts)",
237 .dependencies = featureSet(&[_]Feature{
238 .f,
239 }),
240 };
241 result[@intFromEnum(Feature.experimental_zicond)] = .{
242 .llvm_name = "experimental-zicond",
243 .description = "'Zicond' (Integer Conditional Operations)",
244 .dependencies = featureSet(&[_]Feature{}),
245 };
246 result[@intFromEnum(Feature.experimental_zihintntl)] = .{
247 .llvm_name = "experimental-zihintntl",
248 .description = "'Zihintntl' (Non-Temporal Locality Hints)",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.experimental_ztso)] = .{
252 .llvm_name = "experimental-ztso",
253 .description = "'Ztso' (Memory Model - Total Store Order)",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.experimental_zvbb)] = .{
257 .llvm_name = "experimental-zvbb",
258 .description = "'Zvbb' (Vector Bit-manipulation used in Cryptography)",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.experimental_zvbc)] = .{
262 .llvm_name = "experimental-zvbc",
263 .description = "'Zvbc' (Vector Carryless Multiplication)",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.experimental_zvfbfmin)] = .{
267 .llvm_name = "experimental-zvfbfmin",
268 .description = "'Zvbfmin' (Vector BF16 Converts)",
269 .dependencies = featureSet(&[_]Feature{
270 .zve32f,
271 }),
272 };
273 result[@intFromEnum(Feature.experimental_zvfbfwma)] = .{
274 .llvm_name = "experimental-zvfbfwma",
275 .description = "'Zvfbfwma' (Vector BF16 widening mul-add)",
276 .dependencies = featureSet(&[_]Feature{
277 .zve32f,
278 }),
279 };
280 result[@intFromEnum(Feature.experimental_zvkg)] = .{
281 .llvm_name = "experimental-zvkg",
282 .description = "'Zvkg' (Vector GCM instructions for Cryptography)",
283 .dependencies = featureSet(&[_]Feature{}),
284 };
285 result[@intFromEnum(Feature.experimental_zvkn)] = .{
286 .llvm_name = "experimental-zvkn",
287 .description = "This extension is shorthand for the following set of other extensions: Zvkned, Zvknhb, Zvbb, Zvbc, and Zvkt.",
288 .dependencies = featureSet(&[_]Feature{}),
289 };
290 result[@intFromEnum(Feature.experimental_zvknc)] = .{
291 .llvm_name = "experimental-zvknc",
292 .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvbc.",
293 .dependencies = featureSet(&[_]Feature{}),
294 };
295 result[@intFromEnum(Feature.experimental_zvkned)] = .{
296 .llvm_name = "experimental-zvkned",
297 .description = "'Zvkned' (Vector AES Encryption & Decryption (Single Round))",
298 .dependencies = featureSet(&[_]Feature{}),
299 };
300 result[@intFromEnum(Feature.experimental_zvkng)] = .{
301 .llvm_name = "experimental-zvkng",
302 .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvkg.",
303 .dependencies = featureSet(&[_]Feature{}),
304 };
305 result[@intFromEnum(Feature.experimental_zvknha)] = .{
306 .llvm_name = "experimental-zvknha",
307 .description = "'Zvknha' (Vector SHA-2 (SHA-256 only))",
308 .dependencies = featureSet(&[_]Feature{}),
309 };
310 result[@intFromEnum(Feature.experimental_zvknhb)] = .{
311 .llvm_name = "experimental-zvknhb",
312 .description = "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))",
313 .dependencies = featureSet(&[_]Feature{
314 .experimental_zvknha,
315 }),
316 };
317 result[@intFromEnum(Feature.experimental_zvks)] = .{
318 .llvm_name = "experimental-zvks",
319 .description = "This extension is shorthand for the following set of other extensions: Zvksed, Zvksh, Zvbb, Zvbc, and Zvkt.",
320 .dependencies = featureSet(&[_]Feature{}),
321 };
322 result[@intFromEnum(Feature.experimental_zvksc)] = .{
323 .llvm_name = "experimental-zvksc",
324 .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvbc.",
325 .dependencies = featureSet(&[_]Feature{}),
326 };
327 result[@intFromEnum(Feature.experimental_zvksed)] = .{
328 .llvm_name = "experimental-zvksed",
329 .description = "'Zvksed' (SM4 Block Cipher Instructions)",
330 .dependencies = featureSet(&[_]Feature{}),
331 };
332 result[@intFromEnum(Feature.experimental_zvksg)] = .{
333 .llvm_name = "experimental-zvksg",
334 .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvkg.",
335 .dependencies = featureSet(&[_]Feature{}),
336 };
337 result[@intFromEnum(Feature.experimental_zvksh)] = .{
338 .llvm_name = "experimental-zvksh",
339 .description = "'Zvksh' (SM3 Hash Function Instructions)",
340 .dependencies = featureSet(&[_]Feature{}),
341 };
342 result[@intFromEnum(Feature.experimental_zvkt)] = .{
343 .llvm_name = "experimental-zvkt",
344 .description = "'Zvkt' (Vector Data-Independent Execution Latency)",
345 .dependencies = featureSet(&[_]Feature{}),
346 };
347 result[@intFromEnum(Feature.f)] = .{
348 .llvm_name = "f",
349 .description = "'F' (Single-Precision Floating-Point)",
350 .dependencies = featureSet(&[_]Feature{
351 .zicsr,
352 }),
353 };
354 result[@intFromEnum(Feature.forced_atomics)] = .{
355 .llvm_name = "forced-atomics",
356 .description = "Assume that lock-free native-width atomics are available",
357 .dependencies = featureSet(&[_]Feature{}),
358 };
359 result[@intFromEnum(Feature.h)] = .{
360 .llvm_name = "h",
361 .description = "'H' (Hypervisor)",
362 .dependencies = featureSet(&[_]Feature{}),
363 };
364 result[@intFromEnum(Feature.lui_addi_fusion)] = .{
365 .llvm_name = "lui-addi-fusion",
366 .description = "Enable LUI+ADDI macrofusion",
367 .dependencies = featureSet(&[_]Feature{}),
368 };
369 result[@intFromEnum(Feature.m)] = .{
370 .llvm_name = "m",
371 .description = "'M' (Integer Multiplication and Division)",
372 .dependencies = featureSet(&[_]Feature{}),
373 };
374 result[@intFromEnum(Feature.no_default_unroll)] = .{
375 .llvm_name = "no-default-unroll",
376 .description = "Disable default unroll preference.",
377 .dependencies = featureSet(&[_]Feature{}),
378 };
379 result[@intFromEnum(Feature.no_optimized_zero_stride_load)] = .{
380 .llvm_name = "no-optimized-zero-stride-load",
381 .description = "Hasn't optimized (perform fewer memory operations)zero-stride vector load",
382 .dependencies = featureSet(&[_]Feature{}),
383 };
384 result[@intFromEnum(Feature.no_rvc_hints)] = .{
385 .llvm_name = "no-rvc-hints",
386 .description = "Disable RVC Hint Instructions.",
387 .dependencies = featureSet(&[_]Feature{}),
388 };
389 result[@intFromEnum(Feature.relax)] = .{
390 .llvm_name = "relax",
391 .description = "Enable Linker relaxation.",
392 .dependencies = featureSet(&[_]Feature{}),
393 };
394 result[@intFromEnum(Feature.reserve_x1)] = .{
395 .llvm_name = "reserve-x1",
396 .description = "Reserve X1",
397 .dependencies = featureSet(&[_]Feature{}),
398 };
399 result[@intFromEnum(Feature.reserve_x10)] = .{
400 .llvm_name = "reserve-x10",
401 .description = "Reserve X10",
402 .dependencies = featureSet(&[_]Feature{}),
403 };
404 result[@intFromEnum(Feature.reserve_x11)] = .{
405 .llvm_name = "reserve-x11",
406 .description = "Reserve X11",
407 .dependencies = featureSet(&[_]Feature{}),
408 };
409 result[@intFromEnum(Feature.reserve_x12)] = .{
410 .llvm_name = "reserve-x12",
411 .description = "Reserve X12",
412 .dependencies = featureSet(&[_]Feature{}),
413 };
414 result[@intFromEnum(Feature.reserve_x13)] = .{
415 .llvm_name = "reserve-x13",
416 .description = "Reserve X13",
417 .dependencies = featureSet(&[_]Feature{}),
418 };
419 result[@intFromEnum(Feature.reserve_x14)] = .{
420 .llvm_name = "reserve-x14",
421 .description = "Reserve X14",
422 .dependencies = featureSet(&[_]Feature{}),
423 };
424 result[@intFromEnum(Feature.reserve_x15)] = .{
425 .llvm_name = "reserve-x15",
426 .description = "Reserve X15",
427 .dependencies = featureSet(&[_]Feature{}),
428 };
429 result[@intFromEnum(Feature.reserve_x16)] = .{
430 .llvm_name = "reserve-x16",
431 .description = "Reserve X16",
432 .dependencies = featureSet(&[_]Feature{}),
433 };
434 result[@intFromEnum(Feature.reserve_x17)] = .{
435 .llvm_name = "reserve-x17",
436 .description = "Reserve X17",
437 .dependencies = featureSet(&[_]Feature{}),
438 };
439 result[@intFromEnum(Feature.reserve_x18)] = .{
440 .llvm_name = "reserve-x18",
441 .description = "Reserve X18",
442 .dependencies = featureSet(&[_]Feature{}),
443 };
444 result[@intFromEnum(Feature.reserve_x19)] = .{
445 .llvm_name = "reserve-x19",
446 .description = "Reserve X19",
447 .dependencies = featureSet(&[_]Feature{}),
448 };
449 result[@intFromEnum(Feature.reserve_x2)] = .{
450 .llvm_name = "reserve-x2",
451 .description = "Reserve X2",
452 .dependencies = featureSet(&[_]Feature{}),
453 };
454 result[@intFromEnum(Feature.reserve_x20)] = .{
455 .llvm_name = "reserve-x20",
456 .description = "Reserve X20",
457 .dependencies = featureSet(&[_]Feature{}),
458 };
459 result[@intFromEnum(Feature.reserve_x21)] = .{
460 .llvm_name = "reserve-x21",
461 .description = "Reserve X21",
462 .dependencies = featureSet(&[_]Feature{}),
463 };
464 result[@intFromEnum(Feature.reserve_x22)] = .{
465 .llvm_name = "reserve-x22",
466 .description = "Reserve X22",
467 .dependencies = featureSet(&[_]Feature{}),
468 };
469 result[@intFromEnum(Feature.reserve_x23)] = .{
470 .llvm_name = "reserve-x23",
471 .description = "Reserve X23",
472 .dependencies = featureSet(&[_]Feature{}),
473 };
474 result[@intFromEnum(Feature.reserve_x24)] = .{
475 .llvm_name = "reserve-x24",
476 .description = "Reserve X24",
477 .dependencies = featureSet(&[_]Feature{}),
478 };
479 result[@intFromEnum(Feature.reserve_x25)] = .{
480 .llvm_name = "reserve-x25",
481 .description = "Reserve X25",
482 .dependencies = featureSet(&[_]Feature{}),
483 };
484 result[@intFromEnum(Feature.reserve_x26)] = .{
485 .llvm_name = "reserve-x26",
486 .description = "Reserve X26",
487 .dependencies = featureSet(&[_]Feature{}),
488 };
489 result[@intFromEnum(Feature.reserve_x27)] = .{
490 .llvm_name = "reserve-x27",
491 .description = "Reserve X27",
492 .dependencies = featureSet(&[_]Feature{}),
493 };
494 result[@intFromEnum(Feature.reserve_x28)] = .{
495 .llvm_name = "reserve-x28",
496 .description = "Reserve X28",
497 .dependencies = featureSet(&[_]Feature{}),
498 };
499 result[@intFromEnum(Feature.reserve_x29)] = .{
500 .llvm_name = "reserve-x29",
501 .description = "Reserve X29",
502 .dependencies = featureSet(&[_]Feature{}),
503 };
504 result[@intFromEnum(Feature.reserve_x3)] = .{
505 .llvm_name = "reserve-x3",
506 .description = "Reserve X3",
507 .dependencies = featureSet(&[_]Feature{}),
508 };
509 result[@intFromEnum(Feature.reserve_x30)] = .{
510 .llvm_name = "reserve-x30",
511 .description = "Reserve X30",
512 .dependencies = featureSet(&[_]Feature{}),
513 };
514 result[@intFromEnum(Feature.reserve_x31)] = .{
515 .llvm_name = "reserve-x31",
516 .description = "Reserve X31",
517 .dependencies = featureSet(&[_]Feature{}),
518 };
519 result[@intFromEnum(Feature.reserve_x4)] = .{
520 .llvm_name = "reserve-x4",
521 .description = "Reserve X4",
522 .dependencies = featureSet(&[_]Feature{}),
523 };
524 result[@intFromEnum(Feature.reserve_x5)] = .{
525 .llvm_name = "reserve-x5",
526 .description = "Reserve X5",
527 .dependencies = featureSet(&[_]Feature{}),
528 };
529 result[@intFromEnum(Feature.reserve_x6)] = .{
530 .llvm_name = "reserve-x6",
531 .description = "Reserve X6",
532 .dependencies = featureSet(&[_]Feature{}),
533 };
534 result[@intFromEnum(Feature.reserve_x7)] = .{
535 .llvm_name = "reserve-x7",
536 .description = "Reserve X7",
537 .dependencies = featureSet(&[_]Feature{}),
538 };
539 result[@intFromEnum(Feature.reserve_x8)] = .{
540 .llvm_name = "reserve-x8",
541 .description = "Reserve X8",
542 .dependencies = featureSet(&[_]Feature{}),
543 };
544 result[@intFromEnum(Feature.reserve_x9)] = .{
545 .llvm_name = "reserve-x9",
546 .description = "Reserve X9",
547 .dependencies = featureSet(&[_]Feature{}),
548 };
549 result[@intFromEnum(Feature.save_restore)] = .{
550 .llvm_name = "save-restore",
551 .description = "Enable save/restore.",
552 .dependencies = featureSet(&[_]Feature{}),
553 };
554 result[@intFromEnum(Feature.seq_cst_trailing_fence)] = .{
555 .llvm_name = "seq-cst-trailing-fence",
556 .description = "Enable trailing fence for seq-cst store.",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
559 result[@intFromEnum(Feature.short_forward_branch_opt)] = .{
560 .llvm_name = "short-forward-branch-opt",
561 .description = "Enable short forward branch optimization",
562 .dependencies = featureSet(&[_]Feature{}),
563 };
564 result[@intFromEnum(Feature.svinval)] = .{
565 .llvm_name = "svinval",
566 .description = "'Svinval' (Fine-Grained Address-Translation Cache Invalidation)",
567 .dependencies = featureSet(&[_]Feature{}),
568 };
569 result[@intFromEnum(Feature.svnapot)] = .{
570 .llvm_name = "svnapot",
571 .description = "'Svnapot' (NAPOT Translation Contiguity)",
572 .dependencies = featureSet(&[_]Feature{}),
573 };
574 result[@intFromEnum(Feature.svpbmt)] = .{
575 .llvm_name = "svpbmt",
576 .description = "'Svpbmt' (Page-Based Memory Types)",
577 .dependencies = featureSet(&[_]Feature{}),
578 };
579 result[@intFromEnum(Feature.tagged_globals)] = .{
580 .llvm_name = "tagged-globals",
581 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",
582 .dependencies = featureSet(&[_]Feature{}),
583 };
584 result[@intFromEnum(Feature.unaligned_scalar_mem)] = .{
585 .llvm_name = "unaligned-scalar-mem",
586 .description = "Has reasonably performant unaligned scalar loads and stores",
587 .dependencies = featureSet(&[_]Feature{}),
588 };
589 result[@intFromEnum(Feature.unaligned_vector_mem)] = .{
590 .llvm_name = "unaligned-vector-mem",
591 .description = "Has reasonably performant unaligned vector loads and stores",
592 .dependencies = featureSet(&[_]Feature{}),
593 };
594 result[@intFromEnum(Feature.v)] = .{
595 .llvm_name = "v",
596 .description = "'V' (Vector Extension for Application Processors)",
597 .dependencies = featureSet(&[_]Feature{
598 .zve64d,
599 .zvl128b,
600 }),
601 };
602 result[@intFromEnum(Feature.xcvbitmanip)] = .{
603 .llvm_name = "xcvbitmanip",
604 .description = "'XCVbitmanip' (CORE-V Bit Manipulation)",
605 .dependencies = featureSet(&[_]Feature{}),
606 };
607 result[@intFromEnum(Feature.xcvmac)] = .{
608 .llvm_name = "xcvmac",
609 .description = "'XCVmac' (CORE-V Multiply-Accumulate)",
610 .dependencies = featureSet(&[_]Feature{}),
611 };
612 result[@intFromEnum(Feature.xsfcie)] = .{
613 .llvm_name = "xsfcie",
614 .description = "'XSfcie' (SiFive Custom Instruction Extension SCIE.)",
615 .dependencies = featureSet(&[_]Feature{}),
616 };
617 result[@intFromEnum(Feature.xsfvcp)] = .{
618 .llvm_name = "xsfvcp",
619 .description = "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)",
620 .dependencies = featureSet(&[_]Feature{
621 .zve32x,
622 }),
623 };
624 result[@intFromEnum(Feature.xtheadba)] = .{
625 .llvm_name = "xtheadba",
626 .description = "'xtheadba' (T-Head address calculation instructions)",
627 .dependencies = featureSet(&[_]Feature{}),
628 };
629 result[@intFromEnum(Feature.xtheadbb)] = .{
630 .llvm_name = "xtheadbb",
631 .description = "'xtheadbb' (T-Head basic bit-manipulation instructions)",
632 .dependencies = featureSet(&[_]Feature{}),
633 };
634 result[@intFromEnum(Feature.xtheadbs)] = .{
635 .llvm_name = "xtheadbs",
636 .description = "'xtheadbs' (T-Head single-bit instructions)",
637 .dependencies = featureSet(&[_]Feature{}),
638 };
639 result[@intFromEnum(Feature.xtheadcmo)] = .{
640 .llvm_name = "xtheadcmo",
641 .description = "'xtheadcmo' (T-Head cache management instructions)",
642 .dependencies = featureSet(&[_]Feature{}),
643 };
644 result[@intFromEnum(Feature.xtheadcondmov)] = .{
645 .llvm_name = "xtheadcondmov",
646 .description = "'xtheadcondmov' (T-Head conditional move instructions)",
647 .dependencies = featureSet(&[_]Feature{}),
648 };
649 result[@intFromEnum(Feature.xtheadfmemidx)] = .{
650 .llvm_name = "xtheadfmemidx",
651 .description = "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)",
652 .dependencies = featureSet(&[_]Feature{
653 .f,
654 }),
655 };
656 result[@intFromEnum(Feature.xtheadmac)] = .{
657 .llvm_name = "xtheadmac",
658 .description = "'xtheadmac' (T-Head Multiply-Accumulate Instructions)",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.xtheadmemidx)] = .{
662 .llvm_name = "xtheadmemidx",
663 .description = "'xtheadmemidx' (T-Head Indexed Memory Operations)",
664 .dependencies = featureSet(&[_]Feature{}),
665 };
666 result[@intFromEnum(Feature.xtheadmempair)] = .{
667 .llvm_name = "xtheadmempair",
668 .description = "'xtheadmempair' (T-Head two-GPR Memory Operations)",
669 .dependencies = featureSet(&[_]Feature{}),
670 };
671 result[@intFromEnum(Feature.xtheadsync)] = .{
672 .llvm_name = "xtheadsync",
673 .description = "'xtheadsync' (T-Head multicore synchronization instructions)",
674 .dependencies = featureSet(&[_]Feature{}),
675 };
676 result[@intFromEnum(Feature.xtheadvdot)] = .{
677 .llvm_name = "xtheadvdot",
678 .description = "'xtheadvdot' (T-Head Vector Extensions for Dot)",
679 .dependencies = featureSet(&[_]Feature{
680 .v,
681 }),
682 };
683 result[@intFromEnum(Feature.xventanacondops)] = .{
684 .llvm_name = "xventanacondops",
685 .description = "'XVentanaCondOps' (Ventana Conditional Ops)",
686 .dependencies = featureSet(&[_]Feature{}),
687 };
688 result[@intFromEnum(Feature.zawrs)] = .{
689 .llvm_name = "zawrs",
690 .description = "'Zawrs' (Wait on Reservation Set)",
691 .dependencies = featureSet(&[_]Feature{}),
692 };
693 result[@intFromEnum(Feature.zba)] = .{
694 .llvm_name = "zba",
695 .description = "'Zba' (Address Generation Instructions)",
696 .dependencies = featureSet(&[_]Feature{}),
697 };
698 result[@intFromEnum(Feature.zbb)] = .{
699 .llvm_name = "zbb",
700 .description = "'Zbb' (Basic Bit-Manipulation)",
701 .dependencies = featureSet(&[_]Feature{}),
702 };
703 result[@intFromEnum(Feature.zbc)] = .{
704 .llvm_name = "zbc",
705 .description = "'Zbc' (Carry-Less Multiplication)",
706 .dependencies = featureSet(&[_]Feature{}),
707 };
708 result[@intFromEnum(Feature.zbkb)] = .{
709 .llvm_name = "zbkb",
710 .description = "'Zbkb' (Bitmanip instructions for Cryptography)",
711 .dependencies = featureSet(&[_]Feature{}),
712 };
713 result[@intFromEnum(Feature.zbkc)] = .{
714 .llvm_name = "zbkc",
715 .description = "'Zbkc' (Carry-less multiply instructions for Cryptography)",
716 .dependencies = featureSet(&[_]Feature{}),
717 };
718 result[@intFromEnum(Feature.zbkx)] = .{
719 .llvm_name = "zbkx",
720 .description = "'Zbkx' (Crossbar permutation instructions)",
721 .dependencies = featureSet(&[_]Feature{}),
722 };
723 result[@intFromEnum(Feature.zbs)] = .{
724 .llvm_name = "zbs",
725 .description = "'Zbs' (Single-Bit Instructions)",
726 .dependencies = featureSet(&[_]Feature{}),
727 };
728 result[@intFromEnum(Feature.zca)] = .{
729 .llvm_name = "zca",
730 .description = "'Zca' (part of the C extension, excluding compressed floating point loads/stores)",
731 .dependencies = featureSet(&[_]Feature{}),
732 };
733 result[@intFromEnum(Feature.zcb)] = .{
734 .llvm_name = "zcb",
735 .description = "'Zcb' (Compressed basic bit manipulation instructions)",
736 .dependencies = featureSet(&[_]Feature{
737 .zca,
738 }),
739 };
740 result[@intFromEnum(Feature.zcd)] = .{
741 .llvm_name = "zcd",
742 .description = "'Zcd' (Compressed Double-Precision Floating-Point Instructions)",
743 .dependencies = featureSet(&[_]Feature{
744 .zca,
745 }),
746 };
747 result[@intFromEnum(Feature.zce)] = .{
748 .llvm_name = "zce",
749 .description = "'Zce' (Compressed extensions for microcontrollers)",
750 .dependencies = featureSet(&[_]Feature{
751 .zcb,
752 .zcmp,
753 .zcmt,
754 }),
755 };
756 result[@intFromEnum(Feature.zcf)] = .{
757 .llvm_name = "zcf",
758 .description = "'Zcf' (Compressed Single-Precision Floating-Point Instructions)",
759 .dependencies = featureSet(&[_]Feature{
760 .zca,
761 }),
762 };
763 result[@intFromEnum(Feature.zcmp)] = .{
764 .llvm_name = "zcmp",
765 .description = "'Zcmp' (sequenced instuctions for code-size reduction)",
766 .dependencies = featureSet(&[_]Feature{
767 .zca,
768 }),
769 };
770 result[@intFromEnum(Feature.zcmt)] = .{
771 .llvm_name = "zcmt",
772 .description = "'Zcmt' (table jump instuctions for code-size reduction)",
773 .dependencies = featureSet(&[_]Feature{
774 .zca,
775 .zicsr,
776 }),
777 };
778 result[@intFromEnum(Feature.zdinx)] = .{
779 .llvm_name = "zdinx",
780 .description = "'Zdinx' (Double in Integer)",
781 .dependencies = featureSet(&[_]Feature{
782 .zfinx,
783 }),
784 };
785 result[@intFromEnum(Feature.zfh)] = .{
786 .llvm_name = "zfh",
787 .description = "'Zfh' (Half-Precision Floating-Point)",
788 .dependencies = featureSet(&[_]Feature{
789 .f,
790 }),
791 };
792 result[@intFromEnum(Feature.zfhmin)] = .{
793 .llvm_name = "zfhmin",
794 .description = "'Zfhmin' (Half-Precision Floating-Point Minimal)",
795 .dependencies = featureSet(&[_]Feature{
796 .f,
797 }),
798 };
799 result[@intFromEnum(Feature.zfinx)] = .{
800 .llvm_name = "zfinx",
801 .description = "'Zfinx' (Float in Integer)",
802 .dependencies = featureSet(&[_]Feature{
803 .zicsr,
804 }),
805 };
806 result[@intFromEnum(Feature.zhinx)] = .{
807 .llvm_name = "zhinx",
808 .description = "'Zhinx' (Half Float in Integer)",
809 .dependencies = featureSet(&[_]Feature{
810 .zfinx,
811 }),
812 };
813 result[@intFromEnum(Feature.zhinxmin)] = .{
814 .llvm_name = "zhinxmin",
815 .description = "'Zhinxmin' (Half Float in Integer Minimal)",
816 .dependencies = featureSet(&[_]Feature{
817 .zfinx,
818 }),
819 };
820 result[@intFromEnum(Feature.zicbom)] = .{
821 .llvm_name = "zicbom",
822 .description = "'Zicbom' (Cache-Block Management Instructions)",
823 .dependencies = featureSet(&[_]Feature{}),
824 };
825 result[@intFromEnum(Feature.zicbop)] = .{
826 .llvm_name = "zicbop",
827 .description = "'Zicbop' (Cache-Block Prefetch Instructions)",
828 .dependencies = featureSet(&[_]Feature{}),
829 };
830 result[@intFromEnum(Feature.zicboz)] = .{
831 .llvm_name = "zicboz",
832 .description = "'Zicboz' (Cache-Block Zero Instructions)",
833 .dependencies = featureSet(&[_]Feature{}),
834 };
835 result[@intFromEnum(Feature.zicntr)] = .{
836 .llvm_name = "zicntr",
837 .description = "'Zicntr' (Base Counters and Timers)",
838 .dependencies = featureSet(&[_]Feature{
839 .zicsr,
840 }),
841 };
842 result[@intFromEnum(Feature.zicsr)] = .{
843 .llvm_name = "zicsr",
844 .description = "'zicsr' (CSRs)",
845 .dependencies = featureSet(&[_]Feature{}),
846 };
847 result[@intFromEnum(Feature.zifencei)] = .{
848 .llvm_name = "zifencei",
849 .description = "'Zifencei' (fence.i)",
850 .dependencies = featureSet(&[_]Feature{}),
851 };
852 result[@intFromEnum(Feature.zihintpause)] = .{
853 .llvm_name = "zihintpause",
854 .description = "'Zihintpause' (Pause Hint)",
855 .dependencies = featureSet(&[_]Feature{}),
856 };
857 result[@intFromEnum(Feature.zihpm)] = .{
858 .llvm_name = "zihpm",
859 .description = "'Zihpm' (Hardware Performance Counters)",
860 .dependencies = featureSet(&[_]Feature{
861 .zicsr,
862 }),
863 };
864 result[@intFromEnum(Feature.zk)] = .{
865 .llvm_name = "zk",
866 .description = "'Zk' (Standard scalar cryptography extension)",
867 .dependencies = featureSet(&[_]Feature{
868 .zkn,
869 .zkr,
870 .zkt,
871 }),
872 };
873 result[@intFromEnum(Feature.zkn)] = .{
874 .llvm_name = "zkn",
875 .description = "'Zkn' (NIST Algorithm Suite)",
876 .dependencies = featureSet(&[_]Feature{
877 .zbkb,
878 .zbkc,
879 .zbkx,
880 .zknd,
881 .zkne,
882 .zknh,
883 }),
884 };
885 result[@intFromEnum(Feature.zknd)] = .{
886 .llvm_name = "zknd",
887 .description = "'Zknd' (NIST Suite: AES Decryption)",
888 .dependencies = featureSet(&[_]Feature{}),
889 };
890 result[@intFromEnum(Feature.zkne)] = .{
891 .llvm_name = "zkne",
892 .description = "'Zkne' (NIST Suite: AES Encryption)",
893 .dependencies = featureSet(&[_]Feature{}),
894 };
895 result[@intFromEnum(Feature.zknh)] = .{
896 .llvm_name = "zknh",
897 .description = "'Zknh' (NIST Suite: Hash Function Instructions)",
898 .dependencies = featureSet(&[_]Feature{}),
899 };
900 result[@intFromEnum(Feature.zkr)] = .{
901 .llvm_name = "zkr",
902 .description = "'Zkr' (Entropy Source Extension)",
903 .dependencies = featureSet(&[_]Feature{}),
904 };
905 result[@intFromEnum(Feature.zks)] = .{
906 .llvm_name = "zks",
907 .description = "'Zks' (ShangMi Algorithm Suite)",
908 .dependencies = featureSet(&[_]Feature{
909 .zbkb,
910 .zbkc,
911 .zbkx,
912 .zksed,
913 .zksh,
914 }),
915 };
916 result[@intFromEnum(Feature.zksed)] = .{
917 .llvm_name = "zksed",
918 .description = "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)",
919 .dependencies = featureSet(&[_]Feature{}),
920 };
921 result[@intFromEnum(Feature.zksh)] = .{
922 .llvm_name = "zksh",
923 .description = "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)",
924 .dependencies = featureSet(&[_]Feature{}),
925 };
926 result[@intFromEnum(Feature.zkt)] = .{
927 .llvm_name = "zkt",
928 .description = "'Zkt' (Data Independent Execution Latency)",
929 .dependencies = featureSet(&[_]Feature{}),
930 };
931 result[@intFromEnum(Feature.zmmul)] = .{
932 .llvm_name = "zmmul",
933 .description = "'Zmmul' (Integer Multiplication)",
934 .dependencies = featureSet(&[_]Feature{}),
935 };
936 result[@intFromEnum(Feature.zve32f)] = .{
937 .llvm_name = "zve32f",
938 .description = "'Zve32f' (Vector Extensions for Embedded Processors with maximal 32 EEW and F extension)",
939 .dependencies = featureSet(&[_]Feature{
940 .f,
941 .zve32x,
942 }),
943 };
944 result[@intFromEnum(Feature.zve32x)] = .{
945 .llvm_name = "zve32x",
946 .description = "'Zve32x' (Vector Extensions for Embedded Processors with maximal 32 EEW)",
947 .dependencies = featureSet(&[_]Feature{
948 .zicsr,
949 .zvl32b,
950 }),
951 };
952 result[@intFromEnum(Feature.zve64d)] = .{
953 .llvm_name = "zve64d",
954 .description = "'Zve64d' (Vector Extensions for Embedded Processors with maximal 64 EEW, F and D extension)",
955 .dependencies = featureSet(&[_]Feature{
956 .d,
957 .zve64f,
958 }),
959 };
960 result[@intFromEnum(Feature.zve64f)] = .{
961 .llvm_name = "zve64f",
962 .description = "'Zve64f' (Vector Extensions for Embedded Processors with maximal 64 EEW and F extension)",
963 .dependencies = featureSet(&[_]Feature{
964 .zve32f,
965 .zve64x,
966 }),
967 };
968 result[@intFromEnum(Feature.zve64x)] = .{
969 .llvm_name = "zve64x",
970 .description = "'Zve64x' (Vector Extensions for Embedded Processors with maximal 64 EEW)",
971 .dependencies = featureSet(&[_]Feature{
972 .zve32x,
973 .zvl64b,
974 }),
975 };
976 result[@intFromEnum(Feature.zvfh)] = .{
977 .llvm_name = "zvfh",
978 .description = "'Zvfh' (Vector Half-Precision Floating-Point)",
979 .dependencies = featureSet(&[_]Feature{
980 .zfhmin,
981 .zve32f,
982 }),
983 };
984 result[@intFromEnum(Feature.zvl1024b)] = .{
985 .llvm_name = "zvl1024b",
986 .description = "'Zvl' (Minimum Vector Length) 1024",
987 .dependencies = featureSet(&[_]Feature{
988 .zvl512b,
989 }),
990 };
991 result[@intFromEnum(Feature.zvl128b)] = .{
992 .llvm_name = "zvl128b",
993 .description = "'Zvl' (Minimum Vector Length) 128",
994 .dependencies = featureSet(&[_]Feature{
995 .zvl64b,
996 }),
997 };
998 result[@intFromEnum(Feature.zvl16384b)] = .{
999 .llvm_name = "zvl16384b",
1000 .description = "'Zvl' (Minimum Vector Length) 16384",
1001 .dependencies = featureSet(&[_]Feature{
1002 .zvl8192b,
1003 }),
1004 };
1005 result[@intFromEnum(Feature.zvl2048b)] = .{
1006 .llvm_name = "zvl2048b",
1007 .description = "'Zvl' (Minimum Vector Length) 2048",
1008 .dependencies = featureSet(&[_]Feature{
1009 .zvl1024b,
1010 }),
1011 };
1012 result[@intFromEnum(Feature.zvl256b)] = .{
1013 .llvm_name = "zvl256b",
1014 .description = "'Zvl' (Minimum Vector Length) 256",
1015 .dependencies = featureSet(&[_]Feature{
1016 .zvl128b,
1017 }),
1018 };
1019 result[@intFromEnum(Feature.zvl32768b)] = .{
1020 .llvm_name = "zvl32768b",
1021 .description = "'Zvl' (Minimum Vector Length) 32768",
1022 .dependencies = featureSet(&[_]Feature{
1023 .zvl16384b,
1024 }),
1025 };
1026 result[@intFromEnum(Feature.zvl32b)] = .{
1027 .llvm_name = "zvl32b",
1028 .description = "'Zvl' (Minimum Vector Length) 32",
1029 .dependencies = featureSet(&[_]Feature{}),
1030 };
1031 result[@intFromEnum(Feature.zvl4096b)] = .{
1032 .llvm_name = "zvl4096b",
1033 .description = "'Zvl' (Minimum Vector Length) 4096",
1034 .dependencies = featureSet(&[_]Feature{
1035 .zvl2048b,
1036 }),
1037 };
1038 result[@intFromEnum(Feature.zvl512b)] = .{
1039 .llvm_name = "zvl512b",
1040 .description = "'Zvl' (Minimum Vector Length) 512",
1041 .dependencies = featureSet(&[_]Feature{
1042 .zvl256b,
1043 }),
1044 };
1045 result[@intFromEnum(Feature.zvl64b)] = .{
1046 .llvm_name = "zvl64b",
1047 .description = "'Zvl' (Minimum Vector Length) 64",
1048 .dependencies = featureSet(&[_]Feature{
1049 .zvl32b,
1050 }),
1051 };
1052 result[@intFromEnum(Feature.zvl65536b)] = .{
1053 .llvm_name = "zvl65536b",
1054 .description = "'Zvl' (Minimum Vector Length) 65536",
1055 .dependencies = featureSet(&[_]Feature{
1056 .zvl32768b,
1057 }),
1058 };
1059 result[@intFromEnum(Feature.zvl8192b)] = .{
1060 .llvm_name = "zvl8192b",
1061 .description = "'Zvl' (Minimum Vector Length) 8192",
1062 .dependencies = featureSet(&[_]Feature{
1063 .zvl4096b,
1064 }),
1065 };
1066 const ti = @typeInfo(Feature);
1067 for (&result, 0..) |*elem, i| {
1068 elem.index = i;
1069 elem.name = ti.Enum.fields[i].name;
1070 }
1071 break :blk result;
1072};
1073
1074pub const cpu = struct {
1075 pub const baseline_rv32 = CpuModel{
1076 .name = "baseline_rv32",
1077 .llvm_name = null,
1078 .features = featureSet(&[_]Feature{
1079 .@"32bit",
1080 .a,
1081 .c,
1082 .d,
1083 .m,
1084 }),
1085 };
1086 pub const baseline_rv64 = CpuModel{
1087 .name = "baseline_rv64",
1088 .llvm_name = null,
1089 .features = featureSet(&[_]Feature{
1090 .@"64bit",
1091 .a,
1092 .c,
1093 .d,
1094 .m,
1095 }),
1096 };
1097 pub const generic = CpuModel{
1098 .name = "generic",
1099 .llvm_name = "generic",
1100 .features = featureSet(&[_]Feature{}),
1101 };
1102 pub const generic_rv32 = CpuModel{
1103 .name = "generic_rv32",
1104 .llvm_name = "generic-rv32",
1105 .features = featureSet(&[_]Feature{
1106 .@"32bit",
1107 }),
1108 };
1109 pub const generic_rv64 = CpuModel{
1110 .name = "generic_rv64",
1111 .llvm_name = "generic-rv64",
1112 .features = featureSet(&[_]Feature{
1113 .@"64bit",
1114 }),
1115 };
1116 pub const rocket = CpuModel{
1117 .name = "rocket",
1118 .llvm_name = "rocket",
1119 .features = featureSet(&[_]Feature{}),
1120 };
1121 pub const rocket_rv32 = CpuModel{
1122 .name = "rocket_rv32",
1123 .llvm_name = "rocket-rv32",
1124 .features = featureSet(&[_]Feature{
1125 .@"32bit",
1126 .zicsr,
1127 .zifencei,
1128 }),
1129 };
1130 pub const rocket_rv64 = CpuModel{
1131 .name = "rocket_rv64",
1132 .llvm_name = "rocket-rv64",
1133 .features = featureSet(&[_]Feature{
1134 .@"64bit",
1135 .zicsr,
1136 .zifencei,
1137 }),
1138 };
1139 pub const sifive_7_series = CpuModel{
1140 .name = "sifive_7_series",
1141 .llvm_name = "sifive-7-series",
1142 .features = featureSet(&[_]Feature{
1143 .no_default_unroll,
1144 .short_forward_branch_opt,
1145 }),
1146 };
1147 pub const sifive_e20 = CpuModel{
1148 .name = "sifive_e20",
1149 .llvm_name = "sifive-e20",
1150 .features = featureSet(&[_]Feature{
1151 .@"32bit",
1152 .c,
1153 .m,
1154 .zicsr,
1155 .zifencei,
1156 }),
1157 };
1158 pub const sifive_e21 = CpuModel{
1159 .name = "sifive_e21",
1160 .llvm_name = "sifive-e21",
1161 .features = featureSet(&[_]Feature{
1162 .@"32bit",
1163 .a,
1164 .c,
1165 .m,
1166 .zicsr,
1167 .zifencei,
1168 }),
1169 };
1170 pub const sifive_e24 = CpuModel{
1171 .name = "sifive_e24",
1172 .llvm_name = "sifive-e24",
1173 .features = featureSet(&[_]Feature{
1174 .@"32bit",
1175 .a,
1176 .c,
1177 .f,
1178 .m,
1179 .zifencei,
1180 }),
1181 };
1182 pub const sifive_e31 = CpuModel{
1183 .name = "sifive_e31",
1184 .llvm_name = "sifive-e31",
1185 .features = featureSet(&[_]Feature{
1186 .@"32bit",
1187 .a,
1188 .c,
1189 .m,
1190 .zicsr,
1191 .zifencei,
1192 }),
1193 };
1194 pub const sifive_e34 = CpuModel{
1195 .name = "sifive_e34",
1196 .llvm_name = "sifive-e34",
1197 .features = featureSet(&[_]Feature{
1198 .@"32bit",
1199 .a,
1200 .c,
1201 .f,
1202 .m,
1203 .zifencei,
1204 }),
1205 };
1206 pub const sifive_e76 = CpuModel{
1207 .name = "sifive_e76",
1208 .llvm_name = "sifive-e76",
1209 .features = featureSet(&[_]Feature{
1210 .@"32bit",
1211 .a,
1212 .c,
1213 .f,
1214 .m,
1215 .no_default_unroll,
1216 .short_forward_branch_opt,
1217 .zifencei,
1218 }),
1219 };
1220 pub const sifive_s21 = CpuModel{
1221 .name = "sifive_s21",
1222 .llvm_name = "sifive-s21",
1223 .features = featureSet(&[_]Feature{
1224 .@"64bit",
1225 .a,
1226 .c,
1227 .m,
1228 .zicsr,
1229 .zifencei,
1230 }),
1231 };
1232 pub const sifive_s51 = CpuModel{
1233 .name = "sifive_s51",
1234 .llvm_name = "sifive-s51",
1235 .features = featureSet(&[_]Feature{
1236 .@"64bit",
1237 .a,
1238 .c,
1239 .m,
1240 .zicsr,
1241 .zifencei,
1242 }),
1243 };
1244 pub const sifive_s54 = CpuModel{
1245 .name = "sifive_s54",
1246 .llvm_name = "sifive-s54",
1247 .features = featureSet(&[_]Feature{
1248 .@"64bit",
1249 .a,
1250 .c,
1251 .d,
1252 .m,
1253 .zifencei,
1254 }),
1255 };
1256 pub const sifive_s76 = CpuModel{
1257 .name = "sifive_s76",
1258 .llvm_name = "sifive-s76",
1259 .features = featureSet(&[_]Feature{
1260 .@"64bit",
1261 .a,
1262 .c,
1263 .d,
1264 .m,
1265 .no_default_unroll,
1266 .short_forward_branch_opt,
1267 .xsfcie,
1268 .zifencei,
1269 .zihintpause,
1270 }),
1271 };
1272 pub const sifive_u54 = CpuModel{
1273 .name = "sifive_u54",
1274 .llvm_name = "sifive-u54",
1275 .features = featureSet(&[_]Feature{
1276 .@"64bit",
1277 .a,
1278 .c,
1279 .d,
1280 .m,
1281 .zifencei,
1282 }),
1283 };
1284 pub const sifive_u74 = CpuModel{
1285 .name = "sifive_u74",
1286 .llvm_name = "sifive-u74",
1287 .features = featureSet(&[_]Feature{
1288 .@"64bit",
1289 .a,
1290 .c,
1291 .d,
1292 .m,
1293 .no_default_unroll,
1294 .short_forward_branch_opt,
1295 .zifencei,
1296 }),
1297 };
1298 pub const sifive_x280 = CpuModel{
1299 .name = "sifive_x280",
1300 .llvm_name = "sifive-x280",
1301 .features = featureSet(&[_]Feature{
1302 .@"64bit",
1303 .a,
1304 .c,
1305 .dlen_factor_2,
1306 .m,
1307 .no_default_unroll,
1308 .short_forward_branch_opt,
1309 .v,
1310 .zba,
1311 .zbb,
1312 .zfh,
1313 .zifencei,
1314 .zvfh,
1315 .zvl512b,
1316 }),
1317 };
1318 pub const syntacore_scr1_base = CpuModel{
1319 .name = "syntacore_scr1_base",
1320 .llvm_name = "syntacore-scr1-base",
1321 .features = featureSet(&[_]Feature{
1322 .@"32bit",
1323 .c,
1324 .no_default_unroll,
1325 .zicsr,
1326 .zifencei,
1327 }),
1328 };
1329 pub const syntacore_scr1_max = CpuModel{
1330 .name = "syntacore_scr1_max",
1331 .llvm_name = "syntacore-scr1-max",
1332 .features = featureSet(&[_]Feature{
1333 .@"32bit",
1334 .c,
1335 .m,
1336 .no_default_unroll,
1337 .zicsr,
1338 .zifencei,
1339 }),
1340 };
1341};
lib/std/Target/s390x.zig created+667
......@@ -0,0 +1,667 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 bear_enhancement,
9 deflate_conversion,
10 dfp_packed_conversion,
11 dfp_zoned_conversion,
12 distinct_ops,
13 enhanced_dat_2,
14 enhanced_sort,
15 execution_hint,
16 fast_serialization,
17 fp_extension,
18 guarded_storage,
19 high_word,
20 insert_reference_bits_multiple,
21 interlocked_access1,
22 load_and_trap,
23 load_and_zero_rightmost_byte,
24 load_store_on_cond,
25 load_store_on_cond_2,
26 message_security_assist_extension3,
27 message_security_assist_extension4,
28 message_security_assist_extension5,
29 message_security_assist_extension7,
30 message_security_assist_extension8,
31 message_security_assist_extension9,
32 miscellaneous_extensions,
33 miscellaneous_extensions_2,
34 miscellaneous_extensions_3,
35 nnp_assist,
36 population_count,
37 processor_activity_instrumentation,
38 processor_assist,
39 reset_dat_protection,
40 reset_reference_bits_multiple,
41 soft_float,
42 transactional_execution,
43 vector,
44 vector_enhancements_1,
45 vector_enhancements_2,
46 vector_packed_decimal,
47 vector_packed_decimal_enhancement,
48 vector_packed_decimal_enhancement_2,
49};
50
51pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
52pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
53pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
54pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
55
56pub const all_features = blk: {
57 const len = @typeInfo(Feature).Enum.fields.len;
58 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
59 var result: [len]CpuFeature = undefined;
60 result[@intFromEnum(Feature.bear_enhancement)] = .{
61 .llvm_name = "bear-enhancement",
62 .description = "Assume that the BEAR-enhancement facility is installed",
63 .dependencies = featureSet(&[_]Feature{}),
64 };
65 result[@intFromEnum(Feature.deflate_conversion)] = .{
66 .llvm_name = "deflate-conversion",
67 .description = "Assume that the deflate-conversion facility is installed",
68 .dependencies = featureSet(&[_]Feature{}),
69 };
70 result[@intFromEnum(Feature.dfp_packed_conversion)] = .{
71 .llvm_name = "dfp-packed-conversion",
72 .description = "Assume that the DFP packed-conversion facility is installed",
73 .dependencies = featureSet(&[_]Feature{}),
74 };
75 result[@intFromEnum(Feature.dfp_zoned_conversion)] = .{
76 .llvm_name = "dfp-zoned-conversion",
77 .description = "Assume that the DFP zoned-conversion facility is installed",
78 .dependencies = featureSet(&[_]Feature{}),
79 };
80 result[@intFromEnum(Feature.distinct_ops)] = .{
81 .llvm_name = "distinct-ops",
82 .description = "Assume that the distinct-operands facility is installed",
83 .dependencies = featureSet(&[_]Feature{}),
84 };
85 result[@intFromEnum(Feature.enhanced_dat_2)] = .{
86 .llvm_name = "enhanced-dat-2",
87 .description = "Assume that the enhanced-DAT facility 2 is installed",
88 .dependencies = featureSet(&[_]Feature{}),
89 };
90 result[@intFromEnum(Feature.enhanced_sort)] = .{
91 .llvm_name = "enhanced-sort",
92 .description = "Assume that the enhanced-sort facility is installed",
93 .dependencies = featureSet(&[_]Feature{}),
94 };
95 result[@intFromEnum(Feature.execution_hint)] = .{
96 .llvm_name = "execution-hint",
97 .description = "Assume that the execution-hint facility is installed",
98 .dependencies = featureSet(&[_]Feature{}),
99 };
100 result[@intFromEnum(Feature.fast_serialization)] = .{
101 .llvm_name = "fast-serialization",
102 .description = "Assume that the fast-serialization facility is installed",
103 .dependencies = featureSet(&[_]Feature{}),
104 };
105 result[@intFromEnum(Feature.fp_extension)] = .{
106 .llvm_name = "fp-extension",
107 .description = "Assume that the floating-point extension facility is installed",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.guarded_storage)] = .{
111 .llvm_name = "guarded-storage",
112 .description = "Assume that the guarded-storage facility is installed",
113 .dependencies = featureSet(&[_]Feature{}),
114 };
115 result[@intFromEnum(Feature.high_word)] = .{
116 .llvm_name = "high-word",
117 .description = "Assume that the high-word facility is installed",
118 .dependencies = featureSet(&[_]Feature{}),
119 };
120 result[@intFromEnum(Feature.insert_reference_bits_multiple)] = .{
121 .llvm_name = "insert-reference-bits-multiple",
122 .description = "Assume that the insert-reference-bits-multiple facility is installed",
123 .dependencies = featureSet(&[_]Feature{}),
124 };
125 result[@intFromEnum(Feature.interlocked_access1)] = .{
126 .llvm_name = "interlocked-access1",
127 .description = "Assume that interlocked-access facility 1 is installed",
128 .dependencies = featureSet(&[_]Feature{}),
129 };
130 result[@intFromEnum(Feature.load_and_trap)] = .{
131 .llvm_name = "load-and-trap",
132 .description = "Assume that the load-and-trap facility is installed",
133 .dependencies = featureSet(&[_]Feature{}),
134 };
135 result[@intFromEnum(Feature.load_and_zero_rightmost_byte)] = .{
136 .llvm_name = "load-and-zero-rightmost-byte",
137 .description = "Assume that the load-and-zero-rightmost-byte facility is installed",
138 .dependencies = featureSet(&[_]Feature{}),
139 };
140 result[@intFromEnum(Feature.load_store_on_cond)] = .{
141 .llvm_name = "load-store-on-cond",
142 .description = "Assume that the load/store-on-condition facility is installed",
143 .dependencies = featureSet(&[_]Feature{}),
144 };
145 result[@intFromEnum(Feature.load_store_on_cond_2)] = .{
146 .llvm_name = "load-store-on-cond-2",
147 .description = "Assume that the load/store-on-condition facility 2 is installed",
148 .dependencies = featureSet(&[_]Feature{}),
149 };
150 result[@intFromEnum(Feature.message_security_assist_extension3)] = .{
151 .llvm_name = "message-security-assist-extension3",
152 .description = "Assume that the message-security-assist extension facility 3 is installed",
153 .dependencies = featureSet(&[_]Feature{}),
154 };
155 result[@intFromEnum(Feature.message_security_assist_extension4)] = .{
156 .llvm_name = "message-security-assist-extension4",
157 .description = "Assume that the message-security-assist extension facility 4 is installed",
158 .dependencies = featureSet(&[_]Feature{}),
159 };
160 result[@intFromEnum(Feature.message_security_assist_extension5)] = .{
161 .llvm_name = "message-security-assist-extension5",
162 .description = "Assume that the message-security-assist extension facility 5 is installed",
163 .dependencies = featureSet(&[_]Feature{}),
164 };
165 result[@intFromEnum(Feature.message_security_assist_extension7)] = .{
166 .llvm_name = "message-security-assist-extension7",
167 .description = "Assume that the message-security-assist extension facility 7 is installed",
168 .dependencies = featureSet(&[_]Feature{}),
169 };
170 result[@intFromEnum(Feature.message_security_assist_extension8)] = .{
171 .llvm_name = "message-security-assist-extension8",
172 .description = "Assume that the message-security-assist extension facility 8 is installed",
173 .dependencies = featureSet(&[_]Feature{}),
174 };
175 result[@intFromEnum(Feature.message_security_assist_extension9)] = .{
176 .llvm_name = "message-security-assist-extension9",
177 .description = "Assume that the message-security-assist extension facility 9 is installed",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.miscellaneous_extensions)] = .{
181 .llvm_name = "miscellaneous-extensions",
182 .description = "Assume that the miscellaneous-extensions facility is installed",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.miscellaneous_extensions_2)] = .{
186 .llvm_name = "miscellaneous-extensions-2",
187 .description = "Assume that the miscellaneous-extensions facility 2 is installed",
188 .dependencies = featureSet(&[_]Feature{}),
189 };
190 result[@intFromEnum(Feature.miscellaneous_extensions_3)] = .{
191 .llvm_name = "miscellaneous-extensions-3",
192 .description = "Assume that the miscellaneous-extensions facility 3 is installed",
193 .dependencies = featureSet(&[_]Feature{}),
194 };
195 result[@intFromEnum(Feature.nnp_assist)] = .{
196 .llvm_name = "nnp-assist",
197 .description = "Assume that the NNP-assist facility is installed",
198 .dependencies = featureSet(&[_]Feature{}),
199 };
200 result[@intFromEnum(Feature.population_count)] = .{
201 .llvm_name = "population-count",
202 .description = "Assume that the population-count facility is installed",
203 .dependencies = featureSet(&[_]Feature{}),
204 };
205 result[@intFromEnum(Feature.processor_activity_instrumentation)] = .{
206 .llvm_name = "processor-activity-instrumentation",
207 .description = "Assume that the processor-activity-instrumentation facility is installed",
208 .dependencies = featureSet(&[_]Feature{}),
209 };
210 result[@intFromEnum(Feature.processor_assist)] = .{
211 .llvm_name = "processor-assist",
212 .description = "Assume that the processor-assist facility is installed",
213 .dependencies = featureSet(&[_]Feature{}),
214 };
215 result[@intFromEnum(Feature.reset_dat_protection)] = .{
216 .llvm_name = "reset-dat-protection",
217 .description = "Assume that the reset-DAT-protection facility is installed",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
220 result[@intFromEnum(Feature.reset_reference_bits_multiple)] = .{
221 .llvm_name = "reset-reference-bits-multiple",
222 .description = "Assume that the reset-reference-bits-multiple facility is installed",
223 .dependencies = featureSet(&[_]Feature{}),
224 };
225 result[@intFromEnum(Feature.soft_float)] = .{
226 .llvm_name = "soft-float",
227 .description = "Use software emulation for floating point",
228 .dependencies = featureSet(&[_]Feature{}),
229 };
230 result[@intFromEnum(Feature.transactional_execution)] = .{
231 .llvm_name = "transactional-execution",
232 .description = "Assume that the transactional-execution facility is installed",
233 .dependencies = featureSet(&[_]Feature{}),
234 };
235 result[@intFromEnum(Feature.vector)] = .{
236 .llvm_name = "vector",
237 .description = "Assume that the vectory facility is installed",
238 .dependencies = featureSet(&[_]Feature{}),
239 };
240 result[@intFromEnum(Feature.vector_enhancements_1)] = .{
241 .llvm_name = "vector-enhancements-1",
242 .description = "Assume that the vector enhancements facility 1 is installed",
243 .dependencies = featureSet(&[_]Feature{}),
244 };
245 result[@intFromEnum(Feature.vector_enhancements_2)] = .{
246 .llvm_name = "vector-enhancements-2",
247 .description = "Assume that the vector enhancements facility 2 is installed",
248 .dependencies = featureSet(&[_]Feature{}),
249 };
250 result[@intFromEnum(Feature.vector_packed_decimal)] = .{
251 .llvm_name = "vector-packed-decimal",
252 .description = "Assume that the vector packed decimal facility is installed",
253 .dependencies = featureSet(&[_]Feature{}),
254 };
255 result[@intFromEnum(Feature.vector_packed_decimal_enhancement)] = .{
256 .llvm_name = "vector-packed-decimal-enhancement",
257 .description = "Assume that the vector packed decimal enhancement facility is installed",
258 .dependencies = featureSet(&[_]Feature{}),
259 };
260 result[@intFromEnum(Feature.vector_packed_decimal_enhancement_2)] = .{
261 .llvm_name = "vector-packed-decimal-enhancement-2",
262 .description = "Assume that the vector packed decimal enhancement facility 2 is installed",
263 .dependencies = featureSet(&[_]Feature{}),
264 };
265 const ti = @typeInfo(Feature);
266 for (&result, 0..) |*elem, i| {
267 elem.index = i;
268 elem.name = ti.Enum.fields[i].name;
269 }
270 break :blk result;
271};
272
273pub const cpu = struct {
274 pub const arch10 = CpuModel{
275 .name = "arch10",
276 .llvm_name = "arch10",
277 .features = featureSet(&[_]Feature{
278 .dfp_zoned_conversion,
279 .distinct_ops,
280 .enhanced_dat_2,
281 .execution_hint,
282 .fast_serialization,
283 .fp_extension,
284 .high_word,
285 .interlocked_access1,
286 .load_and_trap,
287 .load_store_on_cond,
288 .message_security_assist_extension3,
289 .message_security_assist_extension4,
290 .miscellaneous_extensions,
291 .population_count,
292 .processor_assist,
293 .reset_reference_bits_multiple,
294 .transactional_execution,
295 }),
296 };
297 pub const arch11 = CpuModel{
298 .name = "arch11",
299 .llvm_name = "arch11",
300 .features = featureSet(&[_]Feature{
301 .dfp_packed_conversion,
302 .dfp_zoned_conversion,
303 .distinct_ops,
304 .enhanced_dat_2,
305 .execution_hint,
306 .fast_serialization,
307 .fp_extension,
308 .high_word,
309 .interlocked_access1,
310 .load_and_trap,
311 .load_and_zero_rightmost_byte,
312 .load_store_on_cond,
313 .load_store_on_cond_2,
314 .message_security_assist_extension3,
315 .message_security_assist_extension4,
316 .message_security_assist_extension5,
317 .miscellaneous_extensions,
318 .population_count,
319 .processor_assist,
320 .reset_reference_bits_multiple,
321 .transactional_execution,
322 .vector,
323 }),
324 };
325 pub const arch12 = CpuModel{
326 .name = "arch12",
327 .llvm_name = "arch12",
328 .features = featureSet(&[_]Feature{
329 .dfp_packed_conversion,
330 .dfp_zoned_conversion,
331 .distinct_ops,
332 .enhanced_dat_2,
333 .execution_hint,
334 .fast_serialization,
335 .fp_extension,
336 .guarded_storage,
337 .high_word,
338 .insert_reference_bits_multiple,
339 .interlocked_access1,
340 .load_and_trap,
341 .load_and_zero_rightmost_byte,
342 .load_store_on_cond,
343 .load_store_on_cond_2,
344 .message_security_assist_extension3,
345 .message_security_assist_extension4,
346 .message_security_assist_extension5,
347 .message_security_assist_extension7,
348 .message_security_assist_extension8,
349 .miscellaneous_extensions,
350 .miscellaneous_extensions_2,
351 .population_count,
352 .processor_assist,
353 .reset_reference_bits_multiple,
354 .transactional_execution,
355 .vector,
356 .vector_enhancements_1,
357 .vector_packed_decimal,
358 }),
359 };
360 pub const arch13 = CpuModel{
361 .name = "arch13",
362 .llvm_name = "arch13",
363 .features = featureSet(&[_]Feature{
364 .deflate_conversion,
365 .dfp_packed_conversion,
366 .dfp_zoned_conversion,
367 .distinct_ops,
368 .enhanced_dat_2,
369 .enhanced_sort,
370 .execution_hint,
371 .fast_serialization,
372 .fp_extension,
373 .guarded_storage,
374 .high_word,
375 .insert_reference_bits_multiple,
376 .interlocked_access1,
377 .load_and_trap,
378 .load_and_zero_rightmost_byte,
379 .load_store_on_cond,
380 .load_store_on_cond_2,
381 .message_security_assist_extension3,
382 .message_security_assist_extension4,
383 .message_security_assist_extension5,
384 .message_security_assist_extension7,
385 .message_security_assist_extension8,
386 .message_security_assist_extension9,
387 .miscellaneous_extensions,
388 .miscellaneous_extensions_2,
389 .miscellaneous_extensions_3,
390 .population_count,
391 .processor_assist,
392 .reset_reference_bits_multiple,
393 .transactional_execution,
394 .vector,
395 .vector_enhancements_1,
396 .vector_enhancements_2,
397 .vector_packed_decimal,
398 .vector_packed_decimal_enhancement,
399 }),
400 };
401 pub const arch14 = CpuModel{
402 .name = "arch14",
403 .llvm_name = "arch14",
404 .features = featureSet(&[_]Feature{
405 .bear_enhancement,
406 .deflate_conversion,
407 .dfp_packed_conversion,
408 .dfp_zoned_conversion,
409 .distinct_ops,
410 .enhanced_dat_2,
411 .enhanced_sort,
412 .execution_hint,
413 .fast_serialization,
414 .fp_extension,
415 .guarded_storage,
416 .high_word,
417 .insert_reference_bits_multiple,
418 .interlocked_access1,
419 .load_and_trap,
420 .load_and_zero_rightmost_byte,
421 .load_store_on_cond,
422 .load_store_on_cond_2,
423 .message_security_assist_extension3,
424 .message_security_assist_extension4,
425 .message_security_assist_extension5,
426 .message_security_assist_extension7,
427 .message_security_assist_extension8,
428 .message_security_assist_extension9,
429 .miscellaneous_extensions,
430 .miscellaneous_extensions_2,
431 .miscellaneous_extensions_3,
432 .nnp_assist,
433 .population_count,
434 .processor_activity_instrumentation,
435 .processor_assist,
436 .reset_dat_protection,
437 .reset_reference_bits_multiple,
438 .transactional_execution,
439 .vector,
440 .vector_enhancements_1,
441 .vector_enhancements_2,
442 .vector_packed_decimal,
443 .vector_packed_decimal_enhancement,
444 .vector_packed_decimal_enhancement_2,
445 }),
446 };
447 pub const arch8 = CpuModel{
448 .name = "arch8",
449 .llvm_name = "arch8",
450 .features = featureSet(&[_]Feature{}),
451 };
452 pub const arch9 = CpuModel{
453 .name = "arch9",
454 .llvm_name = "arch9",
455 .features = featureSet(&[_]Feature{
456 .distinct_ops,
457 .fast_serialization,
458 .fp_extension,
459 .high_word,
460 .interlocked_access1,
461 .load_store_on_cond,
462 .message_security_assist_extension3,
463 .message_security_assist_extension4,
464 .population_count,
465 .reset_reference_bits_multiple,
466 }),
467 };
468 pub const generic = CpuModel{
469 .name = "generic",
470 .llvm_name = "generic",
471 .features = featureSet(&[_]Feature{}),
472 };
473 pub const z10 = CpuModel{
474 .name = "z10",
475 .llvm_name = "z10",
476 .features = featureSet(&[_]Feature{}),
477 };
478 pub const z13 = CpuModel{
479 .name = "z13",
480 .llvm_name = "z13",
481 .features = featureSet(&[_]Feature{
482 .dfp_packed_conversion,
483 .dfp_zoned_conversion,
484 .distinct_ops,
485 .enhanced_dat_2,
486 .execution_hint,
487 .fast_serialization,
488 .fp_extension,
489 .high_word,
490 .interlocked_access1,
491 .load_and_trap,
492 .load_and_zero_rightmost_byte,
493 .load_store_on_cond,
494 .load_store_on_cond_2,
495 .message_security_assist_extension3,
496 .message_security_assist_extension4,
497 .message_security_assist_extension5,
498 .miscellaneous_extensions,
499 .population_count,
500 .processor_assist,
501 .reset_reference_bits_multiple,
502 .transactional_execution,
503 .vector,
504 }),
505 };
506 pub const z14 = CpuModel{
507 .name = "z14",
508 .llvm_name = "z14",
509 .features = featureSet(&[_]Feature{
510 .dfp_packed_conversion,
511 .dfp_zoned_conversion,
512 .distinct_ops,
513 .enhanced_dat_2,
514 .execution_hint,
515 .fast_serialization,
516 .fp_extension,
517 .guarded_storage,
518 .high_word,
519 .insert_reference_bits_multiple,
520 .interlocked_access1,
521 .load_and_trap,
522 .load_and_zero_rightmost_byte,
523 .load_store_on_cond,
524 .load_store_on_cond_2,
525 .message_security_assist_extension3,
526 .message_security_assist_extension4,
527 .message_security_assist_extension5,
528 .message_security_assist_extension7,
529 .message_security_assist_extension8,
530 .miscellaneous_extensions,
531 .miscellaneous_extensions_2,
532 .population_count,
533 .processor_assist,
534 .reset_reference_bits_multiple,
535 .transactional_execution,
536 .vector,
537 .vector_enhancements_1,
538 .vector_packed_decimal,
539 }),
540 };
541 pub const z15 = CpuModel{
542 .name = "z15",
543 .llvm_name = "z15",
544 .features = featureSet(&[_]Feature{
545 .deflate_conversion,
546 .dfp_packed_conversion,
547 .dfp_zoned_conversion,
548 .distinct_ops,
549 .enhanced_dat_2,
550 .enhanced_sort,
551 .execution_hint,
552 .fast_serialization,
553 .fp_extension,
554 .guarded_storage,
555 .high_word,
556 .insert_reference_bits_multiple,
557 .interlocked_access1,
558 .load_and_trap,
559 .load_and_zero_rightmost_byte,
560 .load_store_on_cond,
561 .load_store_on_cond_2,
562 .message_security_assist_extension3,
563 .message_security_assist_extension4,
564 .message_security_assist_extension5,
565 .message_security_assist_extension7,
566 .message_security_assist_extension8,
567 .message_security_assist_extension9,
568 .miscellaneous_extensions,
569 .miscellaneous_extensions_2,
570 .miscellaneous_extensions_3,
571 .population_count,
572 .processor_assist,
573 .reset_reference_bits_multiple,
574 .transactional_execution,
575 .vector,
576 .vector_enhancements_1,
577 .vector_enhancements_2,
578 .vector_packed_decimal,
579 .vector_packed_decimal_enhancement,
580 }),
581 };
582 pub const z16 = CpuModel{
583 .name = "z16",
584 .llvm_name = "z16",
585 .features = featureSet(&[_]Feature{
586 .bear_enhancement,
587 .deflate_conversion,
588 .dfp_packed_conversion,
589 .dfp_zoned_conversion,
590 .distinct_ops,
591 .enhanced_dat_2,
592 .enhanced_sort,
593 .execution_hint,
594 .fast_serialization,
595 .fp_extension,
596 .guarded_storage,
597 .high_word,
598 .insert_reference_bits_multiple,
599 .interlocked_access1,
600 .load_and_trap,
601 .load_and_zero_rightmost_byte,
602 .load_store_on_cond,
603 .load_store_on_cond_2,
604 .message_security_assist_extension3,
605 .message_security_assist_extension4,
606 .message_security_assist_extension5,
607 .message_security_assist_extension7,
608 .message_security_assist_extension8,
609 .message_security_assist_extension9,
610 .miscellaneous_extensions,
611 .miscellaneous_extensions_2,
612 .miscellaneous_extensions_3,
613 .nnp_assist,
614 .population_count,
615 .processor_activity_instrumentation,
616 .processor_assist,
617 .reset_dat_protection,
618 .reset_reference_bits_multiple,
619 .transactional_execution,
620 .vector,
621 .vector_enhancements_1,
622 .vector_enhancements_2,
623 .vector_packed_decimal,
624 .vector_packed_decimal_enhancement,
625 .vector_packed_decimal_enhancement_2,
626 }),
627 };
628 pub const z196 = CpuModel{
629 .name = "z196",
630 .llvm_name = "z196",
631 .features = featureSet(&[_]Feature{
632 .distinct_ops,
633 .fast_serialization,
634 .fp_extension,
635 .high_word,
636 .interlocked_access1,
637 .load_store_on_cond,
638 .message_security_assist_extension3,
639 .message_security_assist_extension4,
640 .population_count,
641 .reset_reference_bits_multiple,
642 }),
643 };
644 pub const zEC12 = CpuModel{
645 .name = "zEC12",
646 .llvm_name = "zEC12",
647 .features = featureSet(&[_]Feature{
648 .dfp_zoned_conversion,
649 .distinct_ops,
650 .enhanced_dat_2,
651 .execution_hint,
652 .fast_serialization,
653 .fp_extension,
654 .high_word,
655 .interlocked_access1,
656 .load_and_trap,
657 .load_store_on_cond,
658 .message_security_assist_extension3,
659 .message_security_assist_extension4,
660 .miscellaneous_extensions,
661 .population_count,
662 .processor_assist,
663 .reset_reference_bits_multiple,
664 .transactional_execution,
665 }),
666 };
667};
lib/std/Target/sparc.zig created+455
......@@ -0,0 +1,455 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 deprecated_v8,
9 detectroundchange,
10 fixallfdivsqrt,
11 hard_quad_float,
12 hasleoncasa,
13 hasumacsmac,
14 insertnopload,
15 leon,
16 leoncyclecounter,
17 leonpwrpsr,
18 no_fmuls,
19 no_fsmuld,
20 popc,
21 soft_float,
22 soft_mul_div,
23 v9,
24 vis,
25 vis2,
26 vis3,
27};
28
29pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
30pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
31pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
32pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
33
34pub const all_features = blk: {
35 const len = @typeInfo(Feature).Enum.fields.len;
36 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
37 var result: [len]CpuFeature = undefined;
38 result[@intFromEnum(Feature.deprecated_v8)] = .{
39 .llvm_name = "deprecated-v8",
40 .description = "Enable deprecated V8 instructions in V9 mode",
41 .dependencies = featureSet(&[_]Feature{}),
42 };
43 result[@intFromEnum(Feature.detectroundchange)] = .{
44 .llvm_name = "detectroundchange",
45 .description = "LEON3 erratum detection: Detects any rounding mode change request: use only the round-to-nearest rounding mode",
46 .dependencies = featureSet(&[_]Feature{}),
47 };
48 result[@intFromEnum(Feature.fixallfdivsqrt)] = .{
49 .llvm_name = "fixallfdivsqrt",
50 .description = "LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store",
51 .dependencies = featureSet(&[_]Feature{}),
52 };
53 result[@intFromEnum(Feature.hard_quad_float)] = .{
54 .llvm_name = "hard-quad-float",
55 .description = "Enable quad-word floating point instructions",
56 .dependencies = featureSet(&[_]Feature{}),
57 };
58 result[@intFromEnum(Feature.hasleoncasa)] = .{
59 .llvm_name = "hasleoncasa",
60 .description = "Enable CASA instruction for LEON3 and LEON4 processors",
61 .dependencies = featureSet(&[_]Feature{}),
62 };
63 result[@intFromEnum(Feature.hasumacsmac)] = .{
64 .llvm_name = "hasumacsmac",
65 .description = "Enable UMAC and SMAC for LEON3 and LEON4 processors",
66 .dependencies = featureSet(&[_]Feature{}),
67 };
68 result[@intFromEnum(Feature.insertnopload)] = .{
69 .llvm_name = "insertnopload",
70 .description = "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction",
71 .dependencies = featureSet(&[_]Feature{}),
72 };
73 result[@intFromEnum(Feature.leon)] = .{
74 .llvm_name = "leon",
75 .description = "Enable LEON extensions",
76 .dependencies = featureSet(&[_]Feature{}),
77 };
78 result[@intFromEnum(Feature.leoncyclecounter)] = .{
79 .llvm_name = "leoncyclecounter",
80 .description = "Use the Leon cycle counter register",
81 .dependencies = featureSet(&[_]Feature{}),
82 };
83 result[@intFromEnum(Feature.leonpwrpsr)] = .{
84 .llvm_name = "leonpwrpsr",
85 .description = "Enable the PWRPSR instruction",
86 .dependencies = featureSet(&[_]Feature{}),
87 };
88 result[@intFromEnum(Feature.no_fmuls)] = .{
89 .llvm_name = "no-fmuls",
90 .description = "Disable the fmuls instruction.",
91 .dependencies = featureSet(&[_]Feature{}),
92 };
93 result[@intFromEnum(Feature.no_fsmuld)] = .{
94 .llvm_name = "no-fsmuld",
95 .description = "Disable the fsmuld instruction.",
96 .dependencies = featureSet(&[_]Feature{}),
97 };
98 result[@intFromEnum(Feature.popc)] = .{
99 .llvm_name = "popc",
100 .description = "Use the popc (population count) instruction",
101 .dependencies = featureSet(&[_]Feature{}),
102 };
103 result[@intFromEnum(Feature.soft_float)] = .{
104 .llvm_name = "soft-float",
105 .description = "Use software emulation for floating point",
106 .dependencies = featureSet(&[_]Feature{}),
107 };
108 result[@intFromEnum(Feature.soft_mul_div)] = .{
109 .llvm_name = "soft-mul-div",
110 .description = "Use software emulation for integer multiply and divide",
111 .dependencies = featureSet(&[_]Feature{}),
112 };
113 result[@intFromEnum(Feature.v9)] = .{
114 .llvm_name = "v9",
115 .description = "Enable SPARC-V9 instructions",
116 .dependencies = featureSet(&[_]Feature{}),
117 };
118 result[@intFromEnum(Feature.vis)] = .{
119 .llvm_name = "vis",
120 .description = "Enable UltraSPARC Visual Instruction Set extensions",
121 .dependencies = featureSet(&[_]Feature{}),
122 };
123 result[@intFromEnum(Feature.vis2)] = .{
124 .llvm_name = "vis2",
125 .description = "Enable Visual Instruction Set extensions II",
126 .dependencies = featureSet(&[_]Feature{}),
127 };
128 result[@intFromEnum(Feature.vis3)] = .{
129 .llvm_name = "vis3",
130 .description = "Enable Visual Instruction Set extensions III",
131 .dependencies = featureSet(&[_]Feature{}),
132 };
133 const ti = @typeInfo(Feature);
134 for (&result, 0..) |*elem, i| {
135 elem.index = i;
136 elem.name = ti.Enum.fields[i].name;
137 }
138 break :blk result;
139};
140
141pub const cpu = struct {
142 pub const at697e = CpuModel{
143 .name = "at697e",
144 .llvm_name = "at697e",
145 .features = featureSet(&[_]Feature{
146 .insertnopload,
147 .leon,
148 }),
149 };
150 pub const at697f = CpuModel{
151 .name = "at697f",
152 .llvm_name = "at697f",
153 .features = featureSet(&[_]Feature{
154 .insertnopload,
155 .leon,
156 }),
157 };
158 pub const f934 = CpuModel{
159 .name = "f934",
160 .llvm_name = "f934",
161 .features = featureSet(&[_]Feature{}),
162 };
163 pub const generic = CpuModel{
164 .name = "generic",
165 .llvm_name = "generic",
166 .features = featureSet(&[_]Feature{}),
167 };
168 pub const gr712rc = CpuModel{
169 .name = "gr712rc",
170 .llvm_name = "gr712rc",
171 .features = featureSet(&[_]Feature{
172 .hasleoncasa,
173 .leon,
174 }),
175 };
176 pub const gr740 = CpuModel{
177 .name = "gr740",
178 .llvm_name = "gr740",
179 .features = featureSet(&[_]Feature{
180 .hasleoncasa,
181 .hasumacsmac,
182 .leon,
183 .leoncyclecounter,
184 .leonpwrpsr,
185 }),
186 };
187 pub const hypersparc = CpuModel{
188 .name = "hypersparc",
189 .llvm_name = "hypersparc",
190 .features = featureSet(&[_]Feature{}),
191 };
192 pub const leon2 = CpuModel{
193 .name = "leon2",
194 .llvm_name = "leon2",
195 .features = featureSet(&[_]Feature{
196 .leon,
197 }),
198 };
199 pub const leon3 = CpuModel{
200 .name = "leon3",
201 .llvm_name = "leon3",
202 .features = featureSet(&[_]Feature{
203 .hasumacsmac,
204 .leon,
205 }),
206 };
207 pub const leon4 = CpuModel{
208 .name = "leon4",
209 .llvm_name = "leon4",
210 .features = featureSet(&[_]Feature{
211 .hasleoncasa,
212 .hasumacsmac,
213 .leon,
214 }),
215 };
216 pub const ma2080 = CpuModel{
217 .name = "ma2080",
218 .llvm_name = "ma2080",
219 .features = featureSet(&[_]Feature{
220 .hasleoncasa,
221 .leon,
222 }),
223 };
224 pub const ma2085 = CpuModel{
225 .name = "ma2085",
226 .llvm_name = "ma2085",
227 .features = featureSet(&[_]Feature{
228 .hasleoncasa,
229 .leon,
230 }),
231 };
232 pub const ma2100 = CpuModel{
233 .name = "ma2100",
234 .llvm_name = "ma2100",
235 .features = featureSet(&[_]Feature{
236 .hasleoncasa,
237 .leon,
238 }),
239 };
240 pub const ma2150 = CpuModel{
241 .name = "ma2150",
242 .llvm_name = "ma2150",
243 .features = featureSet(&[_]Feature{
244 .hasleoncasa,
245 .leon,
246 }),
247 };
248 pub const ma2155 = CpuModel{
249 .name = "ma2155",
250 .llvm_name = "ma2155",
251 .features = featureSet(&[_]Feature{
252 .hasleoncasa,
253 .leon,
254 }),
255 };
256 pub const ma2450 = CpuModel{
257 .name = "ma2450",
258 .llvm_name = "ma2450",
259 .features = featureSet(&[_]Feature{
260 .hasleoncasa,
261 .leon,
262 }),
263 };
264 pub const ma2455 = CpuModel{
265 .name = "ma2455",
266 .llvm_name = "ma2455",
267 .features = featureSet(&[_]Feature{
268 .hasleoncasa,
269 .leon,
270 }),
271 };
272 pub const ma2480 = CpuModel{
273 .name = "ma2480",
274 .llvm_name = "ma2480",
275 .features = featureSet(&[_]Feature{
276 .hasleoncasa,
277 .leon,
278 }),
279 };
280 pub const ma2485 = CpuModel{
281 .name = "ma2485",
282 .llvm_name = "ma2485",
283 .features = featureSet(&[_]Feature{
284 .hasleoncasa,
285 .leon,
286 }),
287 };
288 pub const ma2x5x = CpuModel{
289 .name = "ma2x5x",
290 .llvm_name = "ma2x5x",
291 .features = featureSet(&[_]Feature{
292 .hasleoncasa,
293 .leon,
294 }),
295 };
296 pub const ma2x8x = CpuModel{
297 .name = "ma2x8x",
298 .llvm_name = "ma2x8x",
299 .features = featureSet(&[_]Feature{
300 .hasleoncasa,
301 .leon,
302 }),
303 };
304 pub const myriad2 = CpuModel{
305 .name = "myriad2",
306 .llvm_name = "myriad2",
307 .features = featureSet(&[_]Feature{
308 .hasleoncasa,
309 .leon,
310 }),
311 };
312 pub const myriad2_1 = CpuModel{
313 .name = "myriad2_1",
314 .llvm_name = "myriad2.1",
315 .features = featureSet(&[_]Feature{
316 .hasleoncasa,
317 .leon,
318 }),
319 };
320 pub const myriad2_2 = CpuModel{
321 .name = "myriad2_2",
322 .llvm_name = "myriad2.2",
323 .features = featureSet(&[_]Feature{
324 .hasleoncasa,
325 .leon,
326 }),
327 };
328 pub const myriad2_3 = CpuModel{
329 .name = "myriad2_3",
330 .llvm_name = "myriad2.3",
331 .features = featureSet(&[_]Feature{
332 .hasleoncasa,
333 .leon,
334 }),
335 };
336 pub const niagara = CpuModel{
337 .name = "niagara",
338 .llvm_name = "niagara",
339 .features = featureSet(&[_]Feature{
340 .deprecated_v8,
341 .v9,
342 .vis,
343 .vis2,
344 }),
345 };
346 pub const niagara2 = CpuModel{
347 .name = "niagara2",
348 .llvm_name = "niagara2",
349 .features = featureSet(&[_]Feature{
350 .deprecated_v8,
351 .popc,
352 .v9,
353 .vis,
354 .vis2,
355 }),
356 };
357 pub const niagara3 = CpuModel{
358 .name = "niagara3",
359 .llvm_name = "niagara3",
360 .features = featureSet(&[_]Feature{
361 .deprecated_v8,
362 .popc,
363 .v9,
364 .vis,
365 .vis2,
366 }),
367 };
368 pub const niagara4 = CpuModel{
369 .name = "niagara4",
370 .llvm_name = "niagara4",
371 .features = featureSet(&[_]Feature{
372 .deprecated_v8,
373 .popc,
374 .v9,
375 .vis,
376 .vis2,
377 .vis3,
378 }),
379 };
380 pub const sparclet = CpuModel{
381 .name = "sparclet",
382 .llvm_name = "sparclet",
383 .features = featureSet(&[_]Feature{}),
384 };
385 pub const sparclite = CpuModel{
386 .name = "sparclite",
387 .llvm_name = "sparclite",
388 .features = featureSet(&[_]Feature{}),
389 };
390 pub const sparclite86x = CpuModel{
391 .name = "sparclite86x",
392 .llvm_name = "sparclite86x",
393 .features = featureSet(&[_]Feature{}),
394 };
395 pub const supersparc = CpuModel{
396 .name = "supersparc",
397 .llvm_name = "supersparc",
398 .features = featureSet(&[_]Feature{}),
399 };
400 pub const tsc701 = CpuModel{
401 .name = "tsc701",
402 .llvm_name = "tsc701",
403 .features = featureSet(&[_]Feature{}),
404 };
405 pub const ultrasparc = CpuModel{
406 .name = "ultrasparc",
407 .llvm_name = "ultrasparc",
408 .features = featureSet(&[_]Feature{
409 .deprecated_v8,
410 .v9,
411 .vis,
412 }),
413 };
414 pub const ultrasparc3 = CpuModel{
415 .name = "ultrasparc3",
416 .llvm_name = "ultrasparc3",
417 .features = featureSet(&[_]Feature{
418 .deprecated_v8,
419 .v9,
420 .vis,
421 .vis2,
422 }),
423 };
424 pub const ut699 = CpuModel{
425 .name = "ut699",
426 .llvm_name = "ut699",
427 .features = featureSet(&[_]Feature{
428 .fixallfdivsqrt,
429 .insertnopload,
430 .leon,
431 .no_fmuls,
432 .no_fsmuld,
433 }),
434 };
435 pub const v7 = CpuModel{
436 .name = "v7",
437 .llvm_name = "v7",
438 .features = featureSet(&[_]Feature{
439 .no_fsmuld,
440 .soft_mul_div,
441 }),
442 };
443 pub const v8 = CpuModel{
444 .name = "v8",
445 .llvm_name = "v8",
446 .features = featureSet(&[_]Feature{}),
447 };
448 pub const v9 = CpuModel{
449 .name = "v9",
450 .llvm_name = "v9",
451 .features = featureSet(&[_]Feature{
452 .v9,
453 }),
454 };
455};
lib/std/Target/spirv.zig created+2091
......@@ -0,0 +1,2091 @@
1//! This file is auto-generated by tools/update_spirv_features.zig.
2//! TODO: Dependencies of capabilities on extensions.
3//! TODO: Dependencies of extensions on extensions.
4//! TODO: Dependencies of extensions on versions.
5
6const std = @import("../std.zig");
7const CpuFeature = std.Target.Cpu.Feature;
8const CpuModel = std.Target.Cpu.Model;
9
10pub const Feature = enum {
11 v1_1,
12 v1_2,
13 v1_3,
14 v1_4,
15 v1_5,
16 SPV_AMD_shader_fragment_mask,
17 SPV_AMD_gpu_shader_int16,
18 SPV_AMD_gpu_shader_half_float,
19 SPV_AMD_texture_gather_bias_lod,
20 SPV_AMD_shader_ballot,
21 SPV_AMD_gcn_shader,
22 SPV_AMD_shader_image_load_store_lod,
23 SPV_AMD_shader_explicit_vertex_parameter,
24 SPV_AMD_shader_trinary_minmax,
25 SPV_AMD_gpu_shader_half_float_fetch,
26 SPV_GOOGLE_hlsl_functionality1,
27 SPV_GOOGLE_user_type,
28 SPV_GOOGLE_decorate_string,
29 SPV_EXT_demote_to_helper_invocation,
30 SPV_EXT_descriptor_indexing,
31 SPV_EXT_fragment_fully_covered,
32 SPV_EXT_shader_stencil_export,
33 SPV_EXT_physical_storage_buffer,
34 SPV_EXT_shader_atomic_float_add,
35 SPV_EXT_shader_atomic_float_min_max,
36 SPV_EXT_shader_image_int64,
37 SPV_EXT_fragment_shader_interlock,
38 SPV_EXT_fragment_invocation_density,
39 SPV_EXT_shader_viewport_index_layer,
40 SPV_INTEL_loop_fuse,
41 SPV_INTEL_fpga_dsp_control,
42 SPV_INTEL_fpga_reg,
43 SPV_INTEL_fpga_memory_accesses,
44 SPV_INTEL_fpga_loop_controls,
45 SPV_INTEL_io_pipes,
46 SPV_INTEL_unstructured_loop_controls,
47 SPV_INTEL_blocking_pipes,
48 SPV_INTEL_device_side_avc_motion_estimation,
49 SPV_INTEL_fpga_memory_attributes,
50 SPV_INTEL_fp_fast_math_mode,
51 SPV_INTEL_media_block_io,
52 SPV_INTEL_shader_integer_functions2,
53 SPV_INTEL_subgroups,
54 SPV_INTEL_fpga_cluster_attributes,
55 SPV_INTEL_kernel_attributes,
56 SPV_INTEL_arbitrary_precision_integers,
57 SPV_KHR_8bit_storage,
58 SPV_KHR_shader_clock,
59 SPV_KHR_device_group,
60 SPV_KHR_16bit_storage,
61 SPV_KHR_variable_pointers,
62 SPV_KHR_no_integer_wrap_decoration,
63 SPV_KHR_subgroup_vote,
64 SPV_KHR_multiview,
65 SPV_KHR_shader_ballot,
66 SPV_KHR_vulkan_memory_model,
67 SPV_KHR_physical_storage_buffer,
68 SPV_KHR_workgroup_memory_explicit_layout,
69 SPV_KHR_fragment_shading_rate,
70 SPV_KHR_shader_atomic_counter_ops,
71 SPV_KHR_shader_draw_parameters,
72 SPV_KHR_storage_buffer_storage_class,
73 SPV_KHR_linkonce_odr,
74 SPV_KHR_terminate_invocation,
75 SPV_KHR_non_semantic_info,
76 SPV_KHR_post_depth_coverage,
77 SPV_KHR_expect_assume,
78 SPV_KHR_ray_tracing,
79 SPV_KHR_ray_query,
80 SPV_KHR_float_controls,
81 SPV_NV_viewport_array2,
82 SPV_NV_shader_subgroup_partitioned,
83 SPV_NVX_multiview_per_view_attributes,
84 SPV_NV_ray_tracing,
85 SPV_NV_shader_image_footprint,
86 SPV_NV_shading_rate,
87 SPV_NV_stereo_view_rendering,
88 SPV_NV_compute_shader_derivatives,
89 SPV_NV_shader_sm_builtins,
90 SPV_NV_mesh_shader,
91 SPV_NV_geometry_shader_passthrough,
92 SPV_NV_fragment_shader_barycentric,
93 SPV_NV_cooperative_matrix,
94 SPV_NV_sample_mask_override_coverage,
95 Matrix,
96 Shader,
97 Geometry,
98 Tessellation,
99 Addresses,
100 Linkage,
101 Kernel,
102 Vector16,
103 Float16Buffer,
104 Float16,
105 Float64,
106 Int64,
107 Int64Atomics,
108 ImageBasic,
109 ImageReadWrite,
110 ImageMipmap,
111 Pipes,
112 Groups,
113 DeviceEnqueue,
114 LiteralSampler,
115 AtomicStorage,
116 Int16,
117 TessellationPointSize,
118 GeometryPointSize,
119 ImageGatherExtended,
120 StorageImageMultisample,
121 UniformBufferArrayDynamicIndexing,
122 SampledImageArrayDynamicIndexing,
123 StorageBufferArrayDynamicIndexing,
124 StorageImageArrayDynamicIndexing,
125 ClipDistance,
126 CullDistance,
127 ImageCubeArray,
128 SampleRateShading,
129 ImageRect,
130 SampledRect,
131 GenericPointer,
132 Int8,
133 InputAttachment,
134 SparseResidency,
135 MinLod,
136 Sampled1D,
137 Image1D,
138 SampledCubeArray,
139 SampledBuffer,
140 ImageBuffer,
141 ImageMSArray,
142 StorageImageExtendedFormats,
143 ImageQuery,
144 DerivativeControl,
145 InterpolationFunction,
146 TransformFeedback,
147 GeometryStreams,
148 StorageImageReadWithoutFormat,
149 StorageImageWriteWithoutFormat,
150 MultiViewport,
151 SubgroupDispatch,
152 NamedBarrier,
153 PipeStorage,
154 GroupNonUniform,
155 GroupNonUniformVote,
156 GroupNonUniformArithmetic,
157 GroupNonUniformBallot,
158 GroupNonUniformShuffle,
159 GroupNonUniformShuffleRelative,
160 GroupNonUniformClustered,
161 GroupNonUniformQuad,
162 ShaderLayer,
163 ShaderViewportIndex,
164 FragmentShadingRateKHR,
165 SubgroupBallotKHR,
166 DrawParameters,
167 WorkgroupMemoryExplicitLayoutKHR,
168 WorkgroupMemoryExplicitLayout8BitAccessKHR,
169 WorkgroupMemoryExplicitLayout16BitAccessKHR,
170 SubgroupVoteKHR,
171 StorageBuffer16BitAccess,
172 StorageUniformBufferBlock16,
173 UniformAndStorageBuffer16BitAccess,
174 StorageUniform16,
175 StoragePushConstant16,
176 StorageInputOutput16,
177 DeviceGroup,
178 MultiView,
179 VariablePointersStorageBuffer,
180 VariablePointers,
181 AtomicStorageOps,
182 SampleMaskPostDepthCoverage,
183 StorageBuffer8BitAccess,
184 UniformAndStorageBuffer8BitAccess,
185 StoragePushConstant8,
186 DenormPreserve,
187 DenormFlushToZero,
188 SignedZeroInfNanPreserve,
189 RoundingModeRTE,
190 RoundingModeRTZ,
191 RayQueryProvisionalKHR,
192 RayQueryKHR,
193 RayTraversalPrimitiveCullingKHR,
194 RayTracingKHR,
195 Float16ImageAMD,
196 ImageGatherBiasLodAMD,
197 FragmentMaskAMD,
198 StencilExportEXT,
199 ImageReadWriteLodAMD,
200 Int64ImageEXT,
201 ShaderClockKHR,
202 SampleMaskOverrideCoverageNV,
203 GeometryShaderPassthroughNV,
204 ShaderViewportIndexLayerEXT,
205 ShaderViewportIndexLayerNV,
206 ShaderViewportMaskNV,
207 ShaderStereoViewNV,
208 PerViewAttributesNV,
209 FragmentFullyCoveredEXT,
210 MeshShadingNV,
211 ImageFootprintNV,
212 FragmentBarycentricNV,
213 ComputeDerivativeGroupQuadsNV,
214 FragmentDensityEXT,
215 ShadingRateNV,
216 GroupNonUniformPartitionedNV,
217 ShaderNonUniform,
218 ShaderNonUniformEXT,
219 RuntimeDescriptorArray,
220 RuntimeDescriptorArrayEXT,
221 InputAttachmentArrayDynamicIndexing,
222 InputAttachmentArrayDynamicIndexingEXT,
223 UniformTexelBufferArrayDynamicIndexing,
224 UniformTexelBufferArrayDynamicIndexingEXT,
225 StorageTexelBufferArrayDynamicIndexing,
226 StorageTexelBufferArrayDynamicIndexingEXT,
227 UniformBufferArrayNonUniformIndexing,
228 UniformBufferArrayNonUniformIndexingEXT,
229 SampledImageArrayNonUniformIndexing,
230 SampledImageArrayNonUniformIndexingEXT,
231 StorageBufferArrayNonUniformIndexing,
232 StorageBufferArrayNonUniformIndexingEXT,
233 StorageImageArrayNonUniformIndexing,
234 StorageImageArrayNonUniformIndexingEXT,
235 InputAttachmentArrayNonUniformIndexing,
236 InputAttachmentArrayNonUniformIndexingEXT,
237 UniformTexelBufferArrayNonUniformIndexing,
238 UniformTexelBufferArrayNonUniformIndexingEXT,
239 StorageTexelBufferArrayNonUniformIndexing,
240 StorageTexelBufferArrayNonUniformIndexingEXT,
241 RayTracingNV,
242 VulkanMemoryModel,
243 VulkanMemoryModelKHR,
244 VulkanMemoryModelDeviceScope,
245 VulkanMemoryModelDeviceScopeKHR,
246 PhysicalStorageBufferAddresses,
247 PhysicalStorageBufferAddressesEXT,
248 ComputeDerivativeGroupLinearNV,
249 RayTracingProvisionalKHR,
250 CooperativeMatrixNV,
251 FragmentShaderSampleInterlockEXT,
252 FragmentShaderShadingRateInterlockEXT,
253 ShaderSMBuiltinsNV,
254 FragmentShaderPixelInterlockEXT,
255 DemoteToHelperInvocationEXT,
256 SubgroupShuffleINTEL,
257 SubgroupBufferBlockIOINTEL,
258 SubgroupImageBlockIOINTEL,
259 SubgroupImageMediaBlockIOINTEL,
260 RoundToInfinityINTEL,
261 FloatingPointModeINTEL,
262 IntegerFunctions2INTEL,
263 FunctionPointersINTEL,
264 IndirectReferencesINTEL,
265 AsmINTEL,
266 AtomicFloat32MinMaxEXT,
267 AtomicFloat64MinMaxEXT,
268 AtomicFloat16MinMaxEXT,
269 VectorComputeINTEL,
270 VectorAnyINTEL,
271 ExpectAssumeKHR,
272 SubgroupAvcMotionEstimationINTEL,
273 SubgroupAvcMotionEstimationIntraINTEL,
274 SubgroupAvcMotionEstimationChromaINTEL,
275 VariableLengthArrayINTEL,
276 FunctionFloatControlINTEL,
277 FPGAMemoryAttributesINTEL,
278 FPFastMathModeINTEL,
279 ArbitraryPrecisionIntegersINTEL,
280 UnstructuredLoopControlsINTEL,
281 FPGALoopControlsINTEL,
282 KernelAttributesINTEL,
283 FPGAKernelAttributesINTEL,
284 FPGAMemoryAccessesINTEL,
285 FPGAClusterAttributesINTEL,
286 LoopFuseINTEL,
287 FPGABufferLocationINTEL,
288 USMStorageClassesINTEL,
289 IOPipesINTEL,
290 BlockingPipesINTEL,
291 FPGARegINTEL,
292 AtomicFloat32AddEXT,
293 AtomicFloat64AddEXT,
294 LongConstantCompositeINTEL,
295};
296
297pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
298pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
299pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
300pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
301
302pub const all_features = blk: {
303 @setEvalBranchQuota(2000);
304 const len = @typeInfo(Feature).Enum.fields.len;
305 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
306 var result: [len]CpuFeature = undefined;
307 result[@intFromEnum(Feature.v1_1)] = .{
308 .llvm_name = null,
309 .description = "SPIR-V version 1.1",
310 .dependencies = featureSet(&[_]Feature{}),
311 };
312 result[@intFromEnum(Feature.v1_2)] = .{
313 .llvm_name = null,
314 .description = "SPIR-V version 1.2",
315 .dependencies = featureSet(&[_]Feature{
316 .v1_1,
317 }),
318 };
319 result[@intFromEnum(Feature.v1_3)] = .{
320 .llvm_name = null,
321 .description = "SPIR-V version 1.3",
322 .dependencies = featureSet(&[_]Feature{
323 .v1_2,
324 }),
325 };
326 result[@intFromEnum(Feature.v1_4)] = .{
327 .llvm_name = null,
328 .description = "SPIR-V version 1.4",
329 .dependencies = featureSet(&[_]Feature{
330 .v1_3,
331 }),
332 };
333 result[@intFromEnum(Feature.v1_5)] = .{
334 .llvm_name = null,
335 .description = "SPIR-V version 1.5",
336 .dependencies = featureSet(&[_]Feature{
337 .v1_4,
338 }),
339 };
340 result[@intFromEnum(Feature.SPV_AMD_shader_fragment_mask)] = .{
341 .llvm_name = null,
342 .description = "SPIR-V extension SPV_AMD_shader_fragment_mask",
343 .dependencies = featureSet(&[_]Feature{}),
344 };
345 result[@intFromEnum(Feature.SPV_AMD_gpu_shader_int16)] = .{
346 .llvm_name = null,
347 .description = "SPIR-V extension SPV_AMD_gpu_shader_int16",
348 .dependencies = featureSet(&[_]Feature{}),
349 };
350 result[@intFromEnum(Feature.SPV_AMD_gpu_shader_half_float)] = .{
351 .llvm_name = null,
352 .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float",
353 .dependencies = featureSet(&[_]Feature{}),
354 };
355 result[@intFromEnum(Feature.SPV_AMD_texture_gather_bias_lod)] = .{
356 .llvm_name = null,
357 .description = "SPIR-V extension SPV_AMD_texture_gather_bias_lod",
358 .dependencies = featureSet(&[_]Feature{}),
359 };
360 result[@intFromEnum(Feature.SPV_AMD_shader_ballot)] = .{
361 .llvm_name = null,
362 .description = "SPIR-V extension SPV_AMD_shader_ballot",
363 .dependencies = featureSet(&[_]Feature{}),
364 };
365 result[@intFromEnum(Feature.SPV_AMD_gcn_shader)] = .{
366 .llvm_name = null,
367 .description = "SPIR-V extension SPV_AMD_gcn_shader",
368 .dependencies = featureSet(&[_]Feature{}),
369 };
370 result[@intFromEnum(Feature.SPV_AMD_shader_image_load_store_lod)] = .{
371 .llvm_name = null,
372 .description = "SPIR-V extension SPV_AMD_shader_image_load_store_lod",
373 .dependencies = featureSet(&[_]Feature{}),
374 };
375 result[@intFromEnum(Feature.SPV_AMD_shader_explicit_vertex_parameter)] = .{
376 .llvm_name = null,
377 .description = "SPIR-V extension SPV_AMD_shader_explicit_vertex_parameter",
378 .dependencies = featureSet(&[_]Feature{}),
379 };
380 result[@intFromEnum(Feature.SPV_AMD_shader_trinary_minmax)] = .{
381 .llvm_name = null,
382 .description = "SPIR-V extension SPV_AMD_shader_trinary_minmax",
383 .dependencies = featureSet(&[_]Feature{}),
384 };
385 result[@intFromEnum(Feature.SPV_AMD_gpu_shader_half_float_fetch)] = .{
386 .llvm_name = null,
387 .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float_fetch",
388 .dependencies = featureSet(&[_]Feature{}),
389 };
390 result[@intFromEnum(Feature.SPV_GOOGLE_hlsl_functionality1)] = .{
391 .llvm_name = null,
392 .description = "SPIR-V extension SPV_GOOGLE_hlsl_functionality1",
393 .dependencies = featureSet(&[_]Feature{}),
394 };
395 result[@intFromEnum(Feature.SPV_GOOGLE_user_type)] = .{
396 .llvm_name = null,
397 .description = "SPIR-V extension SPV_GOOGLE_user_type",
398 .dependencies = featureSet(&[_]Feature{}),
399 };
400 result[@intFromEnum(Feature.SPV_GOOGLE_decorate_string)] = .{
401 .llvm_name = null,
402 .description = "SPIR-V extension SPV_GOOGLE_decorate_string",
403 .dependencies = featureSet(&[_]Feature{}),
404 };
405 result[@intFromEnum(Feature.SPV_EXT_demote_to_helper_invocation)] = .{
406 .llvm_name = null,
407 .description = "SPIR-V extension SPV_EXT_demote_to_helper_invocation",
408 .dependencies = featureSet(&[_]Feature{}),
409 };
410 result[@intFromEnum(Feature.SPV_EXT_descriptor_indexing)] = .{
411 .llvm_name = null,
412 .description = "SPIR-V extension SPV_EXT_descriptor_indexing",
413 .dependencies = featureSet(&[_]Feature{}),
414 };
415 result[@intFromEnum(Feature.SPV_EXT_fragment_fully_covered)] = .{
416 .llvm_name = null,
417 .description = "SPIR-V extension SPV_EXT_fragment_fully_covered",
418 .dependencies = featureSet(&[_]Feature{}),
419 };
420 result[@intFromEnum(Feature.SPV_EXT_shader_stencil_export)] = .{
421 .llvm_name = null,
422 .description = "SPIR-V extension SPV_EXT_shader_stencil_export",
423 .dependencies = featureSet(&[_]Feature{}),
424 };
425 result[@intFromEnum(Feature.SPV_EXT_physical_storage_buffer)] = .{
426 .llvm_name = null,
427 .description = "SPIR-V extension SPV_EXT_physical_storage_buffer",
428 .dependencies = featureSet(&[_]Feature{}),
429 };
430 result[@intFromEnum(Feature.SPV_EXT_shader_atomic_float_add)] = .{
431 .llvm_name = null,
432 .description = "SPIR-V extension SPV_EXT_shader_atomic_float_add",
433 .dependencies = featureSet(&[_]Feature{}),
434 };
435 result[@intFromEnum(Feature.SPV_EXT_shader_atomic_float_min_max)] = .{
436 .llvm_name = null,
437 .description = "SPIR-V extension SPV_EXT_shader_atomic_float_min_max",
438 .dependencies = featureSet(&[_]Feature{}),
439 };
440 result[@intFromEnum(Feature.SPV_EXT_shader_image_int64)] = .{
441 .llvm_name = null,
442 .description = "SPIR-V extension SPV_EXT_shader_image_int64",
443 .dependencies = featureSet(&[_]Feature{}),
444 };
445 result[@intFromEnum(Feature.SPV_EXT_fragment_shader_interlock)] = .{
446 .llvm_name = null,
447 .description = "SPIR-V extension SPV_EXT_fragment_shader_interlock",
448 .dependencies = featureSet(&[_]Feature{}),
449 };
450 result[@intFromEnum(Feature.SPV_EXT_fragment_invocation_density)] = .{
451 .llvm_name = null,
452 .description = "SPIR-V extension SPV_EXT_fragment_invocation_density",
453 .dependencies = featureSet(&[_]Feature{}),
454 };
455 result[@intFromEnum(Feature.SPV_EXT_shader_viewport_index_layer)] = .{
456 .llvm_name = null,
457 .description = "SPIR-V extension SPV_EXT_shader_viewport_index_layer",
458 .dependencies = featureSet(&[_]Feature{}),
459 };
460 result[@intFromEnum(Feature.SPV_INTEL_loop_fuse)] = .{
461 .llvm_name = null,
462 .description = "SPIR-V extension SPV_INTEL_loop_fuse",
463 .dependencies = featureSet(&[_]Feature{}),
464 };
465 result[@intFromEnum(Feature.SPV_INTEL_fpga_dsp_control)] = .{
466 .llvm_name = null,
467 .description = "SPIR-V extension SPV_INTEL_fpga_dsp_control",
468 .dependencies = featureSet(&[_]Feature{}),
469 };
470 result[@intFromEnum(Feature.SPV_INTEL_fpga_reg)] = .{
471 .llvm_name = null,
472 .description = "SPIR-V extension SPV_INTEL_fpga_reg",
473 .dependencies = featureSet(&[_]Feature{}),
474 };
475 result[@intFromEnum(Feature.SPV_INTEL_fpga_memory_accesses)] = .{
476 .llvm_name = null,
477 .description = "SPIR-V extension SPV_INTEL_fpga_memory_accesses",
478 .dependencies = featureSet(&[_]Feature{}),
479 };
480 result[@intFromEnum(Feature.SPV_INTEL_fpga_loop_controls)] = .{
481 .llvm_name = null,
482 .description = "SPIR-V extension SPV_INTEL_fpga_loop_controls",
483 .dependencies = featureSet(&[_]Feature{}),
484 };
485 result[@intFromEnum(Feature.SPV_INTEL_io_pipes)] = .{
486 .llvm_name = null,
487 .description = "SPIR-V extension SPV_INTEL_io_pipes",
488 .dependencies = featureSet(&[_]Feature{}),
489 };
490 result[@intFromEnum(Feature.SPV_INTEL_unstructured_loop_controls)] = .{
491 .llvm_name = null,
492 .description = "SPIR-V extension SPV_INTEL_unstructured_loop_controls",
493 .dependencies = featureSet(&[_]Feature{}),
494 };
495 result[@intFromEnum(Feature.SPV_INTEL_blocking_pipes)] = .{
496 .llvm_name = null,
497 .description = "SPIR-V extension SPV_INTEL_blocking_pipes",
498 .dependencies = featureSet(&[_]Feature{}),
499 };
500 result[@intFromEnum(Feature.SPV_INTEL_device_side_avc_motion_estimation)] = .{
501 .llvm_name = null,
502 .description = "SPIR-V extension SPV_INTEL_device_side_avc_motion_estimation",
503 .dependencies = featureSet(&[_]Feature{}),
504 };
505 result[@intFromEnum(Feature.SPV_INTEL_fpga_memory_attributes)] = .{
506 .llvm_name = null,
507 .description = "SPIR-V extension SPV_INTEL_fpga_memory_attributes",
508 .dependencies = featureSet(&[_]Feature{}),
509 };
510 result[@intFromEnum(Feature.SPV_INTEL_fp_fast_math_mode)] = .{
511 .llvm_name = null,
512 .description = "SPIR-V extension SPV_INTEL_fp_fast_math_mode",
513 .dependencies = featureSet(&[_]Feature{}),
514 };
515 result[@intFromEnum(Feature.SPV_INTEL_media_block_io)] = .{
516 .llvm_name = null,
517 .description = "SPIR-V extension SPV_INTEL_media_block_io",
518 .dependencies = featureSet(&[_]Feature{}),
519 };
520 result[@intFromEnum(Feature.SPV_INTEL_shader_integer_functions2)] = .{
521 .llvm_name = null,
522 .description = "SPIR-V extension SPV_INTEL_shader_integer_functions2",
523 .dependencies = featureSet(&[_]Feature{}),
524 };
525 result[@intFromEnum(Feature.SPV_INTEL_subgroups)] = .{
526 .llvm_name = null,
527 .description = "SPIR-V extension SPV_INTEL_subgroups",
528 .dependencies = featureSet(&[_]Feature{}),
529 };
530 result[@intFromEnum(Feature.SPV_INTEL_fpga_cluster_attributes)] = .{
531 .llvm_name = null,
532 .description = "SPIR-V extension SPV_INTEL_fpga_cluster_attributes",
533 .dependencies = featureSet(&[_]Feature{}),
534 };
535 result[@intFromEnum(Feature.SPV_INTEL_kernel_attributes)] = .{
536 .llvm_name = null,
537 .description = "SPIR-V extension SPV_INTEL_kernel_attributes",
538 .dependencies = featureSet(&[_]Feature{}),
539 };
540 result[@intFromEnum(Feature.SPV_INTEL_arbitrary_precision_integers)] = .{
541 .llvm_name = null,
542 .description = "SPIR-V extension SPV_INTEL_arbitrary_precision_integers",
543 .dependencies = featureSet(&[_]Feature{}),
544 };
545 result[@intFromEnum(Feature.SPV_KHR_8bit_storage)] = .{
546 .llvm_name = null,
547 .description = "SPIR-V extension SPV_KHR_8bit_storage",
548 .dependencies = featureSet(&[_]Feature{}),
549 };
550 result[@intFromEnum(Feature.SPV_KHR_shader_clock)] = .{
551 .llvm_name = null,
552 .description = "SPIR-V extension SPV_KHR_shader_clock",
553 .dependencies = featureSet(&[_]Feature{}),
554 };
555 result[@intFromEnum(Feature.SPV_KHR_device_group)] = .{
556 .llvm_name = null,
557 .description = "SPIR-V extension SPV_KHR_device_group",
558 .dependencies = featureSet(&[_]Feature{}),
559 };
560 result[@intFromEnum(Feature.SPV_KHR_16bit_storage)] = .{
561 .llvm_name = null,
562 .description = "SPIR-V extension SPV_KHR_16bit_storage",
563 .dependencies = featureSet(&[_]Feature{}),
564 };
565 result[@intFromEnum(Feature.SPV_KHR_variable_pointers)] = .{
566 .llvm_name = null,
567 .description = "SPIR-V extension SPV_KHR_variable_pointers",
568 .dependencies = featureSet(&[_]Feature{}),
569 };
570 result[@intFromEnum(Feature.SPV_KHR_no_integer_wrap_decoration)] = .{
571 .llvm_name = null,
572 .description = "SPIR-V extension SPV_KHR_no_integer_wrap_decoration",
573 .dependencies = featureSet(&[_]Feature{}),
574 };
575 result[@intFromEnum(Feature.SPV_KHR_subgroup_vote)] = .{
576 .llvm_name = null,
577 .description = "SPIR-V extension SPV_KHR_subgroup_vote",
578 .dependencies = featureSet(&[_]Feature{}),
579 };
580 result[@intFromEnum(Feature.SPV_KHR_multiview)] = .{
581 .llvm_name = null,
582 .description = "SPIR-V extension SPV_KHR_multiview",
583 .dependencies = featureSet(&[_]Feature{}),
584 };
585 result[@intFromEnum(Feature.SPV_KHR_shader_ballot)] = .{
586 .llvm_name = null,
587 .description = "SPIR-V extension SPV_KHR_shader_ballot",
588 .dependencies = featureSet(&[_]Feature{}),
589 };
590 result[@intFromEnum(Feature.SPV_KHR_vulkan_memory_model)] = .{
591 .llvm_name = null,
592 .description = "SPIR-V extension SPV_KHR_vulkan_memory_model",
593 .dependencies = featureSet(&[_]Feature{}),
594 };
595 result[@intFromEnum(Feature.SPV_KHR_physical_storage_buffer)] = .{
596 .llvm_name = null,
597 .description = "SPIR-V extension SPV_KHR_physical_storage_buffer",
598 .dependencies = featureSet(&[_]Feature{}),
599 };
600 result[@intFromEnum(Feature.SPV_KHR_workgroup_memory_explicit_layout)] = .{
601 .llvm_name = null,
602 .description = "SPIR-V extension SPV_KHR_workgroup_memory_explicit_layout",
603 .dependencies = featureSet(&[_]Feature{}),
604 };
605 result[@intFromEnum(Feature.SPV_KHR_fragment_shading_rate)] = .{
606 .llvm_name = null,
607 .description = "SPIR-V extension SPV_KHR_fragment_shading_rate",
608 .dependencies = featureSet(&[_]Feature{}),
609 };
610 result[@intFromEnum(Feature.SPV_KHR_shader_atomic_counter_ops)] = .{
611 .llvm_name = null,
612 .description = "SPIR-V extension SPV_KHR_shader_atomic_counter_ops",
613 .dependencies = featureSet(&[_]Feature{}),
614 };
615 result[@intFromEnum(Feature.SPV_KHR_shader_draw_parameters)] = .{
616 .llvm_name = null,
617 .description = "SPIR-V extension SPV_KHR_shader_draw_parameters",
618 .dependencies = featureSet(&[_]Feature{}),
619 };
620 result[@intFromEnum(Feature.SPV_KHR_storage_buffer_storage_class)] = .{
621 .llvm_name = null,
622 .description = "SPIR-V extension SPV_KHR_storage_buffer_storage_class",
623 .dependencies = featureSet(&[_]Feature{}),
624 };
625 result[@intFromEnum(Feature.SPV_KHR_linkonce_odr)] = .{
626 .llvm_name = null,
627 .description = "SPIR-V extension SPV_KHR_linkonce_odr",
628 .dependencies = featureSet(&[_]Feature{}),
629 };
630 result[@intFromEnum(Feature.SPV_KHR_terminate_invocation)] = .{
631 .llvm_name = null,
632 .description = "SPIR-V extension SPV_KHR_terminate_invocation",
633 .dependencies = featureSet(&[_]Feature{}),
634 };
635 result[@intFromEnum(Feature.SPV_KHR_non_semantic_info)] = .{
636 .llvm_name = null,
637 .description = "SPIR-V extension SPV_KHR_non_semantic_info",
638 .dependencies = featureSet(&[_]Feature{}),
639 };
640 result[@intFromEnum(Feature.SPV_KHR_post_depth_coverage)] = .{
641 .llvm_name = null,
642 .description = "SPIR-V extension SPV_KHR_post_depth_coverage",
643 .dependencies = featureSet(&[_]Feature{}),
644 };
645 result[@intFromEnum(Feature.SPV_KHR_expect_assume)] = .{
646 .llvm_name = null,
647 .description = "SPIR-V extension SPV_KHR_expect_assume",
648 .dependencies = featureSet(&[_]Feature{}),
649 };
650 result[@intFromEnum(Feature.SPV_KHR_ray_tracing)] = .{
651 .llvm_name = null,
652 .description = "SPIR-V extension SPV_KHR_ray_tracing",
653 .dependencies = featureSet(&[_]Feature{}),
654 };
655 result[@intFromEnum(Feature.SPV_KHR_ray_query)] = .{
656 .llvm_name = null,
657 .description = "SPIR-V extension SPV_KHR_ray_query",
658 .dependencies = featureSet(&[_]Feature{}),
659 };
660 result[@intFromEnum(Feature.SPV_KHR_float_controls)] = .{
661 .llvm_name = null,
662 .description = "SPIR-V extension SPV_KHR_float_controls",
663 .dependencies = featureSet(&[_]Feature{}),
664 };
665 result[@intFromEnum(Feature.SPV_NV_viewport_array2)] = .{
666 .llvm_name = null,
667 .description = "SPIR-V extension SPV_NV_viewport_array2",
668 .dependencies = featureSet(&[_]Feature{}),
669 };
670 result[@intFromEnum(Feature.SPV_NV_shader_subgroup_partitioned)] = .{
671 .llvm_name = null,
672 .description = "SPIR-V extension SPV_NV_shader_subgroup_partitioned",
673 .dependencies = featureSet(&[_]Feature{}),
674 };
675 result[@intFromEnum(Feature.SPV_NVX_multiview_per_view_attributes)] = .{
676 .llvm_name = null,
677 .description = "SPIR-V extension SPV_NVX_multiview_per_view_attributes",
678 .dependencies = featureSet(&[_]Feature{}),
679 };
680 result[@intFromEnum(Feature.SPV_NV_ray_tracing)] = .{
681 .llvm_name = null,
682 .description = "SPIR-V extension SPV_NV_ray_tracing",
683 .dependencies = featureSet(&[_]Feature{}),
684 };
685 result[@intFromEnum(Feature.SPV_NV_shader_image_footprint)] = .{
686 .llvm_name = null,
687 .description = "SPIR-V extension SPV_NV_shader_image_footprint",
688 .dependencies = featureSet(&[_]Feature{}),
689 };
690 result[@intFromEnum(Feature.SPV_NV_shading_rate)] = .{
691 .llvm_name = null,
692 .description = "SPIR-V extension SPV_NV_shading_rate",
693 .dependencies = featureSet(&[_]Feature{}),
694 };
695 result[@intFromEnum(Feature.SPV_NV_stereo_view_rendering)] = .{
696 .llvm_name = null,
697 .description = "SPIR-V extension SPV_NV_stereo_view_rendering",
698 .dependencies = featureSet(&[_]Feature{}),
699 };
700 result[@intFromEnum(Feature.SPV_NV_compute_shader_derivatives)] = .{
701 .llvm_name = null,
702 .description = "SPIR-V extension SPV_NV_compute_shader_derivatives",
703 .dependencies = featureSet(&[_]Feature{}),
704 };
705 result[@intFromEnum(Feature.SPV_NV_shader_sm_builtins)] = .{
706 .llvm_name = null,
707 .description = "SPIR-V extension SPV_NV_shader_sm_builtins",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.SPV_NV_mesh_shader)] = .{
711 .llvm_name = null,
712 .description = "SPIR-V extension SPV_NV_mesh_shader",
713 .dependencies = featureSet(&[_]Feature{}),
714 };
715 result[@intFromEnum(Feature.SPV_NV_geometry_shader_passthrough)] = .{
716 .llvm_name = null,
717 .description = "SPIR-V extension SPV_NV_geometry_shader_passthrough",
718 .dependencies = featureSet(&[_]Feature{}),
719 };
720 result[@intFromEnum(Feature.SPV_NV_fragment_shader_barycentric)] = .{
721 .llvm_name = null,
722 .description = "SPIR-V extension SPV_NV_fragment_shader_barycentric",
723 .dependencies = featureSet(&[_]Feature{}),
724 };
725 result[@intFromEnum(Feature.SPV_NV_cooperative_matrix)] = .{
726 .llvm_name = null,
727 .description = "SPIR-V extension SPV_NV_cooperative_matrix",
728 .dependencies = featureSet(&[_]Feature{}),
729 };
730 result[@intFromEnum(Feature.SPV_NV_sample_mask_override_coverage)] = .{
731 .llvm_name = null,
732 .description = "SPIR-V extension SPV_NV_sample_mask_override_coverage",
733 .dependencies = featureSet(&[_]Feature{}),
734 };
735 result[@intFromEnum(Feature.Matrix)] = .{
736 .llvm_name = null,
737 .description = "Enable SPIR-V capability Matrix",
738 .dependencies = featureSet(&[_]Feature{}),
739 };
740 result[@intFromEnum(Feature.Shader)] = .{
741 .llvm_name = null,
742 .description = "Enable SPIR-V capability Shader",
743 .dependencies = featureSet(&[_]Feature{
744 .Matrix,
745 }),
746 };
747 result[@intFromEnum(Feature.Geometry)] = .{
748 .llvm_name = null,
749 .description = "Enable SPIR-V capability Geometry",
750 .dependencies = featureSet(&[_]Feature{
751 .Shader,
752 }),
753 };
754 result[@intFromEnum(Feature.Tessellation)] = .{
755 .llvm_name = null,
756 .description = "Enable SPIR-V capability Tessellation",
757 .dependencies = featureSet(&[_]Feature{
758 .Shader,
759 }),
760 };
761 result[@intFromEnum(Feature.Addresses)] = .{
762 .llvm_name = null,
763 .description = "Enable SPIR-V capability Addresses",
764 .dependencies = featureSet(&[_]Feature{}),
765 };
766 result[@intFromEnum(Feature.Linkage)] = .{
767 .llvm_name = null,
768 .description = "Enable SPIR-V capability Linkage",
769 .dependencies = featureSet(&[_]Feature{}),
770 };
771 result[@intFromEnum(Feature.Kernel)] = .{
772 .llvm_name = null,
773 .description = "Enable SPIR-V capability Kernel",
774 .dependencies = featureSet(&[_]Feature{}),
775 };
776 result[@intFromEnum(Feature.Vector16)] = .{
777 .llvm_name = null,
778 .description = "Enable SPIR-V capability Vector16",
779 .dependencies = featureSet(&[_]Feature{
780 .Kernel,
781 }),
782 };
783 result[@intFromEnum(Feature.Float16Buffer)] = .{
784 .llvm_name = null,
785 .description = "Enable SPIR-V capability Float16Buffer",
786 .dependencies = featureSet(&[_]Feature{
787 .Kernel,
788 }),
789 };
790 result[@intFromEnum(Feature.Float16)] = .{
791 .llvm_name = null,
792 .description = "Enable SPIR-V capability Float16",
793 .dependencies = featureSet(&[_]Feature{}),
794 };
795 result[@intFromEnum(Feature.Float64)] = .{
796 .llvm_name = null,
797 .description = "Enable SPIR-V capability Float64",
798 .dependencies = featureSet(&[_]Feature{}),
799 };
800 result[@intFromEnum(Feature.Int64)] = .{
801 .llvm_name = null,
802 .description = "Enable SPIR-V capability Int64",
803 .dependencies = featureSet(&[_]Feature{}),
804 };
805 result[@intFromEnum(Feature.Int64Atomics)] = .{
806 .llvm_name = null,
807 .description = "Enable SPIR-V capability Int64Atomics",
808 .dependencies = featureSet(&[_]Feature{
809 .Int64,
810 }),
811 };
812 result[@intFromEnum(Feature.ImageBasic)] = .{
813 .llvm_name = null,
814 .description = "Enable SPIR-V capability ImageBasic",
815 .dependencies = featureSet(&[_]Feature{
816 .Kernel,
817 }),
818 };
819 result[@intFromEnum(Feature.ImageReadWrite)] = .{
820 .llvm_name = null,
821 .description = "Enable SPIR-V capability ImageReadWrite",
822 .dependencies = featureSet(&[_]Feature{
823 .ImageBasic,
824 }),
825 };
826 result[@intFromEnum(Feature.ImageMipmap)] = .{
827 .llvm_name = null,
828 .description = "Enable SPIR-V capability ImageMipmap",
829 .dependencies = featureSet(&[_]Feature{
830 .ImageBasic,
831 }),
832 };
833 result[@intFromEnum(Feature.Pipes)] = .{
834 .llvm_name = null,
835 .description = "Enable SPIR-V capability Pipes",
836 .dependencies = featureSet(&[_]Feature{
837 .Kernel,
838 }),
839 };
840 result[@intFromEnum(Feature.Groups)] = .{
841 .llvm_name = null,
842 .description = "Enable SPIR-V capability Groups",
843 .dependencies = featureSet(&[_]Feature{}),
844 };
845 result[@intFromEnum(Feature.DeviceEnqueue)] = .{
846 .llvm_name = null,
847 .description = "Enable SPIR-V capability DeviceEnqueue",
848 .dependencies = featureSet(&[_]Feature{
849 .Kernel,
850 }),
851 };
852 result[@intFromEnum(Feature.LiteralSampler)] = .{
853 .llvm_name = null,
854 .description = "Enable SPIR-V capability LiteralSampler",
855 .dependencies = featureSet(&[_]Feature{
856 .Kernel,
857 }),
858 };
859 result[@intFromEnum(Feature.AtomicStorage)] = .{
860 .llvm_name = null,
861 .description = "Enable SPIR-V capability AtomicStorage",
862 .dependencies = featureSet(&[_]Feature{
863 .Shader,
864 }),
865 };
866 result[@intFromEnum(Feature.Int16)] = .{
867 .llvm_name = null,
868 .description = "Enable SPIR-V capability Int16",
869 .dependencies = featureSet(&[_]Feature{}),
870 };
871 result[@intFromEnum(Feature.TessellationPointSize)] = .{
872 .llvm_name = null,
873 .description = "Enable SPIR-V capability TessellationPointSize",
874 .dependencies = featureSet(&[_]Feature{
875 .Tessellation,
876 }),
877 };
878 result[@intFromEnum(Feature.GeometryPointSize)] = .{
879 .llvm_name = null,
880 .description = "Enable SPIR-V capability GeometryPointSize",
881 .dependencies = featureSet(&[_]Feature{
882 .Geometry,
883 }),
884 };
885 result[@intFromEnum(Feature.ImageGatherExtended)] = .{
886 .llvm_name = null,
887 .description = "Enable SPIR-V capability ImageGatherExtended",
888 .dependencies = featureSet(&[_]Feature{
889 .Shader,
890 }),
891 };
892 result[@intFromEnum(Feature.StorageImageMultisample)] = .{
893 .llvm_name = null,
894 .description = "Enable SPIR-V capability StorageImageMultisample",
895 .dependencies = featureSet(&[_]Feature{
896 .Shader,
897 }),
898 };
899 result[@intFromEnum(Feature.UniformBufferArrayDynamicIndexing)] = .{
900 .llvm_name = null,
901 .description = "Enable SPIR-V capability UniformBufferArrayDynamicIndexing",
902 .dependencies = featureSet(&[_]Feature{
903 .Shader,
904 }),
905 };
906 result[@intFromEnum(Feature.SampledImageArrayDynamicIndexing)] = .{
907 .llvm_name = null,
908 .description = "Enable SPIR-V capability SampledImageArrayDynamicIndexing",
909 .dependencies = featureSet(&[_]Feature{
910 .Shader,
911 }),
912 };
913 result[@intFromEnum(Feature.StorageBufferArrayDynamicIndexing)] = .{
914 .llvm_name = null,
915 .description = "Enable SPIR-V capability StorageBufferArrayDynamicIndexing",
916 .dependencies = featureSet(&[_]Feature{
917 .Shader,
918 }),
919 };
920 result[@intFromEnum(Feature.StorageImageArrayDynamicIndexing)] = .{
921 .llvm_name = null,
922 .description = "Enable SPIR-V capability StorageImageArrayDynamicIndexing",
923 .dependencies = featureSet(&[_]Feature{
924 .Shader,
925 }),
926 };
927 result[@intFromEnum(Feature.ClipDistance)] = .{
928 .llvm_name = null,
929 .description = "Enable SPIR-V capability ClipDistance",
930 .dependencies = featureSet(&[_]Feature{
931 .Shader,
932 }),
933 };
934 result[@intFromEnum(Feature.CullDistance)] = .{
935 .llvm_name = null,
936 .description = "Enable SPIR-V capability CullDistance",
937 .dependencies = featureSet(&[_]Feature{
938 .Shader,
939 }),
940 };
941 result[@intFromEnum(Feature.ImageCubeArray)] = .{
942 .llvm_name = null,
943 .description = "Enable SPIR-V capability ImageCubeArray",
944 .dependencies = featureSet(&[_]Feature{
945 .SampledCubeArray,
946 }),
947 };
948 result[@intFromEnum(Feature.SampleRateShading)] = .{
949 .llvm_name = null,
950 .description = "Enable SPIR-V capability SampleRateShading",
951 .dependencies = featureSet(&[_]Feature{
952 .Shader,
953 }),
954 };
955 result[@intFromEnum(Feature.ImageRect)] = .{
956 .llvm_name = null,
957 .description = "Enable SPIR-V capability ImageRect",
958 .dependencies = featureSet(&[_]Feature{
959 .SampledRect,
960 }),
961 };
962 result[@intFromEnum(Feature.SampledRect)] = .{
963 .llvm_name = null,
964 .description = "Enable SPIR-V capability SampledRect",
965 .dependencies = featureSet(&[_]Feature{
966 .Shader,
967 }),
968 };
969 result[@intFromEnum(Feature.GenericPointer)] = .{
970 .llvm_name = null,
971 .description = "Enable SPIR-V capability GenericPointer",
972 .dependencies = featureSet(&[_]Feature{
973 .Addresses,
974 }),
975 };
976 result[@intFromEnum(Feature.Int8)] = .{
977 .llvm_name = null,
978 .description = "Enable SPIR-V capability Int8",
979 .dependencies = featureSet(&[_]Feature{}),
980 };
981 result[@intFromEnum(Feature.InputAttachment)] = .{
982 .llvm_name = null,
983 .description = "Enable SPIR-V capability InputAttachment",
984 .dependencies = featureSet(&[_]Feature{
985 .Shader,
986 }),
987 };
988 result[@intFromEnum(Feature.SparseResidency)] = .{
989 .llvm_name = null,
990 .description = "Enable SPIR-V capability SparseResidency",
991 .dependencies = featureSet(&[_]Feature{
992 .Shader,
993 }),
994 };
995 result[@intFromEnum(Feature.MinLod)] = .{
996 .llvm_name = null,
997 .description = "Enable SPIR-V capability MinLod",
998 .dependencies = featureSet(&[_]Feature{
999 .Shader,
1000 }),
1001 };
1002 result[@intFromEnum(Feature.Sampled1D)] = .{
1003 .llvm_name = null,
1004 .description = "Enable SPIR-V capability Sampled1D",
1005 .dependencies = featureSet(&[_]Feature{}),
1006 };
1007 result[@intFromEnum(Feature.Image1D)] = .{
1008 .llvm_name = null,
1009 .description = "Enable SPIR-V capability Image1D",
1010 .dependencies = featureSet(&[_]Feature{
1011 .Sampled1D,
1012 }),
1013 };
1014 result[@intFromEnum(Feature.SampledCubeArray)] = .{
1015 .llvm_name = null,
1016 .description = "Enable SPIR-V capability SampledCubeArray",
1017 .dependencies = featureSet(&[_]Feature{
1018 .Shader,
1019 }),
1020 };
1021 result[@intFromEnum(Feature.SampledBuffer)] = .{
1022 .llvm_name = null,
1023 .description = "Enable SPIR-V capability SampledBuffer",
1024 .dependencies = featureSet(&[_]Feature{}),
1025 };
1026 result[@intFromEnum(Feature.ImageBuffer)] = .{
1027 .llvm_name = null,
1028 .description = "Enable SPIR-V capability ImageBuffer",
1029 .dependencies = featureSet(&[_]Feature{
1030 .SampledBuffer,
1031 }),
1032 };
1033 result[@intFromEnum(Feature.ImageMSArray)] = .{
1034 .llvm_name = null,
1035 .description = "Enable SPIR-V capability ImageMSArray",
1036 .dependencies = featureSet(&[_]Feature{
1037 .Shader,
1038 }),
1039 };
1040 result[@intFromEnum(Feature.StorageImageExtendedFormats)] = .{
1041 .llvm_name = null,
1042 .description = "Enable SPIR-V capability StorageImageExtendedFormats",
1043 .dependencies = featureSet(&[_]Feature{
1044 .Shader,
1045 }),
1046 };
1047 result[@intFromEnum(Feature.ImageQuery)] = .{
1048 .llvm_name = null,
1049 .description = "Enable SPIR-V capability ImageQuery",
1050 .dependencies = featureSet(&[_]Feature{
1051 .Shader,
1052 }),
1053 };
1054 result[@intFromEnum(Feature.DerivativeControl)] = .{
1055 .llvm_name = null,
1056 .description = "Enable SPIR-V capability DerivativeControl",
1057 .dependencies = featureSet(&[_]Feature{
1058 .Shader,
1059 }),
1060 };
1061 result[@intFromEnum(Feature.InterpolationFunction)] = .{
1062 .llvm_name = null,
1063 .description = "Enable SPIR-V capability InterpolationFunction",
1064 .dependencies = featureSet(&[_]Feature{
1065 .Shader,
1066 }),
1067 };
1068 result[@intFromEnum(Feature.TransformFeedback)] = .{
1069 .llvm_name = null,
1070 .description = "Enable SPIR-V capability TransformFeedback",
1071 .dependencies = featureSet(&[_]Feature{
1072 .Shader,
1073 }),
1074 };
1075 result[@intFromEnum(Feature.GeometryStreams)] = .{
1076 .llvm_name = null,
1077 .description = "Enable SPIR-V capability GeometryStreams",
1078 .dependencies = featureSet(&[_]Feature{
1079 .Geometry,
1080 }),
1081 };
1082 result[@intFromEnum(Feature.StorageImageReadWithoutFormat)] = .{
1083 .llvm_name = null,
1084 .description = "Enable SPIR-V capability StorageImageReadWithoutFormat",
1085 .dependencies = featureSet(&[_]Feature{
1086 .Shader,
1087 }),
1088 };
1089 result[@intFromEnum(Feature.StorageImageWriteWithoutFormat)] = .{
1090 .llvm_name = null,
1091 .description = "Enable SPIR-V capability StorageImageWriteWithoutFormat",
1092 .dependencies = featureSet(&[_]Feature{
1093 .Shader,
1094 }),
1095 };
1096 result[@intFromEnum(Feature.MultiViewport)] = .{
1097 .llvm_name = null,
1098 .description = "Enable SPIR-V capability MultiViewport",
1099 .dependencies = featureSet(&[_]Feature{
1100 .Geometry,
1101 }),
1102 };
1103 result[@intFromEnum(Feature.SubgroupDispatch)] = .{
1104 .llvm_name = null,
1105 .description = "Enable SPIR-V capability SubgroupDispatch",
1106 .dependencies = featureSet(&[_]Feature{
1107 .v1_1,
1108 .DeviceEnqueue,
1109 }),
1110 };
1111 result[@intFromEnum(Feature.NamedBarrier)] = .{
1112 .llvm_name = null,
1113 .description = "Enable SPIR-V capability NamedBarrier",
1114 .dependencies = featureSet(&[_]Feature{
1115 .v1_1,
1116 .Kernel,
1117 }),
1118 };
1119 result[@intFromEnum(Feature.PipeStorage)] = .{
1120 .llvm_name = null,
1121 .description = "Enable SPIR-V capability PipeStorage",
1122 .dependencies = featureSet(&[_]Feature{
1123 .v1_1,
1124 .Pipes,
1125 }),
1126 };
1127 result[@intFromEnum(Feature.GroupNonUniform)] = .{
1128 .llvm_name = null,
1129 .description = "Enable SPIR-V capability GroupNonUniform",
1130 .dependencies = featureSet(&[_]Feature{
1131 .v1_3,
1132 }),
1133 };
1134 result[@intFromEnum(Feature.GroupNonUniformVote)] = .{
1135 .llvm_name = null,
1136 .description = "Enable SPIR-V capability GroupNonUniformVote",
1137 .dependencies = featureSet(&[_]Feature{
1138 .v1_3,
1139 .GroupNonUniform,
1140 }),
1141 };
1142 result[@intFromEnum(Feature.GroupNonUniformArithmetic)] = .{
1143 .llvm_name = null,
1144 .description = "Enable SPIR-V capability GroupNonUniformArithmetic",
1145 .dependencies = featureSet(&[_]Feature{
1146 .v1_3,
1147 .GroupNonUniform,
1148 }),
1149 };
1150 result[@intFromEnum(Feature.GroupNonUniformBallot)] = .{
1151 .llvm_name = null,
1152 .description = "Enable SPIR-V capability GroupNonUniformBallot",
1153 .dependencies = featureSet(&[_]Feature{
1154 .v1_3,
1155 .GroupNonUniform,
1156 }),
1157 };
1158 result[@intFromEnum(Feature.GroupNonUniformShuffle)] = .{
1159 .llvm_name = null,
1160 .description = "Enable SPIR-V capability GroupNonUniformShuffle",
1161 .dependencies = featureSet(&[_]Feature{
1162 .v1_3,
1163 .GroupNonUniform,
1164 }),
1165 };
1166 result[@intFromEnum(Feature.GroupNonUniformShuffleRelative)] = .{
1167 .llvm_name = null,
1168 .description = "Enable SPIR-V capability GroupNonUniformShuffleRelative",
1169 .dependencies = featureSet(&[_]Feature{
1170 .v1_3,
1171 .GroupNonUniform,
1172 }),
1173 };
1174 result[@intFromEnum(Feature.GroupNonUniformClustered)] = .{
1175 .llvm_name = null,
1176 .description = "Enable SPIR-V capability GroupNonUniformClustered",
1177 .dependencies = featureSet(&[_]Feature{
1178 .v1_3,
1179 .GroupNonUniform,
1180 }),
1181 };
1182 result[@intFromEnum(Feature.GroupNonUniformQuad)] = .{
1183 .llvm_name = null,
1184 .description = "Enable SPIR-V capability GroupNonUniformQuad",
1185 .dependencies = featureSet(&[_]Feature{
1186 .v1_3,
1187 .GroupNonUniform,
1188 }),
1189 };
1190 result[@intFromEnum(Feature.ShaderLayer)] = .{
1191 .llvm_name = null,
1192 .description = "Enable SPIR-V capability ShaderLayer",
1193 .dependencies = featureSet(&[_]Feature{
1194 .v1_5,
1195 }),
1196 };
1197 result[@intFromEnum(Feature.ShaderViewportIndex)] = .{
1198 .llvm_name = null,
1199 .description = "Enable SPIR-V capability ShaderViewportIndex",
1200 .dependencies = featureSet(&[_]Feature{
1201 .v1_5,
1202 }),
1203 };
1204 result[@intFromEnum(Feature.FragmentShadingRateKHR)] = .{
1205 .llvm_name = null,
1206 .description = "Enable SPIR-V capability FragmentShadingRateKHR",
1207 .dependencies = featureSet(&[_]Feature{
1208 .Shader,
1209 }),
1210 };
1211 result[@intFromEnum(Feature.SubgroupBallotKHR)] = .{
1212 .llvm_name = null,
1213 .description = "Enable SPIR-V capability SubgroupBallotKHR",
1214 .dependencies = featureSet(&[_]Feature{}),
1215 };
1216 result[@intFromEnum(Feature.DrawParameters)] = .{
1217 .llvm_name = null,
1218 .description = "Enable SPIR-V capability DrawParameters",
1219 .dependencies = featureSet(&[_]Feature{
1220 .v1_3,
1221 .Shader,
1222 }),
1223 };
1224 result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayoutKHR)] = .{
1225 .llvm_name = null,
1226 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayoutKHR",
1227 .dependencies = featureSet(&[_]Feature{
1228 .Shader,
1229 }),
1230 };
1231 result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayout8BitAccessKHR)] = .{
1232 .llvm_name = null,
1233 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout8BitAccessKHR",
1234 .dependencies = featureSet(&[_]Feature{
1235 .WorkgroupMemoryExplicitLayoutKHR,
1236 }),
1237 };
1238 result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayout16BitAccessKHR)] = .{
1239 .llvm_name = null,
1240 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout16BitAccessKHR",
1241 .dependencies = featureSet(&[_]Feature{
1242 .Shader,
1243 }),
1244 };
1245 result[@intFromEnum(Feature.SubgroupVoteKHR)] = .{
1246 .llvm_name = null,
1247 .description = "Enable SPIR-V capability SubgroupVoteKHR",
1248 .dependencies = featureSet(&[_]Feature{}),
1249 };
1250 result[@intFromEnum(Feature.StorageBuffer16BitAccess)] = .{
1251 .llvm_name = null,
1252 .description = "Enable SPIR-V capability StorageBuffer16BitAccess",
1253 .dependencies = featureSet(&[_]Feature{
1254 .v1_3,
1255 }),
1256 };
1257 result[@intFromEnum(Feature.StorageUniformBufferBlock16)] = .{
1258 .llvm_name = null,
1259 .description = "Enable SPIR-V capability StorageUniformBufferBlock16",
1260 .dependencies = featureSet(&[_]Feature{
1261 .v1_3,
1262 }),
1263 };
1264 result[@intFromEnum(Feature.UniformAndStorageBuffer16BitAccess)] = .{
1265 .llvm_name = null,
1266 .description = "Enable SPIR-V capability UniformAndStorageBuffer16BitAccess",
1267 .dependencies = featureSet(&[_]Feature{
1268 .v1_3,
1269 .StorageBuffer16BitAccess,
1270 .StorageUniformBufferBlock16,
1271 }),
1272 };
1273 result[@intFromEnum(Feature.StorageUniform16)] = .{
1274 .llvm_name = null,
1275 .description = "Enable SPIR-V capability StorageUniform16",
1276 .dependencies = featureSet(&[_]Feature{
1277 .v1_3,
1278 .StorageBuffer16BitAccess,
1279 .StorageUniformBufferBlock16,
1280 }),
1281 };
1282 result[@intFromEnum(Feature.StoragePushConstant16)] = .{
1283 .llvm_name = null,
1284 .description = "Enable SPIR-V capability StoragePushConstant16",
1285 .dependencies = featureSet(&[_]Feature{
1286 .v1_3,
1287 }),
1288 };
1289 result[@intFromEnum(Feature.StorageInputOutput16)] = .{
1290 .llvm_name = null,
1291 .description = "Enable SPIR-V capability StorageInputOutput16",
1292 .dependencies = featureSet(&[_]Feature{
1293 .v1_3,
1294 }),
1295 };
1296 result[@intFromEnum(Feature.DeviceGroup)] = .{
1297 .llvm_name = null,
1298 .description = "Enable SPIR-V capability DeviceGroup",
1299 .dependencies = featureSet(&[_]Feature{
1300 .v1_3,
1301 }),
1302 };
1303 result[@intFromEnum(Feature.MultiView)] = .{
1304 .llvm_name = null,
1305 .description = "Enable SPIR-V capability MultiView",
1306 .dependencies = featureSet(&[_]Feature{
1307 .v1_3,
1308 .Shader,
1309 }),
1310 };
1311 result[@intFromEnum(Feature.VariablePointersStorageBuffer)] = .{
1312 .llvm_name = null,
1313 .description = "Enable SPIR-V capability VariablePointersStorageBuffer",
1314 .dependencies = featureSet(&[_]Feature{
1315 .v1_3,
1316 .Shader,
1317 }),
1318 };
1319 result[@intFromEnum(Feature.VariablePointers)] = .{
1320 .llvm_name = null,
1321 .description = "Enable SPIR-V capability VariablePointers",
1322 .dependencies = featureSet(&[_]Feature{
1323 .v1_3,
1324 .VariablePointersStorageBuffer,
1325 }),
1326 };
1327 result[@intFromEnum(Feature.AtomicStorageOps)] = .{
1328 .llvm_name = null,
1329 .description = "Enable SPIR-V capability AtomicStorageOps",
1330 .dependencies = featureSet(&[_]Feature{}),
1331 };
1332 result[@intFromEnum(Feature.SampleMaskPostDepthCoverage)] = .{
1333 .llvm_name = null,
1334 .description = "Enable SPIR-V capability SampleMaskPostDepthCoverage",
1335 .dependencies = featureSet(&[_]Feature{}),
1336 };
1337 result[@intFromEnum(Feature.StorageBuffer8BitAccess)] = .{
1338 .llvm_name = null,
1339 .description = "Enable SPIR-V capability StorageBuffer8BitAccess",
1340 .dependencies = featureSet(&[_]Feature{
1341 .v1_5,
1342 }),
1343 };
1344 result[@intFromEnum(Feature.UniformAndStorageBuffer8BitAccess)] = .{
1345 .llvm_name = null,
1346 .description = "Enable SPIR-V capability UniformAndStorageBuffer8BitAccess",
1347 .dependencies = featureSet(&[_]Feature{
1348 .v1_5,
1349 .StorageBuffer8BitAccess,
1350 }),
1351 };
1352 result[@intFromEnum(Feature.StoragePushConstant8)] = .{
1353 .llvm_name = null,
1354 .description = "Enable SPIR-V capability StoragePushConstant8",
1355 .dependencies = featureSet(&[_]Feature{
1356 .v1_5,
1357 }),
1358 };
1359 result[@intFromEnum(Feature.DenormPreserve)] = .{
1360 .llvm_name = null,
1361 .description = "Enable SPIR-V capability DenormPreserve",
1362 .dependencies = featureSet(&[_]Feature{
1363 .v1_4,
1364 }),
1365 };
1366 result[@intFromEnum(Feature.DenormFlushToZero)] = .{
1367 .llvm_name = null,
1368 .description = "Enable SPIR-V capability DenormFlushToZero",
1369 .dependencies = featureSet(&[_]Feature{
1370 .v1_4,
1371 }),
1372 };
1373 result[@intFromEnum(Feature.SignedZeroInfNanPreserve)] = .{
1374 .llvm_name = null,
1375 .description = "Enable SPIR-V capability SignedZeroInfNanPreserve",
1376 .dependencies = featureSet(&[_]Feature{
1377 .v1_4,
1378 }),
1379 };
1380 result[@intFromEnum(Feature.RoundingModeRTE)] = .{
1381 .llvm_name = null,
1382 .description = "Enable SPIR-V capability RoundingModeRTE",
1383 .dependencies = featureSet(&[_]Feature{
1384 .v1_4,
1385 }),
1386 };
1387 result[@intFromEnum(Feature.RoundingModeRTZ)] = .{
1388 .llvm_name = null,
1389 .description = "Enable SPIR-V capability RoundingModeRTZ",
1390 .dependencies = featureSet(&[_]Feature{
1391 .v1_4,
1392 }),
1393 };
1394 result[@intFromEnum(Feature.RayQueryProvisionalKHR)] = .{
1395 .llvm_name = null,
1396 .description = "Enable SPIR-V capability RayQueryProvisionalKHR",
1397 .dependencies = featureSet(&[_]Feature{
1398 .Shader,
1399 }),
1400 };
1401 result[@intFromEnum(Feature.RayQueryKHR)] = .{
1402 .llvm_name = null,
1403 .description = "Enable SPIR-V capability RayQueryKHR",
1404 .dependencies = featureSet(&[_]Feature{
1405 .Shader,
1406 }),
1407 };
1408 result[@intFromEnum(Feature.RayTraversalPrimitiveCullingKHR)] = .{
1409 .llvm_name = null,
1410 .description = "Enable SPIR-V capability RayTraversalPrimitiveCullingKHR",
1411 .dependencies = featureSet(&[_]Feature{
1412 .RayQueryKHR,
1413 .RayTracingKHR,
1414 }),
1415 };
1416 result[@intFromEnum(Feature.RayTracingKHR)] = .{
1417 .llvm_name = null,
1418 .description = "Enable SPIR-V capability RayTracingKHR",
1419 .dependencies = featureSet(&[_]Feature{
1420 .Shader,
1421 }),
1422 };
1423 result[@intFromEnum(Feature.Float16ImageAMD)] = .{
1424 .llvm_name = null,
1425 .description = "Enable SPIR-V capability Float16ImageAMD",
1426 .dependencies = featureSet(&[_]Feature{
1427 .Shader,
1428 }),
1429 };
1430 result[@intFromEnum(Feature.ImageGatherBiasLodAMD)] = .{
1431 .llvm_name = null,
1432 .description = "Enable SPIR-V capability ImageGatherBiasLodAMD",
1433 .dependencies = featureSet(&[_]Feature{
1434 .Shader,
1435 }),
1436 };
1437 result[@intFromEnum(Feature.FragmentMaskAMD)] = .{
1438 .llvm_name = null,
1439 .description = "Enable SPIR-V capability FragmentMaskAMD",
1440 .dependencies = featureSet(&[_]Feature{
1441 .Shader,
1442 }),
1443 };
1444 result[@intFromEnum(Feature.StencilExportEXT)] = .{
1445 .llvm_name = null,
1446 .description = "Enable SPIR-V capability StencilExportEXT",
1447 .dependencies = featureSet(&[_]Feature{
1448 .Shader,
1449 }),
1450 };
1451 result[@intFromEnum(Feature.ImageReadWriteLodAMD)] = .{
1452 .llvm_name = null,
1453 .description = "Enable SPIR-V capability ImageReadWriteLodAMD",
1454 .dependencies = featureSet(&[_]Feature{
1455 .Shader,
1456 }),
1457 };
1458 result[@intFromEnum(Feature.Int64ImageEXT)] = .{
1459 .llvm_name = null,
1460 .description = "Enable SPIR-V capability Int64ImageEXT",
1461 .dependencies = featureSet(&[_]Feature{
1462 .Shader,
1463 }),
1464 };
1465 result[@intFromEnum(Feature.ShaderClockKHR)] = .{
1466 .llvm_name = null,
1467 .description = "Enable SPIR-V capability ShaderClockKHR",
1468 .dependencies = featureSet(&[_]Feature{
1469 .Shader,
1470 }),
1471 };
1472 result[@intFromEnum(Feature.SampleMaskOverrideCoverageNV)] = .{
1473 .llvm_name = null,
1474 .description = "Enable SPIR-V capability SampleMaskOverrideCoverageNV",
1475 .dependencies = featureSet(&[_]Feature{
1476 .SampleRateShading,
1477 }),
1478 };
1479 result[@intFromEnum(Feature.GeometryShaderPassthroughNV)] = .{
1480 .llvm_name = null,
1481 .description = "Enable SPIR-V capability GeometryShaderPassthroughNV",
1482 .dependencies = featureSet(&[_]Feature{
1483 .Geometry,
1484 }),
1485 };
1486 result[@intFromEnum(Feature.ShaderViewportIndexLayerEXT)] = .{
1487 .llvm_name = null,
1488 .description = "Enable SPIR-V capability ShaderViewportIndexLayerEXT",
1489 .dependencies = featureSet(&[_]Feature{
1490 .MultiViewport,
1491 }),
1492 };
1493 result[@intFromEnum(Feature.ShaderViewportIndexLayerNV)] = .{
1494 .llvm_name = null,
1495 .description = "Enable SPIR-V capability ShaderViewportIndexLayerNV",
1496 .dependencies = featureSet(&[_]Feature{
1497 .MultiViewport,
1498 }),
1499 };
1500 result[@intFromEnum(Feature.ShaderViewportMaskNV)] = .{
1501 .llvm_name = null,
1502 .description = "Enable SPIR-V capability ShaderViewportMaskNV",
1503 .dependencies = featureSet(&[_]Feature{
1504 .ShaderViewportIndexLayerNV,
1505 }),
1506 };
1507 result[@intFromEnum(Feature.ShaderStereoViewNV)] = .{
1508 .llvm_name = null,
1509 .description = "Enable SPIR-V capability ShaderStereoViewNV",
1510 .dependencies = featureSet(&[_]Feature{
1511 .ShaderViewportMaskNV,
1512 }),
1513 };
1514 result[@intFromEnum(Feature.PerViewAttributesNV)] = .{
1515 .llvm_name = null,
1516 .description = "Enable SPIR-V capability PerViewAttributesNV",
1517 .dependencies = featureSet(&[_]Feature{
1518 .MultiView,
1519 }),
1520 };
1521 result[@intFromEnum(Feature.FragmentFullyCoveredEXT)] = .{
1522 .llvm_name = null,
1523 .description = "Enable SPIR-V capability FragmentFullyCoveredEXT",
1524 .dependencies = featureSet(&[_]Feature{
1525 .Shader,
1526 }),
1527 };
1528 result[@intFromEnum(Feature.MeshShadingNV)] = .{
1529 .llvm_name = null,
1530 .description = "Enable SPIR-V capability MeshShadingNV",
1531 .dependencies = featureSet(&[_]Feature{
1532 .Shader,
1533 }),
1534 };
1535 result[@intFromEnum(Feature.ImageFootprintNV)] = .{
1536 .llvm_name = null,
1537 .description = "Enable SPIR-V capability ImageFootprintNV",
1538 .dependencies = featureSet(&[_]Feature{}),
1539 };
1540 result[@intFromEnum(Feature.FragmentBarycentricNV)] = .{
1541 .llvm_name = null,
1542 .description = "Enable SPIR-V capability FragmentBarycentricNV",
1543 .dependencies = featureSet(&[_]Feature{}),
1544 };
1545 result[@intFromEnum(Feature.ComputeDerivativeGroupQuadsNV)] = .{
1546 .llvm_name = null,
1547 .description = "Enable SPIR-V capability ComputeDerivativeGroupQuadsNV",
1548 .dependencies = featureSet(&[_]Feature{}),
1549 };
1550 result[@intFromEnum(Feature.FragmentDensityEXT)] = .{
1551 .llvm_name = null,
1552 .description = "Enable SPIR-V capability FragmentDensityEXT",
1553 .dependencies = featureSet(&[_]Feature{
1554 .Shader,
1555 }),
1556 };
1557 result[@intFromEnum(Feature.ShadingRateNV)] = .{
1558 .llvm_name = null,
1559 .description = "Enable SPIR-V capability ShadingRateNV",
1560 .dependencies = featureSet(&[_]Feature{
1561 .Shader,
1562 }),
1563 };
1564 result[@intFromEnum(Feature.GroupNonUniformPartitionedNV)] = .{
1565 .llvm_name = null,
1566 .description = "Enable SPIR-V capability GroupNonUniformPartitionedNV",
1567 .dependencies = featureSet(&[_]Feature{}),
1568 };
1569 result[@intFromEnum(Feature.ShaderNonUniform)] = .{
1570 .llvm_name = null,
1571 .description = "Enable SPIR-V capability ShaderNonUniform",
1572 .dependencies = featureSet(&[_]Feature{
1573 .v1_5,
1574 .Shader,
1575 }),
1576 };
1577 result[@intFromEnum(Feature.ShaderNonUniformEXT)] = .{
1578 .llvm_name = null,
1579 .description = "Enable SPIR-V capability ShaderNonUniformEXT",
1580 .dependencies = featureSet(&[_]Feature{
1581 .v1_5,
1582 .Shader,
1583 }),
1584 };
1585 result[@intFromEnum(Feature.RuntimeDescriptorArray)] = .{
1586 .llvm_name = null,
1587 .description = "Enable SPIR-V capability RuntimeDescriptorArray",
1588 .dependencies = featureSet(&[_]Feature{
1589 .v1_5,
1590 .Shader,
1591 }),
1592 };
1593 result[@intFromEnum(Feature.RuntimeDescriptorArrayEXT)] = .{
1594 .llvm_name = null,
1595 .description = "Enable SPIR-V capability RuntimeDescriptorArrayEXT",
1596 .dependencies = featureSet(&[_]Feature{
1597 .v1_5,
1598 .Shader,
1599 }),
1600 };
1601 result[@intFromEnum(Feature.InputAttachmentArrayDynamicIndexing)] = .{
1602 .llvm_name = null,
1603 .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexing",
1604 .dependencies = featureSet(&[_]Feature{
1605 .v1_5,
1606 .InputAttachment,
1607 }),
1608 };
1609 result[@intFromEnum(Feature.InputAttachmentArrayDynamicIndexingEXT)] = .{
1610 .llvm_name = null,
1611 .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexingEXT",
1612 .dependencies = featureSet(&[_]Feature{
1613 .v1_5,
1614 .InputAttachment,
1615 }),
1616 };
1617 result[@intFromEnum(Feature.UniformTexelBufferArrayDynamicIndexing)] = .{
1618 .llvm_name = null,
1619 .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexing",
1620 .dependencies = featureSet(&[_]Feature{
1621 .v1_5,
1622 .SampledBuffer,
1623 }),
1624 };
1625 result[@intFromEnum(Feature.UniformTexelBufferArrayDynamicIndexingEXT)] = .{
1626 .llvm_name = null,
1627 .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexingEXT",
1628 .dependencies = featureSet(&[_]Feature{
1629 .v1_5,
1630 .SampledBuffer,
1631 }),
1632 };
1633 result[@intFromEnum(Feature.StorageTexelBufferArrayDynamicIndexing)] = .{
1634 .llvm_name = null,
1635 .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexing",
1636 .dependencies = featureSet(&[_]Feature{
1637 .v1_5,
1638 .ImageBuffer,
1639 }),
1640 };
1641 result[@intFromEnum(Feature.StorageTexelBufferArrayDynamicIndexingEXT)] = .{
1642 .llvm_name = null,
1643 .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexingEXT",
1644 .dependencies = featureSet(&[_]Feature{
1645 .v1_5,
1646 .ImageBuffer,
1647 }),
1648 };
1649 result[@intFromEnum(Feature.UniformBufferArrayNonUniformIndexing)] = .{
1650 .llvm_name = null,
1651 .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexing",
1652 .dependencies = featureSet(&[_]Feature{
1653 .v1_5,
1654 .ShaderNonUniform,
1655 }),
1656 };
1657 result[@intFromEnum(Feature.UniformBufferArrayNonUniformIndexingEXT)] = .{
1658 .llvm_name = null,
1659 .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexingEXT",
1660 .dependencies = featureSet(&[_]Feature{
1661 .v1_5,
1662 .ShaderNonUniform,
1663 }),
1664 };
1665 result[@intFromEnum(Feature.SampledImageArrayNonUniformIndexing)] = .{
1666 .llvm_name = null,
1667 .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexing",
1668 .dependencies = featureSet(&[_]Feature{
1669 .v1_5,
1670 .ShaderNonUniform,
1671 }),
1672 };
1673 result[@intFromEnum(Feature.SampledImageArrayNonUniformIndexingEXT)] = .{
1674 .llvm_name = null,
1675 .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexingEXT",
1676 .dependencies = featureSet(&[_]Feature{
1677 .v1_5,
1678 .ShaderNonUniform,
1679 }),
1680 };
1681 result[@intFromEnum(Feature.StorageBufferArrayNonUniformIndexing)] = .{
1682 .llvm_name = null,
1683 .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexing",
1684 .dependencies = featureSet(&[_]Feature{
1685 .v1_5,
1686 .ShaderNonUniform,
1687 }),
1688 };
1689 result[@intFromEnum(Feature.StorageBufferArrayNonUniformIndexingEXT)] = .{
1690 .llvm_name = null,
1691 .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexingEXT",
1692 .dependencies = featureSet(&[_]Feature{
1693 .v1_5,
1694 .ShaderNonUniform,
1695 }),
1696 };
1697 result[@intFromEnum(Feature.StorageImageArrayNonUniformIndexing)] = .{
1698 .llvm_name = null,
1699 .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexing",
1700 .dependencies = featureSet(&[_]Feature{
1701 .v1_5,
1702 .ShaderNonUniform,
1703 }),
1704 };
1705 result[@intFromEnum(Feature.StorageImageArrayNonUniformIndexingEXT)] = .{
1706 .llvm_name = null,
1707 .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexingEXT",
1708 .dependencies = featureSet(&[_]Feature{
1709 .v1_5,
1710 .ShaderNonUniform,
1711 }),
1712 };
1713 result[@intFromEnum(Feature.InputAttachmentArrayNonUniformIndexing)] = .{
1714 .llvm_name = null,
1715 .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexing",
1716 .dependencies = featureSet(&[_]Feature{
1717 .v1_5,
1718 .InputAttachment,
1719 .ShaderNonUniform,
1720 }),
1721 };
1722 result[@intFromEnum(Feature.InputAttachmentArrayNonUniformIndexingEXT)] = .{
1723 .llvm_name = null,
1724 .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexingEXT",
1725 .dependencies = featureSet(&[_]Feature{
1726 .v1_5,
1727 .InputAttachment,
1728 .ShaderNonUniform,
1729 }),
1730 };
1731 result[@intFromEnum(Feature.UniformTexelBufferArrayNonUniformIndexing)] = .{
1732 .llvm_name = null,
1733 .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexing",
1734 .dependencies = featureSet(&[_]Feature{
1735 .v1_5,
1736 .SampledBuffer,
1737 .ShaderNonUniform,
1738 }),
1739 };
1740 result[@intFromEnum(Feature.UniformTexelBufferArrayNonUniformIndexingEXT)] = .{
1741 .llvm_name = null,
1742 .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexingEXT",
1743 .dependencies = featureSet(&[_]Feature{
1744 .v1_5,
1745 .SampledBuffer,
1746 .ShaderNonUniform,
1747 }),
1748 };
1749 result[@intFromEnum(Feature.StorageTexelBufferArrayNonUniformIndexing)] = .{
1750 .llvm_name = null,
1751 .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexing",
1752 .dependencies = featureSet(&[_]Feature{
1753 .v1_5,
1754 .ImageBuffer,
1755 .ShaderNonUniform,
1756 }),
1757 };
1758 result[@intFromEnum(Feature.StorageTexelBufferArrayNonUniformIndexingEXT)] = .{
1759 .llvm_name = null,
1760 .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexingEXT",
1761 .dependencies = featureSet(&[_]Feature{
1762 .v1_5,
1763 .ImageBuffer,
1764 .ShaderNonUniform,
1765 }),
1766 };
1767 result[@intFromEnum(Feature.RayTracingNV)] = .{
1768 .llvm_name = null,
1769 .description = "Enable SPIR-V capability RayTracingNV",
1770 .dependencies = featureSet(&[_]Feature{
1771 .Shader,
1772 }),
1773 };
1774 result[@intFromEnum(Feature.VulkanMemoryModel)] = .{
1775 .llvm_name = null,
1776 .description = "Enable SPIR-V capability VulkanMemoryModel",
1777 .dependencies = featureSet(&[_]Feature{
1778 .v1_5,
1779 }),
1780 };
1781 result[@intFromEnum(Feature.VulkanMemoryModelKHR)] = .{
1782 .llvm_name = null,
1783 .description = "Enable SPIR-V capability VulkanMemoryModelKHR",
1784 .dependencies = featureSet(&[_]Feature{
1785 .v1_5,
1786 }),
1787 };
1788 result[@intFromEnum(Feature.VulkanMemoryModelDeviceScope)] = .{
1789 .llvm_name = null,
1790 .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScope",
1791 .dependencies = featureSet(&[_]Feature{
1792 .v1_5,
1793 }),
1794 };
1795 result[@intFromEnum(Feature.VulkanMemoryModelDeviceScopeKHR)] = .{
1796 .llvm_name = null,
1797 .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScopeKHR",
1798 .dependencies = featureSet(&[_]Feature{
1799 .v1_5,
1800 }),
1801 };
1802 result[@intFromEnum(Feature.PhysicalStorageBufferAddresses)] = .{
1803 .llvm_name = null,
1804 .description = "Enable SPIR-V capability PhysicalStorageBufferAddresses",
1805 .dependencies = featureSet(&[_]Feature{
1806 .v1_5,
1807 .Shader,
1808 }),
1809 };
1810 result[@intFromEnum(Feature.PhysicalStorageBufferAddressesEXT)] = .{
1811 .llvm_name = null,
1812 .description = "Enable SPIR-V capability PhysicalStorageBufferAddressesEXT",
1813 .dependencies = featureSet(&[_]Feature{
1814 .v1_5,
1815 .Shader,
1816 }),
1817 };
1818 result[@intFromEnum(Feature.ComputeDerivativeGroupLinearNV)] = .{
1819 .llvm_name = null,
1820 .description = "Enable SPIR-V capability ComputeDerivativeGroupLinearNV",
1821 .dependencies = featureSet(&[_]Feature{}),
1822 };
1823 result[@intFromEnum(Feature.RayTracingProvisionalKHR)] = .{
1824 .llvm_name = null,
1825 .description = "Enable SPIR-V capability RayTracingProvisionalKHR",
1826 .dependencies = featureSet(&[_]Feature{
1827 .Shader,
1828 }),
1829 };
1830 result[@intFromEnum(Feature.CooperativeMatrixNV)] = .{
1831 .llvm_name = null,
1832 .description = "Enable SPIR-V capability CooperativeMatrixNV",
1833 .dependencies = featureSet(&[_]Feature{
1834 .Shader,
1835 }),
1836 };
1837 result[@intFromEnum(Feature.FragmentShaderSampleInterlockEXT)] = .{
1838 .llvm_name = null,
1839 .description = "Enable SPIR-V capability FragmentShaderSampleInterlockEXT",
1840 .dependencies = featureSet(&[_]Feature{
1841 .Shader,
1842 }),
1843 };
1844 result[@intFromEnum(Feature.FragmentShaderShadingRateInterlockEXT)] = .{
1845 .llvm_name = null,
1846 .description = "Enable SPIR-V capability FragmentShaderShadingRateInterlockEXT",
1847 .dependencies = featureSet(&[_]Feature{
1848 .Shader,
1849 }),
1850 };
1851 result[@intFromEnum(Feature.ShaderSMBuiltinsNV)] = .{
1852 .llvm_name = null,
1853 .description = "Enable SPIR-V capability ShaderSMBuiltinsNV",
1854 .dependencies = featureSet(&[_]Feature{
1855 .Shader,
1856 }),
1857 };
1858 result[@intFromEnum(Feature.FragmentShaderPixelInterlockEXT)] = .{
1859 .llvm_name = null,
1860 .description = "Enable SPIR-V capability FragmentShaderPixelInterlockEXT",
1861 .dependencies = featureSet(&[_]Feature{
1862 .Shader,
1863 }),
1864 };
1865 result[@intFromEnum(Feature.DemoteToHelperInvocationEXT)] = .{
1866 .llvm_name = null,
1867 .description = "Enable SPIR-V capability DemoteToHelperInvocationEXT",
1868 .dependencies = featureSet(&[_]Feature{
1869 .Shader,
1870 }),
1871 };
1872 result[@intFromEnum(Feature.SubgroupShuffleINTEL)] = .{
1873 .llvm_name = null,
1874 .description = "Enable SPIR-V capability SubgroupShuffleINTEL",
1875 .dependencies = featureSet(&[_]Feature{}),
1876 };
1877 result[@intFromEnum(Feature.SubgroupBufferBlockIOINTEL)] = .{
1878 .llvm_name = null,
1879 .description = "Enable SPIR-V capability SubgroupBufferBlockIOINTEL",
1880 .dependencies = featureSet(&[_]Feature{}),
1881 };
1882 result[@intFromEnum(Feature.SubgroupImageBlockIOINTEL)] = .{
1883 .llvm_name = null,
1884 .description = "Enable SPIR-V capability SubgroupImageBlockIOINTEL",
1885 .dependencies = featureSet(&[_]Feature{}),
1886 };
1887 result[@intFromEnum(Feature.SubgroupImageMediaBlockIOINTEL)] = .{
1888 .llvm_name = null,
1889 .description = "Enable SPIR-V capability SubgroupImageMediaBlockIOINTEL",
1890 .dependencies = featureSet(&[_]Feature{}),
1891 };
1892 result[@intFromEnum(Feature.RoundToInfinityINTEL)] = .{
1893 .llvm_name = null,
1894 .description = "Enable SPIR-V capability RoundToInfinityINTEL",
1895 .dependencies = featureSet(&[_]Feature{}),
1896 };
1897 result[@intFromEnum(Feature.FloatingPointModeINTEL)] = .{
1898 .llvm_name = null,
1899 .description = "Enable SPIR-V capability FloatingPointModeINTEL",
1900 .dependencies = featureSet(&[_]Feature{}),
1901 };
1902 result[@intFromEnum(Feature.IntegerFunctions2INTEL)] = .{
1903 .llvm_name = null,
1904 .description = "Enable SPIR-V capability IntegerFunctions2INTEL",
1905 .dependencies = featureSet(&[_]Feature{
1906 .Shader,
1907 }),
1908 };
1909 result[@intFromEnum(Feature.FunctionPointersINTEL)] = .{
1910 .llvm_name = null,
1911 .description = "Enable SPIR-V capability FunctionPointersINTEL",
1912 .dependencies = featureSet(&[_]Feature{}),
1913 };
1914 result[@intFromEnum(Feature.IndirectReferencesINTEL)] = .{
1915 .llvm_name = null,
1916 .description = "Enable SPIR-V capability IndirectReferencesINTEL",
1917 .dependencies = featureSet(&[_]Feature{}),
1918 };
1919 result[@intFromEnum(Feature.AsmINTEL)] = .{
1920 .llvm_name = null,
1921 .description = "Enable SPIR-V capability AsmINTEL",
1922 .dependencies = featureSet(&[_]Feature{}),
1923 };
1924 result[@intFromEnum(Feature.AtomicFloat32MinMaxEXT)] = .{
1925 .llvm_name = null,
1926 .description = "Enable SPIR-V capability AtomicFloat32MinMaxEXT",
1927 .dependencies = featureSet(&[_]Feature{}),
1928 };
1929 result[@intFromEnum(Feature.AtomicFloat64MinMaxEXT)] = .{
1930 .llvm_name = null,
1931 .description = "Enable SPIR-V capability AtomicFloat64MinMaxEXT",
1932 .dependencies = featureSet(&[_]Feature{}),
1933 };
1934 result[@intFromEnum(Feature.AtomicFloat16MinMaxEXT)] = .{
1935 .llvm_name = null,
1936 .description = "Enable SPIR-V capability AtomicFloat16MinMaxEXT",
1937 .dependencies = featureSet(&[_]Feature{}),
1938 };
1939 result[@intFromEnum(Feature.VectorComputeINTEL)] = .{
1940 .llvm_name = null,
1941 .description = "Enable SPIR-V capability VectorComputeINTEL",
1942 .dependencies = featureSet(&[_]Feature{
1943 .VectorAnyINTEL,
1944 }),
1945 };
1946 result[@intFromEnum(Feature.VectorAnyINTEL)] = .{
1947 .llvm_name = null,
1948 .description = "Enable SPIR-V capability VectorAnyINTEL",
1949 .dependencies = featureSet(&[_]Feature{}),
1950 };
1951 result[@intFromEnum(Feature.ExpectAssumeKHR)] = .{
1952 .llvm_name = null,
1953 .description = "Enable SPIR-V capability ExpectAssumeKHR",
1954 .dependencies = featureSet(&[_]Feature{}),
1955 };
1956 result[@intFromEnum(Feature.SubgroupAvcMotionEstimationINTEL)] = .{
1957 .llvm_name = null,
1958 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationINTEL",
1959 .dependencies = featureSet(&[_]Feature{}),
1960 };
1961 result[@intFromEnum(Feature.SubgroupAvcMotionEstimationIntraINTEL)] = .{
1962 .llvm_name = null,
1963 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationIntraINTEL",
1964 .dependencies = featureSet(&[_]Feature{}),
1965 };
1966 result[@intFromEnum(Feature.SubgroupAvcMotionEstimationChromaINTEL)] = .{
1967 .llvm_name = null,
1968 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationChromaINTEL",
1969 .dependencies = featureSet(&[_]Feature{}),
1970 };
1971 result[@intFromEnum(Feature.VariableLengthArrayINTEL)] = .{
1972 .llvm_name = null,
1973 .description = "Enable SPIR-V capability VariableLengthArrayINTEL",
1974 .dependencies = featureSet(&[_]Feature{}),
1975 };
1976 result[@intFromEnum(Feature.FunctionFloatControlINTEL)] = .{
1977 .llvm_name = null,
1978 .description = "Enable SPIR-V capability FunctionFloatControlINTEL",
1979 .dependencies = featureSet(&[_]Feature{}),
1980 };
1981 result[@intFromEnum(Feature.FPGAMemoryAttributesINTEL)] = .{
1982 .llvm_name = null,
1983 .description = "Enable SPIR-V capability FPGAMemoryAttributesINTEL",
1984 .dependencies = featureSet(&[_]Feature{}),
1985 };
1986 result[@intFromEnum(Feature.FPFastMathModeINTEL)] = .{
1987 .llvm_name = null,
1988 .description = "Enable SPIR-V capability FPFastMathModeINTEL",
1989 .dependencies = featureSet(&[_]Feature{
1990 .Kernel,
1991 }),
1992 };
1993 result[@intFromEnum(Feature.ArbitraryPrecisionIntegersINTEL)] = .{
1994 .llvm_name = null,
1995 .description = "Enable SPIR-V capability ArbitraryPrecisionIntegersINTEL",
1996 .dependencies = featureSet(&[_]Feature{}),
1997 };
1998 result[@intFromEnum(Feature.UnstructuredLoopControlsINTEL)] = .{
1999 .llvm_name = null,
2000 .description = "Enable SPIR-V capability UnstructuredLoopControlsINTEL",
2001 .dependencies = featureSet(&[_]Feature{}),
2002 };
2003 result[@intFromEnum(Feature.FPGALoopControlsINTEL)] = .{
2004 .llvm_name = null,
2005 .description = "Enable SPIR-V capability FPGALoopControlsINTEL",
2006 .dependencies = featureSet(&[_]Feature{}),
2007 };
2008 result[@intFromEnum(Feature.KernelAttributesINTEL)] = .{
2009 .llvm_name = null,
2010 .description = "Enable SPIR-V capability KernelAttributesINTEL",
2011 .dependencies = featureSet(&[_]Feature{}),
2012 };
2013 result[@intFromEnum(Feature.FPGAKernelAttributesINTEL)] = .{
2014 .llvm_name = null,
2015 .description = "Enable SPIR-V capability FPGAKernelAttributesINTEL",
2016 .dependencies = featureSet(&[_]Feature{}),
2017 };
2018 result[@intFromEnum(Feature.FPGAMemoryAccessesINTEL)] = .{
2019 .llvm_name = null,
2020 .description = "Enable SPIR-V capability FPGAMemoryAccessesINTEL",
2021 .dependencies = featureSet(&[_]Feature{}),
2022 };
2023 result[@intFromEnum(Feature.FPGAClusterAttributesINTEL)] = .{
2024 .llvm_name = null,
2025 .description = "Enable SPIR-V capability FPGAClusterAttributesINTEL",
2026 .dependencies = featureSet(&[_]Feature{}),
2027 };
2028 result[@intFromEnum(Feature.LoopFuseINTEL)] = .{
2029 .llvm_name = null,
2030 .description = "Enable SPIR-V capability LoopFuseINTEL",
2031 .dependencies = featureSet(&[_]Feature{}),
2032 };
2033 result[@intFromEnum(Feature.FPGABufferLocationINTEL)] = .{
2034 .llvm_name = null,
2035 .description = "Enable SPIR-V capability FPGABufferLocationINTEL",
2036 .dependencies = featureSet(&[_]Feature{}),
2037 };
2038 result[@intFromEnum(Feature.USMStorageClassesINTEL)] = .{
2039 .llvm_name = null,
2040 .description = "Enable SPIR-V capability USMStorageClassesINTEL",
2041 .dependencies = featureSet(&[_]Feature{}),
2042 };
2043 result[@intFromEnum(Feature.IOPipesINTEL)] = .{
2044 .llvm_name = null,
2045 .description = "Enable SPIR-V capability IOPipesINTEL",
2046 .dependencies = featureSet(&[_]Feature{}),
2047 };
2048 result[@intFromEnum(Feature.BlockingPipesINTEL)] = .{
2049 .llvm_name = null,
2050 .description = "Enable SPIR-V capability BlockingPipesINTEL",
2051 .dependencies = featureSet(&[_]Feature{}),
2052 };
2053 result[@intFromEnum(Feature.FPGARegINTEL)] = .{
2054 .llvm_name = null,
2055 .description = "Enable SPIR-V capability FPGARegINTEL",
2056 .dependencies = featureSet(&[_]Feature{}),
2057 };
2058 result[@intFromEnum(Feature.AtomicFloat32AddEXT)] = .{
2059 .llvm_name = null,
2060 .description = "Enable SPIR-V capability AtomicFloat32AddEXT",
2061 .dependencies = featureSet(&[_]Feature{
2062 .Shader,
2063 }),
2064 };
2065 result[@intFromEnum(Feature.AtomicFloat64AddEXT)] = .{
2066 .llvm_name = null,
2067 .description = "Enable SPIR-V capability AtomicFloat64AddEXT",
2068 .dependencies = featureSet(&[_]Feature{
2069 .Shader,
2070 }),
2071 };
2072 result[@intFromEnum(Feature.LongConstantCompositeINTEL)] = .{
2073 .llvm_name = null,
2074 .description = "Enable SPIR-V capability LongConstantCompositeINTEL",
2075 .dependencies = featureSet(&[_]Feature{}),
2076 };
2077 const ti = @typeInfo(Feature);
2078 for (&result, 0..) |*elem, i| {
2079 elem.index = i;
2080 elem.name = ti.Enum.fields[i].name;
2081 }
2082 break :blk result;
2083};
2084
2085pub const cpu = struct {
2086 pub const generic = CpuModel{
2087 .name = "generic",
2088 .llvm_name = "generic",
2089 .features = featureSet(&[_]Feature{}),
2090 };
2091};
lib/std/Target/ve.zig created+39
......@@ -0,0 +1,39 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 vpu,
9};
10
11pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
12pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
13pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
14pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
15
16pub const all_features = blk: {
17 const len = @typeInfo(Feature).Enum.fields.len;
18 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
19 var result: [len]CpuFeature = undefined;
20 result[@intFromEnum(Feature.vpu)] = .{
21 .llvm_name = "vpu",
22 .description = "Enable the VPU",
23 .dependencies = featureSet(&[_]Feature{}),
24 };
25 const ti = @typeInfo(Feature);
26 for (&result, 0..) |*elem, i| {
27 elem.index = i;
28 elem.name = ti.Enum.fields[i].name;
29 }
30 break :blk result;
31};
32
33pub const cpu = struct {
34 pub const generic = CpuModel{
35 .name = "generic",
36 .llvm_name = "generic",
37 .features = featureSet(&[_]Feature{}),
38 };
39};
lib/std/Target/wasm.zig created+126
......@@ -0,0 +1,126 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 atomics,
9 bulk_memory,
10 exception_handling,
11 extended_const,
12 multivalue,
13 mutable_globals,
14 nontrapping_fptoint,
15 reference_types,
16 relaxed_simd,
17 sign_ext,
18 simd128,
19 tail_call,
20};
21
22pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
23pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
24pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
25pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
26
27pub const all_features = blk: {
28 const len = @typeInfo(Feature).Enum.fields.len;
29 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
30 var result: [len]CpuFeature = undefined;
31 result[@intFromEnum(Feature.atomics)] = .{
32 .llvm_name = "atomics",
33 .description = "Enable Atomics",
34 .dependencies = featureSet(&[_]Feature{}),
35 };
36 result[@intFromEnum(Feature.bulk_memory)] = .{
37 .llvm_name = "bulk-memory",
38 .description = "Enable bulk memory operations",
39 .dependencies = featureSet(&[_]Feature{}),
40 };
41 result[@intFromEnum(Feature.exception_handling)] = .{
42 .llvm_name = "exception-handling",
43 .description = "Enable Wasm exception handling",
44 .dependencies = featureSet(&[_]Feature{}),
45 };
46 result[@intFromEnum(Feature.extended_const)] = .{
47 .llvm_name = "extended-const",
48 .description = "Enable extended const expressions",
49 .dependencies = featureSet(&[_]Feature{}),
50 };
51 result[@intFromEnum(Feature.multivalue)] = .{
52 .llvm_name = "multivalue",
53 .description = "Enable multivalue blocks, instructions, and functions",
54 .dependencies = featureSet(&[_]Feature{}),
55 };
56 result[@intFromEnum(Feature.mutable_globals)] = .{
57 .llvm_name = "mutable-globals",
58 .description = "Enable mutable globals",
59 .dependencies = featureSet(&[_]Feature{}),
60 };
61 result[@intFromEnum(Feature.nontrapping_fptoint)] = .{
62 .llvm_name = "nontrapping-fptoint",
63 .description = "Enable non-trapping float-to-int conversion operators",
64 .dependencies = featureSet(&[_]Feature{}),
65 };
66 result[@intFromEnum(Feature.reference_types)] = .{
67 .llvm_name = "reference-types",
68 .description = "Enable reference types",
69 .dependencies = featureSet(&[_]Feature{}),
70 };
71 result[@intFromEnum(Feature.relaxed_simd)] = .{
72 .llvm_name = "relaxed-simd",
73 .description = "Enable relaxed-simd instructions",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.sign_ext)] = .{
77 .llvm_name = "sign-ext",
78 .description = "Enable sign extension operators",
79 .dependencies = featureSet(&[_]Feature{}),
80 };
81 result[@intFromEnum(Feature.simd128)] = .{
82 .llvm_name = "simd128",
83 .description = "Enable 128-bit SIMD",
84 .dependencies = featureSet(&[_]Feature{}),
85 };
86 result[@intFromEnum(Feature.tail_call)] = .{
87 .llvm_name = "tail-call",
88 .description = "Enable tail call instructions",
89 .dependencies = featureSet(&[_]Feature{}),
90 };
91 const ti = @typeInfo(Feature);
92 for (&result, 0..) |*elem, i| {
93 elem.index = i;
94 elem.name = ti.Enum.fields[i].name;
95 }
96 break :blk result;
97};
98
99pub const cpu = struct {
100 pub const bleeding_edge = CpuModel{
101 .name = "bleeding_edge",
102 .llvm_name = "bleeding-edge",
103 .features = featureSet(&[_]Feature{
104 .atomics,
105 .bulk_memory,
106 .mutable_globals,
107 .nontrapping_fptoint,
108 .sign_ext,
109 .simd128,
110 .tail_call,
111 }),
112 };
113 pub const generic = CpuModel{
114 .name = "generic",
115 .llvm_name = "generic",
116 .features = featureSet(&[_]Feature{
117 .mutable_globals,
118 .sign_ext,
119 }),
120 };
121 pub const mvp = CpuModel{
122 .name = "mvp",
123 .llvm_name = "mvp",
124 .features = featureSet(&[_]Feature{}),
125 };
126};
lib/std/Target/x86.zig created+4179
......@@ -0,0 +1,4179 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"16bit_mode",
9 @"32bit_mode",
10 @"3dnow",
11 @"3dnowa",
12 @"64bit",
13 adx,
14 aes,
15 allow_light_256_bit,
16 amx_bf16,
17 amx_complex,
18 amx_fp16,
19 amx_int8,
20 amx_tile,
21 avx,
22 avx2,
23 avx512bf16,
24 avx512bitalg,
25 avx512bw,
26 avx512cd,
27 avx512dq,
28 avx512er,
29 avx512f,
30 avx512fp16,
31 avx512ifma,
32 avx512pf,
33 avx512vbmi,
34 avx512vbmi2,
35 avx512vl,
36 avx512vnni,
37 avx512vp2intersect,
38 avx512vpopcntdq,
39 avxifma,
40 avxneconvert,
41 avxvnni,
42 avxvnniint16,
43 avxvnniint8,
44 bmi,
45 bmi2,
46 branchfusion,
47 cldemote,
48 clflushopt,
49 clwb,
50 clzero,
51 cmov,
52 cmpccxadd,
53 crc32,
54 cx16,
55 cx8,
56 enqcmd,
57 ermsb,
58 f16c,
59 false_deps_getmant,
60 false_deps_lzcnt_tzcnt,
61 false_deps_mulc,
62 false_deps_mullq,
63 false_deps_perm,
64 false_deps_popcnt,
65 false_deps_range,
66 fast_11bytenop,
67 fast_15bytenop,
68 fast_7bytenop,
69 fast_bextr,
70 fast_gather,
71 fast_hops,
72 fast_lzcnt,
73 fast_movbe,
74 fast_scalar_fsqrt,
75 fast_scalar_shift_masks,
76 fast_shld_rotate,
77 fast_variable_crosslane_shuffle,
78 fast_variable_perlane_shuffle,
79 fast_vector_fsqrt,
80 fast_vector_shift_masks,
81 faster_shift_than_shuffle,
82 fma,
83 fma4,
84 fsgsbase,
85 fsrm,
86 fxsr,
87 gfni,
88 harden_sls_ijmp,
89 harden_sls_ret,
90 hreset,
91 idivl_to_divb,
92 idivq_to_divl,
93 invpcid,
94 kl,
95 lea_sp,
96 lea_uses_ag,
97 lvi_cfi,
98 lvi_load_hardening,
99 lwp,
100 lzcnt,
101 macrofusion,
102 mmx,
103 movbe,
104 movdir64b,
105 movdiri,
106 mwaitx,
107 no_bypass_delay,
108 no_bypass_delay_blend,
109 no_bypass_delay_mov,
110 no_bypass_delay_shuffle,
111 nopl,
112 pad_short_functions,
113 pclmul,
114 pconfig,
115 pku,
116 popcnt,
117 prefer_128_bit,
118 prefer_256_bit,
119 prefer_mask_registers,
120 prefer_movmsk_over_vtest,
121 prefetchi,
122 prefetchwt1,
123 prfchw,
124 ptwrite,
125 raoint,
126 rdpid,
127 rdpru,
128 rdrnd,
129 rdseed,
130 retpoline,
131 retpoline_external_thunk,
132 retpoline_indirect_branches,
133 retpoline_indirect_calls,
134 rtm,
135 sahf,
136 sbb_dep_breaking,
137 serialize,
138 seses,
139 sgx,
140 sha,
141 sha512,
142 shstk,
143 slow_3ops_lea,
144 slow_incdec,
145 slow_lea,
146 slow_pmaddwd,
147 slow_pmulld,
148 slow_shld,
149 slow_two_mem_ops,
150 slow_unaligned_mem_16,
151 slow_unaligned_mem_32,
152 sm3,
153 sm4,
154 soft_float,
155 sse,
156 sse2,
157 sse3,
158 sse4_1,
159 sse4_2,
160 sse4a,
161 sse_unaligned_mem,
162 ssse3,
163 tagged_globals,
164 tbm,
165 tsxldtrk,
166 tuning_fast_imm_vector_shift,
167 uintr,
168 use_glm_div_sqrt_costs,
169 use_slm_arith_costs,
170 vaes,
171 vpclmulqdq,
172 vzeroupper,
173 waitpkg,
174 wbnoinvd,
175 widekl,
176 x87,
177 xop,
178 xsave,
179 xsavec,
180 xsaveopt,
181 xsaves,
182};
183
184pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
185pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
186pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
187pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
188
189pub const all_features = blk: {
190 const len = @typeInfo(Feature).Enum.fields.len;
191 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
192 var result: [len]CpuFeature = undefined;
193 result[@intFromEnum(Feature.@"16bit_mode")] = .{
194 .llvm_name = "16bit-mode",
195 .description = "16-bit mode (i8086)",
196 .dependencies = featureSet(&[_]Feature{}),
197 };
198 result[@intFromEnum(Feature.@"32bit_mode")] = .{
199 .llvm_name = "32bit-mode",
200 .description = "32-bit mode (80386)",
201 .dependencies = featureSet(&[_]Feature{}),
202 };
203 result[@intFromEnum(Feature.@"3dnow")] = .{
204 .llvm_name = "3dnow",
205 .description = "Enable 3DNow! instructions",
206 .dependencies = featureSet(&[_]Feature{
207 .mmx,
208 }),
209 };
210 result[@intFromEnum(Feature.@"3dnowa")] = .{
211 .llvm_name = "3dnowa",
212 .description = "Enable 3DNow! Athlon instructions",
213 .dependencies = featureSet(&[_]Feature{
214 .@"3dnow",
215 }),
216 };
217 result[@intFromEnum(Feature.@"64bit")] = .{
218 .llvm_name = "64bit",
219 .description = "Support 64-bit instructions",
220 .dependencies = featureSet(&[_]Feature{}),
221 };
222 result[@intFromEnum(Feature.adx)] = .{
223 .llvm_name = "adx",
224 .description = "Support ADX instructions",
225 .dependencies = featureSet(&[_]Feature{}),
226 };
227 result[@intFromEnum(Feature.aes)] = .{
228 .llvm_name = "aes",
229 .description = "Enable AES instructions",
230 .dependencies = featureSet(&[_]Feature{
231 .sse2,
232 }),
233 };
234 result[@intFromEnum(Feature.allow_light_256_bit)] = .{
235 .llvm_name = "allow-light-256-bit",
236 .description = "Enable generation of 256-bit load/stores even if we prefer 128-bit",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.amx_bf16)] = .{
240 .llvm_name = "amx-bf16",
241 .description = "Support AMX-BF16 instructions",
242 .dependencies = featureSet(&[_]Feature{
243 .amx_tile,
244 }),
245 };
246 result[@intFromEnum(Feature.amx_complex)] = .{
247 .llvm_name = "amx-complex",
248 .description = "Support AMX-COMPLEX instructions",
249 .dependencies = featureSet(&[_]Feature{
250 .amx_tile,
251 }),
252 };
253 result[@intFromEnum(Feature.amx_fp16)] = .{
254 .llvm_name = "amx-fp16",
255 .description = "Support AMX amx-fp16 instructions",
256 .dependencies = featureSet(&[_]Feature{
257 .amx_tile,
258 }),
259 };
260 result[@intFromEnum(Feature.amx_int8)] = .{
261 .llvm_name = "amx-int8",
262 .description = "Support AMX-INT8 instructions",
263 .dependencies = featureSet(&[_]Feature{
264 .amx_tile,
265 }),
266 };
267 result[@intFromEnum(Feature.amx_tile)] = .{
268 .llvm_name = "amx-tile",
269 .description = "Support AMX-TILE instructions",
270 .dependencies = featureSet(&[_]Feature{}),
271 };
272 result[@intFromEnum(Feature.avx)] = .{
273 .llvm_name = "avx",
274 .description = "Enable AVX instructions",
275 .dependencies = featureSet(&[_]Feature{
276 .sse4_2,
277 }),
278 };
279 result[@intFromEnum(Feature.avx2)] = .{
280 .llvm_name = "avx2",
281 .description = "Enable AVX2 instructions",
282 .dependencies = featureSet(&[_]Feature{
283 .avx,
284 }),
285 };
286 result[@intFromEnum(Feature.avx512bf16)] = .{
287 .llvm_name = "avx512bf16",
288 .description = "Support bfloat16 floating point",
289 .dependencies = featureSet(&[_]Feature{
290 .avx512bw,
291 }),
292 };
293 result[@intFromEnum(Feature.avx512bitalg)] = .{
294 .llvm_name = "avx512bitalg",
295 .description = "Enable AVX-512 Bit Algorithms",
296 .dependencies = featureSet(&[_]Feature{
297 .avx512bw,
298 }),
299 };
300 result[@intFromEnum(Feature.avx512bw)] = .{
301 .llvm_name = "avx512bw",
302 .description = "Enable AVX-512 Byte and Word Instructions",
303 .dependencies = featureSet(&[_]Feature{
304 .avx512f,
305 }),
306 };
307 result[@intFromEnum(Feature.avx512cd)] = .{
308 .llvm_name = "avx512cd",
309 .description = "Enable AVX-512 Conflict Detection Instructions",
310 .dependencies = featureSet(&[_]Feature{
311 .avx512f,
312 }),
313 };
314 result[@intFromEnum(Feature.avx512dq)] = .{
315 .llvm_name = "avx512dq",
316 .description = "Enable AVX-512 Doubleword and Quadword Instructions",
317 .dependencies = featureSet(&[_]Feature{
318 .avx512f,
319 }),
320 };
321 result[@intFromEnum(Feature.avx512er)] = .{
322 .llvm_name = "avx512er",
323 .description = "Enable AVX-512 Exponential and Reciprocal Instructions",
324 .dependencies = featureSet(&[_]Feature{
325 .avx512f,
326 }),
327 };
328 result[@intFromEnum(Feature.avx512f)] = .{
329 .llvm_name = "avx512f",
330 .description = "Enable AVX-512 instructions",
331 .dependencies = featureSet(&[_]Feature{
332 .avx2,
333 .f16c,
334 .fma,
335 }),
336 };
337 result[@intFromEnum(Feature.avx512fp16)] = .{
338 .llvm_name = "avx512fp16",
339 .description = "Support 16-bit floating point",
340 .dependencies = featureSet(&[_]Feature{
341 .avx512bw,
342 .avx512dq,
343 .avx512vl,
344 }),
345 };
346 result[@intFromEnum(Feature.avx512ifma)] = .{
347 .llvm_name = "avx512ifma",
348 .description = "Enable AVX-512 Integer Fused Multiple-Add",
349 .dependencies = featureSet(&[_]Feature{
350 .avx512f,
351 }),
352 };
353 result[@intFromEnum(Feature.avx512pf)] = .{
354 .llvm_name = "avx512pf",
355 .description = "Enable AVX-512 PreFetch Instructions",
356 .dependencies = featureSet(&[_]Feature{
357 .avx512f,
358 }),
359 };
360 result[@intFromEnum(Feature.avx512vbmi)] = .{
361 .llvm_name = "avx512vbmi",
362 .description = "Enable AVX-512 Vector Byte Manipulation Instructions",
363 .dependencies = featureSet(&[_]Feature{
364 .avx512bw,
365 }),
366 };
367 result[@intFromEnum(Feature.avx512vbmi2)] = .{
368 .llvm_name = "avx512vbmi2",
369 .description = "Enable AVX-512 further Vector Byte Manipulation Instructions",
370 .dependencies = featureSet(&[_]Feature{
371 .avx512bw,
372 }),
373 };
374 result[@intFromEnum(Feature.avx512vl)] = .{
375 .llvm_name = "avx512vl",
376 .description = "Enable AVX-512 Vector Length eXtensions",
377 .dependencies = featureSet(&[_]Feature{
378 .avx512f,
379 }),
380 };
381 result[@intFromEnum(Feature.avx512vnni)] = .{
382 .llvm_name = "avx512vnni",
383 .description = "Enable AVX-512 Vector Neural Network Instructions",
384 .dependencies = featureSet(&[_]Feature{
385 .avx512f,
386 }),
387 };
388 result[@intFromEnum(Feature.avx512vp2intersect)] = .{
389 .llvm_name = "avx512vp2intersect",
390 .description = "Enable AVX-512 vp2intersect",
391 .dependencies = featureSet(&[_]Feature{
392 .avx512f,
393 }),
394 };
395 result[@intFromEnum(Feature.avx512vpopcntdq)] = .{
396 .llvm_name = "avx512vpopcntdq",
397 .description = "Enable AVX-512 Population Count Instructions",
398 .dependencies = featureSet(&[_]Feature{
399 .avx512f,
400 }),
401 };
402 result[@intFromEnum(Feature.avxifma)] = .{
403 .llvm_name = "avxifma",
404 .description = "Enable AVX-IFMA",
405 .dependencies = featureSet(&[_]Feature{
406 .avx2,
407 }),
408 };
409 result[@intFromEnum(Feature.avxneconvert)] = .{
410 .llvm_name = "avxneconvert",
411 .description = "Support AVX-NE-CONVERT instructions",
412 .dependencies = featureSet(&[_]Feature{
413 .avx2,
414 }),
415 };
416 result[@intFromEnum(Feature.avxvnni)] = .{
417 .llvm_name = "avxvnni",
418 .description = "Support AVX_VNNI encoding",
419 .dependencies = featureSet(&[_]Feature{
420 .avx2,
421 }),
422 };
423 result[@intFromEnum(Feature.avxvnniint16)] = .{
424 .llvm_name = "avxvnniint16",
425 .description = "Enable AVX-VNNI-INT16",
426 .dependencies = featureSet(&[_]Feature{
427 .avx2,
428 }),
429 };
430 result[@intFromEnum(Feature.avxvnniint8)] = .{
431 .llvm_name = "avxvnniint8",
432 .description = "Enable AVX-VNNI-INT8",
433 .dependencies = featureSet(&[_]Feature{
434 .avx2,
435 }),
436 };
437 result[@intFromEnum(Feature.bmi)] = .{
438 .llvm_name = "bmi",
439 .description = "Support BMI instructions",
440 .dependencies = featureSet(&[_]Feature{}),
441 };
442 result[@intFromEnum(Feature.bmi2)] = .{
443 .llvm_name = "bmi2",
444 .description = "Support BMI2 instructions",
445 .dependencies = featureSet(&[_]Feature{}),
446 };
447 result[@intFromEnum(Feature.branchfusion)] = .{
448 .llvm_name = "branchfusion",
449 .description = "CMP/TEST can be fused with conditional branches",
450 .dependencies = featureSet(&[_]Feature{}),
451 };
452 result[@intFromEnum(Feature.cldemote)] = .{
453 .llvm_name = "cldemote",
454 .description = "Enable Cache Line Demote",
455 .dependencies = featureSet(&[_]Feature{}),
456 };
457 result[@intFromEnum(Feature.clflushopt)] = .{
458 .llvm_name = "clflushopt",
459 .description = "Flush A Cache Line Optimized",
460 .dependencies = featureSet(&[_]Feature{}),
461 };
462 result[@intFromEnum(Feature.clwb)] = .{
463 .llvm_name = "clwb",
464 .description = "Cache Line Write Back",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@intFromEnum(Feature.clzero)] = .{
468 .llvm_name = "clzero",
469 .description = "Enable Cache Line Zero",
470 .dependencies = featureSet(&[_]Feature{}),
471 };
472 result[@intFromEnum(Feature.cmov)] = .{
473 .llvm_name = "cmov",
474 .description = "Enable conditional move instructions",
475 .dependencies = featureSet(&[_]Feature{}),
476 };
477 result[@intFromEnum(Feature.cmpccxadd)] = .{
478 .llvm_name = "cmpccxadd",
479 .description = "Support CMPCCXADD instructions",
480 .dependencies = featureSet(&[_]Feature{}),
481 };
482 result[@intFromEnum(Feature.crc32)] = .{
483 .llvm_name = "crc32",
484 .description = "Enable SSE 4.2 CRC32 instruction (used when SSE4.2 is supported but function is GPR only)",
485 .dependencies = featureSet(&[_]Feature{}),
486 };
487 result[@intFromEnum(Feature.cx16)] = .{
488 .llvm_name = "cx16",
489 .description = "64-bit with cmpxchg16b (this is true for most x86-64 chips, but not the first AMD chips)",
490 .dependencies = featureSet(&[_]Feature{
491 .cx8,
492 }),
493 };
494 result[@intFromEnum(Feature.cx8)] = .{
495 .llvm_name = "cx8",
496 .description = "Support CMPXCHG8B instructions",
497 .dependencies = featureSet(&[_]Feature{}),
498 };
499 result[@intFromEnum(Feature.enqcmd)] = .{
500 .llvm_name = "enqcmd",
501 .description = "Has ENQCMD instructions",
502 .dependencies = featureSet(&[_]Feature{}),
503 };
504 result[@intFromEnum(Feature.ermsb)] = .{
505 .llvm_name = "ermsb",
506 .description = "REP MOVS/STOS are fast",
507 .dependencies = featureSet(&[_]Feature{}),
508 };
509 result[@intFromEnum(Feature.f16c)] = .{
510 .llvm_name = "f16c",
511 .description = "Support 16-bit floating point conversion instructions",
512 .dependencies = featureSet(&[_]Feature{
513 .avx,
514 }),
515 };
516 result[@intFromEnum(Feature.false_deps_getmant)] = .{
517 .llvm_name = "false-deps-getmant",
518 .description = "VGETMANTSS/SD/SH and VGETMANDPS/PD(memory version) has a false dependency on dest register",
519 .dependencies = featureSet(&[_]Feature{}),
520 };
521 result[@intFromEnum(Feature.false_deps_lzcnt_tzcnt)] = .{
522 .llvm_name = "false-deps-lzcnt-tzcnt",
523 .description = "LZCNT/TZCNT have a false dependency on dest register",
524 .dependencies = featureSet(&[_]Feature{}),
525 };
526 result[@intFromEnum(Feature.false_deps_mulc)] = .{
527 .llvm_name = "false-deps-mulc",
528 .description = "VF[C]MULCPH/SH has a false dependency on dest register",
529 .dependencies = featureSet(&[_]Feature{}),
530 };
531 result[@intFromEnum(Feature.false_deps_mullq)] = .{
532 .llvm_name = "false-deps-mullq",
533 .description = "VPMULLQ has a false dependency on dest register",
534 .dependencies = featureSet(&[_]Feature{}),
535 };
536 result[@intFromEnum(Feature.false_deps_perm)] = .{
537 .llvm_name = "false-deps-perm",
538 .description = "VPERMD/Q/PS/PD has a false dependency on dest register",
539 .dependencies = featureSet(&[_]Feature{}),
540 };
541 result[@intFromEnum(Feature.false_deps_popcnt)] = .{
542 .llvm_name = "false-deps-popcnt",
543 .description = "POPCNT has a false dependency on dest register",
544 .dependencies = featureSet(&[_]Feature{}),
545 };
546 result[@intFromEnum(Feature.false_deps_range)] = .{
547 .llvm_name = "false-deps-range",
548 .description = "VRANGEPD/PS/SD/SS has a false dependency on dest register",
549 .dependencies = featureSet(&[_]Feature{}),
550 };
551 result[@intFromEnum(Feature.fast_11bytenop)] = .{
552 .llvm_name = "fast-11bytenop",
553 .description = "Target can quickly decode up to 11 byte NOPs",
554 .dependencies = featureSet(&[_]Feature{}),
555 };
556 result[@intFromEnum(Feature.fast_15bytenop)] = .{
557 .llvm_name = "fast-15bytenop",
558 .description = "Target can quickly decode up to 15 byte NOPs",
559 .dependencies = featureSet(&[_]Feature{}),
560 };
561 result[@intFromEnum(Feature.fast_7bytenop)] = .{
562 .llvm_name = "fast-7bytenop",
563 .description = "Target can quickly decode up to 7 byte NOPs",
564 .dependencies = featureSet(&[_]Feature{}),
565 };
566 result[@intFromEnum(Feature.fast_bextr)] = .{
567 .llvm_name = "fast-bextr",
568 .description = "Indicates that the BEXTR instruction is implemented as a single uop with good throughput",
569 .dependencies = featureSet(&[_]Feature{}),
570 };
571 result[@intFromEnum(Feature.fast_gather)] = .{
572 .llvm_name = "fast-gather",
573 .description = "Indicates if gather is reasonably fast (this is true for Skylake client and all AVX-512 CPUs)",
574 .dependencies = featureSet(&[_]Feature{}),
575 };
576 result[@intFromEnum(Feature.fast_hops)] = .{
577 .llvm_name = "fast-hops",
578 .description = "Prefer horizontal vector math instructions (haddp, phsub, etc.) over normal vector instructions with shuffles",
579 .dependencies = featureSet(&[_]Feature{}),
580 };
581 result[@intFromEnum(Feature.fast_lzcnt)] = .{
582 .llvm_name = "fast-lzcnt",
583 .description = "LZCNT instructions are as fast as most simple integer ops",
584 .dependencies = featureSet(&[_]Feature{}),
585 };
586 result[@intFromEnum(Feature.fast_movbe)] = .{
587 .llvm_name = "fast-movbe",
588 .description = "Prefer a movbe over a single-use load + bswap / single-use bswap + store",
589 .dependencies = featureSet(&[_]Feature{}),
590 };
591 result[@intFromEnum(Feature.fast_scalar_fsqrt)] = .{
592 .llvm_name = "fast-scalar-fsqrt",
593 .description = "Scalar SQRT is fast (disable Newton-Raphson)",
594 .dependencies = featureSet(&[_]Feature{}),
595 };
596 result[@intFromEnum(Feature.fast_scalar_shift_masks)] = .{
597 .llvm_name = "fast-scalar-shift-masks",
598 .description = "Prefer a left/right scalar logical shift pair over a shift+and pair",
599 .dependencies = featureSet(&[_]Feature{}),
600 };
601 result[@intFromEnum(Feature.fast_shld_rotate)] = .{
602 .llvm_name = "fast-shld-rotate",
603 .description = "SHLD can be used as a faster rotate",
604 .dependencies = featureSet(&[_]Feature{}),
605 };
606 result[@intFromEnum(Feature.fast_variable_crosslane_shuffle)] = .{
607 .llvm_name = "fast-variable-crosslane-shuffle",
608 .description = "Cross-lane shuffles with variable masks are fast",
609 .dependencies = featureSet(&[_]Feature{}),
610 };
611 result[@intFromEnum(Feature.fast_variable_perlane_shuffle)] = .{
612 .llvm_name = "fast-variable-perlane-shuffle",
613 .description = "Per-lane shuffles with variable masks are fast",
614 .dependencies = featureSet(&[_]Feature{}),
615 };
616 result[@intFromEnum(Feature.fast_vector_fsqrt)] = .{
617 .llvm_name = "fast-vector-fsqrt",
618 .description = "Vector SQRT is fast (disable Newton-Raphson)",
619 .dependencies = featureSet(&[_]Feature{}),
620 };
621 result[@intFromEnum(Feature.fast_vector_shift_masks)] = .{
622 .llvm_name = "fast-vector-shift-masks",
623 .description = "Prefer a left/right vector logical shift pair over a shift+and pair",
624 .dependencies = featureSet(&[_]Feature{}),
625 };
626 result[@intFromEnum(Feature.faster_shift_than_shuffle)] = .{
627 .llvm_name = "faster-shift-than-shuffle",
628 .description = "Shifts are faster (or as fast) as shuffle",
629 .dependencies = featureSet(&[_]Feature{}),
630 };
631 result[@intFromEnum(Feature.fma)] = .{
632 .llvm_name = "fma",
633 .description = "Enable three-operand fused multiple-add",
634 .dependencies = featureSet(&[_]Feature{
635 .avx,
636 }),
637 };
638 result[@intFromEnum(Feature.fma4)] = .{
639 .llvm_name = "fma4",
640 .description = "Enable four-operand fused multiple-add",
641 .dependencies = featureSet(&[_]Feature{
642 .avx,
643 .sse4a,
644 }),
645 };
646 result[@intFromEnum(Feature.fsgsbase)] = .{
647 .llvm_name = "fsgsbase",
648 .description = "Support FS/GS Base instructions",
649 .dependencies = featureSet(&[_]Feature{}),
650 };
651 result[@intFromEnum(Feature.fsrm)] = .{
652 .llvm_name = "fsrm",
653 .description = "REP MOVSB of short lengths is faster",
654 .dependencies = featureSet(&[_]Feature{}),
655 };
656 result[@intFromEnum(Feature.fxsr)] = .{
657 .llvm_name = "fxsr",
658 .description = "Support fxsave/fxrestore instructions",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.gfni)] = .{
662 .llvm_name = "gfni",
663 .description = "Enable Galois Field Arithmetic Instructions",
664 .dependencies = featureSet(&[_]Feature{
665 .sse2,
666 }),
667 };
668 result[@intFromEnum(Feature.harden_sls_ijmp)] = .{
669 .llvm_name = "harden-sls-ijmp",
670 .description = "Harden against straight line speculation across indirect JMP instructions.",
671 .dependencies = featureSet(&[_]Feature{}),
672 };
673 result[@intFromEnum(Feature.harden_sls_ret)] = .{
674 .llvm_name = "harden-sls-ret",
675 .description = "Harden against straight line speculation across RET instructions.",
676 .dependencies = featureSet(&[_]Feature{}),
677 };
678 result[@intFromEnum(Feature.hreset)] = .{
679 .llvm_name = "hreset",
680 .description = "Has hreset instruction",
681 .dependencies = featureSet(&[_]Feature{}),
682 };
683 result[@intFromEnum(Feature.idivl_to_divb)] = .{
684 .llvm_name = "idivl-to-divb",
685 .description = "Use 8-bit divide for positive values less than 256",
686 .dependencies = featureSet(&[_]Feature{}),
687 };
688 result[@intFromEnum(Feature.idivq_to_divl)] = .{
689 .llvm_name = "idivq-to-divl",
690 .description = "Use 32-bit divide for positive values less than 2^32",
691 .dependencies = featureSet(&[_]Feature{}),
692 };
693 result[@intFromEnum(Feature.invpcid)] = .{
694 .llvm_name = "invpcid",
695 .description = "Invalidate Process-Context Identifier",
696 .dependencies = featureSet(&[_]Feature{}),
697 };
698 result[@intFromEnum(Feature.kl)] = .{
699 .llvm_name = "kl",
700 .description = "Support Key Locker kl Instructions",
701 .dependencies = featureSet(&[_]Feature{
702 .sse2,
703 }),
704 };
705 result[@intFromEnum(Feature.lea_sp)] = .{
706 .llvm_name = "lea-sp",
707 .description = "Use LEA for adjusting the stack pointer (this is an optimization for Intel Atom processors)",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.lea_uses_ag)] = .{
711 .llvm_name = "lea-uses-ag",
712 .description = "LEA instruction needs inputs at AG stage",
713 .dependencies = featureSet(&[_]Feature{}),
714 };
715 result[@intFromEnum(Feature.lvi_cfi)] = .{
716 .llvm_name = "lvi-cfi",
717 .description = "Prevent indirect calls/branches from using a memory operand, and precede all indirect calls/branches from a register with an LFENCE instruction to serialize control flow. Also decompose RET instructions into a POP+LFENCE+JMP sequence.",
718 .dependencies = featureSet(&[_]Feature{}),
719 };
720 result[@intFromEnum(Feature.lvi_load_hardening)] = .{
721 .llvm_name = "lvi-load-hardening",
722 .description = "Insert LFENCE instructions to prevent data speculatively injected into loads from being used maliciously.",
723 .dependencies = featureSet(&[_]Feature{}),
724 };
725 result[@intFromEnum(Feature.lwp)] = .{
726 .llvm_name = "lwp",
727 .description = "Enable LWP instructions",
728 .dependencies = featureSet(&[_]Feature{}),
729 };
730 result[@intFromEnum(Feature.lzcnt)] = .{
731 .llvm_name = "lzcnt",
732 .description = "Support LZCNT instruction",
733 .dependencies = featureSet(&[_]Feature{}),
734 };
735 result[@intFromEnum(Feature.macrofusion)] = .{
736 .llvm_name = "macrofusion",
737 .description = "Various instructions can be fused with conditional branches",
738 .dependencies = featureSet(&[_]Feature{}),
739 };
740 result[@intFromEnum(Feature.mmx)] = .{
741 .llvm_name = "mmx",
742 .description = "Enable MMX instructions",
743 .dependencies = featureSet(&[_]Feature{}),
744 };
745 result[@intFromEnum(Feature.movbe)] = .{
746 .llvm_name = "movbe",
747 .description = "Support MOVBE instruction",
748 .dependencies = featureSet(&[_]Feature{}),
749 };
750 result[@intFromEnum(Feature.movdir64b)] = .{
751 .llvm_name = "movdir64b",
752 .description = "Support movdir64b instruction (direct store 64 bytes)",
753 .dependencies = featureSet(&[_]Feature{}),
754 };
755 result[@intFromEnum(Feature.movdiri)] = .{
756 .llvm_name = "movdiri",
757 .description = "Support movdiri instruction (direct store integer)",
758 .dependencies = featureSet(&[_]Feature{}),
759 };
760 result[@intFromEnum(Feature.mwaitx)] = .{
761 .llvm_name = "mwaitx",
762 .description = "Enable MONITORX/MWAITX timer functionality",
763 .dependencies = featureSet(&[_]Feature{}),
764 };
765 result[@intFromEnum(Feature.no_bypass_delay)] = .{
766 .llvm_name = "no-bypass-delay",
767 .description = "Has no bypass delay when using the 'wrong' domain",
768 .dependencies = featureSet(&[_]Feature{}),
769 };
770 result[@intFromEnum(Feature.no_bypass_delay_blend)] = .{
771 .llvm_name = "no-bypass-delay-blend",
772 .description = "Has no bypass delay when using the 'wrong' blend type",
773 .dependencies = featureSet(&[_]Feature{}),
774 };
775 result[@intFromEnum(Feature.no_bypass_delay_mov)] = .{
776 .llvm_name = "no-bypass-delay-mov",
777 .description = "Has no bypass delay when using the 'wrong' mov type",
778 .dependencies = featureSet(&[_]Feature{}),
779 };
780 result[@intFromEnum(Feature.no_bypass_delay_shuffle)] = .{
781 .llvm_name = "no-bypass-delay-shuffle",
782 .description = "Has no bypass delay when using the 'wrong' shuffle type",
783 .dependencies = featureSet(&[_]Feature{}),
784 };
785 result[@intFromEnum(Feature.nopl)] = .{
786 .llvm_name = "nopl",
787 .description = "Enable NOPL instruction (generally pentium pro+)",
788 .dependencies = featureSet(&[_]Feature{}),
789 };
790 result[@intFromEnum(Feature.pad_short_functions)] = .{
791 .llvm_name = "pad-short-functions",
792 .description = "Pad short functions (to prevent a stall when returning too early)",
793 .dependencies = featureSet(&[_]Feature{}),
794 };
795 result[@intFromEnum(Feature.pclmul)] = .{
796 .llvm_name = "pclmul",
797 .description = "Enable packed carry-less multiplication instructions",
798 .dependencies = featureSet(&[_]Feature{
799 .sse2,
800 }),
801 };
802 result[@intFromEnum(Feature.pconfig)] = .{
803 .llvm_name = "pconfig",
804 .description = "platform configuration instruction",
805 .dependencies = featureSet(&[_]Feature{}),
806 };
807 result[@intFromEnum(Feature.pku)] = .{
808 .llvm_name = "pku",
809 .description = "Enable protection keys",
810 .dependencies = featureSet(&[_]Feature{}),
811 };
812 result[@intFromEnum(Feature.popcnt)] = .{
813 .llvm_name = "popcnt",
814 .description = "Support POPCNT instruction",
815 .dependencies = featureSet(&[_]Feature{}),
816 };
817 result[@intFromEnum(Feature.prefer_128_bit)] = .{
818 .llvm_name = "prefer-128-bit",
819 .description = "Prefer 128-bit AVX instructions",
820 .dependencies = featureSet(&[_]Feature{}),
821 };
822 result[@intFromEnum(Feature.prefer_256_bit)] = .{
823 .llvm_name = "prefer-256-bit",
824 .description = "Prefer 256-bit AVX instructions",
825 .dependencies = featureSet(&[_]Feature{}),
826 };
827 result[@intFromEnum(Feature.prefer_mask_registers)] = .{
828 .llvm_name = "prefer-mask-registers",
829 .description = "Prefer AVX512 mask registers over PTEST/MOVMSK",
830 .dependencies = featureSet(&[_]Feature{}),
831 };
832 result[@intFromEnum(Feature.prefer_movmsk_over_vtest)] = .{
833 .llvm_name = "prefer-movmsk-over-vtest",
834 .description = "Prefer movmsk over vtest instruction",
835 .dependencies = featureSet(&[_]Feature{}),
836 };
837 result[@intFromEnum(Feature.prefetchi)] = .{
838 .llvm_name = "prefetchi",
839 .description = "Prefetch instruction with T0 or T1 Hint",
840 .dependencies = featureSet(&[_]Feature{}),
841 };
842 result[@intFromEnum(Feature.prefetchwt1)] = .{
843 .llvm_name = "prefetchwt1",
844 .description = "Prefetch with Intent to Write and T1 Hint",
845 .dependencies = featureSet(&[_]Feature{}),
846 };
847 result[@intFromEnum(Feature.prfchw)] = .{
848 .llvm_name = "prfchw",
849 .description = "Support PRFCHW instructions",
850 .dependencies = featureSet(&[_]Feature{}),
851 };
852 result[@intFromEnum(Feature.ptwrite)] = .{
853 .llvm_name = "ptwrite",
854 .description = "Support ptwrite instruction",
855 .dependencies = featureSet(&[_]Feature{}),
856 };
857 result[@intFromEnum(Feature.raoint)] = .{
858 .llvm_name = "raoint",
859 .description = "Support RAO-INT instructions",
860 .dependencies = featureSet(&[_]Feature{}),
861 };
862 result[@intFromEnum(Feature.rdpid)] = .{
863 .llvm_name = "rdpid",
864 .description = "Support RDPID instructions",
865 .dependencies = featureSet(&[_]Feature{}),
866 };
867 result[@intFromEnum(Feature.rdpru)] = .{
868 .llvm_name = "rdpru",
869 .description = "Support RDPRU instructions",
870 .dependencies = featureSet(&[_]Feature{}),
871 };
872 result[@intFromEnum(Feature.rdrnd)] = .{
873 .llvm_name = "rdrnd",
874 .description = "Support RDRAND instruction",
875 .dependencies = featureSet(&[_]Feature{}),
876 };
877 result[@intFromEnum(Feature.rdseed)] = .{
878 .llvm_name = "rdseed",
879 .description = "Support RDSEED instruction",
880 .dependencies = featureSet(&[_]Feature{}),
881 };
882 result[@intFromEnum(Feature.retpoline)] = .{
883 .llvm_name = "retpoline",
884 .description = "Remove speculation of indirect branches from the generated code, either by avoiding them entirely or lowering them with a speculation blocking construct",
885 .dependencies = featureSet(&[_]Feature{
886 .retpoline_indirect_branches,
887 .retpoline_indirect_calls,
888 }),
889 };
890 result[@intFromEnum(Feature.retpoline_external_thunk)] = .{
891 .llvm_name = "retpoline-external-thunk",
892 .description = "When lowering an indirect call or branch using a `retpoline`, rely on the specified user provided thunk rather than emitting one ourselves. Only has effect when combined with some other retpoline feature",
893 .dependencies = featureSet(&[_]Feature{
894 .retpoline_indirect_calls,
895 }),
896 };
897 result[@intFromEnum(Feature.retpoline_indirect_branches)] = .{
898 .llvm_name = "retpoline-indirect-branches",
899 .description = "Remove speculation of indirect branches from the generated code",
900 .dependencies = featureSet(&[_]Feature{}),
901 };
902 result[@intFromEnum(Feature.retpoline_indirect_calls)] = .{
903 .llvm_name = "retpoline-indirect-calls",
904 .description = "Remove speculation of indirect calls from the generated code",
905 .dependencies = featureSet(&[_]Feature{}),
906 };
907 result[@intFromEnum(Feature.rtm)] = .{
908 .llvm_name = "rtm",
909 .description = "Support RTM instructions",
910 .dependencies = featureSet(&[_]Feature{}),
911 };
912 result[@intFromEnum(Feature.sahf)] = .{
913 .llvm_name = "sahf",
914 .description = "Support LAHF and SAHF instructions in 64-bit mode",
915 .dependencies = featureSet(&[_]Feature{}),
916 };
917 result[@intFromEnum(Feature.sbb_dep_breaking)] = .{
918 .llvm_name = "sbb-dep-breaking",
919 .description = "SBB with same register has no source dependency",
920 .dependencies = featureSet(&[_]Feature{}),
921 };
922 result[@intFromEnum(Feature.serialize)] = .{
923 .llvm_name = "serialize",
924 .description = "Has serialize instruction",
925 .dependencies = featureSet(&[_]Feature{}),
926 };
927 result[@intFromEnum(Feature.seses)] = .{
928 .llvm_name = "seses",
929 .description = "Prevent speculative execution side channel timing attacks by inserting a speculation barrier before memory reads, memory writes, and conditional branches. Implies LVI Control Flow integrity.",
930 .dependencies = featureSet(&[_]Feature{
931 .lvi_cfi,
932 }),
933 };
934 result[@intFromEnum(Feature.sgx)] = .{
935 .llvm_name = "sgx",
936 .description = "Enable Software Guard Extensions",
937 .dependencies = featureSet(&[_]Feature{}),
938 };
939 result[@intFromEnum(Feature.sha)] = .{
940 .llvm_name = "sha",
941 .description = "Enable SHA instructions",
942 .dependencies = featureSet(&[_]Feature{
943 .sse2,
944 }),
945 };
946 result[@intFromEnum(Feature.sha512)] = .{
947 .llvm_name = "sha512",
948 .description = "Support SHA512 instructions",
949 .dependencies = featureSet(&[_]Feature{
950 .avx,
951 }),
952 };
953 result[@intFromEnum(Feature.shstk)] = .{
954 .llvm_name = "shstk",
955 .description = "Support CET Shadow-Stack instructions",
956 .dependencies = featureSet(&[_]Feature{}),
957 };
958 result[@intFromEnum(Feature.slow_3ops_lea)] = .{
959 .llvm_name = "slow-3ops-lea",
960 .description = "LEA instruction with 3 ops or certain registers is slow",
961 .dependencies = featureSet(&[_]Feature{}),
962 };
963 result[@intFromEnum(Feature.slow_incdec)] = .{
964 .llvm_name = "slow-incdec",
965 .description = "INC and DEC instructions are slower than ADD and SUB",
966 .dependencies = featureSet(&[_]Feature{}),
967 };
968 result[@intFromEnum(Feature.slow_lea)] = .{
969 .llvm_name = "slow-lea",
970 .description = "LEA instruction with certain arguments is slow",
971 .dependencies = featureSet(&[_]Feature{}),
972 };
973 result[@intFromEnum(Feature.slow_pmaddwd)] = .{
974 .llvm_name = "slow-pmaddwd",
975 .description = "PMADDWD is slower than PMULLD",
976 .dependencies = featureSet(&[_]Feature{}),
977 };
978 result[@intFromEnum(Feature.slow_pmulld)] = .{
979 .llvm_name = "slow-pmulld",
980 .description = "PMULLD instruction is slow (compared to PMULLW/PMULHW and PMULUDQ)",
981 .dependencies = featureSet(&[_]Feature{}),
982 };
983 result[@intFromEnum(Feature.slow_shld)] = .{
984 .llvm_name = "slow-shld",
985 .description = "SHLD instruction is slow",
986 .dependencies = featureSet(&[_]Feature{}),
987 };
988 result[@intFromEnum(Feature.slow_two_mem_ops)] = .{
989 .llvm_name = "slow-two-mem-ops",
990 .description = "Two memory operand instructions are slow",
991 .dependencies = featureSet(&[_]Feature{}),
992 };
993 result[@intFromEnum(Feature.slow_unaligned_mem_16)] = .{
994 .llvm_name = "slow-unaligned-mem-16",
995 .description = "Slow unaligned 16-byte memory access",
996 .dependencies = featureSet(&[_]Feature{}),
997 };
998 result[@intFromEnum(Feature.slow_unaligned_mem_32)] = .{
999 .llvm_name = "slow-unaligned-mem-32",
1000 .description = "Slow unaligned 32-byte memory access",
1001 .dependencies = featureSet(&[_]Feature{}),
1002 };
1003 result[@intFromEnum(Feature.sm3)] = .{
1004 .llvm_name = "sm3",
1005 .description = "Support SM3 instructions",
1006 .dependencies = featureSet(&[_]Feature{
1007 .avx,
1008 }),
1009 };
1010 result[@intFromEnum(Feature.sm4)] = .{
1011 .llvm_name = "sm4",
1012 .description = "Support SM4 instructions",
1013 .dependencies = featureSet(&[_]Feature{
1014 .avx,
1015 }),
1016 };
1017 result[@intFromEnum(Feature.soft_float)] = .{
1018 .llvm_name = "soft-float",
1019 .description = "Use software floating point features",
1020 .dependencies = featureSet(&[_]Feature{}),
1021 };
1022 result[@intFromEnum(Feature.sse)] = .{
1023 .llvm_name = "sse",
1024 .description = "Enable SSE instructions",
1025 .dependencies = featureSet(&[_]Feature{}),
1026 };
1027 result[@intFromEnum(Feature.sse2)] = .{
1028 .llvm_name = "sse2",
1029 .description = "Enable SSE2 instructions",
1030 .dependencies = featureSet(&[_]Feature{
1031 .sse,
1032 }),
1033 };
1034 result[@intFromEnum(Feature.sse3)] = .{
1035 .llvm_name = "sse3",
1036 .description = "Enable SSE3 instructions",
1037 .dependencies = featureSet(&[_]Feature{
1038 .sse2,
1039 }),
1040 };
1041 result[@intFromEnum(Feature.sse4_1)] = .{
1042 .llvm_name = "sse4.1",
1043 .description = "Enable SSE 4.1 instructions",
1044 .dependencies = featureSet(&[_]Feature{
1045 .ssse3,
1046 }),
1047 };
1048 result[@intFromEnum(Feature.sse4_2)] = .{
1049 .llvm_name = "sse4.2",
1050 .description = "Enable SSE 4.2 instructions",
1051 .dependencies = featureSet(&[_]Feature{
1052 .sse4_1,
1053 }),
1054 };
1055 result[@intFromEnum(Feature.sse4a)] = .{
1056 .llvm_name = "sse4a",
1057 .description = "Support SSE 4a instructions",
1058 .dependencies = featureSet(&[_]Feature{
1059 .sse3,
1060 }),
1061 };
1062 result[@intFromEnum(Feature.sse_unaligned_mem)] = .{
1063 .llvm_name = "sse-unaligned-mem",
1064 .description = "Allow unaligned memory operands with SSE instructions (this may require setting a configuration bit in the processor)",
1065 .dependencies = featureSet(&[_]Feature{}),
1066 };
1067 result[@intFromEnum(Feature.ssse3)] = .{
1068 .llvm_name = "ssse3",
1069 .description = "Enable SSSE3 instructions",
1070 .dependencies = featureSet(&[_]Feature{
1071 .sse3,
1072 }),
1073 };
1074 result[@intFromEnum(Feature.tagged_globals)] = .{
1075 .llvm_name = "tagged-globals",
1076 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits.",
1077 .dependencies = featureSet(&[_]Feature{}),
1078 };
1079 result[@intFromEnum(Feature.tbm)] = .{
1080 .llvm_name = "tbm",
1081 .description = "Enable TBM instructions",
1082 .dependencies = featureSet(&[_]Feature{}),
1083 };
1084 result[@intFromEnum(Feature.tsxldtrk)] = .{
1085 .llvm_name = "tsxldtrk",
1086 .description = "Support TSXLDTRK instructions",
1087 .dependencies = featureSet(&[_]Feature{}),
1088 };
1089 result[@intFromEnum(Feature.tuning_fast_imm_vector_shift)] = .{
1090 .llvm_name = "tuning-fast-imm-vector-shift",
1091 .description = "Vector shifts are fast (2/cycle) as opposed to slow (1/cycle)",
1092 .dependencies = featureSet(&[_]Feature{}),
1093 };
1094 result[@intFromEnum(Feature.uintr)] = .{
1095 .llvm_name = "uintr",
1096 .description = "Has UINTR Instructions",
1097 .dependencies = featureSet(&[_]Feature{}),
1098 };
1099 result[@intFromEnum(Feature.use_glm_div_sqrt_costs)] = .{
1100 .llvm_name = "use-glm-div-sqrt-costs",
1101 .description = "Use Goldmont specific floating point div/sqrt costs",
1102 .dependencies = featureSet(&[_]Feature{}),
1103 };
1104 result[@intFromEnum(Feature.use_slm_arith_costs)] = .{
1105 .llvm_name = "use-slm-arith-costs",
1106 .description = "Use Silvermont specific arithmetic costs",
1107 .dependencies = featureSet(&[_]Feature{}),
1108 };
1109 result[@intFromEnum(Feature.vaes)] = .{
1110 .llvm_name = "vaes",
1111 .description = "Promote selected AES instructions to AVX512/AVX registers",
1112 .dependencies = featureSet(&[_]Feature{
1113 .aes,
1114 .avx,
1115 }),
1116 };
1117 result[@intFromEnum(Feature.vpclmulqdq)] = .{
1118 .llvm_name = "vpclmulqdq",
1119 .description = "Enable vpclmulqdq instructions",
1120 .dependencies = featureSet(&[_]Feature{
1121 .avx,
1122 .pclmul,
1123 }),
1124 };
1125 result[@intFromEnum(Feature.vzeroupper)] = .{
1126 .llvm_name = "vzeroupper",
1127 .description = "Should insert vzeroupper instructions",
1128 .dependencies = featureSet(&[_]Feature{}),
1129 };
1130 result[@intFromEnum(Feature.waitpkg)] = .{
1131 .llvm_name = "waitpkg",
1132 .description = "Wait and pause enhancements",
1133 .dependencies = featureSet(&[_]Feature{}),
1134 };
1135 result[@intFromEnum(Feature.wbnoinvd)] = .{
1136 .llvm_name = "wbnoinvd",
1137 .description = "Write Back No Invalidate",
1138 .dependencies = featureSet(&[_]Feature{}),
1139 };
1140 result[@intFromEnum(Feature.widekl)] = .{
1141 .llvm_name = "widekl",
1142 .description = "Support Key Locker wide Instructions",
1143 .dependencies = featureSet(&[_]Feature{
1144 .kl,
1145 }),
1146 };
1147 result[@intFromEnum(Feature.x87)] = .{
1148 .llvm_name = "x87",
1149 .description = "Enable X87 float instructions",
1150 .dependencies = featureSet(&[_]Feature{}),
1151 };
1152 result[@intFromEnum(Feature.xop)] = .{
1153 .llvm_name = "xop",
1154 .description = "Enable XOP instructions",
1155 .dependencies = featureSet(&[_]Feature{
1156 .fma4,
1157 }),
1158 };
1159 result[@intFromEnum(Feature.xsave)] = .{
1160 .llvm_name = "xsave",
1161 .description = "Support xsave instructions",
1162 .dependencies = featureSet(&[_]Feature{}),
1163 };
1164 result[@intFromEnum(Feature.xsavec)] = .{
1165 .llvm_name = "xsavec",
1166 .description = "Support xsavec instructions",
1167 .dependencies = featureSet(&[_]Feature{
1168 .xsave,
1169 }),
1170 };
1171 result[@intFromEnum(Feature.xsaveopt)] = .{
1172 .llvm_name = "xsaveopt",
1173 .description = "Support xsaveopt instructions",
1174 .dependencies = featureSet(&[_]Feature{
1175 .xsave,
1176 }),
1177 };
1178 result[@intFromEnum(Feature.xsaves)] = .{
1179 .llvm_name = "xsaves",
1180 .description = "Support xsaves instructions",
1181 .dependencies = featureSet(&[_]Feature{
1182 .xsave,
1183 }),
1184 };
1185 const ti = @typeInfo(Feature);
1186 for (&result, 0..) |*elem, i| {
1187 elem.index = i;
1188 elem.name = ti.Enum.fields[i].name;
1189 }
1190 break :blk result;
1191};
1192
1193pub const cpu = struct {
1194 pub const alderlake = CpuModel{
1195 .name = "alderlake",
1196 .llvm_name = "alderlake",
1197 .features = featureSet(&[_]Feature{
1198 .@"64bit",
1199 .adx,
1200 .allow_light_256_bit,
1201 .avxvnni,
1202 .bmi,
1203 .bmi2,
1204 .cldemote,
1205 .clflushopt,
1206 .clwb,
1207 .cmov,
1208 .crc32,
1209 .cx16,
1210 .f16c,
1211 .false_deps_perm,
1212 .false_deps_popcnt,
1213 .fast_15bytenop,
1214 .fast_gather,
1215 .fast_scalar_fsqrt,
1216 .fast_shld_rotate,
1217 .fast_variable_crosslane_shuffle,
1218 .fast_variable_perlane_shuffle,
1219 .fast_vector_fsqrt,
1220 .fma,
1221 .fsgsbase,
1222 .fxsr,
1223 .gfni,
1224 .hreset,
1225 .idivq_to_divl,
1226 .invpcid,
1227 .lzcnt,
1228 .macrofusion,
1229 .mmx,
1230 .movbe,
1231 .movdir64b,
1232 .movdiri,
1233 .no_bypass_delay_blend,
1234 .no_bypass_delay_mov,
1235 .no_bypass_delay_shuffle,
1236 .nopl,
1237 .pconfig,
1238 .pku,
1239 .popcnt,
1240 .prefer_movmsk_over_vtest,
1241 .prfchw,
1242 .ptwrite,
1243 .rdpid,
1244 .rdrnd,
1245 .rdseed,
1246 .sahf,
1247 .serialize,
1248 .sha,
1249 .shstk,
1250 .slow_3ops_lea,
1251 .tuning_fast_imm_vector_shift,
1252 .vaes,
1253 .vpclmulqdq,
1254 .vzeroupper,
1255 .waitpkg,
1256 .widekl,
1257 .x87,
1258 .xsavec,
1259 .xsaveopt,
1260 .xsaves,
1261 }),
1262 };
1263 pub const amdfam10 = CpuModel{
1264 .name = "amdfam10",
1265 .llvm_name = "amdfam10",
1266 .features = featureSet(&[_]Feature{
1267 .@"3dnowa",
1268 .@"64bit",
1269 .cmov,
1270 .cx16,
1271 .fast_scalar_shift_masks,
1272 .fxsr,
1273 .lzcnt,
1274 .nopl,
1275 .popcnt,
1276 .prfchw,
1277 .sahf,
1278 .sbb_dep_breaking,
1279 .slow_shld,
1280 .sse4a,
1281 .vzeroupper,
1282 .x87,
1283 }),
1284 };
1285 pub const athlon = CpuModel{
1286 .name = "athlon",
1287 .llvm_name = "athlon",
1288 .features = featureSet(&[_]Feature{
1289 .@"3dnowa",
1290 .cmov,
1291 .cx8,
1292 .nopl,
1293 .slow_shld,
1294 .slow_unaligned_mem_16,
1295 .vzeroupper,
1296 .x87,
1297 }),
1298 };
1299 pub const athlon64 = CpuModel{
1300 .name = "athlon64",
1301 .llvm_name = "athlon64",
1302 .features = featureSet(&[_]Feature{
1303 .@"3dnowa",
1304 .@"64bit",
1305 .cmov,
1306 .cx8,
1307 .fast_scalar_shift_masks,
1308 .fxsr,
1309 .nopl,
1310 .sbb_dep_breaking,
1311 .slow_shld,
1312 .slow_unaligned_mem_16,
1313 .sse2,
1314 .vzeroupper,
1315 .x87,
1316 }),
1317 };
1318 pub const athlon64_sse3 = CpuModel{
1319 .name = "athlon64_sse3",
1320 .llvm_name = "athlon64-sse3",
1321 .features = featureSet(&[_]Feature{
1322 .@"3dnowa",
1323 .@"64bit",
1324 .cmov,
1325 .cx16,
1326 .fast_scalar_shift_masks,
1327 .fxsr,
1328 .nopl,
1329 .sbb_dep_breaking,
1330 .slow_shld,
1331 .slow_unaligned_mem_16,
1332 .sse3,
1333 .vzeroupper,
1334 .x87,
1335 }),
1336 };
1337 pub const athlon_4 = CpuModel{
1338 .name = "athlon_4",
1339 .llvm_name = "athlon-4",
1340 .features = featureSet(&[_]Feature{
1341 .@"3dnowa",
1342 .cmov,
1343 .cx8,
1344 .fxsr,
1345 .nopl,
1346 .slow_shld,
1347 .slow_unaligned_mem_16,
1348 .sse,
1349 .vzeroupper,
1350 .x87,
1351 }),
1352 };
1353 pub const athlon_fx = CpuModel{
1354 .name = "athlon_fx",
1355 .llvm_name = "athlon-fx",
1356 .features = featureSet(&[_]Feature{
1357 .@"3dnowa",
1358 .@"64bit",
1359 .cmov,
1360 .cx8,
1361 .fast_scalar_shift_masks,
1362 .fxsr,
1363 .nopl,
1364 .sbb_dep_breaking,
1365 .slow_shld,
1366 .slow_unaligned_mem_16,
1367 .sse2,
1368 .vzeroupper,
1369 .x87,
1370 }),
1371 };
1372 pub const athlon_mp = CpuModel{
1373 .name = "athlon_mp",
1374 .llvm_name = "athlon-mp",
1375 .features = featureSet(&[_]Feature{
1376 .@"3dnowa",
1377 .cmov,
1378 .cx8,
1379 .fxsr,
1380 .nopl,
1381 .slow_shld,
1382 .slow_unaligned_mem_16,
1383 .sse,
1384 .vzeroupper,
1385 .x87,
1386 }),
1387 };
1388 pub const athlon_tbird = CpuModel{
1389 .name = "athlon_tbird",
1390 .llvm_name = "athlon-tbird",
1391 .features = featureSet(&[_]Feature{
1392 .@"3dnowa",
1393 .cmov,
1394 .cx8,
1395 .nopl,
1396 .slow_shld,
1397 .slow_unaligned_mem_16,
1398 .vzeroupper,
1399 .x87,
1400 }),
1401 };
1402 pub const athlon_xp = CpuModel{
1403 .name = "athlon_xp",
1404 .llvm_name = "athlon-xp",
1405 .features = featureSet(&[_]Feature{
1406 .@"3dnowa",
1407 .cmov,
1408 .cx8,
1409 .fxsr,
1410 .nopl,
1411 .slow_shld,
1412 .slow_unaligned_mem_16,
1413 .sse,
1414 .vzeroupper,
1415 .x87,
1416 }),
1417 };
1418 pub const atom = CpuModel{
1419 .name = "atom",
1420 .llvm_name = "atom",
1421 .features = featureSet(&[_]Feature{
1422 .@"64bit",
1423 .cmov,
1424 .cx16,
1425 .fxsr,
1426 .idivl_to_divb,
1427 .idivq_to_divl,
1428 .lea_sp,
1429 .lea_uses_ag,
1430 .mmx,
1431 .movbe,
1432 .no_bypass_delay,
1433 .nopl,
1434 .pad_short_functions,
1435 .sahf,
1436 .slow_two_mem_ops,
1437 .slow_unaligned_mem_16,
1438 .ssse3,
1439 .vzeroupper,
1440 .x87,
1441 }),
1442 };
1443 pub const atom_sse4_2_movbe = CpuModel{
1444 .name = "atom_sse4_2_movbe",
1445 .llvm_name = "atom_sse4_2_movbe",
1446 .features = featureSet(&[_]Feature{
1447 .@"64bit",
1448 .aes,
1449 .clflushopt,
1450 .cmov,
1451 .crc32,
1452 .cx16,
1453 .false_deps_popcnt,
1454 .fast_7bytenop,
1455 .fast_movbe,
1456 .fsgsbase,
1457 .fxsr,
1458 .idivq_to_divl,
1459 .mmx,
1460 .movbe,
1461 .no_bypass_delay,
1462 .nopl,
1463 .pclmul,
1464 .popcnt,
1465 .prfchw,
1466 .rdrnd,
1467 .rdseed,
1468 .sahf,
1469 .sha,
1470 .slow_incdec,
1471 .slow_lea,
1472 .slow_pmulld,
1473 .slow_two_mem_ops,
1474 .sse4_2,
1475 .use_slm_arith_costs,
1476 .vzeroupper,
1477 .x87,
1478 .xsavec,
1479 .xsaveopt,
1480 .xsaves,
1481 }),
1482 };
1483 pub const barcelona = CpuModel{
1484 .name = "barcelona",
1485 .llvm_name = "barcelona",
1486 .features = featureSet(&[_]Feature{
1487 .@"3dnowa",
1488 .@"64bit",
1489 .cmov,
1490 .cx16,
1491 .fast_scalar_shift_masks,
1492 .fxsr,
1493 .lzcnt,
1494 .nopl,
1495 .popcnt,
1496 .prfchw,
1497 .sahf,
1498 .sbb_dep_breaking,
1499 .slow_shld,
1500 .sse4a,
1501 .vzeroupper,
1502 .x87,
1503 }),
1504 };
1505 pub const bdver1 = CpuModel{
1506 .name = "bdver1",
1507 .llvm_name = "bdver1",
1508 .features = featureSet(&[_]Feature{
1509 .@"64bit",
1510 .aes,
1511 .branchfusion,
1512 .cmov,
1513 .crc32,
1514 .cx16,
1515 .fast_11bytenop,
1516 .fast_scalar_shift_masks,
1517 .fxsr,
1518 .lwp,
1519 .lzcnt,
1520 .mmx,
1521 .nopl,
1522 .pclmul,
1523 .popcnt,
1524 .prfchw,
1525 .sahf,
1526 .sbb_dep_breaking,
1527 .slow_shld,
1528 .vzeroupper,
1529 .x87,
1530 .xop,
1531 .xsave,
1532 }),
1533 };
1534 pub const bdver2 = CpuModel{
1535 .name = "bdver2",
1536 .llvm_name = "bdver2",
1537 .features = featureSet(&[_]Feature{
1538 .@"64bit",
1539 .aes,
1540 .bmi,
1541 .branchfusion,
1542 .cmov,
1543 .crc32,
1544 .cx16,
1545 .f16c,
1546 .fast_11bytenop,
1547 .fast_bextr,
1548 .fast_movbe,
1549 .fast_scalar_shift_masks,
1550 .fma,
1551 .fxsr,
1552 .lwp,
1553 .lzcnt,
1554 .mmx,
1555 .nopl,
1556 .pclmul,
1557 .popcnt,
1558 .prfchw,
1559 .sahf,
1560 .sbb_dep_breaking,
1561 .slow_shld,
1562 .tbm,
1563 .vzeroupper,
1564 .x87,
1565 .xop,
1566 .xsave,
1567 }),
1568 };
1569 pub const bdver3 = CpuModel{
1570 .name = "bdver3",
1571 .llvm_name = "bdver3",
1572 .features = featureSet(&[_]Feature{
1573 .@"64bit",
1574 .aes,
1575 .bmi,
1576 .branchfusion,
1577 .cmov,
1578 .crc32,
1579 .cx16,
1580 .f16c,
1581 .fast_11bytenop,
1582 .fast_bextr,
1583 .fast_movbe,
1584 .fast_scalar_shift_masks,
1585 .fma,
1586 .fsgsbase,
1587 .fxsr,
1588 .lwp,
1589 .lzcnt,
1590 .mmx,
1591 .nopl,
1592 .pclmul,
1593 .popcnt,
1594 .prfchw,
1595 .sahf,
1596 .sbb_dep_breaking,
1597 .slow_shld,
1598 .tbm,
1599 .vzeroupper,
1600 .x87,
1601 .xop,
1602 .xsaveopt,
1603 }),
1604 };
1605 pub const bdver4 = CpuModel{
1606 .name = "bdver4",
1607 .llvm_name = "bdver4",
1608 .features = featureSet(&[_]Feature{
1609 .@"64bit",
1610 .aes,
1611 .avx2,
1612 .bmi,
1613 .bmi2,
1614 .branchfusion,
1615 .cmov,
1616 .crc32,
1617 .cx16,
1618 .f16c,
1619 .fast_11bytenop,
1620 .fast_bextr,
1621 .fast_movbe,
1622 .fast_scalar_shift_masks,
1623 .fma,
1624 .fsgsbase,
1625 .fxsr,
1626 .lwp,
1627 .lzcnt,
1628 .mmx,
1629 .movbe,
1630 .mwaitx,
1631 .nopl,
1632 .pclmul,
1633 .popcnt,
1634 .prfchw,
1635 .rdrnd,
1636 .sahf,
1637 .sbb_dep_breaking,
1638 .slow_shld,
1639 .tbm,
1640 .vzeroupper,
1641 .x87,
1642 .xop,
1643 .xsaveopt,
1644 }),
1645 };
1646 pub const bonnell = CpuModel{
1647 .name = "bonnell",
1648 .llvm_name = "bonnell",
1649 .features = featureSet(&[_]Feature{
1650 .@"64bit",
1651 .cmov,
1652 .cx16,
1653 .fxsr,
1654 .idivl_to_divb,
1655 .idivq_to_divl,
1656 .lea_sp,
1657 .lea_uses_ag,
1658 .mmx,
1659 .movbe,
1660 .no_bypass_delay,
1661 .nopl,
1662 .pad_short_functions,
1663 .sahf,
1664 .slow_two_mem_ops,
1665 .slow_unaligned_mem_16,
1666 .ssse3,
1667 .vzeroupper,
1668 .x87,
1669 }),
1670 };
1671 pub const broadwell = CpuModel{
1672 .name = "broadwell",
1673 .llvm_name = "broadwell",
1674 .features = featureSet(&[_]Feature{
1675 .@"64bit",
1676 .adx,
1677 .allow_light_256_bit,
1678 .avx2,
1679 .bmi,
1680 .bmi2,
1681 .cmov,
1682 .crc32,
1683 .cx16,
1684 .ermsb,
1685 .f16c,
1686 .false_deps_lzcnt_tzcnt,
1687 .false_deps_popcnt,
1688 .fast_15bytenop,
1689 .fast_scalar_fsqrt,
1690 .fast_shld_rotate,
1691 .fast_variable_crosslane_shuffle,
1692 .fast_variable_perlane_shuffle,
1693 .fma,
1694 .fsgsbase,
1695 .fxsr,
1696 .idivq_to_divl,
1697 .invpcid,
1698 .lzcnt,
1699 .macrofusion,
1700 .mmx,
1701 .movbe,
1702 .no_bypass_delay_mov,
1703 .no_bypass_delay_shuffle,
1704 .nopl,
1705 .pclmul,
1706 .popcnt,
1707 .prfchw,
1708 .rdrnd,
1709 .rdseed,
1710 .sahf,
1711 .slow_3ops_lea,
1712 .vzeroupper,
1713 .x87,
1714 .xsaveopt,
1715 }),
1716 };
1717 pub const btver1 = CpuModel{
1718 .name = "btver1",
1719 .llvm_name = "btver1",
1720 .features = featureSet(&[_]Feature{
1721 .@"64bit",
1722 .cmov,
1723 .cx16,
1724 .fast_15bytenop,
1725 .fast_scalar_shift_masks,
1726 .fast_vector_shift_masks,
1727 .fxsr,
1728 .lzcnt,
1729 .mmx,
1730 .nopl,
1731 .popcnt,
1732 .prfchw,
1733 .sahf,
1734 .sbb_dep_breaking,
1735 .slow_shld,
1736 .sse4a,
1737 .ssse3,
1738 .vzeroupper,
1739 .x87,
1740 }),
1741 };
1742 pub const btver2 = CpuModel{
1743 .name = "btver2",
1744 .llvm_name = "btver2",
1745 .features = featureSet(&[_]Feature{
1746 .@"64bit",
1747 .aes,
1748 .bmi,
1749 .cmov,
1750 .crc32,
1751 .cx16,
1752 .f16c,
1753 .fast_15bytenop,
1754 .fast_bextr,
1755 .fast_hops,
1756 .fast_lzcnt,
1757 .fast_movbe,
1758 .fast_scalar_shift_masks,
1759 .fast_vector_shift_masks,
1760 .fxsr,
1761 .lzcnt,
1762 .mmx,
1763 .movbe,
1764 .nopl,
1765 .pclmul,
1766 .popcnt,
1767 .prfchw,
1768 .sahf,
1769 .sbb_dep_breaking,
1770 .slow_shld,
1771 .sse4a,
1772 .x87,
1773 .xsaveopt,
1774 }),
1775 };
1776 pub const c3 = CpuModel{
1777 .name = "c3",
1778 .llvm_name = "c3",
1779 .features = featureSet(&[_]Feature{
1780 .@"3dnow",
1781 .slow_unaligned_mem_16,
1782 .vzeroupper,
1783 .x87,
1784 }),
1785 };
1786 pub const c3_2 = CpuModel{
1787 .name = "c3_2",
1788 .llvm_name = "c3-2",
1789 .features = featureSet(&[_]Feature{
1790 .cmov,
1791 .cx8,
1792 .fxsr,
1793 .mmx,
1794 .slow_unaligned_mem_16,
1795 .sse,
1796 .vzeroupper,
1797 .x87,
1798 }),
1799 };
1800 pub const cannonlake = CpuModel{
1801 .name = "cannonlake",
1802 .llvm_name = "cannonlake",
1803 .features = featureSet(&[_]Feature{
1804 .@"64bit",
1805 .adx,
1806 .aes,
1807 .allow_light_256_bit,
1808 .avx512cd,
1809 .avx512dq,
1810 .avx512ifma,
1811 .avx512vbmi,
1812 .avx512vl,
1813 .bmi,
1814 .bmi2,
1815 .clflushopt,
1816 .cmov,
1817 .crc32,
1818 .cx16,
1819 .ermsb,
1820 .fast_15bytenop,
1821 .fast_gather,
1822 .fast_scalar_fsqrt,
1823 .fast_shld_rotate,
1824 .fast_variable_crosslane_shuffle,
1825 .fast_variable_perlane_shuffle,
1826 .fast_vector_fsqrt,
1827 .fsgsbase,
1828 .fxsr,
1829 .idivq_to_divl,
1830 .invpcid,
1831 .lzcnt,
1832 .macrofusion,
1833 .mmx,
1834 .movbe,
1835 .no_bypass_delay_blend,
1836 .no_bypass_delay_mov,
1837 .no_bypass_delay_shuffle,
1838 .nopl,
1839 .pclmul,
1840 .pku,
1841 .popcnt,
1842 .prefer_256_bit,
1843 .prfchw,
1844 .rdrnd,
1845 .rdseed,
1846 .sahf,
1847 .sha,
1848 .slow_3ops_lea,
1849 .tuning_fast_imm_vector_shift,
1850 .vzeroupper,
1851 .x87,
1852 .xsavec,
1853 .xsaveopt,
1854 .xsaves,
1855 }),
1856 };
1857 pub const cascadelake = CpuModel{
1858 .name = "cascadelake",
1859 .llvm_name = "cascadelake",
1860 .features = featureSet(&[_]Feature{
1861 .@"64bit",
1862 .adx,
1863 .aes,
1864 .allow_light_256_bit,
1865 .avx512bw,
1866 .avx512cd,
1867 .avx512dq,
1868 .avx512vl,
1869 .avx512vnni,
1870 .bmi,
1871 .bmi2,
1872 .clflushopt,
1873 .clwb,
1874 .cmov,
1875 .crc32,
1876 .cx16,
1877 .ermsb,
1878 .false_deps_popcnt,
1879 .fast_15bytenop,
1880 .fast_gather,
1881 .fast_scalar_fsqrt,
1882 .fast_shld_rotate,
1883 .fast_variable_crosslane_shuffle,
1884 .fast_variable_perlane_shuffle,
1885 .fast_vector_fsqrt,
1886 .faster_shift_than_shuffle,
1887 .fsgsbase,
1888 .fxsr,
1889 .idivq_to_divl,
1890 .invpcid,
1891 .lzcnt,
1892 .macrofusion,
1893 .mmx,
1894 .movbe,
1895 .no_bypass_delay_blend,
1896 .no_bypass_delay_mov,
1897 .no_bypass_delay_shuffle,
1898 .nopl,
1899 .pclmul,
1900 .pku,
1901 .popcnt,
1902 .prefer_256_bit,
1903 .prfchw,
1904 .rdrnd,
1905 .rdseed,
1906 .sahf,
1907 .slow_3ops_lea,
1908 .tuning_fast_imm_vector_shift,
1909 .vzeroupper,
1910 .x87,
1911 .xsavec,
1912 .xsaveopt,
1913 .xsaves,
1914 }),
1915 };
1916 pub const cooperlake = CpuModel{
1917 .name = "cooperlake",
1918 .llvm_name = "cooperlake",
1919 .features = featureSet(&[_]Feature{
1920 .@"64bit",
1921 .adx,
1922 .aes,
1923 .allow_light_256_bit,
1924 .avx512bf16,
1925 .avx512cd,
1926 .avx512dq,
1927 .avx512vl,
1928 .avx512vnni,
1929 .bmi,
1930 .bmi2,
1931 .clflushopt,
1932 .clwb,
1933 .cmov,
1934 .crc32,
1935 .cx16,
1936 .ermsb,
1937 .false_deps_popcnt,
1938 .fast_15bytenop,
1939 .fast_gather,
1940 .fast_scalar_fsqrt,
1941 .fast_shld_rotate,
1942 .fast_variable_crosslane_shuffle,
1943 .fast_variable_perlane_shuffle,
1944 .fast_vector_fsqrt,
1945 .faster_shift_than_shuffle,
1946 .fsgsbase,
1947 .fxsr,
1948 .idivq_to_divl,
1949 .invpcid,
1950 .lzcnt,
1951 .macrofusion,
1952 .mmx,
1953 .movbe,
1954 .no_bypass_delay_blend,
1955 .no_bypass_delay_mov,
1956 .no_bypass_delay_shuffle,
1957 .nopl,
1958 .pclmul,
1959 .pku,
1960 .popcnt,
1961 .prefer_256_bit,
1962 .prfchw,
1963 .rdrnd,
1964 .rdseed,
1965 .sahf,
1966 .slow_3ops_lea,
1967 .tuning_fast_imm_vector_shift,
1968 .vzeroupper,
1969 .x87,
1970 .xsavec,
1971 .xsaveopt,
1972 .xsaves,
1973 }),
1974 };
1975 pub const core2 = CpuModel{
1976 .name = "core2",
1977 .llvm_name = "core2",
1978 .features = featureSet(&[_]Feature{
1979 .@"64bit",
1980 .cmov,
1981 .cx16,
1982 .fxsr,
1983 .macrofusion,
1984 .mmx,
1985 .nopl,
1986 .sahf,
1987 .slow_unaligned_mem_16,
1988 .ssse3,
1989 .vzeroupper,
1990 .x87,
1991 }),
1992 };
1993 pub const corei7 = CpuModel{
1994 .name = "corei7",
1995 .llvm_name = "corei7",
1996 .features = featureSet(&[_]Feature{
1997 .@"64bit",
1998 .cmov,
1999 .crc32,
2000 .cx16,
2001 .fxsr,
2002 .macrofusion,
2003 .mmx,
2004 .no_bypass_delay_mov,
2005 .nopl,
2006 .popcnt,
2007 .sahf,
2008 .sse4_2,
2009 .vzeroupper,
2010 .x87,
2011 }),
2012 };
2013 pub const emeraldrapids = CpuModel{
2014 .name = "emeraldrapids",
2015 .llvm_name = "emeraldrapids",
2016 .features = featureSet(&[_]Feature{
2017 .@"64bit",
2018 .adx,
2019 .allow_light_256_bit,
2020 .amx_bf16,
2021 .amx_int8,
2022 .avx512bf16,
2023 .avx512bitalg,
2024 .avx512cd,
2025 .avx512fp16,
2026 .avx512ifma,
2027 .avx512vbmi,
2028 .avx512vbmi2,
2029 .avx512vnni,
2030 .avx512vpopcntdq,
2031 .avxvnni,
2032 .bmi,
2033 .bmi2,
2034 .cldemote,
2035 .clflushopt,
2036 .clwb,
2037 .cmov,
2038 .crc32,
2039 .cx16,
2040 .enqcmd,
2041 .ermsb,
2042 .false_deps_getmant,
2043 .false_deps_mulc,
2044 .false_deps_mullq,
2045 .false_deps_perm,
2046 .false_deps_range,
2047 .fast_15bytenop,
2048 .fast_gather,
2049 .fast_scalar_fsqrt,
2050 .fast_shld_rotate,
2051 .fast_variable_crosslane_shuffle,
2052 .fast_variable_perlane_shuffle,
2053 .fast_vector_fsqrt,
2054 .fsgsbase,
2055 .fsrm,
2056 .fxsr,
2057 .gfni,
2058 .idivq_to_divl,
2059 .invpcid,
2060 .lzcnt,
2061 .macrofusion,
2062 .mmx,
2063 .movbe,
2064 .movdir64b,
2065 .movdiri,
2066 .no_bypass_delay_blend,
2067 .no_bypass_delay_mov,
2068 .no_bypass_delay_shuffle,
2069 .nopl,
2070 .pconfig,
2071 .pku,
2072 .popcnt,
2073 .prefer_256_bit,
2074 .prfchw,
2075 .ptwrite,
2076 .rdpid,
2077 .rdrnd,
2078 .rdseed,
2079 .sahf,
2080 .serialize,
2081 .sha,
2082 .shstk,
2083 .tsxldtrk,
2084 .tuning_fast_imm_vector_shift,
2085 .uintr,
2086 .vaes,
2087 .vpclmulqdq,
2088 .vzeroupper,
2089 .waitpkg,
2090 .wbnoinvd,
2091 .x87,
2092 .xsavec,
2093 .xsaveopt,
2094 .xsaves,
2095 }),
2096 };
2097 pub const generic = CpuModel{
2098 .name = "generic",
2099 .llvm_name = "generic",
2100 .features = featureSet(&[_]Feature{
2101 .@"64bit",
2102 .cx8,
2103 .fast_15bytenop,
2104 .fast_scalar_fsqrt,
2105 .idivq_to_divl,
2106 .macrofusion,
2107 .slow_3ops_lea,
2108 .vzeroupper,
2109 .x87,
2110 }),
2111 };
2112 pub const geode = CpuModel{
2113 .name = "geode",
2114 .llvm_name = "geode",
2115 .features = featureSet(&[_]Feature{
2116 .@"3dnowa",
2117 .cx8,
2118 .slow_unaligned_mem_16,
2119 .vzeroupper,
2120 .x87,
2121 }),
2122 };
2123 pub const goldmont = CpuModel{
2124 .name = "goldmont",
2125 .llvm_name = "goldmont",
2126 .features = featureSet(&[_]Feature{
2127 .@"64bit",
2128 .aes,
2129 .clflushopt,
2130 .cmov,
2131 .crc32,
2132 .cx16,
2133 .false_deps_popcnt,
2134 .fast_movbe,
2135 .fsgsbase,
2136 .fxsr,
2137 .mmx,
2138 .movbe,
2139 .no_bypass_delay,
2140 .nopl,
2141 .pclmul,
2142 .popcnt,
2143 .prfchw,
2144 .rdrnd,
2145 .rdseed,
2146 .sahf,
2147 .sha,
2148 .slow_incdec,
2149 .slow_lea,
2150 .slow_two_mem_ops,
2151 .sse4_2,
2152 .use_glm_div_sqrt_costs,
2153 .vzeroupper,
2154 .x87,
2155 .xsavec,
2156 .xsaveopt,
2157 .xsaves,
2158 }),
2159 };
2160 pub const goldmont_plus = CpuModel{
2161 .name = "goldmont_plus",
2162 .llvm_name = "goldmont-plus",
2163 .features = featureSet(&[_]Feature{
2164 .@"64bit",
2165 .aes,
2166 .clflushopt,
2167 .cmov,
2168 .crc32,
2169 .cx16,
2170 .fast_movbe,
2171 .fsgsbase,
2172 .fxsr,
2173 .mmx,
2174 .movbe,
2175 .no_bypass_delay,
2176 .nopl,
2177 .pclmul,
2178 .popcnt,
2179 .prfchw,
2180 .ptwrite,
2181 .rdpid,
2182 .rdrnd,
2183 .rdseed,
2184 .sahf,
2185 .sha,
2186 .slow_incdec,
2187 .slow_lea,
2188 .slow_two_mem_ops,
2189 .sse4_2,
2190 .use_glm_div_sqrt_costs,
2191 .vzeroupper,
2192 .x87,
2193 .xsavec,
2194 .xsaveopt,
2195 .xsaves,
2196 }),
2197 };
2198 pub const grandridge = CpuModel{
2199 .name = "grandridge",
2200 .llvm_name = "grandridge",
2201 .features = featureSet(&[_]Feature{
2202 .@"64bit",
2203 .adx,
2204 .avxifma,
2205 .avxneconvert,
2206 .avxvnni,
2207 .avxvnniint8,
2208 .bmi,
2209 .bmi2,
2210 .cldemote,
2211 .clflushopt,
2212 .clwb,
2213 .cmov,
2214 .cmpccxadd,
2215 .crc32,
2216 .cx16,
2217 .enqcmd,
2218 .f16c,
2219 .fast_movbe,
2220 .fma,
2221 .fsgsbase,
2222 .fxsr,
2223 .gfni,
2224 .hreset,
2225 .invpcid,
2226 .lzcnt,
2227 .mmx,
2228 .movbe,
2229 .movdir64b,
2230 .movdiri,
2231 .no_bypass_delay,
2232 .nopl,
2233 .pconfig,
2234 .pku,
2235 .popcnt,
2236 .prfchw,
2237 .ptwrite,
2238 .raoint,
2239 .rdpid,
2240 .rdrnd,
2241 .rdseed,
2242 .sahf,
2243 .serialize,
2244 .sha,
2245 .shstk,
2246 .slow_incdec,
2247 .slow_lea,
2248 .slow_two_mem_ops,
2249 .uintr,
2250 .use_glm_div_sqrt_costs,
2251 .vaes,
2252 .vpclmulqdq,
2253 .vzeroupper,
2254 .waitpkg,
2255 .widekl,
2256 .x87,
2257 .xsavec,
2258 .xsaveopt,
2259 .xsaves,
2260 }),
2261 };
2262 pub const graniterapids = CpuModel{
2263 .name = "graniterapids",
2264 .llvm_name = "graniterapids",
2265 .features = featureSet(&[_]Feature{
2266 .@"64bit",
2267 .adx,
2268 .allow_light_256_bit,
2269 .amx_bf16,
2270 .amx_fp16,
2271 .amx_int8,
2272 .avx512bf16,
2273 .avx512bitalg,
2274 .avx512cd,
2275 .avx512fp16,
2276 .avx512ifma,
2277 .avx512vbmi,
2278 .avx512vbmi2,
2279 .avx512vnni,
2280 .avx512vpopcntdq,
2281 .avxvnni,
2282 .bmi,
2283 .bmi2,
2284 .cldemote,
2285 .clflushopt,
2286 .clwb,
2287 .cmov,
2288 .crc32,
2289 .cx16,
2290 .enqcmd,
2291 .ermsb,
2292 .false_deps_getmant,
2293 .false_deps_mulc,
2294 .false_deps_mullq,
2295 .false_deps_perm,
2296 .false_deps_range,
2297 .fast_15bytenop,
2298 .fast_gather,
2299 .fast_scalar_fsqrt,
2300 .fast_shld_rotate,
2301 .fast_variable_crosslane_shuffle,
2302 .fast_variable_perlane_shuffle,
2303 .fast_vector_fsqrt,
2304 .fsgsbase,
2305 .fsrm,
2306 .fxsr,
2307 .gfni,
2308 .idivq_to_divl,
2309 .invpcid,
2310 .lzcnt,
2311 .macrofusion,
2312 .mmx,
2313 .movbe,
2314 .movdir64b,
2315 .movdiri,
2316 .no_bypass_delay_blend,
2317 .no_bypass_delay_mov,
2318 .no_bypass_delay_shuffle,
2319 .nopl,
2320 .pconfig,
2321 .pku,
2322 .popcnt,
2323 .prefer_256_bit,
2324 .prefetchi,
2325 .prfchw,
2326 .ptwrite,
2327 .rdpid,
2328 .rdrnd,
2329 .rdseed,
2330 .sahf,
2331 .serialize,
2332 .sha,
2333 .shstk,
2334 .tsxldtrk,
2335 .tuning_fast_imm_vector_shift,
2336 .uintr,
2337 .vaes,
2338 .vpclmulqdq,
2339 .vzeroupper,
2340 .waitpkg,
2341 .wbnoinvd,
2342 .x87,
2343 .xsavec,
2344 .xsaveopt,
2345 .xsaves,
2346 }),
2347 };
2348 pub const graniterapids_d = CpuModel{
2349 .name = "graniterapids_d",
2350 .llvm_name = "graniterapids-d",
2351 .features = featureSet(&[_]Feature{
2352 .@"64bit",
2353 .adx,
2354 .allow_light_256_bit,
2355 .amx_bf16,
2356 .amx_complex,
2357 .amx_fp16,
2358 .amx_int8,
2359 .avx512bf16,
2360 .avx512bitalg,
2361 .avx512cd,
2362 .avx512fp16,
2363 .avx512ifma,
2364 .avx512vbmi,
2365 .avx512vbmi2,
2366 .avx512vnni,
2367 .avx512vpopcntdq,
2368 .avxvnni,
2369 .bmi,
2370 .bmi2,
2371 .cldemote,
2372 .clflushopt,
2373 .clwb,
2374 .cmov,
2375 .crc32,
2376 .cx16,
2377 .enqcmd,
2378 .ermsb,
2379 .false_deps_getmant,
2380 .false_deps_mulc,
2381 .false_deps_mullq,
2382 .false_deps_perm,
2383 .false_deps_range,
2384 .fast_15bytenop,
2385 .fast_gather,
2386 .fast_scalar_fsqrt,
2387 .fast_shld_rotate,
2388 .fast_variable_crosslane_shuffle,
2389 .fast_variable_perlane_shuffle,
2390 .fast_vector_fsqrt,
2391 .fsgsbase,
2392 .fsrm,
2393 .fxsr,
2394 .gfni,
2395 .idivq_to_divl,
2396 .invpcid,
2397 .lzcnt,
2398 .macrofusion,
2399 .mmx,
2400 .movbe,
2401 .movdir64b,
2402 .movdiri,
2403 .no_bypass_delay_blend,
2404 .no_bypass_delay_mov,
2405 .no_bypass_delay_shuffle,
2406 .nopl,
2407 .pconfig,
2408 .pku,
2409 .popcnt,
2410 .prefer_256_bit,
2411 .prefetchi,
2412 .prfchw,
2413 .ptwrite,
2414 .rdpid,
2415 .rdrnd,
2416 .rdseed,
2417 .sahf,
2418 .serialize,
2419 .sha,
2420 .shstk,
2421 .tsxldtrk,
2422 .tuning_fast_imm_vector_shift,
2423 .uintr,
2424 .vaes,
2425 .vpclmulqdq,
2426 .vzeroupper,
2427 .waitpkg,
2428 .wbnoinvd,
2429 .x87,
2430 .xsavec,
2431 .xsaveopt,
2432 .xsaves,
2433 }),
2434 };
2435 pub const haswell = CpuModel{
2436 .name = "haswell",
2437 .llvm_name = "haswell",
2438 .features = featureSet(&[_]Feature{
2439 .@"64bit",
2440 .allow_light_256_bit,
2441 .avx2,
2442 .bmi,
2443 .bmi2,
2444 .cmov,
2445 .crc32,
2446 .cx16,
2447 .ermsb,
2448 .f16c,
2449 .false_deps_lzcnt_tzcnt,
2450 .false_deps_popcnt,
2451 .fast_15bytenop,
2452 .fast_scalar_fsqrt,
2453 .fast_shld_rotate,
2454 .fast_variable_crosslane_shuffle,
2455 .fast_variable_perlane_shuffle,
2456 .fma,
2457 .fsgsbase,
2458 .fxsr,
2459 .idivq_to_divl,
2460 .invpcid,
2461 .lzcnt,
2462 .macrofusion,
2463 .mmx,
2464 .movbe,
2465 .no_bypass_delay_mov,
2466 .no_bypass_delay_shuffle,
2467 .nopl,
2468 .pclmul,
2469 .popcnt,
2470 .rdrnd,
2471 .sahf,
2472 .slow_3ops_lea,
2473 .vzeroupper,
2474 .x87,
2475 .xsaveopt,
2476 }),
2477 };
2478 pub const @"i386" = CpuModel{
2479 .name = "i386",
2480 .llvm_name = "i386",
2481 .features = featureSet(&[_]Feature{
2482 .slow_unaligned_mem_16,
2483 .vzeroupper,
2484 .x87,
2485 }),
2486 };
2487 pub const @"i486" = CpuModel{
2488 .name = "i486",
2489 .llvm_name = "i486",
2490 .features = featureSet(&[_]Feature{
2491 .slow_unaligned_mem_16,
2492 .vzeroupper,
2493 .x87,
2494 }),
2495 };
2496 pub const @"i586" = CpuModel{
2497 .name = "i586",
2498 .llvm_name = "i586",
2499 .features = featureSet(&[_]Feature{
2500 .cx8,
2501 .slow_unaligned_mem_16,
2502 .vzeroupper,
2503 .x87,
2504 }),
2505 };
2506 pub const @"i686" = CpuModel{
2507 .name = "i686",
2508 .llvm_name = "i686",
2509 .features = featureSet(&[_]Feature{
2510 .cmov,
2511 .cx8,
2512 .slow_unaligned_mem_16,
2513 .vzeroupper,
2514 .x87,
2515 }),
2516 };
2517 pub const icelake_client = CpuModel{
2518 .name = "icelake_client",
2519 .llvm_name = "icelake-client",
2520 .features = featureSet(&[_]Feature{
2521 .@"64bit",
2522 .adx,
2523 .allow_light_256_bit,
2524 .avx512bitalg,
2525 .avx512cd,
2526 .avx512dq,
2527 .avx512ifma,
2528 .avx512vbmi,
2529 .avx512vbmi2,
2530 .avx512vl,
2531 .avx512vnni,
2532 .avx512vpopcntdq,
2533 .bmi,
2534 .bmi2,
2535 .clflushopt,
2536 .cmov,
2537 .crc32,
2538 .cx16,
2539 .ermsb,
2540 .fast_15bytenop,
2541 .fast_gather,
2542 .fast_scalar_fsqrt,
2543 .fast_shld_rotate,
2544 .fast_variable_crosslane_shuffle,
2545 .fast_variable_perlane_shuffle,
2546 .fast_vector_fsqrt,
2547 .fsgsbase,
2548 .fsrm,
2549 .fxsr,
2550 .gfni,
2551 .idivq_to_divl,
2552 .invpcid,
2553 .lzcnt,
2554 .macrofusion,
2555 .mmx,
2556 .movbe,
2557 .no_bypass_delay_blend,
2558 .no_bypass_delay_mov,
2559 .no_bypass_delay_shuffle,
2560 .nopl,
2561 .pku,
2562 .popcnt,
2563 .prefer_256_bit,
2564 .prfchw,
2565 .rdpid,
2566 .rdrnd,
2567 .rdseed,
2568 .sahf,
2569 .sha,
2570 .tuning_fast_imm_vector_shift,
2571 .vaes,
2572 .vpclmulqdq,
2573 .vzeroupper,
2574 .x87,
2575 .xsavec,
2576 .xsaveopt,
2577 .xsaves,
2578 }),
2579 };
2580 pub const icelake_server = CpuModel{
2581 .name = "icelake_server",
2582 .llvm_name = "icelake-server",
2583 .features = featureSet(&[_]Feature{
2584 .@"64bit",
2585 .adx,
2586 .allow_light_256_bit,
2587 .avx512bitalg,
2588 .avx512cd,
2589 .avx512dq,
2590 .avx512ifma,
2591 .avx512vbmi,
2592 .avx512vbmi2,
2593 .avx512vl,
2594 .avx512vnni,
2595 .avx512vpopcntdq,
2596 .bmi,
2597 .bmi2,
2598 .clflushopt,
2599 .clwb,
2600 .cmov,
2601 .crc32,
2602 .cx16,
2603 .ermsb,
2604 .fast_15bytenop,
2605 .fast_gather,
2606 .fast_scalar_fsqrt,
2607 .fast_shld_rotate,
2608 .fast_variable_crosslane_shuffle,
2609 .fast_variable_perlane_shuffle,
2610 .fast_vector_fsqrt,
2611 .fsgsbase,
2612 .fsrm,
2613 .fxsr,
2614 .gfni,
2615 .idivq_to_divl,
2616 .invpcid,
2617 .lzcnt,
2618 .macrofusion,
2619 .mmx,
2620 .movbe,
2621 .no_bypass_delay_blend,
2622 .no_bypass_delay_mov,
2623 .no_bypass_delay_shuffle,
2624 .nopl,
2625 .pconfig,
2626 .pku,
2627 .popcnt,
2628 .prefer_256_bit,
2629 .prfchw,
2630 .rdpid,
2631 .rdrnd,
2632 .rdseed,
2633 .sahf,
2634 .sha,
2635 .tuning_fast_imm_vector_shift,
2636 .vaes,
2637 .vpclmulqdq,
2638 .vzeroupper,
2639 .wbnoinvd,
2640 .x87,
2641 .xsavec,
2642 .xsaveopt,
2643 .xsaves,
2644 }),
2645 };
2646 pub const ivybridge = CpuModel{
2647 .name = "ivybridge",
2648 .llvm_name = "ivybridge",
2649 .features = featureSet(&[_]Feature{
2650 .@"64bit",
2651 .cmov,
2652 .crc32,
2653 .cx16,
2654 .f16c,
2655 .false_deps_popcnt,
2656 .fast_15bytenop,
2657 .fast_scalar_fsqrt,
2658 .fast_shld_rotate,
2659 .fsgsbase,
2660 .fxsr,
2661 .idivq_to_divl,
2662 .macrofusion,
2663 .mmx,
2664 .no_bypass_delay_mov,
2665 .nopl,
2666 .pclmul,
2667 .popcnt,
2668 .rdrnd,
2669 .sahf,
2670 .slow_3ops_lea,
2671 .slow_unaligned_mem_32,
2672 .vzeroupper,
2673 .x87,
2674 .xsaveopt,
2675 }),
2676 };
2677 pub const k6 = CpuModel{
2678 .name = "k6",
2679 .llvm_name = "k6",
2680 .features = featureSet(&[_]Feature{
2681 .cx8,
2682 .mmx,
2683 .slow_unaligned_mem_16,
2684 .vzeroupper,
2685 .x87,
2686 }),
2687 };
2688 pub const k6_2 = CpuModel{
2689 .name = "k6_2",
2690 .llvm_name = "k6-2",
2691 .features = featureSet(&[_]Feature{
2692 .@"3dnow",
2693 .cx8,
2694 .slow_unaligned_mem_16,
2695 .vzeroupper,
2696 .x87,
2697 }),
2698 };
2699 pub const k6_3 = CpuModel{
2700 .name = "k6_3",
2701 .llvm_name = "k6-3",
2702 .features = featureSet(&[_]Feature{
2703 .@"3dnow",
2704 .cx8,
2705 .slow_unaligned_mem_16,
2706 .vzeroupper,
2707 .x87,
2708 }),
2709 };
2710 pub const k8 = CpuModel{
2711 .name = "k8",
2712 .llvm_name = "k8",
2713 .features = featureSet(&[_]Feature{
2714 .@"3dnowa",
2715 .@"64bit",
2716 .cmov,
2717 .cx8,
2718 .fast_scalar_shift_masks,
2719 .fxsr,
2720 .nopl,
2721 .sbb_dep_breaking,
2722 .slow_shld,
2723 .slow_unaligned_mem_16,
2724 .sse2,
2725 .vzeroupper,
2726 .x87,
2727 }),
2728 };
2729 pub const k8_sse3 = CpuModel{
2730 .name = "k8_sse3",
2731 .llvm_name = "k8-sse3",
2732 .features = featureSet(&[_]Feature{
2733 .@"3dnowa",
2734 .@"64bit",
2735 .cmov,
2736 .cx16,
2737 .fast_scalar_shift_masks,
2738 .fxsr,
2739 .nopl,
2740 .sbb_dep_breaking,
2741 .slow_shld,
2742 .slow_unaligned_mem_16,
2743 .sse3,
2744 .vzeroupper,
2745 .x87,
2746 }),
2747 };
2748 pub const knl = CpuModel{
2749 .name = "knl",
2750 .llvm_name = "knl",
2751 .features = featureSet(&[_]Feature{
2752 .@"64bit",
2753 .adx,
2754 .aes,
2755 .avx512cd,
2756 .avx512er,
2757 .avx512pf,
2758 .bmi,
2759 .bmi2,
2760 .cmov,
2761 .crc32,
2762 .cx16,
2763 .fast_gather,
2764 .fast_movbe,
2765 .fsgsbase,
2766 .fxsr,
2767 .idivq_to_divl,
2768 .lzcnt,
2769 .mmx,
2770 .movbe,
2771 .nopl,
2772 .pclmul,
2773 .popcnt,
2774 .prefer_mask_registers,
2775 .prefetchwt1,
2776 .prfchw,
2777 .rdrnd,
2778 .rdseed,
2779 .sahf,
2780 .slow_3ops_lea,
2781 .slow_incdec,
2782 .slow_pmaddwd,
2783 .slow_two_mem_ops,
2784 .x87,
2785 .xsaveopt,
2786 }),
2787 };
2788 pub const knm = CpuModel{
2789 .name = "knm",
2790 .llvm_name = "knm",
2791 .features = featureSet(&[_]Feature{
2792 .@"64bit",
2793 .adx,
2794 .aes,
2795 .avx512cd,
2796 .avx512er,
2797 .avx512pf,
2798 .avx512vpopcntdq,
2799 .bmi,
2800 .bmi2,
2801 .cmov,
2802 .crc32,
2803 .cx16,
2804 .fast_gather,
2805 .fast_movbe,
2806 .fsgsbase,
2807 .fxsr,
2808 .idivq_to_divl,
2809 .lzcnt,
2810 .mmx,
2811 .movbe,
2812 .nopl,
2813 .pclmul,
2814 .popcnt,
2815 .prefer_mask_registers,
2816 .prefetchwt1,
2817 .prfchw,
2818 .rdrnd,
2819 .rdseed,
2820 .sahf,
2821 .slow_3ops_lea,
2822 .slow_incdec,
2823 .slow_pmaddwd,
2824 .slow_two_mem_ops,
2825 .x87,
2826 .xsaveopt,
2827 }),
2828 };
2829 pub const lakemont = CpuModel{
2830 .name = "lakemont",
2831 .llvm_name = "lakemont",
2832 .features = featureSet(&[_]Feature{
2833 .cx8,
2834 .slow_unaligned_mem_16,
2835 .soft_float,
2836 .vzeroupper,
2837 }),
2838 };
2839 pub const meteorlake = CpuModel{
2840 .name = "meteorlake",
2841 .llvm_name = "meteorlake",
2842 .features = featureSet(&[_]Feature{
2843 .@"64bit",
2844 .adx,
2845 .allow_light_256_bit,
2846 .avxvnni,
2847 .bmi,
2848 .bmi2,
2849 .cldemote,
2850 .clflushopt,
2851 .clwb,
2852 .cmov,
2853 .crc32,
2854 .cx16,
2855 .f16c,
2856 .false_deps_perm,
2857 .false_deps_popcnt,
2858 .fast_15bytenop,
2859 .fast_gather,
2860 .fast_scalar_fsqrt,
2861 .fast_shld_rotate,
2862 .fast_variable_crosslane_shuffle,
2863 .fast_variable_perlane_shuffle,
2864 .fast_vector_fsqrt,
2865 .fma,
2866 .fsgsbase,
2867 .fxsr,
2868 .gfni,
2869 .hreset,
2870 .idivq_to_divl,
2871 .invpcid,
2872 .lzcnt,
2873 .macrofusion,
2874 .mmx,
2875 .movbe,
2876 .movdir64b,
2877 .movdiri,
2878 .no_bypass_delay_blend,
2879 .no_bypass_delay_mov,
2880 .no_bypass_delay_shuffle,
2881 .nopl,
2882 .pconfig,
2883 .pku,
2884 .popcnt,
2885 .prefer_movmsk_over_vtest,
2886 .prfchw,
2887 .ptwrite,
2888 .rdpid,
2889 .rdrnd,
2890 .rdseed,
2891 .sahf,
2892 .serialize,
2893 .sha,
2894 .shstk,
2895 .slow_3ops_lea,
2896 .tuning_fast_imm_vector_shift,
2897 .vaes,
2898 .vpclmulqdq,
2899 .vzeroupper,
2900 .waitpkg,
2901 .widekl,
2902 .x87,
2903 .xsavec,
2904 .xsaveopt,
2905 .xsaves,
2906 }),
2907 };
2908 pub const nehalem = CpuModel{
2909 .name = "nehalem",
2910 .llvm_name = "nehalem",
2911 .features = featureSet(&[_]Feature{
2912 .@"64bit",
2913 .cmov,
2914 .crc32,
2915 .cx16,
2916 .fxsr,
2917 .macrofusion,
2918 .mmx,
2919 .no_bypass_delay_mov,
2920 .nopl,
2921 .popcnt,
2922 .sahf,
2923 .sse4_2,
2924 .vzeroupper,
2925 .x87,
2926 }),
2927 };
2928 pub const nocona = CpuModel{
2929 .name = "nocona",
2930 .llvm_name = "nocona",
2931 .features = featureSet(&[_]Feature{
2932 .@"64bit",
2933 .cmov,
2934 .cx16,
2935 .fxsr,
2936 .mmx,
2937 .nopl,
2938 .slow_unaligned_mem_16,
2939 .sse3,
2940 .vzeroupper,
2941 .x87,
2942 }),
2943 };
2944 pub const opteron = CpuModel{
2945 .name = "opteron",
2946 .llvm_name = "opteron",
2947 .features = featureSet(&[_]Feature{
2948 .@"3dnowa",
2949 .@"64bit",
2950 .cmov,
2951 .cx8,
2952 .fast_scalar_shift_masks,
2953 .fxsr,
2954 .nopl,
2955 .sbb_dep_breaking,
2956 .slow_shld,
2957 .slow_unaligned_mem_16,
2958 .sse2,
2959 .vzeroupper,
2960 .x87,
2961 }),
2962 };
2963 pub const opteron_sse3 = CpuModel{
2964 .name = "opteron_sse3",
2965 .llvm_name = "opteron-sse3",
2966 .features = featureSet(&[_]Feature{
2967 .@"3dnowa",
2968 .@"64bit",
2969 .cmov,
2970 .cx16,
2971 .fast_scalar_shift_masks,
2972 .fxsr,
2973 .nopl,
2974 .sbb_dep_breaking,
2975 .slow_shld,
2976 .slow_unaligned_mem_16,
2977 .sse3,
2978 .vzeroupper,
2979 .x87,
2980 }),
2981 };
2982 pub const penryn = CpuModel{
2983 .name = "penryn",
2984 .llvm_name = "penryn",
2985 .features = featureSet(&[_]Feature{
2986 .@"64bit",
2987 .cmov,
2988 .cx16,
2989 .fxsr,
2990 .macrofusion,
2991 .mmx,
2992 .nopl,
2993 .sahf,
2994 .slow_unaligned_mem_16,
2995 .sse4_1,
2996 .vzeroupper,
2997 .x87,
2998 }),
2999 };
3000 pub const pentium = CpuModel{
3001 .name = "pentium",
3002 .llvm_name = "pentium",
3003 .features = featureSet(&[_]Feature{
3004 .cx8,
3005 .slow_unaligned_mem_16,
3006 .vzeroupper,
3007 .x87,
3008 }),
3009 };
3010 pub const pentium2 = CpuModel{
3011 .name = "pentium2",
3012 .llvm_name = "pentium2",
3013 .features = featureSet(&[_]Feature{
3014 .cmov,
3015 .cx8,
3016 .fxsr,
3017 .mmx,
3018 .nopl,
3019 .slow_unaligned_mem_16,
3020 .vzeroupper,
3021 .x87,
3022 }),
3023 };
3024 pub const pentium3 = CpuModel{
3025 .name = "pentium3",
3026 .llvm_name = "pentium3",
3027 .features = featureSet(&[_]Feature{
3028 .cmov,
3029 .cx8,
3030 .fxsr,
3031 .mmx,
3032 .nopl,
3033 .slow_unaligned_mem_16,
3034 .sse,
3035 .vzeroupper,
3036 .x87,
3037 }),
3038 };
3039 pub const pentium3m = CpuModel{
3040 .name = "pentium3m",
3041 .llvm_name = "pentium3m",
3042 .features = featureSet(&[_]Feature{
3043 .cmov,
3044 .cx8,
3045 .fxsr,
3046 .mmx,
3047 .nopl,
3048 .slow_unaligned_mem_16,
3049 .sse,
3050 .vzeroupper,
3051 .x87,
3052 }),
3053 };
3054 pub const pentium4 = CpuModel{
3055 .name = "pentium4",
3056 .llvm_name = "pentium4",
3057 .features = featureSet(&[_]Feature{
3058 .cmov,
3059 .cx8,
3060 .fxsr,
3061 .mmx,
3062 .nopl,
3063 .slow_unaligned_mem_16,
3064 .sse2,
3065 .vzeroupper,
3066 .x87,
3067 }),
3068 };
3069 pub const pentium_m = CpuModel{
3070 .name = "pentium_m",
3071 .llvm_name = "pentium-m",
3072 .features = featureSet(&[_]Feature{
3073 .cmov,
3074 .cx8,
3075 .fxsr,
3076 .mmx,
3077 .nopl,
3078 .slow_unaligned_mem_16,
3079 .sse2,
3080 .vzeroupper,
3081 .x87,
3082 }),
3083 };
3084 pub const pentium_mmx = CpuModel{
3085 .name = "pentium_mmx",
3086 .llvm_name = "pentium-mmx",
3087 .features = featureSet(&[_]Feature{
3088 .cx8,
3089 .mmx,
3090 .slow_unaligned_mem_16,
3091 .vzeroupper,
3092 .x87,
3093 }),
3094 };
3095 pub const pentiumpro = CpuModel{
3096 .name = "pentiumpro",
3097 .llvm_name = "pentiumpro",
3098 .features = featureSet(&[_]Feature{
3099 .cmov,
3100 .cx8,
3101 .nopl,
3102 .slow_unaligned_mem_16,
3103 .vzeroupper,
3104 .x87,
3105 }),
3106 };
3107 pub const prescott = CpuModel{
3108 .name = "prescott",
3109 .llvm_name = "prescott",
3110 .features = featureSet(&[_]Feature{
3111 .cmov,
3112 .cx8,
3113 .fxsr,
3114 .mmx,
3115 .nopl,
3116 .slow_unaligned_mem_16,
3117 .sse3,
3118 .vzeroupper,
3119 .x87,
3120 }),
3121 };
3122 pub const raptorlake = CpuModel{
3123 .name = "raptorlake",
3124 .llvm_name = "raptorlake",
3125 .features = featureSet(&[_]Feature{
3126 .@"64bit",
3127 .adx,
3128 .allow_light_256_bit,
3129 .avxvnni,
3130 .bmi,
3131 .bmi2,
3132 .cldemote,
3133 .clflushopt,
3134 .clwb,
3135 .cmov,
3136 .crc32,
3137 .cx16,
3138 .f16c,
3139 .false_deps_perm,
3140 .false_deps_popcnt,
3141 .fast_15bytenop,
3142 .fast_gather,
3143 .fast_scalar_fsqrt,
3144 .fast_shld_rotate,
3145 .fast_variable_crosslane_shuffle,
3146 .fast_variable_perlane_shuffle,
3147 .fast_vector_fsqrt,
3148 .fma,
3149 .fsgsbase,
3150 .fxsr,
3151 .gfni,
3152 .hreset,
3153 .idivq_to_divl,
3154 .invpcid,
3155 .lzcnt,
3156 .macrofusion,
3157 .mmx,
3158 .movbe,
3159 .movdir64b,
3160 .movdiri,
3161 .no_bypass_delay_blend,
3162 .no_bypass_delay_mov,
3163 .no_bypass_delay_shuffle,
3164 .nopl,
3165 .pconfig,
3166 .pku,
3167 .popcnt,
3168 .prefer_movmsk_over_vtest,
3169 .prfchw,
3170 .ptwrite,
3171 .rdpid,
3172 .rdrnd,
3173 .rdseed,
3174 .sahf,
3175 .serialize,
3176 .sha,
3177 .shstk,
3178 .slow_3ops_lea,
3179 .tuning_fast_imm_vector_shift,
3180 .vaes,
3181 .vpclmulqdq,
3182 .vzeroupper,
3183 .waitpkg,
3184 .widekl,
3185 .x87,
3186 .xsavec,
3187 .xsaveopt,
3188 .xsaves,
3189 }),
3190 };
3191 pub const rocketlake = CpuModel{
3192 .name = "rocketlake",
3193 .llvm_name = "rocketlake",
3194 .features = featureSet(&[_]Feature{
3195 .@"64bit",
3196 .adx,
3197 .allow_light_256_bit,
3198 .avx512bitalg,
3199 .avx512cd,
3200 .avx512dq,
3201 .avx512ifma,
3202 .avx512vbmi,
3203 .avx512vbmi2,
3204 .avx512vl,
3205 .avx512vnni,
3206 .avx512vpopcntdq,
3207 .bmi,
3208 .bmi2,
3209 .clflushopt,
3210 .cmov,
3211 .crc32,
3212 .cx16,
3213 .ermsb,
3214 .fast_15bytenop,
3215 .fast_gather,
3216 .fast_scalar_fsqrt,
3217 .fast_shld_rotate,
3218 .fast_variable_crosslane_shuffle,
3219 .fast_variable_perlane_shuffle,
3220 .fast_vector_fsqrt,
3221 .fsgsbase,
3222 .fsrm,
3223 .fxsr,
3224 .gfni,
3225 .idivq_to_divl,
3226 .invpcid,
3227 .lzcnt,
3228 .macrofusion,
3229 .mmx,
3230 .movbe,
3231 .no_bypass_delay_blend,
3232 .no_bypass_delay_mov,
3233 .no_bypass_delay_shuffle,
3234 .nopl,
3235 .pku,
3236 .popcnt,
3237 .prefer_256_bit,
3238 .prfchw,
3239 .rdpid,
3240 .rdrnd,
3241 .rdseed,
3242 .sahf,
3243 .sha,
3244 .tuning_fast_imm_vector_shift,
3245 .vaes,
3246 .vpclmulqdq,
3247 .vzeroupper,
3248 .x87,
3249 .xsavec,
3250 .xsaveopt,
3251 .xsaves,
3252 }),
3253 };
3254 pub const sandybridge = CpuModel{
3255 .name = "sandybridge",
3256 .llvm_name = "sandybridge",
3257 .features = featureSet(&[_]Feature{
3258 .@"64bit",
3259 .avx,
3260 .cmov,
3261 .crc32,
3262 .cx16,
3263 .false_deps_popcnt,
3264 .fast_15bytenop,
3265 .fast_scalar_fsqrt,
3266 .fast_shld_rotate,
3267 .fxsr,
3268 .idivq_to_divl,
3269 .macrofusion,
3270 .mmx,
3271 .no_bypass_delay_mov,
3272 .nopl,
3273 .pclmul,
3274 .popcnt,
3275 .sahf,
3276 .slow_3ops_lea,
3277 .slow_unaligned_mem_32,
3278 .vzeroupper,
3279 .x87,
3280 .xsaveopt,
3281 }),
3282 };
3283 pub const sapphirerapids = CpuModel{
3284 .name = "sapphirerapids",
3285 .llvm_name = "sapphirerapids",
3286 .features = featureSet(&[_]Feature{
3287 .@"64bit",
3288 .adx,
3289 .allow_light_256_bit,
3290 .amx_bf16,
3291 .amx_int8,
3292 .avx512bf16,
3293 .avx512bitalg,
3294 .avx512cd,
3295 .avx512fp16,
3296 .avx512ifma,
3297 .avx512vbmi,
3298 .avx512vbmi2,
3299 .avx512vnni,
3300 .avx512vpopcntdq,
3301 .avxvnni,
3302 .bmi,
3303 .bmi2,
3304 .cldemote,
3305 .clflushopt,
3306 .clwb,
3307 .cmov,
3308 .crc32,
3309 .cx16,
3310 .enqcmd,
3311 .ermsb,
3312 .false_deps_getmant,
3313 .false_deps_mulc,
3314 .false_deps_mullq,
3315 .false_deps_perm,
3316 .false_deps_range,
3317 .fast_15bytenop,
3318 .fast_gather,
3319 .fast_scalar_fsqrt,
3320 .fast_shld_rotate,
3321 .fast_variable_crosslane_shuffle,
3322 .fast_variable_perlane_shuffle,
3323 .fast_vector_fsqrt,
3324 .fsgsbase,
3325 .fsrm,
3326 .fxsr,
3327 .gfni,
3328 .idivq_to_divl,
3329 .invpcid,
3330 .lzcnt,
3331 .macrofusion,
3332 .mmx,
3333 .movbe,
3334 .movdir64b,
3335 .movdiri,
3336 .no_bypass_delay_blend,
3337 .no_bypass_delay_mov,
3338 .no_bypass_delay_shuffle,
3339 .nopl,
3340 .pconfig,
3341 .pku,
3342 .popcnt,
3343 .prefer_256_bit,
3344 .prfchw,
3345 .ptwrite,
3346 .rdpid,
3347 .rdrnd,
3348 .rdseed,
3349 .sahf,
3350 .serialize,
3351 .sha,
3352 .shstk,
3353 .tsxldtrk,
3354 .tuning_fast_imm_vector_shift,
3355 .uintr,
3356 .vaes,
3357 .vpclmulqdq,
3358 .vzeroupper,
3359 .waitpkg,
3360 .wbnoinvd,
3361 .x87,
3362 .xsavec,
3363 .xsaveopt,
3364 .xsaves,
3365 }),
3366 };
3367 pub const sierraforest = CpuModel{
3368 .name = "sierraforest",
3369 .llvm_name = "sierraforest",
3370 .features = featureSet(&[_]Feature{
3371 .@"64bit",
3372 .adx,
3373 .avxifma,
3374 .avxneconvert,
3375 .avxvnni,
3376 .avxvnniint8,
3377 .bmi,
3378 .bmi2,
3379 .cldemote,
3380 .clflushopt,
3381 .clwb,
3382 .cmov,
3383 .cmpccxadd,
3384 .crc32,
3385 .cx16,
3386 .enqcmd,
3387 .f16c,
3388 .fast_movbe,
3389 .fma,
3390 .fsgsbase,
3391 .fxsr,
3392 .gfni,
3393 .hreset,
3394 .invpcid,
3395 .lzcnt,
3396 .mmx,
3397 .movbe,
3398 .movdir64b,
3399 .movdiri,
3400 .no_bypass_delay,
3401 .nopl,
3402 .pconfig,
3403 .pku,
3404 .popcnt,
3405 .prfchw,
3406 .ptwrite,
3407 .rdpid,
3408 .rdrnd,
3409 .rdseed,
3410 .sahf,
3411 .serialize,
3412 .sha,
3413 .shstk,
3414 .slow_incdec,
3415 .slow_lea,
3416 .slow_two_mem_ops,
3417 .uintr,
3418 .use_glm_div_sqrt_costs,
3419 .vaes,
3420 .vpclmulqdq,
3421 .vzeroupper,
3422 .waitpkg,
3423 .widekl,
3424 .x87,
3425 .xsavec,
3426 .xsaveopt,
3427 .xsaves,
3428 }),
3429 };
3430 pub const silvermont = CpuModel{
3431 .name = "silvermont",
3432 .llvm_name = "silvermont",
3433 .features = featureSet(&[_]Feature{
3434 .@"64bit",
3435 .cmov,
3436 .crc32,
3437 .cx16,
3438 .false_deps_popcnt,
3439 .fast_7bytenop,
3440 .fast_movbe,
3441 .fxsr,
3442 .idivq_to_divl,
3443 .mmx,
3444 .movbe,
3445 .no_bypass_delay,
3446 .nopl,
3447 .pclmul,
3448 .popcnt,
3449 .prfchw,
3450 .rdrnd,
3451 .sahf,
3452 .slow_incdec,
3453 .slow_lea,
3454 .slow_pmulld,
3455 .slow_two_mem_ops,
3456 .sse4_2,
3457 .use_slm_arith_costs,
3458 .vzeroupper,
3459 .x87,
3460 }),
3461 };
3462 pub const skx = CpuModel{
3463 .name = "skx",
3464 .llvm_name = "skx",
3465 .features = featureSet(&[_]Feature{
3466 .@"64bit",
3467 .adx,
3468 .aes,
3469 .allow_light_256_bit,
3470 .avx512bw,
3471 .avx512cd,
3472 .avx512dq,
3473 .avx512vl,
3474 .bmi,
3475 .bmi2,
3476 .clflushopt,
3477 .clwb,
3478 .cmov,
3479 .crc32,
3480 .cx16,
3481 .ermsb,
3482 .false_deps_popcnt,
3483 .fast_15bytenop,
3484 .fast_gather,
3485 .fast_scalar_fsqrt,
3486 .fast_shld_rotate,
3487 .fast_variable_crosslane_shuffle,
3488 .fast_variable_perlane_shuffle,
3489 .fast_vector_fsqrt,
3490 .faster_shift_than_shuffle,
3491 .fsgsbase,
3492 .fxsr,
3493 .idivq_to_divl,
3494 .invpcid,
3495 .lzcnt,
3496 .macrofusion,
3497 .mmx,
3498 .movbe,
3499 .no_bypass_delay_blend,
3500 .no_bypass_delay_mov,
3501 .no_bypass_delay_shuffle,
3502 .nopl,
3503 .pclmul,
3504 .pku,
3505 .popcnt,
3506 .prefer_256_bit,
3507 .prfchw,
3508 .rdrnd,
3509 .rdseed,
3510 .sahf,
3511 .slow_3ops_lea,
3512 .tuning_fast_imm_vector_shift,
3513 .vzeroupper,
3514 .x87,
3515 .xsavec,
3516 .xsaveopt,
3517 .xsaves,
3518 }),
3519 };
3520 pub const skylake = CpuModel{
3521 .name = "skylake",
3522 .llvm_name = "skylake",
3523 .features = featureSet(&[_]Feature{
3524 .@"64bit",
3525 .adx,
3526 .aes,
3527 .allow_light_256_bit,
3528 .avx2,
3529 .bmi,
3530 .bmi2,
3531 .clflushopt,
3532 .cmov,
3533 .crc32,
3534 .cx16,
3535 .ermsb,
3536 .f16c,
3537 .false_deps_popcnt,
3538 .fast_15bytenop,
3539 .fast_gather,
3540 .fast_scalar_fsqrt,
3541 .fast_shld_rotate,
3542 .fast_variable_crosslane_shuffle,
3543 .fast_variable_perlane_shuffle,
3544 .fast_vector_fsqrt,
3545 .fma,
3546 .fsgsbase,
3547 .fxsr,
3548 .idivq_to_divl,
3549 .invpcid,
3550 .lzcnt,
3551 .macrofusion,
3552 .mmx,
3553 .movbe,
3554 .no_bypass_delay_blend,
3555 .no_bypass_delay_mov,
3556 .no_bypass_delay_shuffle,
3557 .nopl,
3558 .pclmul,
3559 .popcnt,
3560 .prfchw,
3561 .rdrnd,
3562 .rdseed,
3563 .sahf,
3564 .slow_3ops_lea,
3565 .vzeroupper,
3566 .x87,
3567 .xsavec,
3568 .xsaveopt,
3569 .xsaves,
3570 }),
3571 };
3572 pub const skylake_avx512 = CpuModel{
3573 .name = "skylake_avx512",
3574 .llvm_name = "skylake-avx512",
3575 .features = featureSet(&[_]Feature{
3576 .@"64bit",
3577 .adx,
3578 .aes,
3579 .allow_light_256_bit,
3580 .avx512bw,
3581 .avx512cd,
3582 .avx512dq,
3583 .avx512vl,
3584 .bmi,
3585 .bmi2,
3586 .clflushopt,
3587 .clwb,
3588 .cmov,
3589 .crc32,
3590 .cx16,
3591 .ermsb,
3592 .false_deps_popcnt,
3593 .fast_15bytenop,
3594 .fast_gather,
3595 .fast_scalar_fsqrt,
3596 .fast_shld_rotate,
3597 .fast_variable_crosslane_shuffle,
3598 .fast_variable_perlane_shuffle,
3599 .fast_vector_fsqrt,
3600 .faster_shift_than_shuffle,
3601 .fsgsbase,
3602 .fxsr,
3603 .idivq_to_divl,
3604 .invpcid,
3605 .lzcnt,
3606 .macrofusion,
3607 .mmx,
3608 .movbe,
3609 .no_bypass_delay_blend,
3610 .no_bypass_delay_mov,
3611 .no_bypass_delay_shuffle,
3612 .nopl,
3613 .pclmul,
3614 .pku,
3615 .popcnt,
3616 .prefer_256_bit,
3617 .prfchw,
3618 .rdrnd,
3619 .rdseed,
3620 .sahf,
3621 .slow_3ops_lea,
3622 .tuning_fast_imm_vector_shift,
3623 .vzeroupper,
3624 .x87,
3625 .xsavec,
3626 .xsaveopt,
3627 .xsaves,
3628 }),
3629 };
3630 pub const slm = CpuModel{
3631 .name = "slm",
3632 .llvm_name = "slm",
3633 .features = featureSet(&[_]Feature{
3634 .@"64bit",
3635 .cmov,
3636 .crc32,
3637 .cx16,
3638 .false_deps_popcnt,
3639 .fast_7bytenop,
3640 .fast_movbe,
3641 .fxsr,
3642 .idivq_to_divl,
3643 .mmx,
3644 .movbe,
3645 .no_bypass_delay,
3646 .nopl,
3647 .pclmul,
3648 .popcnt,
3649 .prfchw,
3650 .rdrnd,
3651 .sahf,
3652 .slow_incdec,
3653 .slow_lea,
3654 .slow_pmulld,
3655 .slow_two_mem_ops,
3656 .sse4_2,
3657 .use_slm_arith_costs,
3658 .vzeroupper,
3659 .x87,
3660 }),
3661 };
3662 pub const tigerlake = CpuModel{
3663 .name = "tigerlake",
3664 .llvm_name = "tigerlake",
3665 .features = featureSet(&[_]Feature{
3666 .@"64bit",
3667 .adx,
3668 .allow_light_256_bit,
3669 .avx512bitalg,
3670 .avx512cd,
3671 .avx512dq,
3672 .avx512ifma,
3673 .avx512vbmi,
3674 .avx512vbmi2,
3675 .avx512vl,
3676 .avx512vnni,
3677 .avx512vp2intersect,
3678 .avx512vpopcntdq,
3679 .bmi,
3680 .bmi2,
3681 .clflushopt,
3682 .clwb,
3683 .cmov,
3684 .crc32,
3685 .cx16,
3686 .ermsb,
3687 .fast_15bytenop,
3688 .fast_gather,
3689 .fast_scalar_fsqrt,
3690 .fast_shld_rotate,
3691 .fast_variable_crosslane_shuffle,
3692 .fast_variable_perlane_shuffle,
3693 .fast_vector_fsqrt,
3694 .fsgsbase,
3695 .fsrm,
3696 .fxsr,
3697 .gfni,
3698 .idivq_to_divl,
3699 .invpcid,
3700 .lzcnt,
3701 .macrofusion,
3702 .mmx,
3703 .movbe,
3704 .movdir64b,
3705 .movdiri,
3706 .no_bypass_delay_blend,
3707 .no_bypass_delay_mov,
3708 .no_bypass_delay_shuffle,
3709 .nopl,
3710 .pku,
3711 .popcnt,
3712 .prefer_256_bit,
3713 .prfchw,
3714 .rdpid,
3715 .rdrnd,
3716 .rdseed,
3717 .sahf,
3718 .sha,
3719 .shstk,
3720 .tuning_fast_imm_vector_shift,
3721 .vaes,
3722 .vpclmulqdq,
3723 .vzeroupper,
3724 .x87,
3725 .xsavec,
3726 .xsaveopt,
3727 .xsaves,
3728 }),
3729 };
3730 pub const tremont = CpuModel{
3731 .name = "tremont",
3732 .llvm_name = "tremont",
3733 .features = featureSet(&[_]Feature{
3734 .@"64bit",
3735 .aes,
3736 .clflushopt,
3737 .clwb,
3738 .cmov,
3739 .crc32,
3740 .cx16,
3741 .fast_movbe,
3742 .fsgsbase,
3743 .fxsr,
3744 .gfni,
3745 .mmx,
3746 .movbe,
3747 .no_bypass_delay,
3748 .nopl,
3749 .pclmul,
3750 .popcnt,
3751 .prfchw,
3752 .ptwrite,
3753 .rdpid,
3754 .rdrnd,
3755 .rdseed,
3756 .sahf,
3757 .sha,
3758 .slow_incdec,
3759 .slow_lea,
3760 .slow_two_mem_ops,
3761 .sse4_2,
3762 .use_glm_div_sqrt_costs,
3763 .vzeroupper,
3764 .x87,
3765 .xsavec,
3766 .xsaveopt,
3767 .xsaves,
3768 }),
3769 };
3770 pub const westmere = CpuModel{
3771 .name = "westmere",
3772 .llvm_name = "westmere",
3773 .features = featureSet(&[_]Feature{
3774 .@"64bit",
3775 .cmov,
3776 .crc32,
3777 .cx16,
3778 .fxsr,
3779 .macrofusion,
3780 .mmx,
3781 .no_bypass_delay_mov,
3782 .nopl,
3783 .pclmul,
3784 .popcnt,
3785 .sahf,
3786 .sse4_2,
3787 .vzeroupper,
3788 .x87,
3789 }),
3790 };
3791 pub const winchip2 = CpuModel{
3792 .name = "winchip2",
3793 .llvm_name = "winchip2",
3794 .features = featureSet(&[_]Feature{
3795 .@"3dnow",
3796 .slow_unaligned_mem_16,
3797 .vzeroupper,
3798 .x87,
3799 }),
3800 };
3801 pub const winchip_c6 = CpuModel{
3802 .name = "winchip_c6",
3803 .llvm_name = "winchip-c6",
3804 .features = featureSet(&[_]Feature{
3805 .mmx,
3806 .slow_unaligned_mem_16,
3807 .vzeroupper,
3808 .x87,
3809 }),
3810 };
3811 pub const x86_64 = CpuModel{
3812 .name = "x86_64",
3813 .llvm_name = "x86-64",
3814 .features = featureSet(&[_]Feature{
3815 .@"64bit",
3816 .cmov,
3817 .cx8,
3818 .fxsr,
3819 .idivq_to_divl,
3820 .macrofusion,
3821 .mmx,
3822 .nopl,
3823 .slow_3ops_lea,
3824 .slow_incdec,
3825 .sse2,
3826 .vzeroupper,
3827 .x87,
3828 }),
3829 };
3830 pub const x86_64_v2 = CpuModel{
3831 .name = "x86_64_v2",
3832 .llvm_name = "x86-64-v2",
3833 .features = featureSet(&[_]Feature{
3834 .@"64bit",
3835 .cmov,
3836 .crc32,
3837 .cx16,
3838 .false_deps_popcnt,
3839 .fast_15bytenop,
3840 .fast_scalar_fsqrt,
3841 .fast_shld_rotate,
3842 .fxsr,
3843 .idivq_to_divl,
3844 .macrofusion,
3845 .mmx,
3846 .nopl,
3847 .popcnt,
3848 .sahf,
3849 .slow_3ops_lea,
3850 .slow_unaligned_mem_32,
3851 .sse4_2,
3852 .vzeroupper,
3853 .x87,
3854 }),
3855 };
3856 pub const x86_64_v3 = CpuModel{
3857 .name = "x86_64_v3",
3858 .llvm_name = "x86-64-v3",
3859 .features = featureSet(&[_]Feature{
3860 .@"64bit",
3861 .allow_light_256_bit,
3862 .avx2,
3863 .bmi,
3864 .bmi2,
3865 .cmov,
3866 .crc32,
3867 .cx16,
3868 .f16c,
3869 .false_deps_lzcnt_tzcnt,
3870 .false_deps_popcnt,
3871 .fast_15bytenop,
3872 .fast_scalar_fsqrt,
3873 .fast_shld_rotate,
3874 .fast_variable_crosslane_shuffle,
3875 .fast_variable_perlane_shuffle,
3876 .fma,
3877 .fxsr,
3878 .idivq_to_divl,
3879 .lzcnt,
3880 .macrofusion,
3881 .mmx,
3882 .movbe,
3883 .nopl,
3884 .popcnt,
3885 .sahf,
3886 .slow_3ops_lea,
3887 .vzeroupper,
3888 .x87,
3889 .xsave,
3890 }),
3891 };
3892 pub const x86_64_v4 = CpuModel{
3893 .name = "x86_64_v4",
3894 .llvm_name = "x86-64-v4",
3895 .features = featureSet(&[_]Feature{
3896 .@"64bit",
3897 .allow_light_256_bit,
3898 .avx512bw,
3899 .avx512cd,
3900 .avx512dq,
3901 .avx512vl,
3902 .bmi,
3903 .bmi2,
3904 .cmov,
3905 .crc32,
3906 .cx16,
3907 .false_deps_popcnt,
3908 .fast_15bytenop,
3909 .fast_gather,
3910 .fast_scalar_fsqrt,
3911 .fast_shld_rotate,
3912 .fast_variable_crosslane_shuffle,
3913 .fast_variable_perlane_shuffle,
3914 .fast_vector_fsqrt,
3915 .fxsr,
3916 .idivq_to_divl,
3917 .lzcnt,
3918 .macrofusion,
3919 .mmx,
3920 .movbe,
3921 .nopl,
3922 .popcnt,
3923 .prefer_256_bit,
3924 .sahf,
3925 .slow_3ops_lea,
3926 .vzeroupper,
3927 .x87,
3928 .xsave,
3929 }),
3930 };
3931 pub const yonah = CpuModel{
3932 .name = "yonah",
3933 .llvm_name = "yonah",
3934 .features = featureSet(&[_]Feature{
3935 .cmov,
3936 .cx8,
3937 .fxsr,
3938 .mmx,
3939 .nopl,
3940 .slow_unaligned_mem_16,
3941 .sse3,
3942 .vzeroupper,
3943 .x87,
3944 }),
3945 };
3946 pub const znver1 = CpuModel{
3947 .name = "znver1",
3948 .llvm_name = "znver1",
3949 .features = featureSet(&[_]Feature{
3950 .@"64bit",
3951 .adx,
3952 .aes,
3953 .allow_light_256_bit,
3954 .avx2,
3955 .bmi,
3956 .bmi2,
3957 .branchfusion,
3958 .clflushopt,
3959 .clzero,
3960 .cmov,
3961 .crc32,
3962 .cx16,
3963 .f16c,
3964 .fast_15bytenop,
3965 .fast_bextr,
3966 .fast_lzcnt,
3967 .fast_movbe,
3968 .fast_scalar_fsqrt,
3969 .fast_scalar_shift_masks,
3970 .fast_variable_perlane_shuffle,
3971 .fast_vector_fsqrt,
3972 .fma,
3973 .fsgsbase,
3974 .fxsr,
3975 .lzcnt,
3976 .mmx,
3977 .movbe,
3978 .mwaitx,
3979 .nopl,
3980 .pclmul,
3981 .popcnt,
3982 .prfchw,
3983 .rdrnd,
3984 .rdseed,
3985 .sahf,
3986 .sbb_dep_breaking,
3987 .sha,
3988 .slow_shld,
3989 .sse4a,
3990 .vzeroupper,
3991 .x87,
3992 .xsavec,
3993 .xsaveopt,
3994 .xsaves,
3995 }),
3996 };
3997 pub const znver2 = CpuModel{
3998 .name = "znver2",
3999 .llvm_name = "znver2",
4000 .features = featureSet(&[_]Feature{
4001 .@"64bit",
4002 .adx,
4003 .aes,
4004 .allow_light_256_bit,
4005 .avx2,
4006 .bmi,
4007 .bmi2,
4008 .branchfusion,
4009 .clflushopt,
4010 .clwb,
4011 .clzero,
4012 .cmov,
4013 .crc32,
4014 .cx16,
4015 .f16c,
4016 .fast_15bytenop,
4017 .fast_bextr,
4018 .fast_lzcnt,
4019 .fast_movbe,
4020 .fast_scalar_fsqrt,
4021 .fast_scalar_shift_masks,
4022 .fast_variable_perlane_shuffle,
4023 .fast_vector_fsqrt,
4024 .fma,
4025 .fsgsbase,
4026 .fxsr,
4027 .lzcnt,
4028 .mmx,
4029 .movbe,
4030 .mwaitx,
4031 .nopl,
4032 .pclmul,
4033 .popcnt,
4034 .prfchw,
4035 .rdpid,
4036 .rdpru,
4037 .rdrnd,
4038 .rdseed,
4039 .sahf,
4040 .sbb_dep_breaking,
4041 .sha,
4042 .slow_shld,
4043 .sse4a,
4044 .vzeroupper,
4045 .wbnoinvd,
4046 .x87,
4047 .xsavec,
4048 .xsaveopt,
4049 .xsaves,
4050 }),
4051 };
4052 pub const znver3 = CpuModel{
4053 .name = "znver3",
4054 .llvm_name = "znver3",
4055 .features = featureSet(&[_]Feature{
4056 .@"64bit",
4057 .adx,
4058 .allow_light_256_bit,
4059 .avx2,
4060 .bmi,
4061 .bmi2,
4062 .branchfusion,
4063 .clflushopt,
4064 .clwb,
4065 .clzero,
4066 .cmov,
4067 .crc32,
4068 .cx16,
4069 .f16c,
4070 .fast_15bytenop,
4071 .fast_bextr,
4072 .fast_lzcnt,
4073 .fast_movbe,
4074 .fast_scalar_fsqrt,
4075 .fast_scalar_shift_masks,
4076 .fast_variable_perlane_shuffle,
4077 .fast_vector_fsqrt,
4078 .fma,
4079 .fsgsbase,
4080 .fsrm,
4081 .fxsr,
4082 .invpcid,
4083 .lzcnt,
4084 .macrofusion,
4085 .mmx,
4086 .movbe,
4087 .mwaitx,
4088 .nopl,
4089 .pku,
4090 .popcnt,
4091 .prfchw,
4092 .rdpid,
4093 .rdpru,
4094 .rdrnd,
4095 .rdseed,
4096 .sahf,
4097 .sbb_dep_breaking,
4098 .sha,
4099 .slow_shld,
4100 .sse4a,
4101 .vaes,
4102 .vpclmulqdq,
4103 .vzeroupper,
4104 .wbnoinvd,
4105 .x87,
4106 .xsavec,
4107 .xsaveopt,
4108 .xsaves,
4109 }),
4110 };
4111 pub const znver4 = CpuModel{
4112 .name = "znver4",
4113 .llvm_name = "znver4",
4114 .features = featureSet(&[_]Feature{
4115 .@"64bit",
4116 .adx,
4117 .allow_light_256_bit,
4118 .avx512bf16,
4119 .avx512bitalg,
4120 .avx512cd,
4121 .avx512dq,
4122 .avx512ifma,
4123 .avx512vbmi,
4124 .avx512vbmi2,
4125 .avx512vl,
4126 .avx512vnni,
4127 .avx512vpopcntdq,
4128 .bmi,
4129 .bmi2,
4130 .branchfusion,
4131 .clflushopt,
4132 .clwb,
4133 .clzero,
4134 .cmov,
4135 .crc32,
4136 .cx16,
4137 .fast_15bytenop,
4138 .fast_bextr,
4139 .fast_lzcnt,
4140 .fast_movbe,
4141 .fast_scalar_fsqrt,
4142 .fast_scalar_shift_masks,
4143 .fast_variable_perlane_shuffle,
4144 .fast_vector_fsqrt,
4145 .fsgsbase,
4146 .fsrm,
4147 .fxsr,
4148 .gfni,
4149 .invpcid,
4150 .lzcnt,
4151 .macrofusion,
4152 .mmx,
4153 .movbe,
4154 .mwaitx,
4155 .nopl,
4156 .pku,
4157 .popcnt,
4158 .prfchw,
4159 .rdpid,
4160 .rdpru,
4161 .rdrnd,
4162 .rdseed,
4163 .sahf,
4164 .sbb_dep_breaking,
4165 .sha,
4166 .shstk,
4167 .slow_shld,
4168 .sse4a,
4169 .vaes,
4170 .vpclmulqdq,
4171 .vzeroupper,
4172 .wbnoinvd,
4173 .x87,
4174 .xsavec,
4175 .xsaveopt,
4176 .xsaves,
4177 }),
4178 };
4179};
lib/std/Target/xtensa.zig created+39
......@@ -0,0 +1,39 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 density,
9};
10
11pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
12pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
13pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
14pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
15
16pub const all_features = blk: {
17 const len = @typeInfo(Feature).Enum.fields.len;
18 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
19 var result: [len]CpuFeature = undefined;
20 result[@intFromEnum(Feature.density)] = .{
21 .llvm_name = "density",
22 .description = "Enable Density instructions",
23 .dependencies = featureSet(&[_]Feature{}),
24 };
25 const ti = @typeInfo(Feature);
26 for (&result, 0..) |*elem, i| {
27 elem.index = i;
28 elem.name = ti.Enum.fields[i].name;
29 }
30 break :blk result;
31};
32
33pub const cpu = struct {
34 pub const generic = CpuModel{
35 .name = "generic",
36 .llvm_name = "generic",
37 .features = featureSet(&[_]Feature{}),
38 };
39};
lib/std/Uri.zig+6-6
......@@ -6,13 +6,13 @@ const std = @import("std.zig");
66const testing = std.testing;
77
88scheme: []const u8,
9user: ?[]const u8,
10password: ?[]const u8,
11host: ?[]const u8,
12port: ?u16,
9user: ?[]const u8 = null,
10password: ?[]const u8 = null,
11host: ?[]const u8 = null,
12port: ?u16 = null,
1313path: []const u8,
14query: ?[]const u8,
15fragment: ?[]const u8,
14query: ?[]const u8 = null,
15fragment: ?[]const u8 = null,
1616
1717/// Applies URI encoding and replaces all reserved characters with their respective %XX code.
1818pub fn escapeString(allocator: std.mem.Allocator, input: []const u8) error{OutOfMemory}![]u8 {
lib/std/fs/AtomicFile.zig+4
......@@ -65,6 +65,10 @@ pub fn deinit(self: *AtomicFile) void {
6565
6666pub const FinishError = posix.RenameError;
6767
68/// On Windows, this function introduces a period of time where some file
69/// system operations on the destination file will result in
70/// `error.AccessDenied`, including rename operations (such as the one used in
71/// this function).
6872pub fn finish(self: *AtomicFile) FinishError!void {
6973 assert(self.file_exists);
7074 if (self.file_open) {
lib/std/fs/Dir.zig+11-5
......@@ -2416,15 +2416,21 @@ fn copy_file(fd_in: posix.fd_t, fd_out: posix.fd_t, maybe_size: ?u64) CopyFileRa
24162416
24172417pub const AtomicFileOptions = struct {
24182418 mode: File.Mode = File.default_mode,
2419 make_path: bool = false,
24192420};
24202421
2421/// Directly access the `.file` field, and then call `AtomicFile.finish`
2422/// to atomically replace `dest_path` with contents.
2423/// Always call `AtomicFile.deinit` to clean up, regardless of whether `AtomicFile.finish` succeeded.
2424/// `dest_path` must remain valid until `AtomicFile.deinit` is called.
2422/// Directly access the `.file` field, and then call `AtomicFile.finish` to
2423/// atomically replace `dest_path` with contents.
2424/// Always call `AtomicFile.deinit` to clean up, regardless of whether
2425/// `AtomicFile.finish` succeeded. `dest_path` must remain valid until
2426/// `AtomicFile.deinit` is called.
24252427pub fn atomicFile(self: Dir, dest_path: []const u8, options: AtomicFileOptions) !AtomicFile {
24262428 if (fs.path.dirname(dest_path)) |dirname| {
2427 const dir = try self.openDir(dirname, .{});
2429 const dir = if (options.make_path)
2430 try self.makeOpenPath(dirname, .{})
2431 else
2432 try self.openDir(dirname, .{});
2433
24282434 return AtomicFile.init(fs.path.basename(dest_path), options.mode, dir, true);
24292435 } else {
24302436 return AtomicFile.init(dest_path, options.mode, self, false);
lib/std/os/test.zig+5
......@@ -752,6 +752,11 @@ test "fsync" {
752752}
753753
754754test "getrlimit and setrlimit" {
755 if (builtin.target.os.tag == .macos) {
756 // https://github.com/ziglang/zig/issues/18395
757 return error.SkipZigTest;
758 }
759
755760 if (!@hasDecl(os.system, "rlimit")) {
756761 return error.SkipZigTest;
757762 }
lib/std/std.zig+1-4
......@@ -47,7 +47,7 @@ pub const StringArrayHashMap = array_hash_map.StringArrayHashMap;
4747pub const StringArrayHashMapUnmanaged = array_hash_map.StringArrayHashMapUnmanaged;
4848/// deprecated: use `DoublyLinkedList`.
4949pub const TailQueue = DoublyLinkedList;
50pub const Target = @import("target.zig").Target;
50pub const Target = @import("Target.zig");
5151pub const Thread = @import("Thread.zig");
5252pub const Treap = @import("treap.zig").Treap;
5353pub const Tz = tz.Tz;
......@@ -194,9 +194,6 @@ pub const zig = @import("zig.zig");
194194
195195pub const start = @import("start.zig");
196196
197/// deprecated: use `Build`.
198pub const build = Build;
199
200197const root = @import("root");
201198const options_override = if (@hasDecl(root, "std_options")) root.std_options else struct {};
202199
lib/std/target.zig deleted-2608
......@@ -1,2608 +0,0 @@
1const std = @import("std.zig");
2const builtin = @import("builtin");
3const mem = std.mem;
4const Version = std.SemanticVersion;
5
6pub const Target = struct {
7 cpu: Cpu,
8 os: Os,
9 abi: Abi,
10 ofmt: ObjectFormat,
11
12 pub const Os = struct {
13 tag: Tag,
14 version_range: VersionRange,
15
16 pub const Tag = enum {
17 freestanding,
18 ananas,
19 cloudabi,
20 dragonfly,
21 freebsd,
22 fuchsia,
23 ios,
24 kfreebsd,
25 linux,
26 lv2,
27 macos,
28 netbsd,
29 openbsd,
30 solaris,
31 uefi,
32 windows,
33 zos,
34 haiku,
35 minix,
36 rtems,
37 nacl,
38 aix,
39 cuda,
40 nvcl,
41 amdhsa,
42 ps4,
43 ps5,
44 elfiamcu,
45 tvos,
46 watchos,
47 driverkit,
48 mesa3d,
49 contiki,
50 amdpal,
51 hermit,
52 hurd,
53 wasi,
54 emscripten,
55 shadermodel,
56 liteos,
57 opencl,
58 glsl450,
59 vulkan,
60 plan9,
61 illumos,
62 other,
63
64 pub inline fn isDarwin(tag: Tag) bool {
65 return switch (tag) {
66 .ios, .macos, .watchos, .tvos => true,
67 else => false,
68 };
69 }
70
71 pub inline fn isBSD(tag: Tag) bool {
72 return tag.isDarwin() or switch (tag) {
73 .kfreebsd, .freebsd, .openbsd, .netbsd, .dragonfly => true,
74 else => false,
75 };
76 }
77
78 pub inline fn isSolarish(tag: Tag) bool {
79 return tag == .solaris or tag == .illumos;
80 }
81
82 pub fn dynamicLibSuffix(tag: Tag) [:0]const u8 {
83 if (tag.isDarwin()) {
84 return ".dylib";
85 }
86 switch (tag) {
87 .windows => return ".dll",
88 else => return ".so",
89 }
90 }
91
92 pub fn defaultVersionRange(tag: Tag, arch: Cpu.Arch) Os {
93 return .{
94 .tag = tag,
95 .version_range = VersionRange.default(tag, arch),
96 };
97 }
98 };
99
100 /// Based on NTDDI version constants from
101 /// https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
102 pub const WindowsVersion = enum(u32) {
103 nt4 = 0x04000000,
104 win2k = 0x05000000,
105 xp = 0x05010000,
106 ws2003 = 0x05020000,
107 vista = 0x06000000,
108 win7 = 0x06010000,
109 win8 = 0x06020000,
110 win8_1 = 0x06030000,
111 win10 = 0x0A000000, //aka win10_th1
112 win10_th2 = 0x0A000001,
113 win10_rs1 = 0x0A000002,
114 win10_rs2 = 0x0A000003,
115 win10_rs3 = 0x0A000004,
116 win10_rs4 = 0x0A000005,
117 win10_rs5 = 0x0A000006,
118 win10_19h1 = 0x0A000007,
119 win10_vb = 0x0A000008, //aka win10_19h2
120 win10_mn = 0x0A000009, //aka win10_20h1
121 win10_fe = 0x0A00000A, //aka win10_20h2
122 _,
123
124 /// Latest Windows version that the Zig Standard Library is aware of
125 pub const latest = WindowsVersion.win10_fe;
126
127 /// Compared against build numbers reported by the runtime to distinguish win10 versions,
128 /// where 0x0A000000 + index corresponds to the WindowsVersion u32 value.
129 pub const known_win10_build_numbers = [_]u32{
130 10240, //win10 aka win10_th1
131 10586, //win10_th2
132 14393, //win10_rs1
133 15063, //win10_rs2
134 16299, //win10_rs3
135 17134, //win10_rs4
136 17763, //win10_rs5
137 18362, //win10_19h1
138 18363, //win10_vb aka win10_19h2
139 19041, //win10_mn aka win10_20h1
140 19042, //win10_fe aka win10_20h2
141 };
142
143 /// Returns whether the first version `self` is newer (greater) than or equal to the second version `ver`.
144 pub inline fn isAtLeast(self: WindowsVersion, ver: WindowsVersion) bool {
145 return @intFromEnum(self) >= @intFromEnum(ver);
146 }
147
148 pub const Range = struct {
149 min: WindowsVersion,
150 max: WindowsVersion,
151
152 pub inline fn includesVersion(self: Range, ver: WindowsVersion) bool {
153 return @intFromEnum(ver) >= @intFromEnum(self.min) and @intFromEnum(ver) <= @intFromEnum(self.max);
154 }
155
156 /// Checks if system is guaranteed to be at least `version` or older than `version`.
157 /// Returns `null` if a runtime check is required.
158 pub inline fn isAtLeast(self: Range, ver: WindowsVersion) ?bool {
159 if (@intFromEnum(self.min) >= @intFromEnum(ver)) return true;
160 if (@intFromEnum(self.max) < @intFromEnum(ver)) return false;
161 return null;
162 }
163 };
164
165 /// This function is defined to serialize a Zig source code representation of this
166 /// type, that, when parsed, will deserialize into the same data.
167 pub fn format(
168 self: WindowsVersion,
169 comptime fmt: []const u8,
170 _: std.fmt.FormatOptions,
171 out_stream: anytype,
172 ) !void {
173 if (comptime std.mem.eql(u8, fmt, "s")) {
174 if (@intFromEnum(self) >= @intFromEnum(WindowsVersion.nt4) and @intFromEnum(self) <= @intFromEnum(WindowsVersion.latest)) {
175 try std.fmt.format(out_stream, ".{s}", .{@tagName(self)});
176 } else {
177 // TODO this code path breaks zig triples, but it is used in `builtin`
178 try std.fmt.format(out_stream, "@enumFromInt(Target.Os.WindowsVersion, 0x{X:0>8})", .{@intFromEnum(self)});
179 }
180 } else if (fmt.len == 0) {
181 if (@intFromEnum(self) >= @intFromEnum(WindowsVersion.nt4) and @intFromEnum(self) <= @intFromEnum(WindowsVersion.latest)) {
182 try std.fmt.format(out_stream, "WindowsVersion.{s}", .{@tagName(self)});
183 } else {
184 try std.fmt.format(out_stream, "WindowsVersion(0x{X:0>8})", .{@intFromEnum(self)});
185 }
186 } else {
187 std.fmt.invalidFmtError(fmt, self);
188 }
189 }
190 };
191
192 pub const LinuxVersionRange = struct {
193 range: Version.Range,
194 glibc: Version,
195
196 pub inline fn includesVersion(self: LinuxVersionRange, ver: Version) bool {
197 return self.range.includesVersion(ver);
198 }
199
200 /// Checks if system is guaranteed to be at least `version` or older than `version`.
201 /// Returns `null` if a runtime check is required.
202 pub inline fn isAtLeast(self: LinuxVersionRange, ver: Version) ?bool {
203 return self.range.isAtLeast(ver);
204 }
205 };
206
207 /// The version ranges here represent the minimum OS version to be supported
208 /// and the maximum OS version to be supported. The default values represent
209 /// the range that the Zig Standard Library bases its abstractions on.
210 ///
211 /// The minimum version of the range is the main setting to tweak for a target.
212 /// Usually, the maximum target OS version will remain the default, which is
213 /// the latest released version of the OS.
214 ///
215 /// To test at compile time if the target is guaranteed to support a given OS feature,
216 /// one should check that the minimum version of the range is greater than or equal to
217 /// the version the feature was introduced in.
218 ///
219 /// To test at compile time if the target certainly will not support a given OS feature,
220 /// one should check that the maximum version of the range is less than the version the
221 /// feature was introduced in.
222 ///
223 /// If neither of these cases apply, a runtime check should be used to determine if the
224 /// target supports a given OS feature.
225 ///
226 /// Binaries built with a given maximum version will continue to function on newer
227 /// operating system versions. However, such a binary may not take full advantage of the
228 /// newer operating system APIs.
229 ///
230 /// See `Os.isAtLeast`.
231 pub const VersionRange = union {
232 none: void,
233 semver: Version.Range,
234 linux: LinuxVersionRange,
235 windows: WindowsVersion.Range,
236
237 /// The default `VersionRange` represents the range that the Zig Standard Library
238 /// bases its abstractions on.
239 pub fn default(tag: Tag, arch: Cpu.Arch) VersionRange {
240 switch (tag) {
241 .freestanding,
242 .ananas,
243 .cloudabi,
244 .fuchsia,
245 .kfreebsd,
246 .lv2,
247 .zos,
248 .haiku,
249 .minix,
250 .rtems,
251 .nacl,
252 .aix,
253 .cuda,
254 .nvcl,
255 .amdhsa,
256 .ps4,
257 .ps5,
258 .elfiamcu,
259 .mesa3d,
260 .contiki,
261 .amdpal,
262 .hermit,
263 .hurd,
264 .wasi,
265 .emscripten,
266 .driverkit,
267 .shadermodel,
268 .liteos,
269 .uefi,
270 .opencl, // TODO: OpenCL versions
271 .glsl450, // TODO: GLSL versions
272 .vulkan,
273 .plan9,
274 .illumos,
275 .other,
276 => return .{ .none = {} },
277
278 .freebsd => return .{
279 .semver = Version.Range{
280 .min = .{ .major = 12, .minor = 0, .patch = 0 },
281 .max = .{ .major = 14, .minor = 0, .patch = 0 },
282 },
283 },
284 .macos => return switch (arch) {
285 .aarch64 => VersionRange{
286 .semver = .{
287 .min = .{ .major = 11, .minor = 7, .patch = 1 },
288 .max = .{ .major = 14, .minor = 1, .patch = 0 },
289 },
290 },
291 .x86_64 => VersionRange{
292 .semver = .{
293 .min = .{ .major = 11, .minor = 7, .patch = 1 },
294 .max = .{ .major = 14, .minor = 1, .patch = 0 },
295 },
296 },
297 else => unreachable,
298 },
299 .ios => return .{
300 .semver = .{
301 .min = .{ .major = 12, .minor = 0, .patch = 0 },
302 .max = .{ .major = 17, .minor = 1, .patch = 0 },
303 },
304 },
305 .watchos => return .{
306 .semver = .{
307 .min = .{ .major = 6, .minor = 0, .patch = 0 },
308 .max = .{ .major = 10, .minor = 1, .patch = 0 },
309 },
310 },
311 .tvos => return .{
312 .semver = .{
313 .min = .{ .major = 13, .minor = 0, .patch = 0 },
314 .max = .{ .major = 17, .minor = 1, .patch = 0 },
315 },
316 },
317 .netbsd => return .{
318 .semver = .{
319 .min = .{ .major = 8, .minor = 0, .patch = 0 },
320 .max = .{ .major = 10, .minor = 0, .patch = 0 },
321 },
322 },
323 .openbsd => return .{
324 .semver = .{
325 .min = .{ .major = 6, .minor = 8, .patch = 0 },
326 .max = .{ .major = 7, .minor = 4, .patch = 0 },
327 },
328 },
329 .dragonfly => return .{
330 .semver = .{
331 .min = .{ .major = 5, .minor = 8, .patch = 0 },
332 .max = .{ .major = 6, .minor = 4, .patch = 0 },
333 },
334 },
335 .solaris => return .{
336 .semver = .{
337 .min = .{ .major = 5, .minor = 11, .patch = 0 },
338 .max = .{ .major = 5, .minor = 11, .patch = 0 },
339 },
340 },
341
342 .linux => return .{
343 .linux = .{
344 .range = .{
345 .min = .{ .major = 4, .minor = 19, .patch = 0 },
346 .max = .{ .major = 6, .minor = 5, .patch = 7 },
347 },
348 .glibc = .{ .major = 2, .minor = 28, .patch = 0 },
349 },
350 },
351
352 .windows => return .{
353 .windows = .{
354 .min = .win8_1,
355 .max = WindowsVersion.latest,
356 },
357 },
358 }
359 }
360 };
361
362 pub const TaggedVersionRange = union(enum) {
363 none: void,
364 semver: Version.Range,
365 linux: LinuxVersionRange,
366 windows: WindowsVersion.Range,
367 };
368
369 /// Provides a tagged union. `Target` does not store the tag because it is
370 /// redundant with the OS tag; this function abstracts that part away.
371 pub inline fn getVersionRange(self: Os) TaggedVersionRange {
372 switch (self.tag) {
373 .linux => return TaggedVersionRange{ .linux = self.version_range.linux },
374 .windows => return TaggedVersionRange{ .windows = self.version_range.windows },
375
376 .freebsd,
377 .macos,
378 .ios,
379 .tvos,
380 .watchos,
381 .netbsd,
382 .openbsd,
383 .dragonfly,
384 .solaris,
385 => return TaggedVersionRange{ .semver = self.version_range.semver },
386
387 else => return .none,
388 }
389 }
390
391 /// Checks if system is guaranteed to be at least `version` or older than `version`.
392 /// Returns `null` if a runtime check is required.
393 pub inline fn isAtLeast(self: Os, comptime tag: Tag, version: anytype) ?bool {
394 if (self.tag != tag) return false;
395
396 return switch (tag) {
397 .linux => self.version_range.linux.isAtLeast(version),
398 .windows => self.version_range.windows.isAtLeast(version),
399 else => self.version_range.semver.isAtLeast(version),
400 };
401 }
402
403 /// On Darwin, we always link libSystem which contains libc.
404 /// Similarly on FreeBSD and NetBSD we always link system libc
405 /// since this is the stable syscall interface.
406 pub fn requiresLibC(os: Os) bool {
407 return switch (os.tag) {
408 .freebsd,
409 .netbsd,
410 .macos,
411 .ios,
412 .tvos,
413 .watchos,
414 .dragonfly,
415 .openbsd,
416 .haiku,
417 .solaris,
418 .illumos,
419 => true,
420
421 .linux,
422 .windows,
423 .freestanding,
424 .ananas,
425 .cloudabi,
426 .fuchsia,
427 .kfreebsd,
428 .lv2,
429 .zos,
430 .minix,
431 .rtems,
432 .nacl,
433 .aix,
434 .cuda,
435 .nvcl,
436 .amdhsa,
437 .ps4,
438 .ps5,
439 .elfiamcu,
440 .mesa3d,
441 .contiki,
442 .amdpal,
443 .hermit,
444 .hurd,
445 .wasi,
446 .emscripten,
447 .driverkit,
448 .shadermodel,
449 .liteos,
450 .uefi,
451 .opencl,
452 .glsl450,
453 .vulkan,
454 .plan9,
455 .other,
456 => false,
457 };
458 }
459 };
460
461 pub const aarch64 = @import("target/aarch64.zig");
462 pub const arc = @import("target/arc.zig");
463 pub const amdgpu = @import("target/amdgpu.zig");
464 pub const arm = @import("target/arm.zig");
465 pub const avr = @import("target/avr.zig");
466 pub const bpf = @import("target/bpf.zig");
467 pub const csky = @import("target/csky.zig");
468 pub const hexagon = @import("target/hexagon.zig");
469 pub const loongarch = @import("target/loongarch.zig");
470 pub const m68k = @import("target/m68k.zig");
471 pub const mips = @import("target/mips.zig");
472 pub const msp430 = @import("target/msp430.zig");
473 pub const nvptx = @import("target/nvptx.zig");
474 pub const powerpc = @import("target/powerpc.zig");
475 pub const riscv = @import("target/riscv.zig");
476 pub const sparc = @import("target/sparc.zig");
477 pub const spirv = @import("target/spirv.zig");
478 pub const s390x = @import("target/s390x.zig");
479 pub const ve = @import("target/ve.zig");
480 pub const wasm = @import("target/wasm.zig");
481 pub const x86 = @import("target/x86.zig");
482 pub const xtensa = @import("target/xtensa.zig");
483
484 pub const Abi = enum {
485 none,
486 gnu,
487 gnuabin32,
488 gnuabi64,
489 gnueabi,
490 gnueabihf,
491 gnuf32,
492 gnuf64,
493 gnusf,
494 gnux32,
495 gnuilp32,
496 code16,
497 eabi,
498 eabihf,
499 android,
500 musl,
501 musleabi,
502 musleabihf,
503 muslx32,
504 msvc,
505 itanium,
506 cygnus,
507 coreclr,
508 simulator,
509 macabi,
510 pixel,
511 vertex,
512 geometry,
513 hull,
514 domain,
515 compute,
516 library,
517 raygeneration,
518 intersection,
519 anyhit,
520 closesthit,
521 miss,
522 callable,
523 mesh,
524 amplification,
525
526 pub fn default(arch: Cpu.Arch, target_os: Os) Abi {
527 if (arch.isWasm()) {
528 return .musl;
529 }
530 switch (target_os.tag) {
531 .freestanding,
532 .ananas,
533 .cloudabi,
534 .dragonfly,
535 .lv2,
536 .zos,
537 .minix,
538 .rtems,
539 .nacl,
540 .aix,
541 .cuda,
542 .nvcl,
543 .amdhsa,
544 .ps4,
545 .ps5,
546 .elfiamcu,
547 .mesa3d,
548 .contiki,
549 .amdpal,
550 .hermit,
551 .other,
552 => return .eabi,
553 .openbsd,
554 .freebsd,
555 .fuchsia,
556 .kfreebsd,
557 .netbsd,
558 .hurd,
559 .haiku,
560 .windows,
561 => return .gnu,
562 .uefi => return .msvc,
563 .linux,
564 .wasi,
565 .emscripten,
566 => return .musl,
567 .opencl, // TODO: SPIR-V ABIs with Linkage capability
568 .glsl450,
569 .vulkan,
570 .plan9, // TODO specify abi
571 .macos,
572 .ios,
573 .tvos,
574 .watchos,
575 .driverkit,
576 .shadermodel,
577 .liteos, // TODO: audit this
578 .solaris,
579 .illumos,
580 => return .none,
581 }
582 }
583
584 pub inline fn isGnu(abi: Abi) bool {
585 return switch (abi) {
586 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true,
587 else => false,
588 };
589 }
590
591 pub inline fn isMusl(abi: Abi) bool {
592 return switch (abi) {
593 .musl, .musleabi, .musleabihf => true,
594 else => false,
595 };
596 }
597
598 pub inline fn floatAbi(abi: Abi) FloatAbi {
599 return switch (abi) {
600 .gnueabihf,
601 .eabihf,
602 .musleabihf,
603 => .hard,
604 else => .soft,
605 };
606 }
607 };
608
609 pub const ObjectFormat = enum {
610 /// Common Object File Format (Windows)
611 coff,
612 /// DirectX Container
613 dxcontainer,
614 /// Executable and Linking Format
615 elf,
616 /// macOS relocatables
617 macho,
618 /// Standard, Portable Intermediate Representation V
619 spirv,
620 /// WebAssembly
621 wasm,
622 /// C source code
623 c,
624 /// Intel IHEX
625 hex,
626 /// Machine code with no metadata.
627 raw,
628 /// Plan 9 from Bell Labs
629 plan9,
630 /// Nvidia PTX format
631 nvptx,
632
633 pub fn fileExt(of: ObjectFormat, cpu_arch: Cpu.Arch) [:0]const u8 {
634 return switch (of) {
635 .coff => ".obj",
636 .elf, .macho, .wasm => ".o",
637 .c => ".c",
638 .spirv => ".spv",
639 .hex => ".ihex",
640 .raw => ".bin",
641 .plan9 => plan9Ext(cpu_arch),
642 .nvptx => ".ptx",
643 .dxcontainer => ".dxil",
644 };
645 }
646
647 pub fn default(os_tag: Os.Tag, cpu_arch: Cpu.Arch) ObjectFormat {
648 return switch (os_tag) {
649 .windows, .uefi => .coff,
650 .ios, .macos, .watchos, .tvos => .macho,
651 .plan9 => .plan9,
652 else => return switch (cpu_arch) {
653 .wasm32, .wasm64 => .wasm,
654 .spirv32, .spirv64 => .spirv,
655 .nvptx, .nvptx64 => .nvptx,
656 else => .elf,
657 },
658 };
659 }
660 };
661
662 pub const SubSystem = enum {
663 Console,
664 Windows,
665 Posix,
666 Native,
667 EfiApplication,
668 EfiBootServiceDriver,
669 EfiRom,
670 EfiRuntimeDriver,
671 };
672
673 pub const Cpu = struct {
674 /// Architecture
675 arch: Arch,
676
677 /// The CPU model to target. It has a set of features
678 /// which are overridden with the `features` field.
679 model: *const Model,
680
681 /// An explicit list of the entire CPU feature set. It may differ from the specific CPU model's features.
682 features: Feature.Set,
683
684 pub const Feature = struct {
685 /// The bit index into `Set`. Has a default value of `undefined` because the canonical
686 /// structures are populated via comptime logic.
687 index: Set.Index = undefined,
688
689 /// Has a default value of `undefined` because the canonical
690 /// structures are populated via comptime logic.
691 name: []const u8 = undefined,
692
693 /// If this corresponds to an LLVM-recognized feature, this will be populated;
694 /// otherwise null.
695 llvm_name: ?[:0]const u8,
696
697 /// Human-friendly UTF-8 text.
698 description: []const u8,
699
700 /// Sparse `Set` of features this depends on.
701 dependencies: Set,
702
703 /// A bit set of all the features.
704 pub const Set = struct {
705 ints: [usize_count]usize,
706
707 pub const needed_bit_count = 288;
708 pub const byte_count = (needed_bit_count + 7) / 8;
709 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
710 pub const Index = std.math.Log2Int(std.meta.Int(.unsigned, usize_count * @bitSizeOf(usize)));
711 pub const ShiftInt = std.math.Log2Int(usize);
712
713 pub const empty = Set{ .ints = [1]usize{0} ** usize_count };
714
715 pub fn isEmpty(set: Set) bool {
716 return for (set.ints) |x| {
717 if (x != 0) break false;
718 } else true;
719 }
720
721 pub fn isEnabled(set: Set, arch_feature_index: Index) bool {
722 const usize_index = arch_feature_index / @bitSizeOf(usize);
723 const bit_index = @as(ShiftInt, @intCast(arch_feature_index % @bitSizeOf(usize)));
724 return (set.ints[usize_index] & (@as(usize, 1) << bit_index)) != 0;
725 }
726
727 /// Adds the specified feature but not its dependencies.
728 pub fn addFeature(set: *Set, arch_feature_index: Index) void {
729 const usize_index = arch_feature_index / @bitSizeOf(usize);
730 const bit_index = @as(ShiftInt, @intCast(arch_feature_index % @bitSizeOf(usize)));
731 set.ints[usize_index] |= @as(usize, 1) << bit_index;
732 }
733
734 /// Adds the specified feature set but not its dependencies.
735 pub fn addFeatureSet(set: *Set, other_set: Set) void {
736 switch (builtin.zig_backend) {
737 .stage2_x86_64 => {
738 for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* |= other_set_int;
739 },
740 else => {
741 set.ints = @as(@Vector(usize_count, usize), set.ints) | @as(@Vector(usize_count, usize), other_set.ints);
742 },
743 }
744 }
745
746 /// Removes the specified feature but not its dependents.
747 pub fn removeFeature(set: *Set, arch_feature_index: Index) void {
748 const usize_index = arch_feature_index / @bitSizeOf(usize);
749 const bit_index = @as(ShiftInt, @intCast(arch_feature_index % @bitSizeOf(usize)));
750 set.ints[usize_index] &= ~(@as(usize, 1) << bit_index);
751 }
752
753 /// Removes the specified feature but not its dependents.
754 pub fn removeFeatureSet(set: *Set, other_set: Set) void {
755 switch (builtin.zig_backend) {
756 .stage2_x86_64 => {
757 for (&set.ints, other_set.ints) |*set_int, other_set_int| set_int.* &= ~other_set_int;
758 },
759 else => {
760 set.ints = @as(@Vector(usize_count, usize), set.ints) & ~@as(@Vector(usize_count, usize), other_set.ints);
761 },
762 }
763 }
764
765 pub fn populateDependencies(set: *Set, all_features_list: []const Cpu.Feature) void {
766 @setEvalBranchQuota(1000000);
767
768 var old = set.ints;
769 while (true) {
770 for (all_features_list, 0..) |feature, index_usize| {
771 const index = @as(Index, @intCast(index_usize));
772 if (set.isEnabled(index)) {
773 set.addFeatureSet(feature.dependencies);
774 }
775 }
776 const nothing_changed = mem.eql(usize, &old, &set.ints);
777 if (nothing_changed) return;
778 old = set.ints;
779 }
780 }
781
782 pub fn asBytes(set: *const Set) *const [byte_count]u8 {
783 return @as(*const [byte_count]u8, @ptrCast(&set.ints));
784 }
785
786 pub fn eql(set: Set, other_set: Set) bool {
787 return mem.eql(usize, &set.ints, &other_set.ints);
788 }
789
790 pub fn isSuperSetOf(set: Set, other_set: Set) bool {
791 switch (builtin.zig_backend) {
792 .stage2_x86_64 => {
793 var result = true;
794 for (&set.ints, other_set.ints) |*set_int, other_set_int|
795 result = result and (set_int.* & other_set_int) == other_set_int;
796 return result;
797 },
798 else => {
799 const V = @Vector(usize_count, usize);
800 const set_v: V = set.ints;
801 const other_v: V = other_set.ints;
802 return @reduce(.And, (set_v & other_v) == other_v);
803 },
804 }
805 }
806 };
807
808 pub fn feature_set_fns(comptime F: type) type {
809 return struct {
810 /// Populates only the feature bits specified.
811 pub fn featureSet(features: []const F) Set {
812 var x = Set.empty;
813 for (features) |feature| {
814 x.addFeature(@intFromEnum(feature));
815 }
816 return x;
817 }
818
819 /// Returns true if the specified feature is enabled.
820 pub fn featureSetHas(set: Set, feature: F) bool {
821 return set.isEnabled(@intFromEnum(feature));
822 }
823
824 /// Returns true if any specified feature is enabled.
825 pub fn featureSetHasAny(set: Set, features: anytype) bool {
826 inline for (features) |feature| {
827 if (set.isEnabled(@intFromEnum(@as(F, feature)))) return true;
828 }
829 return false;
830 }
831
832 /// Returns true if every specified feature is enabled.
833 pub fn featureSetHasAll(set: Set, features: anytype) bool {
834 inline for (features) |feature| {
835 if (!set.isEnabled(@intFromEnum(@as(F, feature)))) return false;
836 }
837 return true;
838 }
839 };
840 }
841 };
842
843 pub const Arch = enum {
844 arm,
845 armeb,
846 aarch64,
847 aarch64_be,
848 aarch64_32,
849 arc,
850 avr,
851 bpfel,
852 bpfeb,
853 csky,
854 dxil,
855 hexagon,
856 loongarch32,
857 loongarch64,
858 m68k,
859 mips,
860 mipsel,
861 mips64,
862 mips64el,
863 msp430,
864 powerpc,
865 powerpcle,
866 powerpc64,
867 powerpc64le,
868 r600,
869 amdgcn,
870 riscv32,
871 riscv64,
872 sparc,
873 sparc64,
874 sparcel,
875 s390x,
876 tce,
877 tcele,
878 thumb,
879 thumbeb,
880 x86,
881 x86_64,
882 xcore,
883 xtensa,
884 nvptx,
885 nvptx64,
886 le32,
887 le64,
888 amdil,
889 amdil64,
890 hsail,
891 hsail64,
892 spir,
893 spir64,
894 spirv32,
895 spirv64,
896 kalimba,
897 shave,
898 lanai,
899 wasm32,
900 wasm64,
901 renderscript32,
902 renderscript64,
903 ve,
904 // Stage1 currently assumes that architectures above this comment
905 // map one-to-one with the ZigLLVM_ArchType enum.
906 spu_2,
907
908 pub inline fn isX86(arch: Arch) bool {
909 return switch (arch) {
910 .x86, .x86_64 => true,
911 else => false,
912 };
913 }
914
915 pub inline fn isARM(arch: Arch) bool {
916 return switch (arch) {
917 .arm, .armeb => true,
918 else => false,
919 };
920 }
921
922 pub inline fn isAARCH64(arch: Arch) bool {
923 return switch (arch) {
924 .aarch64, .aarch64_be, .aarch64_32 => true,
925 else => false,
926 };
927 }
928
929 pub inline fn isThumb(arch: Arch) bool {
930 return switch (arch) {
931 .thumb, .thumbeb => true,
932 else => false,
933 };
934 }
935
936 pub inline fn isArmOrThumb(arch: Arch) bool {
937 return arch.isARM() or arch.isThumb();
938 }
939
940 pub inline fn isWasm(arch: Arch) bool {
941 return switch (arch) {
942 .wasm32, .wasm64 => true,
943 else => false,
944 };
945 }
946
947 pub inline fn isRISCV(arch: Arch) bool {
948 return switch (arch) {
949 .riscv32, .riscv64 => true,
950 else => false,
951 };
952 }
953
954 pub inline fn isMIPS(arch: Arch) bool {
955 return switch (arch) {
956 .mips, .mipsel, .mips64, .mips64el => true,
957 else => false,
958 };
959 }
960
961 pub inline fn isPPC(arch: Arch) bool {
962 return switch (arch) {
963 .powerpc, .powerpcle => true,
964 else => false,
965 };
966 }
967
968 pub inline fn isPPC64(arch: Arch) bool {
969 return switch (arch) {
970 .powerpc64, .powerpc64le => true,
971 else => false,
972 };
973 }
974
975 pub inline fn isSPARC(arch: Arch) bool {
976 return switch (arch) {
977 .sparc, .sparcel, .sparc64 => true,
978 else => false,
979 };
980 }
981
982 pub inline fn isSpirV(arch: Arch) bool {
983 return switch (arch) {
984 .spirv32, .spirv64 => true,
985 else => false,
986 };
987 }
988
989 pub inline fn isBpf(arch: Arch) bool {
990 return switch (arch) {
991 .bpfel, .bpfeb => true,
992 else => false,
993 };
994 }
995
996 pub inline fn isNvptx(arch: Arch) bool {
997 return switch (arch) {
998 .nvptx, .nvptx64 => true,
999 else => false,
1000 };
1001 }
1002
1003 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
1004 for (arch.allCpuModels()) |cpu| {
1005 if (mem.eql(u8, cpu_name, cpu.name)) {
1006 return cpu;
1007 }
1008 }
1009 return error.UnknownCpuModel;
1010 }
1011
1012 pub fn toElfMachine(arch: Arch) std.elf.EM {
1013 return switch (arch) {
1014 .avr => .AVR,
1015 .msp430 => .MSP430,
1016 .arc => .ARC,
1017 .arm => .ARM,
1018 .armeb => .ARM,
1019 .hexagon => .HEXAGON,
1020 .dxil => .NONE,
1021 .m68k => .@"68K",
1022 .le32 => .NONE,
1023 .mips => .MIPS,
1024 .mipsel => .MIPS_RS3_LE,
1025 .powerpc, .powerpcle => .PPC,
1026 .r600 => .NONE,
1027 .riscv32 => .RISCV,
1028 .sparc => .SPARC,
1029 .sparcel => .SPARC,
1030 .tce => .NONE,
1031 .tcele => .NONE,
1032 .thumb => .ARM,
1033 .thumbeb => .ARM,
1034 .x86 => .@"386",
1035 .xcore => .XCORE,
1036 .xtensa => .XTENSA,
1037 .nvptx => .NONE,
1038 .amdil => .NONE,
1039 .hsail => .NONE,
1040 .spir => .NONE,
1041 .kalimba => .CSR_KALIMBA,
1042 .shave => .NONE,
1043 .lanai => .LANAI,
1044 .wasm32 => .NONE,
1045 .renderscript32 => .NONE,
1046 .aarch64_32 => .AARCH64,
1047 .aarch64 => .AARCH64,
1048 .aarch64_be => .AARCH64,
1049 .mips64 => .MIPS,
1050 .mips64el => .MIPS_RS3_LE,
1051 .powerpc64 => .PPC64,
1052 .powerpc64le => .PPC64,
1053 .riscv64 => .RISCV,
1054 .x86_64 => .X86_64,
1055 .nvptx64 => .NONE,
1056 .le64 => .NONE,
1057 .amdil64 => .NONE,
1058 .hsail64 => .NONE,
1059 .spir64 => .NONE,
1060 .wasm64 => .NONE,
1061 .renderscript64 => .NONE,
1062 .amdgcn => .AMDGPU,
1063 .bpfel => .BPF,
1064 .bpfeb => .BPF,
1065 .csky => .CSKY,
1066 .sparc64 => .SPARCV9,
1067 .s390x => .S390,
1068 .ve => .NONE,
1069 .spu_2 => .SPU_2,
1070 .spirv32 => .NONE,
1071 .spirv64 => .NONE,
1072 .loongarch32 => .NONE,
1073 .loongarch64 => .NONE,
1074 };
1075 }
1076
1077 pub fn toCoffMachine(arch: Arch) std.coff.MachineType {
1078 return switch (arch) {
1079 .avr => .Unknown,
1080 .msp430 => .Unknown,
1081 .arc => .Unknown,
1082 .arm => .ARM,
1083 .armeb => .Unknown,
1084 .dxil => .Unknown,
1085 .hexagon => .Unknown,
1086 .m68k => .Unknown,
1087 .le32 => .Unknown,
1088 .mips => .Unknown,
1089 .mipsel => .Unknown,
1090 .powerpc, .powerpcle => .POWERPC,
1091 .r600 => .Unknown,
1092 .riscv32 => .RISCV32,
1093 .sparc => .Unknown,
1094 .sparcel => .Unknown,
1095 .tce => .Unknown,
1096 .tcele => .Unknown,
1097 .thumb => .Thumb,
1098 .thumbeb => .Thumb,
1099 .x86 => .I386,
1100 .xcore => .Unknown,
1101 .xtensa => .Unknown,
1102 .nvptx => .Unknown,
1103 .amdil => .Unknown,
1104 .hsail => .Unknown,
1105 .spir => .Unknown,
1106 .kalimba => .Unknown,
1107 .shave => .Unknown,
1108 .lanai => .Unknown,
1109 .wasm32 => .Unknown,
1110 .renderscript32 => .Unknown,
1111 .aarch64_32 => .ARM64,
1112 .aarch64 => .ARM64,
1113 .aarch64_be => .ARM64,
1114 .mips64 => .Unknown,
1115 .mips64el => .Unknown,
1116 .powerpc64 => .Unknown,
1117 .powerpc64le => .Unknown,
1118 .riscv64 => .RISCV64,
1119 .x86_64 => .X64,
1120 .nvptx64 => .Unknown,
1121 .le64 => .Unknown,
1122 .amdil64 => .Unknown,
1123 .hsail64 => .Unknown,
1124 .spir64 => .Unknown,
1125 .wasm64 => .Unknown,
1126 .renderscript64 => .Unknown,
1127 .amdgcn => .Unknown,
1128 .bpfel => .Unknown,
1129 .bpfeb => .Unknown,
1130 .csky => .Unknown,
1131 .sparc64 => .Unknown,
1132 .s390x => .Unknown,
1133 .ve => .Unknown,
1134 .spu_2 => .Unknown,
1135 .spirv32 => .Unknown,
1136 .spirv64 => .Unknown,
1137 .loongarch32 => .Unknown,
1138 .loongarch64 => .Unknown,
1139 };
1140 }
1141
1142 pub fn endian(arch: Arch) std.builtin.Endian {
1143 return switch (arch) {
1144 .avr,
1145 .arm,
1146 .aarch64_32,
1147 .aarch64,
1148 .amdgcn,
1149 .amdil,
1150 .amdil64,
1151 .bpfel,
1152 .csky,
1153 .xtensa,
1154 .hexagon,
1155 .hsail,
1156 .hsail64,
1157 .kalimba,
1158 .le32,
1159 .le64,
1160 .mipsel,
1161 .mips64el,
1162 .msp430,
1163 .nvptx,
1164 .nvptx64,
1165 .sparcel,
1166 .tcele,
1167 .powerpcle,
1168 .powerpc64le,
1169 .r600,
1170 .riscv32,
1171 .riscv64,
1172 .x86,
1173 .x86_64,
1174 .wasm32,
1175 .wasm64,
1176 .xcore,
1177 .thumb,
1178 .spir,
1179 .spir64,
1180 .renderscript32,
1181 .renderscript64,
1182 .shave,
1183 .ve,
1184 .spu_2,
1185 // GPU bitness is opaque. For now, assume little endian.
1186 .spirv32,
1187 .spirv64,
1188 .dxil,
1189 .loongarch32,
1190 .loongarch64,
1191 .arc,
1192 => .little,
1193
1194 .armeb,
1195 .aarch64_be,
1196 .bpfeb,
1197 .m68k,
1198 .mips,
1199 .mips64,
1200 .powerpc,
1201 .powerpc64,
1202 .thumbeb,
1203 .sparc,
1204 .sparc64,
1205 .tce,
1206 .lanai,
1207 .s390x,
1208 => .big,
1209 };
1210 }
1211
1212 /// Returns whether this architecture supports the address space
1213 pub fn supportsAddressSpace(arch: Arch, address_space: std.builtin.AddressSpace) bool {
1214 const is_nvptx = arch == .nvptx or arch == .nvptx64;
1215 const is_spirv = arch == .spirv32 or arch == .spirv64;
1216 const is_gpu = is_nvptx or is_spirv or arch == .amdgcn;
1217 return switch (address_space) {
1218 .generic => true,
1219 .fs, .gs, .ss => arch == .x86_64 or arch == .x86,
1220 .global, .constant, .local, .shared => is_gpu,
1221 .param => is_nvptx,
1222 // TODO this should also check how many flash banks the cpu has
1223 .flash, .flash1, .flash2, .flash3, .flash4, .flash5 => arch == .avr,
1224 };
1225 }
1226
1227 /// Returns a name that matches the lib/std/target/* source file name.
1228 pub fn genericName(arch: Arch) []const u8 {
1229 return switch (arch) {
1230 .arm, .armeb, .thumb, .thumbeb => "arm",
1231 .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
1232 .bpfel, .bpfeb => "bpf",
1233 .loongarch32, .loongarch64 => "loongarch",
1234 .mips, .mipsel, .mips64, .mips64el => "mips",
1235 .powerpc, .powerpcle, .powerpc64, .powerpc64le => "powerpc",
1236 .amdgcn => "amdgpu",
1237 .riscv32, .riscv64 => "riscv",
1238 .sparc, .sparc64, .sparcel => "sparc",
1239 .s390x => "s390x",
1240 .x86, .x86_64 => "x86",
1241 .nvptx, .nvptx64 => "nvptx",
1242 .wasm32, .wasm64 => "wasm",
1243 .spirv32, .spirv64 => "spirv",
1244 else => @tagName(arch),
1245 };
1246 }
1247
1248 /// All CPU features Zig is aware of, sorted lexicographically by name.
1249 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
1250 return switch (arch) {
1251 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
1252 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
1253 .arc => &arc.all_features,
1254 .avr => &avr.all_features,
1255 .bpfel, .bpfeb => &bpf.all_features,
1256 .csky => &csky.all_features,
1257 .hexagon => &hexagon.all_features,
1258 .loongarch32, .loongarch64 => &loongarch.all_features,
1259 .m68k => &m68k.all_features,
1260 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
1261 .msp430 => &msp430.all_features,
1262 .powerpc, .powerpcle, .powerpc64, .powerpc64le => &powerpc.all_features,
1263 .amdgcn => &amdgpu.all_features,
1264 .riscv32, .riscv64 => &riscv.all_features,
1265 .sparc, .sparc64, .sparcel => &sparc.all_features,
1266 .spirv32, .spirv64 => &spirv.all_features,
1267 .s390x => &s390x.all_features,
1268 .x86, .x86_64 => &x86.all_features,
1269 .xtensa => &xtensa.all_features,
1270 .nvptx, .nvptx64 => &nvptx.all_features,
1271 .ve => &ve.all_features,
1272 .wasm32, .wasm64 => &wasm.all_features,
1273
1274 else => &[0]Cpu.Feature{},
1275 };
1276 }
1277
1278 /// All processors Zig is aware of, sorted lexicographically by name.
1279 pub fn allCpuModels(arch: Arch) []const *const Cpu.Model {
1280 return switch (arch) {
1281 .arc => comptime allCpusFromDecls(arc.cpu),
1282 .arm, .armeb, .thumb, .thumbeb => comptime allCpusFromDecls(arm.cpu),
1283 .aarch64, .aarch64_be, .aarch64_32 => comptime allCpusFromDecls(aarch64.cpu),
1284 .avr => comptime allCpusFromDecls(avr.cpu),
1285 .bpfel, .bpfeb => comptime allCpusFromDecls(bpf.cpu),
1286 .csky => comptime allCpusFromDecls(csky.cpu),
1287 .hexagon => comptime allCpusFromDecls(hexagon.cpu),
1288 .loongarch32, .loongarch64 => comptime allCpusFromDecls(loongarch.cpu),
1289 .m68k => comptime allCpusFromDecls(m68k.cpu),
1290 .mips, .mipsel, .mips64, .mips64el => comptime allCpusFromDecls(mips.cpu),
1291 .msp430 => comptime allCpusFromDecls(msp430.cpu),
1292 .powerpc, .powerpcle, .powerpc64, .powerpc64le => comptime allCpusFromDecls(powerpc.cpu),
1293 .amdgcn => comptime allCpusFromDecls(amdgpu.cpu),
1294 .riscv32, .riscv64 => comptime allCpusFromDecls(riscv.cpu),
1295 .sparc, .sparc64, .sparcel => comptime allCpusFromDecls(sparc.cpu),
1296 .spirv32, .spirv64 => comptime allCpusFromDecls(spirv.cpu),
1297 .s390x => comptime allCpusFromDecls(s390x.cpu),
1298 .x86, .x86_64 => comptime allCpusFromDecls(x86.cpu),
1299 .xtensa => comptime allCpusFromDecls(xtensa.cpu),
1300 .nvptx, .nvptx64 => comptime allCpusFromDecls(nvptx.cpu),
1301 .ve => comptime allCpusFromDecls(ve.cpu),
1302 .wasm32, .wasm64 => comptime allCpusFromDecls(wasm.cpu),
1303
1304 else => &[0]*const Model{},
1305 };
1306 }
1307
1308 fn allCpusFromDecls(comptime cpus: type) []const *const Cpu.Model {
1309 const decls = @typeInfo(cpus).Struct.decls;
1310 var array: [decls.len]*const Cpu.Model = undefined;
1311 for (decls, 0..) |decl, i| {
1312 array[i] = &@field(cpus, decl.name);
1313 }
1314 return &array;
1315 }
1316 };
1317
1318 pub const Model = struct {
1319 name: []const u8,
1320 llvm_name: ?[:0]const u8,
1321 features: Feature.Set,
1322
1323 pub fn toCpu(model: *const Model, arch: Arch) Cpu {
1324 var features = model.features;
1325 features.populateDependencies(arch.allFeaturesList());
1326 return .{
1327 .arch = arch,
1328 .model = model,
1329 .features = features,
1330 };
1331 }
1332
1333 pub fn generic(arch: Arch) *const Model {
1334 const S = struct {
1335 const generic_model = Model{
1336 .name = "generic",
1337 .llvm_name = null,
1338 .features = Cpu.Feature.Set.empty,
1339 };
1340 };
1341 return switch (arch) {
1342 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
1343 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
1344 .avr => &avr.cpu.avr2,
1345 .bpfel, .bpfeb => &bpf.cpu.generic,
1346 .hexagon => &hexagon.cpu.generic,
1347 .loongarch32 => &loongarch.cpu.generic_la32,
1348 .loongarch64 => &loongarch.cpu.generic_la64,
1349 .m68k => &m68k.cpu.generic,
1350 .mips, .mipsel => &mips.cpu.mips32,
1351 .mips64, .mips64el => &mips.cpu.mips64,
1352 .msp430 => &msp430.cpu.generic,
1353 .powerpc => &powerpc.cpu.ppc,
1354 .powerpcle => &powerpc.cpu.ppc,
1355 .powerpc64 => &powerpc.cpu.ppc64,
1356 .powerpc64le => &powerpc.cpu.ppc64le,
1357 .amdgcn => &amdgpu.cpu.generic,
1358 .riscv32 => &riscv.cpu.generic_rv32,
1359 .riscv64 => &riscv.cpu.generic_rv64,
1360 .spirv32, .spirv64 => &spirv.cpu.generic,
1361 .sparc, .sparcel => &sparc.cpu.generic,
1362 .sparc64 => &sparc.cpu.v9, // 64-bit SPARC needs v9 as the baseline
1363 .s390x => &s390x.cpu.generic,
1364 .x86 => &x86.cpu.i386,
1365 .x86_64 => &x86.cpu.x86_64,
1366 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
1367 .ve => &ve.cpu.generic,
1368 .wasm32, .wasm64 => &wasm.cpu.generic,
1369
1370 else => &S.generic_model,
1371 };
1372 }
1373
1374 pub fn baseline(arch: Arch) *const Model {
1375 return switch (arch) {
1376 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline,
1377 .riscv32 => &riscv.cpu.baseline_rv32,
1378 .riscv64 => &riscv.cpu.baseline_rv64,
1379 .x86 => &x86.cpu.pentium4,
1380 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
1381 .sparc, .sparcel => &sparc.cpu.v8,
1382
1383 else => generic(arch),
1384 };
1385 }
1386 };
1387
1388 /// The "default" set of CPU features for cross-compiling. A conservative set
1389 /// of features that is expected to be supported on most available hardware.
1390 pub fn baseline(arch: Arch) Cpu {
1391 return Model.baseline(arch).toCpu(arch);
1392 }
1393 };
1394
1395 pub fn zigTriple(self: Target, allocator: mem.Allocator) ![]u8 {
1396 return std.zig.CrossTarget.fromTarget(self).zigTriple(allocator);
1397 }
1398
1399 pub fn linuxTripleSimple(allocator: mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
1400 return std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
1401 }
1402
1403 pub fn linuxTriple(self: Target, allocator: mem.Allocator) ![]u8 {
1404 return linuxTripleSimple(allocator, self.cpu.arch, self.os.tag, self.abi);
1405 }
1406
1407 pub fn exeFileExtSimple(cpu_arch: Cpu.Arch, os_tag: Os.Tag) [:0]const u8 {
1408 return switch (os_tag) {
1409 .windows => ".exe",
1410 .uefi => ".efi",
1411 .plan9 => plan9Ext(cpu_arch),
1412 else => switch (cpu_arch) {
1413 .wasm32, .wasm64 => ".wasm",
1414 else => "",
1415 },
1416 };
1417 }
1418
1419 pub fn exeFileExt(self: Target) [:0]const u8 {
1420 return exeFileExtSimple(self.cpu.arch, self.os.tag);
1421 }
1422
1423 pub fn staticLibSuffix_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 {
1424 if (abi == .msvc) {
1425 return ".lib";
1426 }
1427 switch (os_tag) {
1428 .windows, .uefi => return ".lib",
1429 else => return ".a",
1430 }
1431 }
1432
1433 pub fn staticLibSuffix(self: Target) [:0]const u8 {
1434 return staticLibSuffix_os_abi(self.os.tag, self.abi);
1435 }
1436
1437 pub fn dynamicLibSuffix(self: Target) [:0]const u8 {
1438 return self.os.tag.dynamicLibSuffix();
1439 }
1440
1441 pub fn libPrefix_os_abi(os_tag: Os.Tag, abi: Abi) [:0]const u8 {
1442 if (abi == .msvc) {
1443 return "";
1444 }
1445 switch (os_tag) {
1446 .windows, .uefi => return "",
1447 else => return "lib",
1448 }
1449 }
1450
1451 pub fn libPrefix(self: Target) [:0]const u8 {
1452 return libPrefix_os_abi(self.os.tag, self.abi);
1453 }
1454
1455 pub inline fn isMinGW(self: Target) bool {
1456 return self.os.tag == .windows and self.isGnu();
1457 }
1458
1459 pub inline fn isGnu(self: Target) bool {
1460 return self.abi.isGnu();
1461 }
1462
1463 pub inline fn isMusl(self: Target) bool {
1464 return self.abi.isMusl();
1465 }
1466
1467 pub inline fn isAndroid(self: Target) bool {
1468 return self.abi == .android;
1469 }
1470
1471 pub inline fn isWasm(self: Target) bool {
1472 return self.cpu.arch.isWasm();
1473 }
1474
1475 pub inline fn isDarwin(self: Target) bool {
1476 return self.os.tag.isDarwin();
1477 }
1478
1479 pub inline fn isBSD(self: Target) bool {
1480 return self.os.tag.isBSD();
1481 }
1482
1483 pub inline fn isBpfFreestanding(self: Target) bool {
1484 return self.cpu.arch.isBpf() and self.os.tag == .freestanding;
1485 }
1486
1487 pub inline fn isGnuLibC_os_tag_abi(os_tag: Os.Tag, abi: Abi) bool {
1488 return os_tag == .linux and abi.isGnu();
1489 }
1490
1491 pub inline fn isGnuLibC(self: Target) bool {
1492 return isGnuLibC_os_tag_abi(self.os.tag, self.abi);
1493 }
1494
1495 pub inline fn supportsNewStackCall(self: Target) bool {
1496 return !self.cpu.arch.isWasm();
1497 }
1498
1499 pub inline fn isSpirV(self: Target) bool {
1500 return self.cpu.arch.isSpirV();
1501 }
1502
1503 pub const FloatAbi = enum {
1504 hard,
1505 soft,
1506 };
1507
1508 pub inline fn getFloatAbi(self: Target) FloatAbi {
1509 return self.abi.floatAbi();
1510 }
1511
1512 pub inline fn hasDynamicLinker(self: Target) bool {
1513 if (self.cpu.arch.isWasm()) {
1514 return false;
1515 }
1516 switch (self.os.tag) {
1517 .freestanding,
1518 .ios,
1519 .tvos,
1520 .watchos,
1521 .macos,
1522 .uefi,
1523 .windows,
1524 .emscripten,
1525 .opencl,
1526 .glsl450,
1527 .vulkan,
1528 .plan9,
1529 .other,
1530 => return false,
1531 else => return true,
1532 }
1533 }
1534
1535 pub const DynamicLinker = struct {
1536 /// Contains the memory used to store the dynamic linker path. This field should
1537 /// not be used directly. See `get` and `set`. This field exists so that this API requires no allocator.
1538 buffer: [255]u8 = undefined,
1539
1540 /// Used to construct the dynamic linker path. This field should not be used
1541 /// directly. See `get` and `set`.
1542 max_byte: ?u8 = null,
1543
1544 /// Asserts that the length is less than or equal to 255 bytes.
1545 pub fn init(dl_or_null: ?[]const u8) DynamicLinker {
1546 var result: DynamicLinker = undefined;
1547 result.set(dl_or_null);
1548 return result;
1549 }
1550
1551 /// The returned memory has the same lifetime as the `DynamicLinker`.
1552 pub fn get(self: *const DynamicLinker) ?[]const u8 {
1553 const m: usize = self.max_byte orelse return null;
1554 return self.buffer[0 .. m + 1];
1555 }
1556
1557 /// Asserts that the length is less than or equal to 255 bytes.
1558 pub fn set(self: *DynamicLinker, dl_or_null: ?[]const u8) void {
1559 if (dl_or_null) |dl| {
1560 @memcpy(self.buffer[0..dl.len], dl);
1561 self.max_byte = @as(u8, @intCast(dl.len - 1));
1562 } else {
1563 self.max_byte = null;
1564 }
1565 }
1566 };
1567
1568 pub fn standardDynamicLinkerPath(self: Target) DynamicLinker {
1569 var result: DynamicLinker = .{};
1570 const S = struct {
1571 fn print(r: *DynamicLinker, comptime fmt: []const u8, args: anytype) DynamicLinker {
1572 r.max_byte = @as(u8, @intCast((std.fmt.bufPrint(&r.buffer, fmt, args) catch unreachable).len - 1));
1573 return r.*;
1574 }
1575 fn copy(r: *DynamicLinker, s: []const u8) DynamicLinker {
1576 @memcpy(r.buffer[0..s.len], s);
1577 r.max_byte = @as(u8, @intCast(s.len - 1));
1578 return r.*;
1579 }
1580 };
1581 const print = S.print;
1582 const copy = S.copy;
1583
1584 if (self.abi == .android) {
1585 const suffix = if (self.ptrBitWidth() == 64) "64" else "";
1586 return print(&result, "/system/bin/linker{s}", .{suffix});
1587 }
1588
1589 if (self.abi.isMusl()) {
1590 const is_arm = switch (self.cpu.arch) {
1591 .arm, .armeb, .thumb, .thumbeb => true,
1592 else => false,
1593 };
1594 const arch_part = switch (self.cpu.arch) {
1595 .arm, .thumb => "arm",
1596 .armeb, .thumbeb => "armeb",
1597 else => |arch| @tagName(arch),
1598 };
1599 const arch_suffix = if (is_arm and self.abi.floatAbi() == .hard) "hf" else "";
1600 return print(&result, "/lib/ld-musl-{s}{s}.so.1", .{ arch_part, arch_suffix });
1601 }
1602
1603 switch (self.os.tag) {
1604 .freebsd => return copy(&result, "/libexec/ld-elf.so.1"),
1605 .netbsd => return copy(&result, "/libexec/ld.elf_so"),
1606 .openbsd => return copy(&result, "/usr/libexec/ld.so"),
1607 .dragonfly => return copy(&result, "/libexec/ld-elf.so.2"),
1608 .solaris, .illumos => return copy(&result, "/lib/64/ld.so.1"),
1609 .linux => switch (self.cpu.arch) {
1610 .x86,
1611 .sparc,
1612 .sparcel,
1613 => return copy(&result, "/lib/ld-linux.so.2"),
1614
1615 .aarch64 => return copy(&result, "/lib/ld-linux-aarch64.so.1"),
1616 .aarch64_be => return copy(&result, "/lib/ld-linux-aarch64_be.so.1"),
1617 .aarch64_32 => return copy(&result, "/lib/ld-linux-aarch64_32.so.1"),
1618
1619 .arm,
1620 .armeb,
1621 .thumb,
1622 .thumbeb,
1623 => return copy(&result, switch (self.abi.floatAbi()) {
1624 .hard => "/lib/ld-linux-armhf.so.3",
1625 else => "/lib/ld-linux.so.3",
1626 }),
1627
1628 .mips,
1629 .mipsel,
1630 .mips64,
1631 .mips64el,
1632 => {
1633 const lib_suffix = switch (self.abi) {
1634 .gnuabin32, .gnux32 => "32",
1635 .gnuabi64 => "64",
1636 else => "",
1637 };
1638 const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008);
1639 const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1";
1640 return print(&result, "/lib{s}/{s}", .{ lib_suffix, loader });
1641 },
1642
1643 .powerpc, .powerpcle => return copy(&result, "/lib/ld.so.1"),
1644 .powerpc64, .powerpc64le => return copy(&result, "/lib64/ld64.so.2"),
1645 .s390x => return copy(&result, "/lib64/ld64.so.1"),
1646 .sparc64 => return copy(&result, "/lib64/ld-linux.so.2"),
1647 .x86_64 => return copy(&result, switch (self.abi) {
1648 .gnux32 => "/libx32/ld-linux-x32.so.2",
1649 else => "/lib64/ld-linux-x86-64.so.2",
1650 }),
1651
1652 .riscv32 => return copy(&result, "/lib/ld-linux-riscv32-ilp32.so.1"),
1653 .riscv64 => return copy(&result, "/lib/ld-linux-riscv64-lp64.so.1"),
1654
1655 // Architectures in this list have been verified as not having a standard
1656 // dynamic linker path.
1657 .wasm32,
1658 .wasm64,
1659 .bpfel,
1660 .bpfeb,
1661 .nvptx,
1662 .nvptx64,
1663 .spu_2,
1664 .avr,
1665 .spirv32,
1666 .spirv64,
1667 => return result,
1668
1669 // TODO go over each item in this list and either move it to the above list, or
1670 // implement the standard dynamic linker path code for it.
1671 .arc,
1672 .csky,
1673 .hexagon,
1674 .m68k,
1675 .msp430,
1676 .r600,
1677 .amdgcn,
1678 .tce,
1679 .tcele,
1680 .xcore,
1681 .le32,
1682 .le64,
1683 .amdil,
1684 .amdil64,
1685 .hsail,
1686 .hsail64,
1687 .spir,
1688 .spir64,
1689 .kalimba,
1690 .shave,
1691 .lanai,
1692 .renderscript32,
1693 .renderscript64,
1694 .ve,
1695 .dxil,
1696 .loongarch32,
1697 .loongarch64,
1698 .xtensa,
1699 => return result,
1700 },
1701
1702 .ios,
1703 .tvos,
1704 .watchos,
1705 .macos,
1706 => return copy(&result, "/usr/lib/dyld"),
1707
1708 // Operating systems in this list have been verified as not having a standard
1709 // dynamic linker path.
1710 .freestanding,
1711 .uefi,
1712 .windows,
1713 .emscripten,
1714 .wasi,
1715 .opencl,
1716 .glsl450,
1717 .vulkan,
1718 .other,
1719 .plan9,
1720 => return result,
1721
1722 // TODO revisit when multi-arch for Haiku is available
1723 .haiku => return copy(&result, "/system/runtime_loader"),
1724
1725 // TODO go over each item in this list and either move it to the above list, or
1726 // implement the standard dynamic linker path code for it.
1727 .ananas,
1728 .cloudabi,
1729 .fuchsia,
1730 .kfreebsd,
1731 .lv2,
1732 .zos,
1733 .minix,
1734 .rtems,
1735 .nacl,
1736 .aix,
1737 .cuda,
1738 .nvcl,
1739 .amdhsa,
1740 .ps4,
1741 .ps5,
1742 .elfiamcu,
1743 .mesa3d,
1744 .contiki,
1745 .amdpal,
1746 .hermit,
1747 .hurd,
1748 .driverkit,
1749 .shadermodel,
1750 .liteos,
1751 => return result,
1752 }
1753 }
1754
1755 /// 0c spim little-endian MIPS 3000 family
1756 /// 1c 68000 Motorola MC68000
1757 /// 2c 68020 Motorola MC68020
1758 /// 5c arm little-endian ARM
1759 /// 6c amd64 AMD64 and compatibles (e.g., Intel EM64T)
1760 /// 7c arm64 ARM64 (ARMv8)
1761 /// 8c 386 Intel x86, i486, Pentium, etc.
1762 /// kc sparc Sun SPARC
1763 /// qc power Power PC
1764 /// vc mips big-endian MIPS 3000 family
1765 pub fn plan9Ext(cpu_arch: Cpu.Arch) [:0]const u8 {
1766 return switch (cpu_arch) {
1767 .arm => ".5",
1768 .x86_64 => ".6",
1769 .aarch64 => ".7",
1770 .x86 => ".8",
1771 .sparc => ".k",
1772 .powerpc, .powerpcle => ".q",
1773 .mips, .mipsel => ".v",
1774 // ISAs without designated characters get 'X' for lack of a better option.
1775 else => ".X",
1776 };
1777 }
1778
1779 pub fn maxIntAlignment(target: Target) u16 {
1780 return switch (target.cpu.arch) {
1781 .avr => 1,
1782 .msp430 => 2,
1783 .xcore => 4,
1784
1785 .arm,
1786 .armeb,
1787 .thumb,
1788 .thumbeb,
1789 .hexagon,
1790 .mips,
1791 .mipsel,
1792 .powerpc,
1793 .powerpcle,
1794 .r600,
1795 .amdgcn,
1796 .riscv32,
1797 .sparc,
1798 .sparcel,
1799 .s390x,
1800 .lanai,
1801 .wasm32,
1802 .wasm64,
1803 => 8,
1804
1805 .x86 => if (target.ofmt == .c) 16 else return switch (target.os.tag) {
1806 .windows, .uefi => 8,
1807 else => 4,
1808 },
1809
1810 // For these, LLVMABIAlignmentOfType(i128) reports 8. Note that 16
1811 // is a relevant number in three cases:
1812 // 1. Different machine code instruction when loading into SIMD register.
1813 // 2. The C ABI wants 16 for extern structs.
1814 // 3. 16-byte cmpxchg needs 16-byte alignment.
1815 // Same logic for powerpc64, mips64, sparc64.
1816 .x86_64,
1817 .powerpc64,
1818 .powerpc64le,
1819 .mips64,
1820 .mips64el,
1821 .sparc64,
1822 => return switch (target.ofmt) {
1823 .c => 16,
1824 else => 8,
1825 },
1826
1827 // Even LLVMABIAlignmentOfType(i128) agrees on these targets.
1828 .aarch64,
1829 .aarch64_be,
1830 .aarch64_32,
1831 .riscv64,
1832 .bpfel,
1833 .bpfeb,
1834 .nvptx,
1835 .nvptx64,
1836 => 16,
1837
1838 // Below this comment are unverified but based on the fact that C requires
1839 // int128_t to be 16 bytes aligned, it's a safe default.
1840 .spu_2,
1841 .csky,
1842 .arc,
1843 .m68k,
1844 .tce,
1845 .tcele,
1846 .le32,
1847 .amdil,
1848 .hsail,
1849 .spir,
1850 .kalimba,
1851 .renderscript32,
1852 .spirv32,
1853 .shave,
1854 .le64,
1855 .amdil64,
1856 .hsail64,
1857 .spir64,
1858 .renderscript64,
1859 .ve,
1860 .spirv64,
1861 .dxil,
1862 .loongarch32,
1863 .loongarch64,
1864 .xtensa,
1865 => 16,
1866 };
1867 }
1868
1869 pub fn ptrBitWidth(target: Target) u16 {
1870 switch (target.abi) {
1871 .gnux32, .muslx32, .gnuabin32, .gnuilp32 => return 32,
1872 .gnuabi64 => return 64,
1873 else => {},
1874 }
1875 switch (target.cpu.arch) {
1876 .avr,
1877 .msp430,
1878 .spu_2,
1879 => return 16,
1880
1881 .arc,
1882 .arm,
1883 .armeb,
1884 .csky,
1885 .hexagon,
1886 .m68k,
1887 .le32,
1888 .mips,
1889 .mipsel,
1890 .powerpc,
1891 .powerpcle,
1892 .r600,
1893 .riscv32,
1894 .sparcel,
1895 .tce,
1896 .tcele,
1897 .thumb,
1898 .thumbeb,
1899 .x86,
1900 .xcore,
1901 .nvptx,
1902 .amdil,
1903 .hsail,
1904 .spir,
1905 .kalimba,
1906 .shave,
1907 .lanai,
1908 .wasm32,
1909 .renderscript32,
1910 .aarch64_32,
1911 .spirv32,
1912 .loongarch32,
1913 .dxil,
1914 .xtensa,
1915 => return 32,
1916
1917 .aarch64,
1918 .aarch64_be,
1919 .mips64,
1920 .mips64el,
1921 .powerpc64,
1922 .powerpc64le,
1923 .riscv64,
1924 .x86_64,
1925 .nvptx64,
1926 .le64,
1927 .amdil64,
1928 .hsail64,
1929 .spir64,
1930 .wasm64,
1931 .renderscript64,
1932 .amdgcn,
1933 .bpfel,
1934 .bpfeb,
1935 .sparc64,
1936 .s390x,
1937 .ve,
1938 .spirv64,
1939 .loongarch64,
1940 => return 64,
1941
1942 .sparc => return if (std.Target.sparc.featureSetHas(target.cpu.features, .v9)) 64 else 32,
1943 }
1944 }
1945
1946 pub fn stackAlignment(target: Target) u16 {
1947 return switch (target.cpu.arch) {
1948 .m68k => 2,
1949 .amdgcn => 4,
1950 .x86 => switch (target.os.tag) {
1951 .windows, .uefi => 4,
1952 else => 16,
1953 },
1954 .arm,
1955 .armeb,
1956 .thumb,
1957 .thumbeb,
1958 .mips,
1959 .mipsel,
1960 .sparc,
1961 .sparcel,
1962 => 8,
1963 .aarch64,
1964 .aarch64_be,
1965 .aarch64_32,
1966 .bpfeb,
1967 .bpfel,
1968 .mips64,
1969 .mips64el,
1970 .riscv32,
1971 .riscv64,
1972 .sparc64,
1973 .x86_64,
1974 .ve,
1975 .wasm32,
1976 .wasm64,
1977 => 16,
1978 .powerpc64,
1979 .powerpc64le,
1980 => switch (target.os.tag) {
1981 else => 8,
1982 .linux => 16,
1983 },
1984 else => @divExact(target.ptrBitWidth(), 8),
1985 };
1986 }
1987
1988 /// Default signedness of `char` for the native C compiler for this target
1989 /// Note that char signedness is implementation-defined and many compilers provide
1990 /// an option to override the default signedness e.g. GCC's -funsigned-char / -fsigned-char
1991 pub fn charSignedness(target: Target) std.builtin.Signedness {
1992 switch (target.cpu.arch) {
1993 .aarch64,
1994 .aarch64_32,
1995 .aarch64_be,
1996 .arm,
1997 .armeb,
1998 .thumb,
1999 .thumbeb,
2000 => return if (target.os.tag.isDarwin() or target.os.tag == .windows) .signed else .unsigned,
2001 .powerpc, .powerpc64 => return if (target.os.tag.isDarwin()) .signed else .unsigned,
2002 .powerpcle,
2003 .powerpc64le,
2004 .s390x,
2005 .xcore,
2006 .arc,
2007 .msp430,
2008 .riscv32,
2009 .riscv64,
2010 => return .unsigned,
2011 else => return .signed,
2012 }
2013 }
2014
2015 pub const CType = enum {
2016 char,
2017 short,
2018 ushort,
2019 int,
2020 uint,
2021 long,
2022 ulong,
2023 longlong,
2024 ulonglong,
2025 float,
2026 double,
2027 longdouble,
2028 };
2029
2030 pub fn c_type_byte_size(t: Target, c_type: CType) u16 {
2031 return switch (c_type) {
2032 .char,
2033 .short,
2034 .ushort,
2035 .int,
2036 .uint,
2037 .long,
2038 .ulong,
2039 .longlong,
2040 .ulonglong,
2041 .float,
2042 .double,
2043 => @divExact(c_type_bit_size(t, c_type), 8),
2044
2045 .longdouble => switch (c_type_bit_size(t, c_type)) {
2046 16 => 2,
2047 32 => 4,
2048 64 => 8,
2049 80 => @as(u16, @intCast(mem.alignForward(usize, 10, c_type_alignment(t, .longdouble)))),
2050 128 => 16,
2051 else => unreachable,
2052 },
2053 };
2054 }
2055
2056 pub fn c_type_bit_size(target: Target, c_type: CType) u16 {
2057 switch (target.os.tag) {
2058 .freestanding, .other => switch (target.cpu.arch) {
2059 .msp430 => switch (c_type) {
2060 .char => return 8,
2061 .short, .ushort, .int, .uint => return 16,
2062 .float, .long, .ulong => return 32,
2063 .longlong, .ulonglong, .double, .longdouble => return 64,
2064 },
2065 .avr => switch (c_type) {
2066 .char => return 8,
2067 .short, .ushort, .int, .uint => return 16,
2068 .long, .ulong, .float, .double, .longdouble => return 32,
2069 .longlong, .ulonglong => return 64,
2070 },
2071 .tce, .tcele => switch (c_type) {
2072 .char => return 8,
2073 .short, .ushort => return 16,
2074 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
2075 .float, .double, .longdouble => return 32,
2076 },
2077 .mips64, .mips64el => switch (c_type) {
2078 .char => return 8,
2079 .short, .ushort => return 16,
2080 .int, .uint, .float => return 32,
2081 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
2082 .longlong, .ulonglong, .double => return 64,
2083 .longdouble => return 128,
2084 },
2085 .x86_64 => switch (c_type) {
2086 .char => return 8,
2087 .short, .ushort => return 16,
2088 .int, .uint, .float => return 32,
2089 .long, .ulong => switch (target.abi) {
2090 .gnux32, .muslx32 => return 32,
2091 else => return 64,
2092 },
2093 .longlong, .ulonglong, .double => return 64,
2094 .longdouble => return 80,
2095 },
2096 else => switch (c_type) {
2097 .char => return 8,
2098 .short, .ushort => return 16,
2099 .int, .uint, .float => return 32,
2100 .long, .ulong => return target.ptrBitWidth(),
2101 .longlong, .ulonglong, .double => return 64,
2102 .longdouble => switch (target.cpu.arch) {
2103 .x86 => switch (target.abi) {
2104 .android => return 64,
2105 else => return 80,
2106 },
2107
2108 .powerpc,
2109 .powerpcle,
2110 .powerpc64,
2111 .powerpc64le,
2112 => switch (target.abi) {
2113 .musl,
2114 .musleabi,
2115 .musleabihf,
2116 .muslx32,
2117 => return 64,
2118 else => return 128,
2119 },
2120
2121 .riscv32,
2122 .riscv64,
2123 .aarch64,
2124 .aarch64_be,
2125 .aarch64_32,
2126 .s390x,
2127 .sparc,
2128 .sparc64,
2129 .sparcel,
2130 .wasm32,
2131 .wasm64,
2132 => return 128,
2133
2134 else => return 64,
2135 },
2136 },
2137 },
2138
2139 .linux,
2140 .freebsd,
2141 .netbsd,
2142 .dragonfly,
2143 .openbsd,
2144 .wasi,
2145 .emscripten,
2146 .plan9,
2147 .solaris,
2148 .illumos,
2149 .haiku,
2150 .ananas,
2151 .fuchsia,
2152 .minix,
2153 => switch (target.cpu.arch) {
2154 .msp430 => switch (c_type) {
2155 .char => return 8,
2156 .short, .ushort, .int, .uint => return 16,
2157 .long, .ulong, .float => return 32,
2158 .longlong, .ulonglong, .double, .longdouble => return 64,
2159 },
2160 .avr => switch (c_type) {
2161 .char => return 8,
2162 .short, .ushort, .int, .uint => return 16,
2163 .long, .ulong, .float, .double, .longdouble => return 32,
2164 .longlong, .ulonglong => return 64,
2165 },
2166 .tce, .tcele => switch (c_type) {
2167 .char => return 8,
2168 .short, .ushort => return 16,
2169 .int, .uint, .long, .ulong, .longlong, .ulonglong => return 32,
2170 .float, .double, .longdouble => return 32,
2171 },
2172 .mips64, .mips64el => switch (c_type) {
2173 .char => return 8,
2174 .short, .ushort => return 16,
2175 .int, .uint, .float => return 32,
2176 .long, .ulong => return if (target.abi != .gnuabin32) 64 else 32,
2177 .longlong, .ulonglong, .double => return 64,
2178 .longdouble => if (target.os.tag == .freebsd) return 64 else return 128,
2179 },
2180 .x86_64 => switch (c_type) {
2181 .char => return 8,
2182 .short, .ushort => return 16,
2183 .int, .uint, .float => return 32,
2184 .long, .ulong => switch (target.abi) {
2185 .gnux32, .muslx32 => return 32,
2186 else => return 64,
2187 },
2188 .longlong, .ulonglong, .double => return 64,
2189 .longdouble => return 80,
2190 },
2191 else => switch (c_type) {
2192 .char => return 8,
2193 .short, .ushort => return 16,
2194 .int, .uint, .float => return 32,
2195 .long, .ulong => return target.ptrBitWidth(),
2196 .longlong, .ulonglong, .double => return 64,
2197 .longdouble => switch (target.cpu.arch) {
2198 .x86 => switch (target.abi) {
2199 .android => return 64,
2200 else => return 80,
2201 },
2202
2203 .powerpc,
2204 .powerpcle,
2205 => switch (target.abi) {
2206 .musl,
2207 .musleabi,
2208 .musleabihf,
2209 .muslx32,
2210 => return 64,
2211 else => switch (target.os.tag) {
2212 .freebsd, .netbsd, .openbsd => return 64,
2213 else => return 128,
2214 },
2215 },
2216
2217 .powerpc64,
2218 .powerpc64le,
2219 => switch (target.abi) {
2220 .musl,
2221 .musleabi,
2222 .musleabihf,
2223 .muslx32,
2224 => return 64,
2225 else => switch (target.os.tag) {
2226 .freebsd, .openbsd => return 64,
2227 else => return 128,
2228 },
2229 },
2230
2231 .riscv32,
2232 .riscv64,
2233 .aarch64,
2234 .aarch64_be,
2235 .aarch64_32,
2236 .s390x,
2237 .mips64,
2238 .mips64el,
2239 .sparc,
2240 .sparc64,
2241 .sparcel,
2242 .wasm32,
2243 .wasm64,
2244 => return 128,
2245
2246 else => return 64,
2247 },
2248 },
2249 },
2250
2251 .windows, .uefi => switch (target.cpu.arch) {
2252 .x86 => switch (c_type) {
2253 .char => return 8,
2254 .short, .ushort => return 16,
2255 .int, .uint, .float => return 32,
2256 .long, .ulong => return 32,
2257 .longlong, .ulonglong, .double => return 64,
2258 .longdouble => switch (target.abi) {
2259 .gnu, .gnuilp32, .cygnus => return 80,
2260 else => return 64,
2261 },
2262 },
2263 .x86_64 => switch (c_type) {
2264 .char => return 8,
2265 .short, .ushort => return 16,
2266 .int, .uint, .float => return 32,
2267 .long, .ulong => switch (target.abi) {
2268 .cygnus => return 64,
2269 else => return 32,
2270 },
2271 .longlong, .ulonglong, .double => return 64,
2272 .longdouble => switch (target.abi) {
2273 .gnu, .gnuilp32, .cygnus => return 80,
2274 else => return 64,
2275 },
2276 },
2277 else => switch (c_type) {
2278 .char => return 8,
2279 .short, .ushort => return 16,
2280 .int, .uint, .float => return 32,
2281 .long, .ulong => return 32,
2282 .longlong, .ulonglong, .double => return 64,
2283 .longdouble => return 64,
2284 },
2285 },
2286
2287 .macos, .ios, .tvos, .watchos => switch (c_type) {
2288 .char => return 8,
2289 .short, .ushort => return 16,
2290 .int, .uint, .float => return 32,
2291 .long, .ulong => switch (target.cpu.arch) {
2292 .x86, .arm, .aarch64_32 => return 32,
2293 .x86_64 => switch (target.abi) {
2294 .gnux32, .muslx32 => return 32,
2295 else => return 64,
2296 },
2297 else => return 64,
2298 },
2299 .longlong, .ulonglong, .double => return 64,
2300 .longdouble => switch (target.cpu.arch) {
2301 .x86 => switch (target.abi) {
2302 .android => return 64,
2303 else => return 80,
2304 },
2305 .x86_64 => return 80,
2306 else => return 64,
2307 },
2308 },
2309
2310 .nvcl, .cuda => switch (c_type) {
2311 .char => return 8,
2312 .short, .ushort => return 16,
2313 .int, .uint, .float => return 32,
2314 .long, .ulong => switch (target.cpu.arch) {
2315 .nvptx => return 32,
2316 .nvptx64 => return 64,
2317 else => return 64,
2318 },
2319 .longlong, .ulonglong, .double => return 64,
2320 .longdouble => return 64,
2321 },
2322
2323 .amdhsa, .amdpal => switch (c_type) {
2324 .char => return 8,
2325 .short, .ushort => return 16,
2326 .int, .uint, .float => return 32,
2327 .long, .ulong, .longlong, .ulonglong, .double => return 64,
2328 .longdouble => return 128,
2329 },
2330
2331 .opencl => switch (c_type) {
2332 .char => return 8,
2333 .short, .ushort => return 16,
2334 .int, .uint, .float => return 32,
2335 .long, .ulong, .double => return 64,
2336 .longlong, .ulonglong => return 128,
2337 // Note: The OpenCL specification does not guarantee a particular size for long double,
2338 // but clang uses 128 bits.
2339 .longdouble => return 128,
2340 },
2341
2342 .ps4, .ps5 => switch (c_type) {
2343 .char => return 8,
2344 .short, .ushort => return 16,
2345 .int, .uint, .float => return 32,
2346 .long, .ulong => return 64,
2347 .longlong, .ulonglong, .double => return 64,
2348 .longdouble => return 80,
2349 },
2350
2351 .cloudabi,
2352 .kfreebsd,
2353 .lv2,
2354 .zos,
2355 .rtems,
2356 .nacl,
2357 .aix,
2358 .elfiamcu,
2359 .mesa3d,
2360 .contiki,
2361 .hermit,
2362 .hurd,
2363 .glsl450,
2364 .vulkan,
2365 .driverkit,
2366 .shadermodel,
2367 .liteos,
2368 => @panic("TODO specify the C integer and float type sizes for this OS"),
2369 }
2370 }
2371
2372 pub fn c_type_alignment(target: Target, c_type: CType) u16 {
2373 // Overrides for unusual alignments
2374 switch (target.cpu.arch) {
2375 .avr => return 1,
2376 .x86 => switch (target.os.tag) {
2377 .windows, .uefi => switch (c_type) {
2378 .longlong, .ulonglong, .double => return 8,
2379 .longdouble => switch (target.abi) {
2380 .gnu, .gnuilp32, .cygnus => return 4,
2381 else => return 8,
2382 },
2383 else => {},
2384 },
2385 else => {},
2386 },
2387 else => {},
2388 }
2389
2390 // Next-power-of-two-aligned, up to a maximum.
2391 return @min(
2392 std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
2393 switch (target.cpu.arch) {
2394 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
2395 .netbsd => switch (target.abi) {
2396 .gnueabi,
2397 .gnueabihf,
2398 .eabi,
2399 .eabihf,
2400 .android,
2401 .musleabi,
2402 .musleabihf,
2403 => 8,
2404
2405 else => @as(u16, 4),
2406 },
2407 .ios, .tvos, .watchos => 4,
2408 else => 8,
2409 },
2410
2411 .msp430,
2412 .avr,
2413 => 2,
2414
2415 .arc,
2416 .csky,
2417 .x86,
2418 .xcore,
2419 .dxil,
2420 .loongarch32,
2421 .tce,
2422 .tcele,
2423 .le32,
2424 .amdil,
2425 .hsail,
2426 .spir,
2427 .spirv32,
2428 .kalimba,
2429 .shave,
2430 .renderscript32,
2431 .ve,
2432 .spu_2,
2433 .xtensa,
2434 => 4,
2435
2436 .aarch64_32,
2437 .amdgcn,
2438 .amdil64,
2439 .bpfel,
2440 .bpfeb,
2441 .hexagon,
2442 .hsail64,
2443 .loongarch64,
2444 .m68k,
2445 .mips,
2446 .mipsel,
2447 .sparc,
2448 .sparcel,
2449 .sparc64,
2450 .lanai,
2451 .le64,
2452 .nvptx,
2453 .nvptx64,
2454 .r600,
2455 .s390x,
2456 .spir64,
2457 .spirv64,
2458 .renderscript64,
2459 => 8,
2460
2461 .aarch64,
2462 .aarch64_be,
2463 .mips64,
2464 .mips64el,
2465 .powerpc,
2466 .powerpcle,
2467 .powerpc64,
2468 .powerpc64le,
2469 .riscv32,
2470 .riscv64,
2471 .x86_64,
2472 .wasm32,
2473 .wasm64,
2474 => 16,
2475 },
2476 );
2477 }
2478
2479 pub fn c_type_preferred_alignment(target: Target, c_type: CType) u16 {
2480 // Overrides for unusual alignments
2481 switch (target.cpu.arch) {
2482 .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) {
2483 .netbsd => switch (target.abi) {
2484 .gnueabi,
2485 .gnueabihf,
2486 .eabi,
2487 .eabihf,
2488 .android,
2489 .musleabi,
2490 .musleabihf,
2491 => {},
2492
2493 else => switch (c_type) {
2494 .longdouble => return 4,
2495 else => {},
2496 },
2497 },
2498 .ios, .tvos, .watchos => switch (c_type) {
2499 .longdouble => return 4,
2500 else => {},
2501 },
2502 else => {},
2503 },
2504 .arc => switch (c_type) {
2505 .longdouble => return 4,
2506 else => {},
2507 },
2508 .avr => switch (c_type) {
2509 .char, .int, .uint, .long, .ulong, .float, .longdouble => return 1,
2510 .short, .ushort => return 2,
2511 .double => return 4,
2512 .longlong, .ulonglong => return 8,
2513 },
2514 .x86 => switch (target.os.tag) {
2515 .windows, .uefi => switch (c_type) {
2516 .longdouble => switch (target.abi) {
2517 .gnu, .gnuilp32, .cygnus => return 4,
2518 else => return 8,
2519 },
2520 else => {},
2521 },
2522 else => switch (c_type) {
2523 .longdouble => return 4,
2524 else => {},
2525 },
2526 },
2527 else => {},
2528 }
2529
2530 // Next-power-of-two-aligned, up to a maximum.
2531 return @min(
2532 std.math.ceilPowerOfTwoAssert(u16, (c_type_bit_size(target, c_type) + 7) / 8),
2533 switch (target.cpu.arch) {
2534 .msp430 => @as(u16, 2),
2535
2536 .csky,
2537 .xcore,
2538 .dxil,
2539 .loongarch32,
2540 .tce,
2541 .tcele,
2542 .le32,
2543 .amdil,
2544 .hsail,
2545 .spir,
2546 .spirv32,
2547 .kalimba,
2548 .shave,
2549 .renderscript32,
2550 .ve,
2551 .spu_2,
2552 .xtensa,
2553 => 4,
2554
2555 .arc,
2556 .arm,
2557 .armeb,
2558 .avr,
2559 .thumb,
2560 .thumbeb,
2561 .aarch64_32,
2562 .amdgcn,
2563 .amdil64,
2564 .bpfel,
2565 .bpfeb,
2566 .hexagon,
2567 .hsail64,
2568 .x86,
2569 .loongarch64,
2570 .m68k,
2571 .mips,
2572 .mipsel,
2573 .sparc,
2574 .sparcel,
2575 .sparc64,
2576 .lanai,
2577 .le64,
2578 .nvptx,
2579 .nvptx64,
2580 .r600,
2581 .s390x,
2582 .spir64,
2583 .spirv64,
2584 .renderscript64,
2585 => 8,
2586
2587 .aarch64,
2588 .aarch64_be,
2589 .mips64,
2590 .mips64el,
2591 .powerpc,
2592 .powerpcle,
2593 .powerpc64,
2594 .powerpc64le,
2595 .riscv32,
2596 .riscv64,
2597 .x86_64,
2598 .wasm32,
2599 .wasm64,
2600 => 16,
2601 },
2602 );
2603 }
2604};
2605
2606test {
2607 std.testing.refAllDecls(Target.Cpu.Arch);
2608}
lib/std/target/aarch64.zig deleted-2656
......@@ -1,2656 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 a510,
9 a65,
10 a710,
11 a76,
12 a78,
13 a78c,
14 aes,
15 aggressive_fma,
16 alternate_sextload_cvt_f32_pattern,
17 altnzcv,
18 am,
19 amvs,
20 arith_bcc_fusion,
21 arith_cbz_fusion,
22 ascend_store_address,
23 b16b16,
24 balance_fp_ops,
25 bf16,
26 brbe,
27 bti,
28 call_saved_x10,
29 call_saved_x11,
30 call_saved_x12,
31 call_saved_x13,
32 call_saved_x14,
33 call_saved_x15,
34 call_saved_x18,
35 call_saved_x8,
36 call_saved_x9,
37 ccdp,
38 ccidx,
39 ccpp,
40 chk,
41 clrbhb,
42 cmp_bcc_fusion,
43 complxnum,
44 contextidr_el2,
45 cortex_r82,
46 crc,
47 crypto,
48 cssc,
49 custom_cheap_as_move,
50 d128,
51 disable_latency_sched_heuristic,
52 dit,
53 dotprod,
54 ecv,
55 el2vmsa,
56 el3,
57 enable_select_opt,
58 ete,
59 exynos_cheap_as_move,
60 f32mm,
61 f64mm,
62 fgt,
63 fix_cortex_a53_835769,
64 flagm,
65 fmv,
66 force_32bit_jump_tables,
67 fp16fml,
68 fp_armv8,
69 fptoint,
70 fullfp16,
71 fuse_address,
72 fuse_addsub_2reg_const1,
73 fuse_adrp_add,
74 fuse_aes,
75 fuse_arith_logic,
76 fuse_crypto_eor,
77 fuse_csel,
78 fuse_literals,
79 gcs,
80 harden_sls_blr,
81 harden_sls_nocomdat,
82 harden_sls_retbr,
83 hbc,
84 hcx,
85 i8mm,
86 ite,
87 jsconv,
88 lor,
89 ls64,
90 lse,
91 lse128,
92 lse2,
93 lsl_fast,
94 mec,
95 mops,
96 mpam,
97 mte,
98 neon,
99 nmi,
100 no_bti_at_return_twice,
101 no_neg_immediates,
102 no_sve_fp_ld1r,
103 no_zcz_fp,
104 nv,
105 outline_atomics,
106 pan,
107 pan_rwv,
108 pauth,
109 perfmon,
110 predictable_select_expensive,
111 predres,
112 prfm_slc_target,
113 rand,
114 ras,
115 rasv2,
116 rcpc,
117 rcpc3,
118 rcpc_immo,
119 rdm,
120 reserve_x1,
121 reserve_x10,
122 reserve_x11,
123 reserve_x12,
124 reserve_x13,
125 reserve_x14,
126 reserve_x15,
127 reserve_x18,
128 reserve_x2,
129 reserve_x20,
130 reserve_x21,
131 reserve_x22,
132 reserve_x23,
133 reserve_x24,
134 reserve_x25,
135 reserve_x26,
136 reserve_x27,
137 reserve_x28,
138 reserve_x3,
139 reserve_x30,
140 reserve_x4,
141 reserve_x5,
142 reserve_x6,
143 reserve_x7,
144 reserve_x9,
145 rme,
146 sb,
147 sel2,
148 sha2,
149 sha3,
150 slow_misaligned_128store,
151 slow_paired_128,
152 slow_strqro_store,
153 sm4,
154 sme,
155 sme2,
156 sme2p1,
157 sme_f16f16,
158 sme_f64f64,
159 sme_i16i64,
160 spe,
161 spe_eef,
162 specres2,
163 specrestrict,
164 ssbs,
165 strict_align,
166 sve,
167 sve2,
168 sve2_aes,
169 sve2_bitperm,
170 sve2_sha3,
171 sve2_sm4,
172 sve2p1,
173 tagged_globals,
174 the,
175 tlb_rmi,
176 tme,
177 tpidr_el1,
178 tpidr_el2,
179 tpidr_el3,
180 tpidrro_el0,
181 tracev8_4,
182 trbe,
183 uaops,
184 use_experimental_zeroing_pseudos,
185 use_postra_scheduler,
186 use_reciprocal_square_root,
187 use_scalar_inc_vl,
188 v8_1a,
189 v8_2a,
190 v8_3a,
191 v8_4a,
192 v8_5a,
193 v8_6a,
194 v8_7a,
195 v8_8a,
196 v8_9a,
197 v8a,
198 v8r,
199 v9_1a,
200 v9_2a,
201 v9_3a,
202 v9_4a,
203 v9a,
204 vh,
205 wfxt,
206 xs,
207 zcm,
208 zcz,
209 zcz_fp_workaround,
210 zcz_gp,
211};
212
213pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
214pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
215pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
216pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
217
218pub const all_features = blk: {
219 @setEvalBranchQuota(2000);
220 const len = @typeInfo(Feature).Enum.fields.len;
221 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
222 var result: [len]CpuFeature = undefined;
223 result[@intFromEnum(Feature.a510)] = .{
224 .llvm_name = "a510",
225 .description = "Cortex-A510 ARM processors",
226 .dependencies = featureSet(&[_]Feature{
227 .fuse_adrp_add,
228 .fuse_aes,
229 .use_postra_scheduler,
230 }),
231 };
232 result[@intFromEnum(Feature.a65)] = .{
233 .llvm_name = "a65",
234 .description = "Cortex-A65 ARM processors",
235 .dependencies = featureSet(&[_]Feature{
236 .enable_select_opt,
237 .fuse_address,
238 .fuse_adrp_add,
239 .fuse_aes,
240 .fuse_literals,
241 .predictable_select_expensive,
242 }),
243 };
244 result[@intFromEnum(Feature.a710)] = .{
245 .llvm_name = "a710",
246 .description = "Cortex-A710 ARM processors",
247 .dependencies = featureSet(&[_]Feature{
248 .cmp_bcc_fusion,
249 .enable_select_opt,
250 .fuse_adrp_add,
251 .fuse_aes,
252 .lsl_fast,
253 .predictable_select_expensive,
254 .use_postra_scheduler,
255 }),
256 };
257 result[@intFromEnum(Feature.a76)] = .{
258 .llvm_name = "a76",
259 .description = "Cortex-A76 ARM processors",
260 .dependencies = featureSet(&[_]Feature{
261 .enable_select_opt,
262 .fuse_adrp_add,
263 .fuse_aes,
264 .lsl_fast,
265 .predictable_select_expensive,
266 }),
267 };
268 result[@intFromEnum(Feature.a78)] = .{
269 .llvm_name = "a78",
270 .description = "Cortex-A78 ARM processors",
271 .dependencies = featureSet(&[_]Feature{
272 .cmp_bcc_fusion,
273 .enable_select_opt,
274 .fuse_adrp_add,
275 .fuse_aes,
276 .lsl_fast,
277 .predictable_select_expensive,
278 .use_postra_scheduler,
279 }),
280 };
281 result[@intFromEnum(Feature.a78c)] = .{
282 .llvm_name = "a78c",
283 .description = "Cortex-A78C ARM processors",
284 .dependencies = featureSet(&[_]Feature{
285 .cmp_bcc_fusion,
286 .enable_select_opt,
287 .fuse_adrp_add,
288 .fuse_aes,
289 .lsl_fast,
290 .predictable_select_expensive,
291 .use_postra_scheduler,
292 }),
293 };
294 result[@intFromEnum(Feature.aes)] = .{
295 .llvm_name = "aes",
296 .description = "Enable AES support (FEAT_AES, FEAT_PMULL)",
297 .dependencies = featureSet(&[_]Feature{
298 .neon,
299 }),
300 };
301 result[@intFromEnum(Feature.aggressive_fma)] = .{
302 .llvm_name = "aggressive-fma",
303 .description = "Enable Aggressive FMA for floating-point.",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@intFromEnum(Feature.alternate_sextload_cvt_f32_pattern)] = .{
307 .llvm_name = "alternate-sextload-cvt-f32-pattern",
308 .description = "Use alternative pattern for sextload convert to f32",
309 .dependencies = featureSet(&[_]Feature{}),
310 };
311 result[@intFromEnum(Feature.altnzcv)] = .{
312 .llvm_name = "altnzcv",
313 .description = "Enable alternative NZCV format for floating point comparisons (FEAT_FlagM2)",
314 .dependencies = featureSet(&[_]Feature{}),
315 };
316 result[@intFromEnum(Feature.am)] = .{
317 .llvm_name = "am",
318 .description = "Enable v8.4-A Activity Monitors extension (FEAT_AMUv1)",
319 .dependencies = featureSet(&[_]Feature{}),
320 };
321 result[@intFromEnum(Feature.amvs)] = .{
322 .llvm_name = "amvs",
323 .description = "Enable v8.6-A Activity Monitors Virtualization support (FEAT_AMUv1p1)",
324 .dependencies = featureSet(&[_]Feature{
325 .am,
326 }),
327 };
328 result[@intFromEnum(Feature.arith_bcc_fusion)] = .{
329 .llvm_name = "arith-bcc-fusion",
330 .description = "CPU fuses arithmetic+bcc operations",
331 .dependencies = featureSet(&[_]Feature{}),
332 };
333 result[@intFromEnum(Feature.arith_cbz_fusion)] = .{
334 .llvm_name = "arith-cbz-fusion",
335 .description = "CPU fuses arithmetic + cbz/cbnz operations",
336 .dependencies = featureSet(&[_]Feature{}),
337 };
338 result[@intFromEnum(Feature.ascend_store_address)] = .{
339 .llvm_name = "ascend-store-address",
340 .description = "Schedule vector stores by ascending address",
341 .dependencies = featureSet(&[_]Feature{}),
342 };
343 result[@intFromEnum(Feature.b16b16)] = .{
344 .llvm_name = "b16b16",
345 .description = "Enable SVE2.1 or SME2.1 non-widening BFloat16 to BFloat16 instructions (FEAT_B16B16)",
346 .dependencies = featureSet(&[_]Feature{}),
347 };
348 result[@intFromEnum(Feature.balance_fp_ops)] = .{
349 .llvm_name = "balance-fp-ops",
350 .description = "balance mix of odd and even D-registers for fp multiply(-accumulate) ops",
351 .dependencies = featureSet(&[_]Feature{}),
352 };
353 result[@intFromEnum(Feature.bf16)] = .{
354 .llvm_name = "bf16",
355 .description = "Enable BFloat16 Extension (FEAT_BF16)",
356 .dependencies = featureSet(&[_]Feature{}),
357 };
358 result[@intFromEnum(Feature.brbe)] = .{
359 .llvm_name = "brbe",
360 .description = "Enable Branch Record Buffer Extension (FEAT_BRBE)",
361 .dependencies = featureSet(&[_]Feature{}),
362 };
363 result[@intFromEnum(Feature.bti)] = .{
364 .llvm_name = "bti",
365 .description = "Enable Branch Target Identification (FEAT_BTI)",
366 .dependencies = featureSet(&[_]Feature{}),
367 };
368 result[@intFromEnum(Feature.call_saved_x10)] = .{
369 .llvm_name = "call-saved-x10",
370 .description = "Make X10 callee saved.",
371 .dependencies = featureSet(&[_]Feature{}),
372 };
373 result[@intFromEnum(Feature.call_saved_x11)] = .{
374 .llvm_name = "call-saved-x11",
375 .description = "Make X11 callee saved.",
376 .dependencies = featureSet(&[_]Feature{}),
377 };
378 result[@intFromEnum(Feature.call_saved_x12)] = .{
379 .llvm_name = "call-saved-x12",
380 .description = "Make X12 callee saved.",
381 .dependencies = featureSet(&[_]Feature{}),
382 };
383 result[@intFromEnum(Feature.call_saved_x13)] = .{
384 .llvm_name = "call-saved-x13",
385 .description = "Make X13 callee saved.",
386 .dependencies = featureSet(&[_]Feature{}),
387 };
388 result[@intFromEnum(Feature.call_saved_x14)] = .{
389 .llvm_name = "call-saved-x14",
390 .description = "Make X14 callee saved.",
391 .dependencies = featureSet(&[_]Feature{}),
392 };
393 result[@intFromEnum(Feature.call_saved_x15)] = .{
394 .llvm_name = "call-saved-x15",
395 .description = "Make X15 callee saved.",
396 .dependencies = featureSet(&[_]Feature{}),
397 };
398 result[@intFromEnum(Feature.call_saved_x18)] = .{
399 .llvm_name = "call-saved-x18",
400 .description = "Make X18 callee saved.",
401 .dependencies = featureSet(&[_]Feature{}),
402 };
403 result[@intFromEnum(Feature.call_saved_x8)] = .{
404 .llvm_name = "call-saved-x8",
405 .description = "Make X8 callee saved.",
406 .dependencies = featureSet(&[_]Feature{}),
407 };
408 result[@intFromEnum(Feature.call_saved_x9)] = .{
409 .llvm_name = "call-saved-x9",
410 .description = "Make X9 callee saved.",
411 .dependencies = featureSet(&[_]Feature{}),
412 };
413 result[@intFromEnum(Feature.ccdp)] = .{
414 .llvm_name = "ccdp",
415 .description = "Enable v8.5 Cache Clean to Point of Deep Persistence (FEAT_DPB2)",
416 .dependencies = featureSet(&[_]Feature{}),
417 };
418 result[@intFromEnum(Feature.ccidx)] = .{
419 .llvm_name = "ccidx",
420 .description = "Enable v8.3-A Extend of the CCSIDR number of sets (FEAT_CCIDX)",
421 .dependencies = featureSet(&[_]Feature{}),
422 };
423 result[@intFromEnum(Feature.ccpp)] = .{
424 .llvm_name = "ccpp",
425 .description = "Enable v8.2 data Cache Clean to Point of Persistence (FEAT_DPB)",
426 .dependencies = featureSet(&[_]Feature{}),
427 };
428 result[@intFromEnum(Feature.chk)] = .{
429 .llvm_name = "chk",
430 .description = "Enable Armv8.0-A Check Feature Status Extension (FEAT_CHK)",
431 .dependencies = featureSet(&[_]Feature{}),
432 };
433 result[@intFromEnum(Feature.clrbhb)] = .{
434 .llvm_name = "clrbhb",
435 .description = "Enable Clear BHB instruction (FEAT_CLRBHB)",
436 .dependencies = featureSet(&[_]Feature{}),
437 };
438 result[@intFromEnum(Feature.cmp_bcc_fusion)] = .{
439 .llvm_name = "cmp-bcc-fusion",
440 .description = "CPU fuses cmp+bcc operations",
441 .dependencies = featureSet(&[_]Feature{}),
442 };
443 result[@intFromEnum(Feature.complxnum)] = .{
444 .llvm_name = "complxnum",
445 .description = "Enable v8.3-A Floating-point complex number support (FEAT_FCMA)",
446 .dependencies = featureSet(&[_]Feature{
447 .neon,
448 }),
449 };
450 result[@intFromEnum(Feature.contextidr_el2)] = .{
451 .llvm_name = "CONTEXTIDREL2",
452 .description = "Enable RW operand Context ID Register (EL2)",
453 .dependencies = featureSet(&[_]Feature{}),
454 };
455 result[@intFromEnum(Feature.cortex_r82)] = .{
456 .llvm_name = "cortex-r82",
457 .description = "Cortex-R82 ARM processors",
458 .dependencies = featureSet(&[_]Feature{
459 .use_postra_scheduler,
460 }),
461 };
462 result[@intFromEnum(Feature.crc)] = .{
463 .llvm_name = "crc",
464 .description = "Enable ARMv8 CRC-32 checksum instructions (FEAT_CRC32)",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@intFromEnum(Feature.crypto)] = .{
468 .llvm_name = "crypto",
469 .description = "Enable cryptographic instructions",
470 .dependencies = featureSet(&[_]Feature{
471 .aes,
472 .sha2,
473 }),
474 };
475 result[@intFromEnum(Feature.cssc)] = .{
476 .llvm_name = "cssc",
477 .description = "Enable Common Short Sequence Compression (CSSC) instructions (FEAT_CSSC)",
478 .dependencies = featureSet(&[_]Feature{}),
479 };
480 result[@intFromEnum(Feature.custom_cheap_as_move)] = .{
481 .llvm_name = "custom-cheap-as-move",
482 .description = "Use custom handling of cheap instructions",
483 .dependencies = featureSet(&[_]Feature{}),
484 };
485 result[@intFromEnum(Feature.d128)] = .{
486 .llvm_name = "d128",
487 .description = "Enable Armv9.4-A 128-bit Page Table Descriptors, System Registers and Instructions (FEAT_D128, FEAT_LVA3, FEAT_SYSREG128, FEAT_SYSINSTR128)",
488 .dependencies = featureSet(&[_]Feature{
489 .lse128,
490 }),
491 };
492 result[@intFromEnum(Feature.disable_latency_sched_heuristic)] = .{
493 .llvm_name = "disable-latency-sched-heuristic",
494 .description = "Disable latency scheduling heuristic",
495 .dependencies = featureSet(&[_]Feature{}),
496 };
497 result[@intFromEnum(Feature.dit)] = .{
498 .llvm_name = "dit",
499 .description = "Enable v8.4-A Data Independent Timing instructions (FEAT_DIT)",
500 .dependencies = featureSet(&[_]Feature{}),
501 };
502 result[@intFromEnum(Feature.dotprod)] = .{
503 .llvm_name = "dotprod",
504 .description = "Enable dot product support (FEAT_DotProd)",
505 .dependencies = featureSet(&[_]Feature{}),
506 };
507 result[@intFromEnum(Feature.ecv)] = .{
508 .llvm_name = "ecv",
509 .description = "Enable enhanced counter virtualization extension (FEAT_ECV)",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@intFromEnum(Feature.el2vmsa)] = .{
513 .llvm_name = "el2vmsa",
514 .description = "Enable Exception Level 2 Virtual Memory System Architecture",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@intFromEnum(Feature.el3)] = .{
518 .llvm_name = "el3",
519 .description = "Enable Exception Level 3",
520 .dependencies = featureSet(&[_]Feature{}),
521 };
522 result[@intFromEnum(Feature.enable_select_opt)] = .{
523 .llvm_name = "enable-select-opt",
524 .description = "Enable the select optimize pass for select loop heuristics",
525 .dependencies = featureSet(&[_]Feature{}),
526 };
527 result[@intFromEnum(Feature.ete)] = .{
528 .llvm_name = "ete",
529 .description = "Enable Embedded Trace Extension (FEAT_ETE)",
530 .dependencies = featureSet(&[_]Feature{
531 .trbe,
532 }),
533 };
534 result[@intFromEnum(Feature.exynos_cheap_as_move)] = .{
535 .llvm_name = "exynos-cheap-as-move",
536 .description = "Use Exynos specific handling of cheap instructions",
537 .dependencies = featureSet(&[_]Feature{
538 .custom_cheap_as_move,
539 }),
540 };
541 result[@intFromEnum(Feature.f32mm)] = .{
542 .llvm_name = "f32mm",
543 .description = "Enable Matrix Multiply FP32 Extension (FEAT_F32MM)",
544 .dependencies = featureSet(&[_]Feature{
545 .sve,
546 }),
547 };
548 result[@intFromEnum(Feature.f64mm)] = .{
549 .llvm_name = "f64mm",
550 .description = "Enable Matrix Multiply FP64 Extension (FEAT_F64MM)",
551 .dependencies = featureSet(&[_]Feature{
552 .sve,
553 }),
554 };
555 result[@intFromEnum(Feature.fgt)] = .{
556 .llvm_name = "fgt",
557 .description = "Enable fine grained virtualization traps extension (FEAT_FGT)",
558 .dependencies = featureSet(&[_]Feature{}),
559 };
560 result[@intFromEnum(Feature.fix_cortex_a53_835769)] = .{
561 .llvm_name = "fix-cortex-a53-835769",
562 .description = "Mitigate Cortex-A53 Erratum 835769",
563 .dependencies = featureSet(&[_]Feature{}),
564 };
565 result[@intFromEnum(Feature.flagm)] = .{
566 .llvm_name = "flagm",
567 .description = "Enable v8.4-A Flag Manipulation Instructions (FEAT_FlagM)",
568 .dependencies = featureSet(&[_]Feature{}),
569 };
570 result[@intFromEnum(Feature.fmv)] = .{
571 .llvm_name = "fmv",
572 .description = "Enable Function Multi Versioning support.",
573 .dependencies = featureSet(&[_]Feature{}),
574 };
575 result[@intFromEnum(Feature.force_32bit_jump_tables)] = .{
576 .llvm_name = "force-32bit-jump-tables",
577 .description = "Force jump table entries to be 32-bits wide except at MinSize",
578 .dependencies = featureSet(&[_]Feature{}),
579 };
580 result[@intFromEnum(Feature.fp16fml)] = .{
581 .llvm_name = "fp16fml",
582 .description = "Enable FP16 FML instructions (FEAT_FHM)",
583 .dependencies = featureSet(&[_]Feature{
584 .fullfp16,
585 }),
586 };
587 result[@intFromEnum(Feature.fp_armv8)] = .{
588 .llvm_name = "fp-armv8",
589 .description = "Enable ARMv8 FP (FEAT_FP)",
590 .dependencies = featureSet(&[_]Feature{}),
591 };
592 result[@intFromEnum(Feature.fptoint)] = .{
593 .llvm_name = "fptoint",
594 .description = "Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int (FEAT_FRINTTS)",
595 .dependencies = featureSet(&[_]Feature{}),
596 };
597 result[@intFromEnum(Feature.fullfp16)] = .{
598 .llvm_name = "fullfp16",
599 .description = "Full FP16 (FEAT_FP16)",
600 .dependencies = featureSet(&[_]Feature{
601 .fp_armv8,
602 }),
603 };
604 result[@intFromEnum(Feature.fuse_address)] = .{
605 .llvm_name = "fuse-address",
606 .description = "CPU fuses address generation and memory operations",
607 .dependencies = featureSet(&[_]Feature{}),
608 };
609 result[@intFromEnum(Feature.fuse_addsub_2reg_const1)] = .{
610 .llvm_name = "fuse-addsub-2reg-const1",
611 .description = "CPU fuses (a + b + 1) and (a - b - 1)",
612 .dependencies = featureSet(&[_]Feature{}),
613 };
614 result[@intFromEnum(Feature.fuse_adrp_add)] = .{
615 .llvm_name = "fuse-adrp-add",
616 .description = "CPU fuses adrp+add operations",
617 .dependencies = featureSet(&[_]Feature{}),
618 };
619 result[@intFromEnum(Feature.fuse_aes)] = .{
620 .llvm_name = "fuse-aes",
621 .description = "CPU fuses AES crypto operations",
622 .dependencies = featureSet(&[_]Feature{}),
623 };
624 result[@intFromEnum(Feature.fuse_arith_logic)] = .{
625 .llvm_name = "fuse-arith-logic",
626 .description = "CPU fuses arithmetic and logic operations",
627 .dependencies = featureSet(&[_]Feature{}),
628 };
629 result[@intFromEnum(Feature.fuse_crypto_eor)] = .{
630 .llvm_name = "fuse-crypto-eor",
631 .description = "CPU fuses AES/PMULL and EOR operations",
632 .dependencies = featureSet(&[_]Feature{}),
633 };
634 result[@intFromEnum(Feature.fuse_csel)] = .{
635 .llvm_name = "fuse-csel",
636 .description = "CPU fuses conditional select operations",
637 .dependencies = featureSet(&[_]Feature{}),
638 };
639 result[@intFromEnum(Feature.fuse_literals)] = .{
640 .llvm_name = "fuse-literals",
641 .description = "CPU fuses literal generation operations",
642 .dependencies = featureSet(&[_]Feature{}),
643 };
644 result[@intFromEnum(Feature.gcs)] = .{
645 .llvm_name = "gcs",
646 .description = "Enable Armv9.4-A Guarded Call Stack Extension",
647 .dependencies = featureSet(&[_]Feature{
648 .chk,
649 }),
650 };
651 result[@intFromEnum(Feature.harden_sls_blr)] = .{
652 .llvm_name = "harden-sls-blr",
653 .description = "Harden against straight line speculation across BLR instructions",
654 .dependencies = featureSet(&[_]Feature{}),
655 };
656 result[@intFromEnum(Feature.harden_sls_nocomdat)] = .{
657 .llvm_name = "harden-sls-nocomdat",
658 .description = "Generate thunk code for SLS mitigation in the normal text section",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.harden_sls_retbr)] = .{
662 .llvm_name = "harden-sls-retbr",
663 .description = "Harden against straight line speculation across RET and BR instructions",
664 .dependencies = featureSet(&[_]Feature{}),
665 };
666 result[@intFromEnum(Feature.hbc)] = .{
667 .llvm_name = "hbc",
668 .description = "Enable Armv8.8-A Hinted Conditional Branches Extension (FEAT_HBC)",
669 .dependencies = featureSet(&[_]Feature{}),
670 };
671 result[@intFromEnum(Feature.hcx)] = .{
672 .llvm_name = "hcx",
673 .description = "Enable Armv8.7-A HCRX_EL2 system register (FEAT_HCX)",
674 .dependencies = featureSet(&[_]Feature{}),
675 };
676 result[@intFromEnum(Feature.i8mm)] = .{
677 .llvm_name = "i8mm",
678 .description = "Enable Matrix Multiply Int8 Extension (FEAT_I8MM)",
679 .dependencies = featureSet(&[_]Feature{}),
680 };
681 result[@intFromEnum(Feature.ite)] = .{
682 .llvm_name = "ite",
683 .description = "Enable Armv9.4-A Instrumentation Extension FEAT_ITE",
684 .dependencies = featureSet(&[_]Feature{
685 .ete,
686 }),
687 };
688 result[@intFromEnum(Feature.jsconv)] = .{
689 .llvm_name = "jsconv",
690 .description = "Enable v8.3-A JavaScript FP conversion instructions (FEAT_JSCVT)",
691 .dependencies = featureSet(&[_]Feature{
692 .fp_armv8,
693 }),
694 };
695 result[@intFromEnum(Feature.lor)] = .{
696 .llvm_name = "lor",
697 .description = "Enables ARM v8.1 Limited Ordering Regions extension (FEAT_LOR)",
698 .dependencies = featureSet(&[_]Feature{}),
699 };
700 result[@intFromEnum(Feature.ls64)] = .{
701 .llvm_name = "ls64",
702 .description = "Enable Armv8.7-A LD64B/ST64B Accelerator Extension (FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA)",
703 .dependencies = featureSet(&[_]Feature{}),
704 };
705 result[@intFromEnum(Feature.lse)] = .{
706 .llvm_name = "lse",
707 .description = "Enable ARMv8.1 Large System Extension (LSE) atomic instructions (FEAT_LSE)",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.lse128)] = .{
711 .llvm_name = "lse128",
712 .description = "Enable Armv9.4-A 128-bit Atomic Instructions (FEAT_LSE128)",
713 .dependencies = featureSet(&[_]Feature{
714 .lse,
715 }),
716 };
717 result[@intFromEnum(Feature.lse2)] = .{
718 .llvm_name = "lse2",
719 .description = "Enable ARMv8.4 Large System Extension 2 (LSE2) atomicity rules (FEAT_LSE2)",
720 .dependencies = featureSet(&[_]Feature{}),
721 };
722 result[@intFromEnum(Feature.lsl_fast)] = .{
723 .llvm_name = "lsl-fast",
724 .description = "CPU has a fastpath logical shift of up to 3 places",
725 .dependencies = featureSet(&[_]Feature{}),
726 };
727 result[@intFromEnum(Feature.mec)] = .{
728 .llvm_name = "mec",
729 .description = "Enable Memory Encryption Contexts Extension",
730 .dependencies = featureSet(&[_]Feature{
731 .rme,
732 }),
733 };
734 result[@intFromEnum(Feature.mops)] = .{
735 .llvm_name = "mops",
736 .description = "Enable Armv8.8-A memcpy and memset acceleration instructions (FEAT_MOPS)",
737 .dependencies = featureSet(&[_]Feature{}),
738 };
739 result[@intFromEnum(Feature.mpam)] = .{
740 .llvm_name = "mpam",
741 .description = "Enable v8.4-A Memory system Partitioning and Monitoring extension (FEAT_MPAM)",
742 .dependencies = featureSet(&[_]Feature{}),
743 };
744 result[@intFromEnum(Feature.mte)] = .{
745 .llvm_name = "mte",
746 .description = "Enable Memory Tagging Extension (FEAT_MTE, FEAT_MTE2)",
747 .dependencies = featureSet(&[_]Feature{}),
748 };
749 result[@intFromEnum(Feature.neon)] = .{
750 .llvm_name = "neon",
751 .description = "Enable Advanced SIMD instructions (FEAT_AdvSIMD)",
752 .dependencies = featureSet(&[_]Feature{
753 .fp_armv8,
754 }),
755 };
756 result[@intFromEnum(Feature.nmi)] = .{
757 .llvm_name = "nmi",
758 .description = "Enable Armv8.8-A Non-maskable Interrupts (FEAT_NMI, FEAT_GICv3_NMI)",
759 .dependencies = featureSet(&[_]Feature{}),
760 };
761 result[@intFromEnum(Feature.no_bti_at_return_twice)] = .{
762 .llvm_name = "no-bti-at-return-twice",
763 .description = "Don't place a BTI instruction after a return-twice",
764 .dependencies = featureSet(&[_]Feature{}),
765 };
766 result[@intFromEnum(Feature.no_neg_immediates)] = .{
767 .llvm_name = "no-neg-immediates",
768 .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
769 .dependencies = featureSet(&[_]Feature{}),
770 };
771 result[@intFromEnum(Feature.no_sve_fp_ld1r)] = .{
772 .llvm_name = "no-sve-fp-ld1r",
773 .description = "Avoid using LD1RX instructions for FP",
774 .dependencies = featureSet(&[_]Feature{}),
775 };
776 result[@intFromEnum(Feature.no_zcz_fp)] = .{
777 .llvm_name = "no-zcz-fp",
778 .description = "Has no zero-cycle zeroing instructions for FP registers",
779 .dependencies = featureSet(&[_]Feature{}),
780 };
781 result[@intFromEnum(Feature.nv)] = .{
782 .llvm_name = "nv",
783 .description = "Enable v8.4-A Nested Virtualization Enchancement (FEAT_NV, FEAT_NV2)",
784 .dependencies = featureSet(&[_]Feature{}),
785 };
786 result[@intFromEnum(Feature.outline_atomics)] = .{
787 .llvm_name = "outline-atomics",
788 .description = "Enable out of line atomics to support LSE instructions",
789 .dependencies = featureSet(&[_]Feature{}),
790 };
791 result[@intFromEnum(Feature.pan)] = .{
792 .llvm_name = "pan",
793 .description = "Enables ARM v8.1 Privileged Access-Never extension (FEAT_PAN)",
794 .dependencies = featureSet(&[_]Feature{}),
795 };
796 result[@intFromEnum(Feature.pan_rwv)] = .{
797 .llvm_name = "pan-rwv",
798 .description = "Enable v8.2 PAN s1e1R and s1e1W Variants (FEAT_PAN2)",
799 .dependencies = featureSet(&[_]Feature{
800 .pan,
801 }),
802 };
803 result[@intFromEnum(Feature.pauth)] = .{
804 .llvm_name = "pauth",
805 .description = "Enable v8.3-A Pointer Authentication extension (FEAT_PAuth)",
806 .dependencies = featureSet(&[_]Feature{}),
807 };
808 result[@intFromEnum(Feature.perfmon)] = .{
809 .llvm_name = "perfmon",
810 .description = "Enable Code Generation for ARMv8 PMUv3 Performance Monitors extension (FEAT_PMUv3)",
811 .dependencies = featureSet(&[_]Feature{}),
812 };
813 result[@intFromEnum(Feature.predictable_select_expensive)] = .{
814 .llvm_name = "predictable-select-expensive",
815 .description = "Prefer likely predicted branches over selects",
816 .dependencies = featureSet(&[_]Feature{}),
817 };
818 result[@intFromEnum(Feature.predres)] = .{
819 .llvm_name = "predres",
820 .description = "Enable v8.5a execution and data prediction invalidation instructions (FEAT_SPECRES)",
821 .dependencies = featureSet(&[_]Feature{}),
822 };
823 result[@intFromEnum(Feature.prfm_slc_target)] = .{
824 .llvm_name = "prfm-slc-target",
825 .description = "Enable SLC target for PRFM instruction",
826 .dependencies = featureSet(&[_]Feature{}),
827 };
828 result[@intFromEnum(Feature.rand)] = .{
829 .llvm_name = "rand",
830 .description = "Enable Random Number generation instructions (FEAT_RNG)",
831 .dependencies = featureSet(&[_]Feature{}),
832 };
833 result[@intFromEnum(Feature.ras)] = .{
834 .llvm_name = "ras",
835 .description = "Enable ARMv8 Reliability, Availability and Serviceability Extensions (FEAT_RAS, FEAT_RASv1p1)",
836 .dependencies = featureSet(&[_]Feature{}),
837 };
838 result[@intFromEnum(Feature.rasv2)] = .{
839 .llvm_name = "rasv2",
840 .description = "Enable ARMv8.9-A Reliability, Availability and Serviceability Extensions (FEAT_RASv2)",
841 .dependencies = featureSet(&[_]Feature{
842 .ras,
843 }),
844 };
845 result[@intFromEnum(Feature.rcpc)] = .{
846 .llvm_name = "rcpc",
847 .description = "Enable support for RCPC extension (FEAT_LRCPC)",
848 .dependencies = featureSet(&[_]Feature{}),
849 };
850 result[@intFromEnum(Feature.rcpc3)] = .{
851 .llvm_name = "rcpc3",
852 .description = "Enable Armv8.9-A RCPC instructions for A64 and Advanced SIMD and floating-point instruction set (FEAT_LRCPC3)",
853 .dependencies = featureSet(&[_]Feature{
854 .rcpc_immo,
855 }),
856 };
857 result[@intFromEnum(Feature.rcpc_immo)] = .{
858 .llvm_name = "rcpc-immo",
859 .description = "Enable v8.4-A RCPC instructions with Immediate Offsets (FEAT_LRCPC2)",
860 .dependencies = featureSet(&[_]Feature{
861 .rcpc,
862 }),
863 };
864 result[@intFromEnum(Feature.rdm)] = .{
865 .llvm_name = "rdm",
866 .description = "Enable ARMv8.1 Rounding Double Multiply Add/Subtract instructions (FEAT_RDM)",
867 .dependencies = featureSet(&[_]Feature{}),
868 };
869 result[@intFromEnum(Feature.reserve_x1)] = .{
870 .llvm_name = "reserve-x1",
871 .description = "Reserve X1, making it unavailable as a GPR",
872 .dependencies = featureSet(&[_]Feature{}),
873 };
874 result[@intFromEnum(Feature.reserve_x10)] = .{
875 .llvm_name = "reserve-x10",
876 .description = "Reserve X10, making it unavailable as a GPR",
877 .dependencies = featureSet(&[_]Feature{}),
878 };
879 result[@intFromEnum(Feature.reserve_x11)] = .{
880 .llvm_name = "reserve-x11",
881 .description = "Reserve X11, making it unavailable as a GPR",
882 .dependencies = featureSet(&[_]Feature{}),
883 };
884 result[@intFromEnum(Feature.reserve_x12)] = .{
885 .llvm_name = "reserve-x12",
886 .description = "Reserve X12, making it unavailable as a GPR",
887 .dependencies = featureSet(&[_]Feature{}),
888 };
889 result[@intFromEnum(Feature.reserve_x13)] = .{
890 .llvm_name = "reserve-x13",
891 .description = "Reserve X13, making it unavailable as a GPR",
892 .dependencies = featureSet(&[_]Feature{}),
893 };
894 result[@intFromEnum(Feature.reserve_x14)] = .{
895 .llvm_name = "reserve-x14",
896 .description = "Reserve X14, making it unavailable as a GPR",
897 .dependencies = featureSet(&[_]Feature{}),
898 };
899 result[@intFromEnum(Feature.reserve_x15)] = .{
900 .llvm_name = "reserve-x15",
901 .description = "Reserve X15, making it unavailable as a GPR",
902 .dependencies = featureSet(&[_]Feature{}),
903 };
904 result[@intFromEnum(Feature.reserve_x18)] = .{
905 .llvm_name = "reserve-x18",
906 .description = "Reserve X18, making it unavailable as a GPR",
907 .dependencies = featureSet(&[_]Feature{}),
908 };
909 result[@intFromEnum(Feature.reserve_x2)] = .{
910 .llvm_name = "reserve-x2",
911 .description = "Reserve X2, making it unavailable as a GPR",
912 .dependencies = featureSet(&[_]Feature{}),
913 };
914 result[@intFromEnum(Feature.reserve_x20)] = .{
915 .llvm_name = "reserve-x20",
916 .description = "Reserve X20, making it unavailable as a GPR",
917 .dependencies = featureSet(&[_]Feature{}),
918 };
919 result[@intFromEnum(Feature.reserve_x21)] = .{
920 .llvm_name = "reserve-x21",
921 .description = "Reserve X21, making it unavailable as a GPR",
922 .dependencies = featureSet(&[_]Feature{}),
923 };
924 result[@intFromEnum(Feature.reserve_x22)] = .{
925 .llvm_name = "reserve-x22",
926 .description = "Reserve X22, making it unavailable as a GPR",
927 .dependencies = featureSet(&[_]Feature{}),
928 };
929 result[@intFromEnum(Feature.reserve_x23)] = .{
930 .llvm_name = "reserve-x23",
931 .description = "Reserve X23, making it unavailable as a GPR",
932 .dependencies = featureSet(&[_]Feature{}),
933 };
934 result[@intFromEnum(Feature.reserve_x24)] = .{
935 .llvm_name = "reserve-x24",
936 .description = "Reserve X24, making it unavailable as a GPR",
937 .dependencies = featureSet(&[_]Feature{}),
938 };
939 result[@intFromEnum(Feature.reserve_x25)] = .{
940 .llvm_name = "reserve-x25",
941 .description = "Reserve X25, making it unavailable as a GPR",
942 .dependencies = featureSet(&[_]Feature{}),
943 };
944 result[@intFromEnum(Feature.reserve_x26)] = .{
945 .llvm_name = "reserve-x26",
946 .description = "Reserve X26, making it unavailable as a GPR",
947 .dependencies = featureSet(&[_]Feature{}),
948 };
949 result[@intFromEnum(Feature.reserve_x27)] = .{
950 .llvm_name = "reserve-x27",
951 .description = "Reserve X27, making it unavailable as a GPR",
952 .dependencies = featureSet(&[_]Feature{}),
953 };
954 result[@intFromEnum(Feature.reserve_x28)] = .{
955 .llvm_name = "reserve-x28",
956 .description = "Reserve X28, making it unavailable as a GPR",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.reserve_x3)] = .{
960 .llvm_name = "reserve-x3",
961 .description = "Reserve X3, making it unavailable as a GPR",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.reserve_x30)] = .{
965 .llvm_name = "reserve-x30",
966 .description = "Reserve X30, making it unavailable as a GPR",
967 .dependencies = featureSet(&[_]Feature{}),
968 };
969 result[@intFromEnum(Feature.reserve_x4)] = .{
970 .llvm_name = "reserve-x4",
971 .description = "Reserve X4, making it unavailable as a GPR",
972 .dependencies = featureSet(&[_]Feature{}),
973 };
974 result[@intFromEnum(Feature.reserve_x5)] = .{
975 .llvm_name = "reserve-x5",
976 .description = "Reserve X5, making it unavailable as a GPR",
977 .dependencies = featureSet(&[_]Feature{}),
978 };
979 result[@intFromEnum(Feature.reserve_x6)] = .{
980 .llvm_name = "reserve-x6",
981 .description = "Reserve X6, making it unavailable as a GPR",
982 .dependencies = featureSet(&[_]Feature{}),
983 };
984 result[@intFromEnum(Feature.reserve_x7)] = .{
985 .llvm_name = "reserve-x7",
986 .description = "Reserve X7, making it unavailable as a GPR",
987 .dependencies = featureSet(&[_]Feature{}),
988 };
989 result[@intFromEnum(Feature.reserve_x9)] = .{
990 .llvm_name = "reserve-x9",
991 .description = "Reserve X9, making it unavailable as a GPR",
992 .dependencies = featureSet(&[_]Feature{}),
993 };
994 result[@intFromEnum(Feature.rme)] = .{
995 .llvm_name = "rme",
996 .description = "Enable Realm Management Extension (FEAT_RME)",
997 .dependencies = featureSet(&[_]Feature{}),
998 };
999 result[@intFromEnum(Feature.sb)] = .{
1000 .llvm_name = "sb",
1001 .description = "Enable v8.5 Speculation Barrier (FEAT_SB)",
1002 .dependencies = featureSet(&[_]Feature{}),
1003 };
1004 result[@intFromEnum(Feature.sel2)] = .{
1005 .llvm_name = "sel2",
1006 .description = "Enable v8.4-A Secure Exception Level 2 extension (FEAT_SEL2)",
1007 .dependencies = featureSet(&[_]Feature{}),
1008 };
1009 result[@intFromEnum(Feature.sha2)] = .{
1010 .llvm_name = "sha2",
1011 .description = "Enable SHA1 and SHA256 support (FEAT_SHA1, FEAT_SHA256)",
1012 .dependencies = featureSet(&[_]Feature{
1013 .neon,
1014 }),
1015 };
1016 result[@intFromEnum(Feature.sha3)] = .{
1017 .llvm_name = "sha3",
1018 .description = "Enable SHA512 and SHA3 support (FEAT_SHA3, FEAT_SHA512)",
1019 .dependencies = featureSet(&[_]Feature{
1020 .sha2,
1021 }),
1022 };
1023 result[@intFromEnum(Feature.slow_misaligned_128store)] = .{
1024 .llvm_name = "slow-misaligned-128store",
1025 .description = "Misaligned 128 bit stores are slow",
1026 .dependencies = featureSet(&[_]Feature{}),
1027 };
1028 result[@intFromEnum(Feature.slow_paired_128)] = .{
1029 .llvm_name = "slow-paired-128",
1030 .description = "Paired 128 bit loads and stores are slow",
1031 .dependencies = featureSet(&[_]Feature{}),
1032 };
1033 result[@intFromEnum(Feature.slow_strqro_store)] = .{
1034 .llvm_name = "slow-strqro-store",
1035 .description = "STR of Q register with register offset is slow",
1036 .dependencies = featureSet(&[_]Feature{}),
1037 };
1038 result[@intFromEnum(Feature.sm4)] = .{
1039 .llvm_name = "sm4",
1040 .description = "Enable SM3 and SM4 support (FEAT_SM4, FEAT_SM3)",
1041 .dependencies = featureSet(&[_]Feature{
1042 .neon,
1043 }),
1044 };
1045 result[@intFromEnum(Feature.sme)] = .{
1046 .llvm_name = "sme",
1047 .description = "Enable Scalable Matrix Extension (SME) (FEAT_SME)",
1048 .dependencies = featureSet(&[_]Feature{
1049 .bf16,
1050 .use_scalar_inc_vl,
1051 }),
1052 };
1053 result[@intFromEnum(Feature.sme2)] = .{
1054 .llvm_name = "sme2",
1055 .description = "Enable Scalable Matrix Extension 2 (SME2) instructions",
1056 .dependencies = featureSet(&[_]Feature{
1057 .sme,
1058 }),
1059 };
1060 result[@intFromEnum(Feature.sme2p1)] = .{
1061 .llvm_name = "sme2p1",
1062 .description = "Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions",
1063 .dependencies = featureSet(&[_]Feature{
1064 .sme2,
1065 }),
1066 };
1067 result[@intFromEnum(Feature.sme_f16f16)] = .{
1068 .llvm_name = "sme-f16f16",
1069 .description = "Enable SME2.1 non-widening Float16 instructions (FEAT_SME_F16F16)",
1070 .dependencies = featureSet(&[_]Feature{}),
1071 };
1072 result[@intFromEnum(Feature.sme_f64f64)] = .{
1073 .llvm_name = "sme-f64f64",
1074 .description = "Enable Scalable Matrix Extension (SME) F64F64 instructions (FEAT_SME_F64F64)",
1075 .dependencies = featureSet(&[_]Feature{
1076 .sme,
1077 }),
1078 };
1079 result[@intFromEnum(Feature.sme_i16i64)] = .{
1080 .llvm_name = "sme-i16i64",
1081 .description = "Enable Scalable Matrix Extension (SME) I16I64 instructions (FEAT_SME_I16I64)",
1082 .dependencies = featureSet(&[_]Feature{
1083 .sme,
1084 }),
1085 };
1086 result[@intFromEnum(Feature.spe)] = .{
1087 .llvm_name = "spe",
1088 .description = "Enable Statistical Profiling extension (FEAT_SPE)",
1089 .dependencies = featureSet(&[_]Feature{}),
1090 };
1091 result[@intFromEnum(Feature.spe_eef)] = .{
1092 .llvm_name = "spe-eef",
1093 .description = "Enable extra register in the Statistical Profiling Extension (FEAT_SPEv1p2)",
1094 .dependencies = featureSet(&[_]Feature{}),
1095 };
1096 result[@intFromEnum(Feature.specres2)] = .{
1097 .llvm_name = "specres2",
1098 .description = "Enable Speculation Restriction Instruction (FEAT_SPECRES2)",
1099 .dependencies = featureSet(&[_]Feature{
1100 .predres,
1101 }),
1102 };
1103 result[@intFromEnum(Feature.specrestrict)] = .{
1104 .llvm_name = "specrestrict",
1105 .description = "Enable architectural speculation restriction (FEAT_CSV2_2)",
1106 .dependencies = featureSet(&[_]Feature{}),
1107 };
1108 result[@intFromEnum(Feature.ssbs)] = .{
1109 .llvm_name = "ssbs",
1110 .description = "Enable Speculative Store Bypass Safe bit (FEAT_SSBS, FEAT_SSBS2)",
1111 .dependencies = featureSet(&[_]Feature{}),
1112 };
1113 result[@intFromEnum(Feature.strict_align)] = .{
1114 .llvm_name = "strict-align",
1115 .description = "Disallow all unaligned memory access",
1116 .dependencies = featureSet(&[_]Feature{}),
1117 };
1118 result[@intFromEnum(Feature.sve)] = .{
1119 .llvm_name = "sve",
1120 .description = "Enable Scalable Vector Extension (SVE) instructions (FEAT_SVE)",
1121 .dependencies = featureSet(&[_]Feature{
1122 .fullfp16,
1123 }),
1124 };
1125 result[@intFromEnum(Feature.sve2)] = .{
1126 .llvm_name = "sve2",
1127 .description = "Enable Scalable Vector Extension 2 (SVE2) instructions (FEAT_SVE2)",
1128 .dependencies = featureSet(&[_]Feature{
1129 .sve,
1130 .use_scalar_inc_vl,
1131 }),
1132 };
1133 result[@intFromEnum(Feature.sve2_aes)] = .{
1134 .llvm_name = "sve2-aes",
1135 .description = "Enable AES SVE2 instructions (FEAT_SVE_AES, FEAT_SVE_PMULL128)",
1136 .dependencies = featureSet(&[_]Feature{
1137 .aes,
1138 .sve2,
1139 }),
1140 };
1141 result[@intFromEnum(Feature.sve2_bitperm)] = .{
1142 .llvm_name = "sve2-bitperm",
1143 .description = "Enable bit permutation SVE2 instructions (FEAT_SVE_BitPerm)",
1144 .dependencies = featureSet(&[_]Feature{
1145 .sve2,
1146 }),
1147 };
1148 result[@intFromEnum(Feature.sve2_sha3)] = .{
1149 .llvm_name = "sve2-sha3",
1150 .description = "Enable SHA3 SVE2 instructions (FEAT_SVE_SHA3)",
1151 .dependencies = featureSet(&[_]Feature{
1152 .sha3,
1153 .sve2,
1154 }),
1155 };
1156 result[@intFromEnum(Feature.sve2_sm4)] = .{
1157 .llvm_name = "sve2-sm4",
1158 .description = "Enable SM4 SVE2 instructions (FEAT_SVE_SM4)",
1159 .dependencies = featureSet(&[_]Feature{
1160 .sm4,
1161 .sve2,
1162 }),
1163 };
1164 result[@intFromEnum(Feature.sve2p1)] = .{
1165 .llvm_name = "sve2p1",
1166 .description = "Enable Scalable Vector Extension 2.1 instructions",
1167 .dependencies = featureSet(&[_]Feature{
1168 .sve2,
1169 }),
1170 };
1171 result[@intFromEnum(Feature.tagged_globals)] = .{
1172 .llvm_name = "tagged-globals",
1173 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",
1174 .dependencies = featureSet(&[_]Feature{}),
1175 };
1176 result[@intFromEnum(Feature.the)] = .{
1177 .llvm_name = "the",
1178 .description = "Enable Armv8.9-A Translation Hardening Extension (FEAT_THE)",
1179 .dependencies = featureSet(&[_]Feature{}),
1180 };
1181 result[@intFromEnum(Feature.tlb_rmi)] = .{
1182 .llvm_name = "tlb-rmi",
1183 .description = "Enable v8.4-A TLB Range and Maintenance Instructions (FEAT_TLBIOS, FEAT_TLBIRANGE)",
1184 .dependencies = featureSet(&[_]Feature{}),
1185 };
1186 result[@intFromEnum(Feature.tme)] = .{
1187 .llvm_name = "tme",
1188 .description = "Enable Transactional Memory Extension (FEAT_TME)",
1189 .dependencies = featureSet(&[_]Feature{}),
1190 };
1191 result[@intFromEnum(Feature.tpidr_el1)] = .{
1192 .llvm_name = "tpidr-el1",
1193 .description = "Permit use of TPIDR_EL1 for the TLS base",
1194 .dependencies = featureSet(&[_]Feature{}),
1195 };
1196 result[@intFromEnum(Feature.tpidr_el2)] = .{
1197 .llvm_name = "tpidr-el2",
1198 .description = "Permit use of TPIDR_EL2 for the TLS base",
1199 .dependencies = featureSet(&[_]Feature{}),
1200 };
1201 result[@intFromEnum(Feature.tpidr_el3)] = .{
1202 .llvm_name = "tpidr-el3",
1203 .description = "Permit use of TPIDR_EL3 for the TLS base",
1204 .dependencies = featureSet(&[_]Feature{}),
1205 };
1206 result[@intFromEnum(Feature.tpidrro_el0)] = .{
1207 .llvm_name = "tpidrro-el0",
1208 .description = "Permit use of TPIDRRO_EL0 for the TLS base",
1209 .dependencies = featureSet(&[_]Feature{}),
1210 };
1211 result[@intFromEnum(Feature.tracev8_4)] = .{
1212 .llvm_name = "tracev8.4",
1213 .description = "Enable v8.4-A Trace extension (FEAT_TRF)",
1214 .dependencies = featureSet(&[_]Feature{}),
1215 };
1216 result[@intFromEnum(Feature.trbe)] = .{
1217 .llvm_name = "trbe",
1218 .description = "Enable Trace Buffer Extension (FEAT_TRBE)",
1219 .dependencies = featureSet(&[_]Feature{}),
1220 };
1221 result[@intFromEnum(Feature.uaops)] = .{
1222 .llvm_name = "uaops",
1223 .description = "Enable v8.2 UAO PState (FEAT_UAO)",
1224 .dependencies = featureSet(&[_]Feature{}),
1225 };
1226 result[@intFromEnum(Feature.use_experimental_zeroing_pseudos)] = .{
1227 .llvm_name = "use-experimental-zeroing-pseudos",
1228 .description = "Hint to the compiler that the MOVPRFX instruction is merged with destructive operations",
1229 .dependencies = featureSet(&[_]Feature{}),
1230 };
1231 result[@intFromEnum(Feature.use_postra_scheduler)] = .{
1232 .llvm_name = "use-postra-scheduler",
1233 .description = "Schedule again after register allocation",
1234 .dependencies = featureSet(&[_]Feature{}),
1235 };
1236 result[@intFromEnum(Feature.use_reciprocal_square_root)] = .{
1237 .llvm_name = "use-reciprocal-square-root",
1238 .description = "Use the reciprocal square root approximation",
1239 .dependencies = featureSet(&[_]Feature{}),
1240 };
1241 result[@intFromEnum(Feature.use_scalar_inc_vl)] = .{
1242 .llvm_name = "use-scalar-inc-vl",
1243 .description = "Prefer inc/dec over add+cnt",
1244 .dependencies = featureSet(&[_]Feature{}),
1245 };
1246 result[@intFromEnum(Feature.v8_1a)] = .{
1247 .llvm_name = "v8.1a",
1248 .description = "Support ARM v8.1a instructions",
1249 .dependencies = featureSet(&[_]Feature{
1250 .crc,
1251 .lor,
1252 .lse,
1253 .pan,
1254 .rdm,
1255 .v8a,
1256 .vh,
1257 }),
1258 };
1259 result[@intFromEnum(Feature.v8_2a)] = .{
1260 .llvm_name = "v8.2a",
1261 .description = "Support ARM v8.2a instructions",
1262 .dependencies = featureSet(&[_]Feature{
1263 .ccpp,
1264 .pan_rwv,
1265 .ras,
1266 .uaops,
1267 .v8_1a,
1268 }),
1269 };
1270 result[@intFromEnum(Feature.v8_3a)] = .{
1271 .llvm_name = "v8.3a",
1272 .description = "Support ARM v8.3a instructions",
1273 .dependencies = featureSet(&[_]Feature{
1274 .ccidx,
1275 .complxnum,
1276 .jsconv,
1277 .pauth,
1278 .rcpc,
1279 .v8_2a,
1280 }),
1281 };
1282 result[@intFromEnum(Feature.v8_4a)] = .{
1283 .llvm_name = "v8.4a",
1284 .description = "Support ARM v8.4a instructions",
1285 .dependencies = featureSet(&[_]Feature{
1286 .am,
1287 .dit,
1288 .dotprod,
1289 .flagm,
1290 .lse2,
1291 .mpam,
1292 .nv,
1293 .rcpc_immo,
1294 .sel2,
1295 .tlb_rmi,
1296 .tracev8_4,
1297 .v8_3a,
1298 }),
1299 };
1300 result[@intFromEnum(Feature.v8_5a)] = .{
1301 .llvm_name = "v8.5a",
1302 .description = "Support ARM v8.5a instructions",
1303 .dependencies = featureSet(&[_]Feature{
1304 .altnzcv,
1305 .bti,
1306 .ccdp,
1307 .fptoint,
1308 .predres,
1309 .sb,
1310 .specrestrict,
1311 .ssbs,
1312 .v8_4a,
1313 }),
1314 };
1315 result[@intFromEnum(Feature.v8_6a)] = .{
1316 .llvm_name = "v8.6a",
1317 .description = "Support ARM v8.6a instructions",
1318 .dependencies = featureSet(&[_]Feature{
1319 .amvs,
1320 .bf16,
1321 .ecv,
1322 .fgt,
1323 .i8mm,
1324 .v8_5a,
1325 }),
1326 };
1327 result[@intFromEnum(Feature.v8_7a)] = .{
1328 .llvm_name = "v8.7a",
1329 .description = "Support ARM v8.7a instructions",
1330 .dependencies = featureSet(&[_]Feature{
1331 .hcx,
1332 .v8_6a,
1333 .wfxt,
1334 .xs,
1335 }),
1336 };
1337 result[@intFromEnum(Feature.v8_8a)] = .{
1338 .llvm_name = "v8.8a",
1339 .description = "Support ARM v8.8a instructions",
1340 .dependencies = featureSet(&[_]Feature{
1341 .hbc,
1342 .mops,
1343 .nmi,
1344 .v8_7a,
1345 }),
1346 };
1347 result[@intFromEnum(Feature.v8_9a)] = .{
1348 .llvm_name = "v8.9a",
1349 .description = "Support ARM v8.9a instructions",
1350 .dependencies = featureSet(&[_]Feature{
1351 .chk,
1352 .clrbhb,
1353 .cssc,
1354 .prfm_slc_target,
1355 .rasv2,
1356 .specres2,
1357 .v8_8a,
1358 }),
1359 };
1360 result[@intFromEnum(Feature.v8a)] = .{
1361 .llvm_name = "v8a",
1362 .description = "Support ARM v8.0a instructions",
1363 .dependencies = featureSet(&[_]Feature{
1364 .el2vmsa,
1365 .el3,
1366 .neon,
1367 }),
1368 };
1369 result[@intFromEnum(Feature.v8r)] = .{
1370 .llvm_name = "v8r",
1371 .description = "Support ARM v8r instructions",
1372 .dependencies = featureSet(&[_]Feature{
1373 .ccidx,
1374 .ccpp,
1375 .complxnum,
1376 .contextidr_el2,
1377 .crc,
1378 .dit,
1379 .dotprod,
1380 .flagm,
1381 .jsconv,
1382 .lse,
1383 .pan_rwv,
1384 .pauth,
1385 .ras,
1386 .rcpc_immo,
1387 .rdm,
1388 .sel2,
1389 .specrestrict,
1390 .tlb_rmi,
1391 .tracev8_4,
1392 .uaops,
1393 }),
1394 };
1395 result[@intFromEnum(Feature.v9_1a)] = .{
1396 .llvm_name = "v9.1a",
1397 .description = "Support ARM v9.1a instructions",
1398 .dependencies = featureSet(&[_]Feature{
1399 .v8_6a,
1400 .v9a,
1401 }),
1402 };
1403 result[@intFromEnum(Feature.v9_2a)] = .{
1404 .llvm_name = "v9.2a",
1405 .description = "Support ARM v9.2a instructions",
1406 .dependencies = featureSet(&[_]Feature{
1407 .v8_7a,
1408 .v9_1a,
1409 }),
1410 };
1411 result[@intFromEnum(Feature.v9_3a)] = .{
1412 .llvm_name = "v9.3a",
1413 .description = "Support ARM v9.3a instructions",
1414 .dependencies = featureSet(&[_]Feature{
1415 .v8_8a,
1416 .v9_2a,
1417 }),
1418 };
1419 result[@intFromEnum(Feature.v9_4a)] = .{
1420 .llvm_name = "v9.4a",
1421 .description = "Support ARM v9.4a instructions",
1422 .dependencies = featureSet(&[_]Feature{
1423 .v8_9a,
1424 .v9_3a,
1425 }),
1426 };
1427 result[@intFromEnum(Feature.v9a)] = .{
1428 .llvm_name = "v9a",
1429 .description = "Support ARM v9a instructions",
1430 .dependencies = featureSet(&[_]Feature{
1431 .mec,
1432 .sve2,
1433 .v8_5a,
1434 }),
1435 };
1436 result[@intFromEnum(Feature.vh)] = .{
1437 .llvm_name = "vh",
1438 .description = "Enables ARM v8.1 Virtual Host extension (FEAT_VHE)",
1439 .dependencies = featureSet(&[_]Feature{
1440 .contextidr_el2,
1441 }),
1442 };
1443 result[@intFromEnum(Feature.wfxt)] = .{
1444 .llvm_name = "wfxt",
1445 .description = "Enable Armv8.7-A WFET and WFIT instruction (FEAT_WFxT)",
1446 .dependencies = featureSet(&[_]Feature{}),
1447 };
1448 result[@intFromEnum(Feature.xs)] = .{
1449 .llvm_name = "xs",
1450 .description = "Enable Armv8.7-A limited-TLB-maintenance instruction (FEAT_XS)",
1451 .dependencies = featureSet(&[_]Feature{}),
1452 };
1453 result[@intFromEnum(Feature.zcm)] = .{
1454 .llvm_name = "zcm",
1455 .description = "Has zero-cycle register moves",
1456 .dependencies = featureSet(&[_]Feature{}),
1457 };
1458 result[@intFromEnum(Feature.zcz)] = .{
1459 .llvm_name = "zcz",
1460 .description = "Has zero-cycle zeroing instructions",
1461 .dependencies = featureSet(&[_]Feature{
1462 .zcz_gp,
1463 }),
1464 };
1465 result[@intFromEnum(Feature.zcz_fp_workaround)] = .{
1466 .llvm_name = "zcz-fp-workaround",
1467 .description = "The zero-cycle floating-point zeroing instruction has a bug",
1468 .dependencies = featureSet(&[_]Feature{}),
1469 };
1470 result[@intFromEnum(Feature.zcz_gp)] = .{
1471 .llvm_name = "zcz-gp",
1472 .description = "Has zero-cycle zeroing instructions for generic registers",
1473 .dependencies = featureSet(&[_]Feature{}),
1474 };
1475 const ti = @typeInfo(Feature);
1476 for (&result, 0..) |*elem, i| {
1477 elem.index = i;
1478 elem.name = ti.Enum.fields[i].name;
1479 }
1480 break :blk result;
1481};
1482
1483pub const cpu = struct {
1484 pub const a64fx = CpuModel{
1485 .name = "a64fx",
1486 .llvm_name = "a64fx",
1487 .features = featureSet(&[_]Feature{
1488 .aggressive_fma,
1489 .arith_bcc_fusion,
1490 .complxnum,
1491 .perfmon,
1492 .predictable_select_expensive,
1493 .sha2,
1494 .sve,
1495 .use_postra_scheduler,
1496 .v8_2a,
1497 }),
1498 };
1499 pub const ampere1 = CpuModel{
1500 .name = "ampere1",
1501 .llvm_name = "ampere1",
1502 .features = featureSet(&[_]Feature{
1503 .aes,
1504 .aggressive_fma,
1505 .arith_bcc_fusion,
1506 .cmp_bcc_fusion,
1507 .fuse_address,
1508 .fuse_aes,
1509 .fuse_literals,
1510 .lsl_fast,
1511 .perfmon,
1512 .rand,
1513 .sha3,
1514 .use_postra_scheduler,
1515 .v8_6a,
1516 }),
1517 };
1518 pub const ampere1a = CpuModel{
1519 .name = "ampere1a",
1520 .llvm_name = "ampere1a",
1521 .features = featureSet(&[_]Feature{
1522 .aes,
1523 .aggressive_fma,
1524 .arith_bcc_fusion,
1525 .cmp_bcc_fusion,
1526 .fuse_address,
1527 .fuse_aes,
1528 .fuse_literals,
1529 .lsl_fast,
1530 .mte,
1531 .perfmon,
1532 .rand,
1533 .sha3,
1534 .sm4,
1535 .use_postra_scheduler,
1536 .v8_6a,
1537 }),
1538 };
1539 pub const apple_a10 = CpuModel{
1540 .name = "apple_a10",
1541 .llvm_name = "apple-a10",
1542 .features = featureSet(&[_]Feature{
1543 .alternate_sextload_cvt_f32_pattern,
1544 .arith_bcc_fusion,
1545 .arith_cbz_fusion,
1546 .crc,
1547 .crypto,
1548 .disable_latency_sched_heuristic,
1549 .fuse_aes,
1550 .fuse_crypto_eor,
1551 .lor,
1552 .pan,
1553 .perfmon,
1554 .rdm,
1555 .v8a,
1556 .vh,
1557 .zcm,
1558 .zcz,
1559 }),
1560 };
1561 pub const apple_a11 = CpuModel{
1562 .name = "apple_a11",
1563 .llvm_name = "apple-a11",
1564 .features = featureSet(&[_]Feature{
1565 .alternate_sextload_cvt_f32_pattern,
1566 .arith_bcc_fusion,
1567 .arith_cbz_fusion,
1568 .crypto,
1569 .disable_latency_sched_heuristic,
1570 .fullfp16,
1571 .fuse_aes,
1572 .fuse_crypto_eor,
1573 .perfmon,
1574 .v8_2a,
1575 .zcm,
1576 .zcz,
1577 }),
1578 };
1579 pub const apple_a12 = CpuModel{
1580 .name = "apple_a12",
1581 .llvm_name = "apple-a12",
1582 .features = featureSet(&[_]Feature{
1583 .alternate_sextload_cvt_f32_pattern,
1584 .arith_bcc_fusion,
1585 .arith_cbz_fusion,
1586 .crypto,
1587 .disable_latency_sched_heuristic,
1588 .fullfp16,
1589 .fuse_aes,
1590 .fuse_crypto_eor,
1591 .perfmon,
1592 .v8_3a,
1593 .zcm,
1594 .zcz,
1595 }),
1596 };
1597 pub const apple_a13 = CpuModel{
1598 .name = "apple_a13",
1599 .llvm_name = "apple-a13",
1600 .features = featureSet(&[_]Feature{
1601 .alternate_sextload_cvt_f32_pattern,
1602 .arith_bcc_fusion,
1603 .arith_cbz_fusion,
1604 .crypto,
1605 .disable_latency_sched_heuristic,
1606 .fp16fml,
1607 .fuse_aes,
1608 .fuse_crypto_eor,
1609 .perfmon,
1610 .sha3,
1611 .v8_4a,
1612 .zcm,
1613 .zcz,
1614 }),
1615 };
1616 pub const apple_a14 = CpuModel{
1617 .name = "apple_a14",
1618 .llvm_name = "apple-a14",
1619 .features = featureSet(&[_]Feature{
1620 .aggressive_fma,
1621 .alternate_sextload_cvt_f32_pattern,
1622 .altnzcv,
1623 .arith_bcc_fusion,
1624 .arith_cbz_fusion,
1625 .ccdp,
1626 .crypto,
1627 .disable_latency_sched_heuristic,
1628 .fp16fml,
1629 .fptoint,
1630 .fuse_address,
1631 .fuse_adrp_add,
1632 .fuse_aes,
1633 .fuse_arith_logic,
1634 .fuse_crypto_eor,
1635 .fuse_csel,
1636 .fuse_literals,
1637 .perfmon,
1638 .predres,
1639 .sb,
1640 .sha3,
1641 .specrestrict,
1642 .ssbs,
1643 .v8_4a,
1644 .zcm,
1645 .zcz,
1646 }),
1647 };
1648 pub const apple_a15 = CpuModel{
1649 .name = "apple_a15",
1650 .llvm_name = "apple-a15",
1651 .features = featureSet(&[_]Feature{
1652 .alternate_sextload_cvt_f32_pattern,
1653 .arith_bcc_fusion,
1654 .arith_cbz_fusion,
1655 .crypto,
1656 .disable_latency_sched_heuristic,
1657 .fp16fml,
1658 .fuse_address,
1659 .fuse_aes,
1660 .fuse_arith_logic,
1661 .fuse_crypto_eor,
1662 .fuse_csel,
1663 .fuse_literals,
1664 .perfmon,
1665 .sha3,
1666 .v8_6a,
1667 .zcm,
1668 .zcz,
1669 }),
1670 };
1671 pub const apple_a16 = CpuModel{
1672 .name = "apple_a16",
1673 .llvm_name = "apple-a16",
1674 .features = featureSet(&[_]Feature{
1675 .alternate_sextload_cvt_f32_pattern,
1676 .arith_bcc_fusion,
1677 .arith_cbz_fusion,
1678 .crypto,
1679 .disable_latency_sched_heuristic,
1680 .fp16fml,
1681 .fuse_address,
1682 .fuse_aes,
1683 .fuse_arith_logic,
1684 .fuse_crypto_eor,
1685 .fuse_csel,
1686 .fuse_literals,
1687 .hcx,
1688 .perfmon,
1689 .sha3,
1690 .v8_6a,
1691 .zcm,
1692 .zcz,
1693 }),
1694 };
1695 pub const apple_a7 = CpuModel{
1696 .name = "apple_a7",
1697 .llvm_name = "apple-a7",
1698 .features = featureSet(&[_]Feature{
1699 .alternate_sextload_cvt_f32_pattern,
1700 .arith_bcc_fusion,
1701 .arith_cbz_fusion,
1702 .crypto,
1703 .disable_latency_sched_heuristic,
1704 .fuse_aes,
1705 .fuse_crypto_eor,
1706 .perfmon,
1707 .v8a,
1708 .zcm,
1709 .zcz,
1710 .zcz_fp_workaround,
1711 }),
1712 };
1713 pub const apple_a8 = CpuModel{
1714 .name = "apple_a8",
1715 .llvm_name = "apple-a8",
1716 .features = featureSet(&[_]Feature{
1717 .alternate_sextload_cvt_f32_pattern,
1718 .arith_bcc_fusion,
1719 .arith_cbz_fusion,
1720 .crypto,
1721 .disable_latency_sched_heuristic,
1722 .fuse_aes,
1723 .fuse_crypto_eor,
1724 .perfmon,
1725 .v8a,
1726 .zcm,
1727 .zcz,
1728 .zcz_fp_workaround,
1729 }),
1730 };
1731 pub const apple_a9 = CpuModel{
1732 .name = "apple_a9",
1733 .llvm_name = "apple-a9",
1734 .features = featureSet(&[_]Feature{
1735 .alternate_sextload_cvt_f32_pattern,
1736 .arith_bcc_fusion,
1737 .arith_cbz_fusion,
1738 .crypto,
1739 .disable_latency_sched_heuristic,
1740 .fuse_aes,
1741 .fuse_crypto_eor,
1742 .perfmon,
1743 .v8a,
1744 .zcm,
1745 .zcz,
1746 .zcz_fp_workaround,
1747 }),
1748 };
1749 pub const apple_latest = CpuModel{
1750 .name = "apple_latest",
1751 .llvm_name = "apple-latest",
1752 .features = featureSet(&[_]Feature{
1753 .alternate_sextload_cvt_f32_pattern,
1754 .arith_bcc_fusion,
1755 .arith_cbz_fusion,
1756 .crypto,
1757 .disable_latency_sched_heuristic,
1758 .fp16fml,
1759 .fuse_address,
1760 .fuse_aes,
1761 .fuse_arith_logic,
1762 .fuse_crypto_eor,
1763 .fuse_csel,
1764 .fuse_literals,
1765 .hcx,
1766 .perfmon,
1767 .sha3,
1768 .v8_6a,
1769 .zcm,
1770 .zcz,
1771 }),
1772 };
1773 pub const apple_m1 = CpuModel{
1774 .name = "apple_m1",
1775 .llvm_name = "apple-m1",
1776 .features = featureSet(&[_]Feature{
1777 .aggressive_fma,
1778 .alternate_sextload_cvt_f32_pattern,
1779 .altnzcv,
1780 .arith_bcc_fusion,
1781 .arith_cbz_fusion,
1782 .ccdp,
1783 .crypto,
1784 .disable_latency_sched_heuristic,
1785 .fp16fml,
1786 .fptoint,
1787 .fuse_address,
1788 .fuse_adrp_add,
1789 .fuse_aes,
1790 .fuse_arith_logic,
1791 .fuse_crypto_eor,
1792 .fuse_csel,
1793 .fuse_literals,
1794 .perfmon,
1795 .predres,
1796 .sb,
1797 .sha3,
1798 .specrestrict,
1799 .ssbs,
1800 .v8_4a,
1801 .zcm,
1802 .zcz,
1803 }),
1804 };
1805 pub const apple_m2 = CpuModel{
1806 .name = "apple_m2",
1807 .llvm_name = "apple-m2",
1808 .features = featureSet(&[_]Feature{
1809 .alternate_sextload_cvt_f32_pattern,
1810 .arith_bcc_fusion,
1811 .arith_cbz_fusion,
1812 .crypto,
1813 .disable_latency_sched_heuristic,
1814 .fp16fml,
1815 .fuse_address,
1816 .fuse_aes,
1817 .fuse_arith_logic,
1818 .fuse_crypto_eor,
1819 .fuse_csel,
1820 .fuse_literals,
1821 .perfmon,
1822 .sha3,
1823 .v8_6a,
1824 .zcm,
1825 .zcz,
1826 }),
1827 };
1828 pub const apple_s4 = CpuModel{
1829 .name = "apple_s4",
1830 .llvm_name = "apple-s4",
1831 .features = featureSet(&[_]Feature{
1832 .alternate_sextload_cvt_f32_pattern,
1833 .arith_bcc_fusion,
1834 .arith_cbz_fusion,
1835 .crypto,
1836 .disable_latency_sched_heuristic,
1837 .fullfp16,
1838 .fuse_aes,
1839 .fuse_crypto_eor,
1840 .perfmon,
1841 .v8_3a,
1842 .zcm,
1843 .zcz,
1844 }),
1845 };
1846 pub const apple_s5 = CpuModel{
1847 .name = "apple_s5",
1848 .llvm_name = "apple-s5",
1849 .features = featureSet(&[_]Feature{
1850 .alternate_sextload_cvt_f32_pattern,
1851 .arith_bcc_fusion,
1852 .arith_cbz_fusion,
1853 .crypto,
1854 .disable_latency_sched_heuristic,
1855 .fullfp16,
1856 .fuse_aes,
1857 .fuse_crypto_eor,
1858 .perfmon,
1859 .v8_3a,
1860 .zcm,
1861 .zcz,
1862 }),
1863 };
1864 pub const carmel = CpuModel{
1865 .name = "carmel",
1866 .llvm_name = "carmel",
1867 .features = featureSet(&[_]Feature{
1868 .crypto,
1869 .fullfp16,
1870 .v8_2a,
1871 }),
1872 };
1873 pub const cortex_a34 = CpuModel{
1874 .name = "cortex_a34",
1875 .llvm_name = "cortex-a34",
1876 .features = featureSet(&[_]Feature{
1877 .crc,
1878 .crypto,
1879 .perfmon,
1880 .v8a,
1881 }),
1882 };
1883 pub const cortex_a35 = CpuModel{
1884 .name = "cortex_a35",
1885 .llvm_name = "cortex-a35",
1886 .features = featureSet(&[_]Feature{
1887 .crc,
1888 .crypto,
1889 .perfmon,
1890 .v8a,
1891 }),
1892 };
1893 pub const cortex_a510 = CpuModel{
1894 .name = "cortex_a510",
1895 .llvm_name = "cortex-a510",
1896 .features = featureSet(&[_]Feature{
1897 .a510,
1898 .bf16,
1899 .ete,
1900 .fp16fml,
1901 .i8mm,
1902 .mte,
1903 .perfmon,
1904 .sve2_bitperm,
1905 .v9a,
1906 }),
1907 };
1908 pub const cortex_a53 = CpuModel{
1909 .name = "cortex_a53",
1910 .llvm_name = "cortex-a53",
1911 .features = featureSet(&[_]Feature{
1912 .balance_fp_ops,
1913 .crc,
1914 .crypto,
1915 .custom_cheap_as_move,
1916 .fuse_adrp_add,
1917 .fuse_aes,
1918 .perfmon,
1919 .use_postra_scheduler,
1920 .v8a,
1921 }),
1922 };
1923 pub const cortex_a55 = CpuModel{
1924 .name = "cortex_a55",
1925 .llvm_name = "cortex-a55",
1926 .features = featureSet(&[_]Feature{
1927 .crypto,
1928 .dotprod,
1929 .fullfp16,
1930 .fuse_address,
1931 .fuse_adrp_add,
1932 .fuse_aes,
1933 .perfmon,
1934 .rcpc,
1935 .use_postra_scheduler,
1936 .v8_2a,
1937 }),
1938 };
1939 pub const cortex_a57 = CpuModel{
1940 .name = "cortex_a57",
1941 .llvm_name = "cortex-a57",
1942 .features = featureSet(&[_]Feature{
1943 .balance_fp_ops,
1944 .crc,
1945 .crypto,
1946 .custom_cheap_as_move,
1947 .enable_select_opt,
1948 .fuse_adrp_add,
1949 .fuse_aes,
1950 .fuse_literals,
1951 .perfmon,
1952 .predictable_select_expensive,
1953 .use_postra_scheduler,
1954 .v8a,
1955 }),
1956 };
1957 pub const cortex_a65 = CpuModel{
1958 .name = "cortex_a65",
1959 .llvm_name = "cortex-a65",
1960 .features = featureSet(&[_]Feature{
1961 .a65,
1962 .crypto,
1963 .dotprod,
1964 .fullfp16,
1965 .perfmon,
1966 .rcpc,
1967 .ssbs,
1968 .v8_2a,
1969 }),
1970 };
1971 pub const cortex_a65ae = CpuModel{
1972 .name = "cortex_a65ae",
1973 .llvm_name = "cortex-a65ae",
1974 .features = featureSet(&[_]Feature{
1975 .a65,
1976 .crypto,
1977 .dotprod,
1978 .fullfp16,
1979 .perfmon,
1980 .rcpc,
1981 .ssbs,
1982 .v8_2a,
1983 }),
1984 };
1985 pub const cortex_a710 = CpuModel{
1986 .name = "cortex_a710",
1987 .llvm_name = "cortex-a710",
1988 .features = featureSet(&[_]Feature{
1989 .a710,
1990 .bf16,
1991 .ete,
1992 .fp16fml,
1993 .i8mm,
1994 .mte,
1995 .perfmon,
1996 .sve2_bitperm,
1997 .v9a,
1998 }),
1999 };
2000 pub const cortex_a715 = CpuModel{
2001 .name = "cortex_a715",
2002 .llvm_name = "cortex-a715",
2003 .features = featureSet(&[_]Feature{
2004 .bf16,
2005 .cmp_bcc_fusion,
2006 .enable_select_opt,
2007 .ete,
2008 .fp16fml,
2009 .fuse_adrp_add,
2010 .fuse_aes,
2011 .i8mm,
2012 .lsl_fast,
2013 .mte,
2014 .perfmon,
2015 .predictable_select_expensive,
2016 .spe,
2017 .sve2_bitperm,
2018 .use_postra_scheduler,
2019 .v9a,
2020 }),
2021 };
2022 pub const cortex_a72 = CpuModel{
2023 .name = "cortex_a72",
2024 .llvm_name = "cortex-a72",
2025 .features = featureSet(&[_]Feature{
2026 .crc,
2027 .crypto,
2028 .enable_select_opt,
2029 .fuse_adrp_add,
2030 .fuse_aes,
2031 .fuse_literals,
2032 .perfmon,
2033 .predictable_select_expensive,
2034 .v8a,
2035 }),
2036 };
2037 pub const cortex_a73 = CpuModel{
2038 .name = "cortex_a73",
2039 .llvm_name = "cortex-a73",
2040 .features = featureSet(&[_]Feature{
2041 .crc,
2042 .crypto,
2043 .enable_select_opt,
2044 .fuse_adrp_add,
2045 .fuse_aes,
2046 .perfmon,
2047 .predictable_select_expensive,
2048 .v8a,
2049 }),
2050 };
2051 pub const cortex_a75 = CpuModel{
2052 .name = "cortex_a75",
2053 .llvm_name = "cortex-a75",
2054 .features = featureSet(&[_]Feature{
2055 .crypto,
2056 .dotprod,
2057 .enable_select_opt,
2058 .fullfp16,
2059 .fuse_adrp_add,
2060 .fuse_aes,
2061 .perfmon,
2062 .predictable_select_expensive,
2063 .rcpc,
2064 .v8_2a,
2065 }),
2066 };
2067 pub const cortex_a76 = CpuModel{
2068 .name = "cortex_a76",
2069 .llvm_name = "cortex-a76",
2070 .features = featureSet(&[_]Feature{
2071 .a76,
2072 .crypto,
2073 .dotprod,
2074 .fullfp16,
2075 .perfmon,
2076 .rcpc,
2077 .ssbs,
2078 .v8_2a,
2079 }),
2080 };
2081 pub const cortex_a76ae = CpuModel{
2082 .name = "cortex_a76ae",
2083 .llvm_name = "cortex-a76ae",
2084 .features = featureSet(&[_]Feature{
2085 .a76,
2086 .crypto,
2087 .dotprod,
2088 .fullfp16,
2089 .perfmon,
2090 .rcpc,
2091 .ssbs,
2092 .v8_2a,
2093 }),
2094 };
2095 pub const cortex_a77 = CpuModel{
2096 .name = "cortex_a77",
2097 .llvm_name = "cortex-a77",
2098 .features = featureSet(&[_]Feature{
2099 .cmp_bcc_fusion,
2100 .crypto,
2101 .dotprod,
2102 .enable_select_opt,
2103 .fullfp16,
2104 .fuse_adrp_add,
2105 .fuse_aes,
2106 .lsl_fast,
2107 .perfmon,
2108 .predictable_select_expensive,
2109 .rcpc,
2110 .ssbs,
2111 .v8_2a,
2112 }),
2113 };
2114 pub const cortex_a78 = CpuModel{
2115 .name = "cortex_a78",
2116 .llvm_name = "cortex-a78",
2117 .features = featureSet(&[_]Feature{
2118 .a78,
2119 .crypto,
2120 .dotprod,
2121 .fullfp16,
2122 .perfmon,
2123 .rcpc,
2124 .spe,
2125 .ssbs,
2126 .v8_2a,
2127 }),
2128 };
2129 pub const cortex_a78c = CpuModel{
2130 .name = "cortex_a78c",
2131 .llvm_name = "cortex-a78c",
2132 .features = featureSet(&[_]Feature{
2133 .a78c,
2134 .crypto,
2135 .dotprod,
2136 .flagm,
2137 .fp16fml,
2138 .pauth,
2139 .perfmon,
2140 .rcpc,
2141 .spe,
2142 .ssbs,
2143 .v8_2a,
2144 }),
2145 };
2146 pub const cortex_r82 = CpuModel{
2147 .name = "cortex_r82",
2148 .llvm_name = "cortex-r82",
2149 .features = featureSet(&[_]Feature{
2150 .cortex_r82,
2151 .fp16fml,
2152 .perfmon,
2153 .predres,
2154 .sb,
2155 .ssbs,
2156 .v8r,
2157 }),
2158 };
2159 pub const cortex_x1 = CpuModel{
2160 .name = "cortex_x1",
2161 .llvm_name = "cortex-x1",
2162 .features = featureSet(&[_]Feature{
2163 .cmp_bcc_fusion,
2164 .crypto,
2165 .dotprod,
2166 .enable_select_opt,
2167 .fullfp16,
2168 .fuse_adrp_add,
2169 .fuse_aes,
2170 .lsl_fast,
2171 .perfmon,
2172 .predictable_select_expensive,
2173 .rcpc,
2174 .spe,
2175 .ssbs,
2176 .use_postra_scheduler,
2177 .v8_2a,
2178 }),
2179 };
2180 pub const cortex_x1c = CpuModel{
2181 .name = "cortex_x1c",
2182 .llvm_name = "cortex-x1c",
2183 .features = featureSet(&[_]Feature{
2184 .cmp_bcc_fusion,
2185 .crypto,
2186 .dotprod,
2187 .enable_select_opt,
2188 .flagm,
2189 .fullfp16,
2190 .fuse_adrp_add,
2191 .fuse_aes,
2192 .lse2,
2193 .lsl_fast,
2194 .pauth,
2195 .perfmon,
2196 .predictable_select_expensive,
2197 .rcpc_immo,
2198 .spe,
2199 .ssbs,
2200 .use_postra_scheduler,
2201 .v8_2a,
2202 }),
2203 };
2204 pub const cortex_x2 = CpuModel{
2205 .name = "cortex_x2",
2206 .llvm_name = "cortex-x2",
2207 .features = featureSet(&[_]Feature{
2208 .bf16,
2209 .cmp_bcc_fusion,
2210 .enable_select_opt,
2211 .ete,
2212 .fp16fml,
2213 .fuse_adrp_add,
2214 .fuse_aes,
2215 .i8mm,
2216 .lsl_fast,
2217 .mte,
2218 .perfmon,
2219 .predictable_select_expensive,
2220 .sve2_bitperm,
2221 .use_postra_scheduler,
2222 .v9a,
2223 }),
2224 };
2225 pub const cortex_x3 = CpuModel{
2226 .name = "cortex_x3",
2227 .llvm_name = "cortex-x3",
2228 .features = featureSet(&[_]Feature{
2229 .bf16,
2230 .enable_select_opt,
2231 .ete,
2232 .fp16fml,
2233 .fuse_adrp_add,
2234 .fuse_aes,
2235 .i8mm,
2236 .lsl_fast,
2237 .mte,
2238 .perfmon,
2239 .predictable_select_expensive,
2240 .spe,
2241 .sve2_bitperm,
2242 .use_postra_scheduler,
2243 .v9a,
2244 }),
2245 };
2246 pub const cyclone = CpuModel{
2247 .name = "cyclone",
2248 .llvm_name = "cyclone",
2249 .features = featureSet(&[_]Feature{
2250 .alternate_sextload_cvt_f32_pattern,
2251 .arith_bcc_fusion,
2252 .arith_cbz_fusion,
2253 .crypto,
2254 .disable_latency_sched_heuristic,
2255 .fuse_aes,
2256 .fuse_crypto_eor,
2257 .perfmon,
2258 .v8a,
2259 .zcm,
2260 .zcz,
2261 .zcz_fp_workaround,
2262 }),
2263 };
2264 pub const emag = CpuModel{
2265 .name = "emag",
2266 .llvm_name = null,
2267 .features = featureSet(&[_]Feature{
2268 .crc,
2269 .crypto,
2270 .perfmon,
2271 .v8a,
2272 }),
2273 };
2274 pub const exynos_m1 = CpuModel{
2275 .name = "exynos_m1",
2276 .llvm_name = null,
2277 .features = featureSet(&[_]Feature{
2278 .crc,
2279 .crypto,
2280 .exynos_cheap_as_move,
2281 .force_32bit_jump_tables,
2282 .fuse_aes,
2283 .perfmon,
2284 .slow_misaligned_128store,
2285 .slow_paired_128,
2286 .use_postra_scheduler,
2287 .use_reciprocal_square_root,
2288 .v8a,
2289 }),
2290 };
2291 pub const exynos_m2 = CpuModel{
2292 .name = "exynos_m2",
2293 .llvm_name = null,
2294 .features = featureSet(&[_]Feature{
2295 .crc,
2296 .crypto,
2297 .exynos_cheap_as_move,
2298 .force_32bit_jump_tables,
2299 .fuse_aes,
2300 .perfmon,
2301 .slow_misaligned_128store,
2302 .slow_paired_128,
2303 .use_postra_scheduler,
2304 .v8a,
2305 }),
2306 };
2307 pub const exynos_m3 = CpuModel{
2308 .name = "exynos_m3",
2309 .llvm_name = "exynos-m3",
2310 .features = featureSet(&[_]Feature{
2311 .crc,
2312 .crypto,
2313 .exynos_cheap_as_move,
2314 .force_32bit_jump_tables,
2315 .fuse_address,
2316 .fuse_adrp_add,
2317 .fuse_aes,
2318 .fuse_csel,
2319 .fuse_literals,
2320 .lsl_fast,
2321 .perfmon,
2322 .predictable_select_expensive,
2323 .use_postra_scheduler,
2324 .v8a,
2325 }),
2326 };
2327 pub const exynos_m4 = CpuModel{
2328 .name = "exynos_m4",
2329 .llvm_name = "exynos-m4",
2330 .features = featureSet(&[_]Feature{
2331 .arith_bcc_fusion,
2332 .arith_cbz_fusion,
2333 .crypto,
2334 .dotprod,
2335 .exynos_cheap_as_move,
2336 .force_32bit_jump_tables,
2337 .fullfp16,
2338 .fuse_address,
2339 .fuse_adrp_add,
2340 .fuse_aes,
2341 .fuse_arith_logic,
2342 .fuse_csel,
2343 .fuse_literals,
2344 .lsl_fast,
2345 .perfmon,
2346 .use_postra_scheduler,
2347 .v8_2a,
2348 .zcz,
2349 }),
2350 };
2351 pub const exynos_m5 = CpuModel{
2352 .name = "exynos_m5",
2353 .llvm_name = "exynos-m5",
2354 .features = featureSet(&[_]Feature{
2355 .arith_bcc_fusion,
2356 .arith_cbz_fusion,
2357 .crypto,
2358 .dotprod,
2359 .exynos_cheap_as_move,
2360 .force_32bit_jump_tables,
2361 .fullfp16,
2362 .fuse_address,
2363 .fuse_adrp_add,
2364 .fuse_aes,
2365 .fuse_arith_logic,
2366 .fuse_csel,
2367 .fuse_literals,
2368 .lsl_fast,
2369 .perfmon,
2370 .use_postra_scheduler,
2371 .v8_2a,
2372 .zcz,
2373 }),
2374 };
2375 pub const falkor = CpuModel{
2376 .name = "falkor",
2377 .llvm_name = "falkor",
2378 .features = featureSet(&[_]Feature{
2379 .crc,
2380 .crypto,
2381 .custom_cheap_as_move,
2382 .lsl_fast,
2383 .perfmon,
2384 .predictable_select_expensive,
2385 .rdm,
2386 .slow_strqro_store,
2387 .use_postra_scheduler,
2388 .v8a,
2389 .zcz,
2390 }),
2391 };
2392 pub const generic = CpuModel{
2393 .name = "generic",
2394 .llvm_name = "generic",
2395 .features = featureSet(&[_]Feature{
2396 .enable_select_opt,
2397 .ete,
2398 .fuse_adrp_add,
2399 .fuse_aes,
2400 .neon,
2401 .use_postra_scheduler,
2402 }),
2403 };
2404 pub const kryo = CpuModel{
2405 .name = "kryo",
2406 .llvm_name = "kryo",
2407 .features = featureSet(&[_]Feature{
2408 .crc,
2409 .crypto,
2410 .custom_cheap_as_move,
2411 .lsl_fast,
2412 .perfmon,
2413 .predictable_select_expensive,
2414 .use_postra_scheduler,
2415 .v8a,
2416 .zcz,
2417 }),
2418 };
2419 pub const neoverse_512tvb = CpuModel{
2420 .name = "neoverse_512tvb",
2421 .llvm_name = "neoverse-512tvb",
2422 .features = featureSet(&[_]Feature{
2423 .bf16,
2424 .ccdp,
2425 .crypto,
2426 .enable_select_opt,
2427 .fp16fml,
2428 .fuse_adrp_add,
2429 .fuse_aes,
2430 .i8mm,
2431 .lsl_fast,
2432 .perfmon,
2433 .predictable_select_expensive,
2434 .rand,
2435 .spe,
2436 .ssbs,
2437 .sve,
2438 .use_postra_scheduler,
2439 .v8_4a,
2440 }),
2441 };
2442 pub const neoverse_e1 = CpuModel{
2443 .name = "neoverse_e1",
2444 .llvm_name = "neoverse-e1",
2445 .features = featureSet(&[_]Feature{
2446 .crypto,
2447 .dotprod,
2448 .fullfp16,
2449 .fuse_adrp_add,
2450 .fuse_aes,
2451 .perfmon,
2452 .rcpc,
2453 .ssbs,
2454 .use_postra_scheduler,
2455 .v8_2a,
2456 }),
2457 };
2458 pub const neoverse_n1 = CpuModel{
2459 .name = "neoverse_n1",
2460 .llvm_name = "neoverse-n1",
2461 .features = featureSet(&[_]Feature{
2462 .crypto,
2463 .dotprod,
2464 .enable_select_opt,
2465 .fullfp16,
2466 .fuse_adrp_add,
2467 .fuse_aes,
2468 .lsl_fast,
2469 .perfmon,
2470 .predictable_select_expensive,
2471 .rcpc,
2472 .spe,
2473 .ssbs,
2474 .use_postra_scheduler,
2475 .v8_2a,
2476 }),
2477 };
2478 pub const neoverse_n2 = CpuModel{
2479 .name = "neoverse_n2",
2480 .llvm_name = "neoverse-n2",
2481 .features = featureSet(&[_]Feature{
2482 .bf16,
2483 .crypto,
2484 .enable_select_opt,
2485 .ete,
2486 .fuse_adrp_add,
2487 .fuse_aes,
2488 .i8mm,
2489 .lsl_fast,
2490 .mte,
2491 .perfmon,
2492 .predictable_select_expensive,
2493 .sve2_bitperm,
2494 .use_postra_scheduler,
2495 .v8_5a,
2496 }),
2497 };
2498 pub const neoverse_v1 = CpuModel{
2499 .name = "neoverse_v1",
2500 .llvm_name = "neoverse-v1",
2501 .features = featureSet(&[_]Feature{
2502 .bf16,
2503 .ccdp,
2504 .crypto,
2505 .enable_select_opt,
2506 .fp16fml,
2507 .fuse_adrp_add,
2508 .fuse_aes,
2509 .i8mm,
2510 .lsl_fast,
2511 .no_sve_fp_ld1r,
2512 .perfmon,
2513 .predictable_select_expensive,
2514 .rand,
2515 .spe,
2516 .ssbs,
2517 .sve,
2518 .use_postra_scheduler,
2519 .v8_4a,
2520 }),
2521 };
2522 pub const neoverse_v2 = CpuModel{
2523 .name = "neoverse_v2",
2524 .llvm_name = "neoverse-v2",
2525 .features = featureSet(&[_]Feature{
2526 .bf16,
2527 .enable_select_opt,
2528 .ete,
2529 .fp16fml,
2530 .fuse_aes,
2531 .i8mm,
2532 .lsl_fast,
2533 .mte,
2534 .perfmon,
2535 .predictable_select_expensive,
2536 .rand,
2537 .spe,
2538 .sve2_bitperm,
2539 .use_postra_scheduler,
2540 .v9a,
2541 }),
2542 };
2543 pub const saphira = CpuModel{
2544 .name = "saphira",
2545 .llvm_name = "saphira",
2546 .features = featureSet(&[_]Feature{
2547 .crypto,
2548 .custom_cheap_as_move,
2549 .lsl_fast,
2550 .perfmon,
2551 .predictable_select_expensive,
2552 .spe,
2553 .use_postra_scheduler,
2554 .v8_4a,
2555 .zcz,
2556 }),
2557 };
2558 pub const thunderx = CpuModel{
2559 .name = "thunderx",
2560 .llvm_name = "thunderx",
2561 .features = featureSet(&[_]Feature{
2562 .crc,
2563 .crypto,
2564 .perfmon,
2565 .predictable_select_expensive,
2566 .use_postra_scheduler,
2567 .v8a,
2568 }),
2569 };
2570 pub const thunderx2t99 = CpuModel{
2571 .name = "thunderx2t99",
2572 .llvm_name = "thunderx2t99",
2573 .features = featureSet(&[_]Feature{
2574 .aggressive_fma,
2575 .arith_bcc_fusion,
2576 .crypto,
2577 .predictable_select_expensive,
2578 .use_postra_scheduler,
2579 .v8_1a,
2580 }),
2581 };
2582 pub const thunderx3t110 = CpuModel{
2583 .name = "thunderx3t110",
2584 .llvm_name = "thunderx3t110",
2585 .features = featureSet(&[_]Feature{
2586 .aggressive_fma,
2587 .arith_bcc_fusion,
2588 .balance_fp_ops,
2589 .crypto,
2590 .perfmon,
2591 .predictable_select_expensive,
2592 .strict_align,
2593 .use_postra_scheduler,
2594 .v8_3a,
2595 }),
2596 };
2597 pub const thunderxt81 = CpuModel{
2598 .name = "thunderxt81",
2599 .llvm_name = "thunderxt81",
2600 .features = featureSet(&[_]Feature{
2601 .crc,
2602 .crypto,
2603 .perfmon,
2604 .predictable_select_expensive,
2605 .use_postra_scheduler,
2606 .v8a,
2607 }),
2608 };
2609 pub const thunderxt83 = CpuModel{
2610 .name = "thunderxt83",
2611 .llvm_name = "thunderxt83",
2612 .features = featureSet(&[_]Feature{
2613 .crc,
2614 .crypto,
2615 .perfmon,
2616 .predictable_select_expensive,
2617 .use_postra_scheduler,
2618 .v8a,
2619 }),
2620 };
2621 pub const thunderxt88 = CpuModel{
2622 .name = "thunderxt88",
2623 .llvm_name = "thunderxt88",
2624 .features = featureSet(&[_]Feature{
2625 .crc,
2626 .crypto,
2627 .perfmon,
2628 .predictable_select_expensive,
2629 .use_postra_scheduler,
2630 .v8a,
2631 }),
2632 };
2633 pub const tsv110 = CpuModel{
2634 .name = "tsv110",
2635 .llvm_name = "tsv110",
2636 .features = featureSet(&[_]Feature{
2637 .crypto,
2638 .custom_cheap_as_move,
2639 .dotprod,
2640 .fp16fml,
2641 .fuse_aes,
2642 .perfmon,
2643 .spe,
2644 .use_postra_scheduler,
2645 .v8_2a,
2646 }),
2647 };
2648 pub const xgene1 = CpuModel{
2649 .name = "xgene1",
2650 .llvm_name = null,
2651 .features = featureSet(&[_]Feature{
2652 .perfmon,
2653 .v8a,
2654 }),
2655 };
2656};
lib/std/target/amdgpu.zig deleted-2153
......@@ -1,2153 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"16_bit_insts",
9 a16,
10 add_no_carry_insts,
11 aperture_regs,
12 architected_flat_scratch,
13 architected_sgprs,
14 atomic_buffer_global_pk_add_f16_insts,
15 atomic_buffer_global_pk_add_f16_no_rtn_insts,
16 atomic_ds_pk_add_16_insts,
17 atomic_fadd_no_rtn_insts,
18 atomic_fadd_rtn_insts,
19 atomic_flat_pk_add_16_insts,
20 atomic_global_pk_add_bf16_inst,
21 auto_waitcnt_before_barrier,
22 back_off_barrier,
23 ci_insts,
24 cumode,
25 dl_insts,
26 dot10_insts,
27 dot1_insts,
28 dot2_insts,
29 dot3_insts,
30 dot4_insts,
31 dot5_insts,
32 dot6_insts,
33 dot7_insts,
34 dot8_insts,
35 dot9_insts,
36 dpp,
37 dpp8,
38 dpp_64bit,
39 ds128,
40 ds_src2_insts,
41 extended_image_insts,
42 fast_denormal_f32,
43 fast_fmaf,
44 flat_address_space,
45 flat_atomic_fadd_f32_inst,
46 flat_for_global,
47 flat_global_insts,
48 flat_inst_offsets,
49 flat_scratch,
50 flat_scratch_insts,
51 flat_segment_offset_bug,
52 fma_mix_insts,
53 fmacf64_inst,
54 fmaf,
55 force_store_sc0_sc1,
56 fp64,
57 fp8_insts,
58 full_rate_64_ops,
59 g16,
60 gcn3_encoding,
61 get_wave_id_inst,
62 gfx10,
63 gfx10_3_insts,
64 gfx10_a_encoding,
65 gfx10_b_encoding,
66 gfx10_insts,
67 gfx11,
68 gfx11_full_vgprs,
69 gfx11_insts,
70 gfx7_gfx8_gfx9_insts,
71 gfx8_insts,
72 gfx9,
73 gfx90a_insts,
74 gfx940_insts,
75 gfx9_insts,
76 half_rate_64_ops,
77 image_gather4_d16_bug,
78 image_insts,
79 image_store_d16_bug,
80 inst_fwd_prefetch_bug,
81 int_clamp_insts,
82 inv_2pi_inline_imm,
83 lds_branch_vmem_war_hazard,
84 lds_misaligned_bug,
85 ldsbankcount16,
86 ldsbankcount32,
87 load_store_opt,
88 localmemorysize32768,
89 localmemorysize65536,
90 mad_intra_fwd_bug,
91 mad_mac_f32_insts,
92 mad_mix_insts,
93 mai_insts,
94 max_private_element_size_16,
95 max_private_element_size_4,
96 max_private_element_size_8,
97 mfma_inline_literal_bug,
98 mimg_r128,
99 movrel,
100 negative_scratch_offset_bug,
101 negative_unaligned_scratch_offset_bug,
102 no_data_dep_hazard,
103 no_sdst_cmpx,
104 nsa_clause_bug,
105 nsa_encoding,
106 nsa_to_vmem_bug,
107 offset_3f_bug,
108 packed_fp32_ops,
109 packed_tid,
110 partial_nsa_encoding,
111 pk_fmac_f16_inst,
112 promote_alloca,
113 prt_strict_null,
114 r128_a16,
115 s_memrealtime,
116 s_memtime_inst,
117 scalar_atomics,
118 scalar_flat_scratch_insts,
119 scalar_stores,
120 sdwa,
121 sdwa_mav,
122 sdwa_omod,
123 sdwa_out_mods_vopc,
124 sdwa_scalar,
125 sdwa_sdst,
126 sea_islands,
127 sgpr_init_bug,
128 shader_cycles_register,
129 si_scheduler,
130 smem_to_vector_write_hazard,
131 southern_islands,
132 sramecc,
133 sramecc_support,
134 tgsplit,
135 trap_handler,
136 trig_reduced_range,
137 true16,
138 unaligned_access_mode,
139 unaligned_buffer_access,
140 unaligned_ds_access,
141 unaligned_scratch_access,
142 unpacked_d16_vmem,
143 unsafe_ds_offset_folding,
144 user_sgpr_init16_bug,
145 valu_trans_use_hazard,
146 vcmpx_exec_war_hazard,
147 vcmpx_permlane_hazard,
148 vgpr_index_mode,
149 vmem_to_scalar_write_hazard,
150 volcanic_islands,
151 vop3_literal,
152 vop3p,
153 vopd,
154 vscnt,
155 wavefrontsize16,
156 wavefrontsize32,
157 wavefrontsize64,
158 xnack,
159 xnack_support,
160};
161
162pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
163pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
164pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
165pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
166
167pub const all_features = blk: {
168 const len = @typeInfo(Feature).Enum.fields.len;
169 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
170 var result: [len]CpuFeature = undefined;
171 result[@intFromEnum(Feature.@"16_bit_insts")] = .{
172 .llvm_name = "16-bit-insts",
173 .description = "Has i16/f16 instructions",
174 .dependencies = featureSet(&[_]Feature{}),
175 };
176 result[@intFromEnum(Feature.a16)] = .{
177 .llvm_name = "a16",
178 .description = "Support A16 for 16-bit coordinates/gradients/lod/clamp/mip image operands",
179 .dependencies = featureSet(&[_]Feature{}),
180 };
181 result[@intFromEnum(Feature.add_no_carry_insts)] = .{
182 .llvm_name = "add-no-carry-insts",
183 .description = "Have VALU add/sub instructions without carry out",
184 .dependencies = featureSet(&[_]Feature{}),
185 };
186 result[@intFromEnum(Feature.aperture_regs)] = .{
187 .llvm_name = "aperture-regs",
188 .description = "Has Memory Aperture Base and Size Registers",
189 .dependencies = featureSet(&[_]Feature{}),
190 };
191 result[@intFromEnum(Feature.architected_flat_scratch)] = .{
192 .llvm_name = "architected-flat-scratch",
193 .description = "Flat Scratch register is a readonly SPI initialized architected register",
194 .dependencies = featureSet(&[_]Feature{}),
195 };
196 result[@intFromEnum(Feature.architected_sgprs)] = .{
197 .llvm_name = "architected-sgprs",
198 .description = "Enable the architected SGPRs",
199 .dependencies = featureSet(&[_]Feature{}),
200 };
201 result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_insts)] = .{
202 .llvm_name = "atomic-buffer-global-pk-add-f16-insts",
203 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that can return original value",
204 .dependencies = featureSet(&[_]Feature{
205 .flat_global_insts,
206 }),
207 };
208 result[@intFromEnum(Feature.atomic_buffer_global_pk_add_f16_no_rtn_insts)] = .{
209 .llvm_name = "atomic-buffer-global-pk-add-f16-no-rtn-insts",
210 .description = "Has buffer_atomic_pk_add_f16 and global_atomic_pk_add_f16 instructions that don't return original value",
211 .dependencies = featureSet(&[_]Feature{
212 .flat_global_insts,
213 }),
214 };
215 result[@intFromEnum(Feature.atomic_ds_pk_add_16_insts)] = .{
216 .llvm_name = "atomic-ds-pk-add-16-insts",
217 .description = "Has ds_pk_add_bf16, ds_pk_add_f16, ds_pk_add_rtn_bf16, ds_pk_add_rtn_f16 instructions",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
220 result[@intFromEnum(Feature.atomic_fadd_no_rtn_insts)] = .{
221 .llvm_name = "atomic-fadd-no-rtn-insts",
222 .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that don't return original value",
223 .dependencies = featureSet(&[_]Feature{
224 .flat_global_insts,
225 }),
226 };
227 result[@intFromEnum(Feature.atomic_fadd_rtn_insts)] = .{
228 .llvm_name = "atomic-fadd-rtn-insts",
229 .description = "Has buffer_atomic_add_f32 and global_atomic_add_f32 instructions that return original value",
230 .dependencies = featureSet(&[_]Feature{
231 .flat_global_insts,
232 }),
233 };
234 result[@intFromEnum(Feature.atomic_flat_pk_add_16_insts)] = .{
235 .llvm_name = "atomic-flat-pk-add-16-insts",
236 .description = "Has flat_atomic_pk_add_f16 and flat_atomic_pk_add_bf16 instructions",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.atomic_global_pk_add_bf16_inst)] = .{
240 .llvm_name = "atomic-global-pk-add-bf16-inst",
241 .description = "Has global_atomic_pk_add_bf16 instruction",
242 .dependencies = featureSet(&[_]Feature{
243 .flat_global_insts,
244 }),
245 };
246 result[@intFromEnum(Feature.auto_waitcnt_before_barrier)] = .{
247 .llvm_name = "auto-waitcnt-before-barrier",
248 .description = "Hardware automatically inserts waitcnt before barrier",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.back_off_barrier)] = .{
252 .llvm_name = "back-off-barrier",
253 .description = "Hardware supports backing off s_barrier if an exception occurs",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.ci_insts)] = .{
257 .llvm_name = "ci-insts",
258 .description = "Additional instructions for CI+",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.cumode)] = .{
262 .llvm_name = "cumode",
263 .description = "Enable CU wavefront execution mode",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.dl_insts)] = .{
267 .llvm_name = "dl-insts",
268 .description = "Has v_fmac_f32 and v_xnor_b32 instructions",
269 .dependencies = featureSet(&[_]Feature{}),
270 };
271 result[@intFromEnum(Feature.dot10_insts)] = .{
272 .llvm_name = "dot10-insts",
273 .description = "Has v_dot2_f32_f16 instruction",
274 .dependencies = featureSet(&[_]Feature{}),
275 };
276 result[@intFromEnum(Feature.dot1_insts)] = .{
277 .llvm_name = "dot1-insts",
278 .description = "Has v_dot4_i32_i8 and v_dot8_i32_i4 instructions",
279 .dependencies = featureSet(&[_]Feature{}),
280 };
281 result[@intFromEnum(Feature.dot2_insts)] = .{
282 .llvm_name = "dot2-insts",
283 .description = "Has v_dot2_i32_i16, v_dot2_u32_u16 instructions",
284 .dependencies = featureSet(&[_]Feature{}),
285 };
286 result[@intFromEnum(Feature.dot3_insts)] = .{
287 .llvm_name = "dot3-insts",
288 .description = "Has v_dot8c_i32_i4 instruction",
289 .dependencies = featureSet(&[_]Feature{}),
290 };
291 result[@intFromEnum(Feature.dot4_insts)] = .{
292 .llvm_name = "dot4-insts",
293 .description = "Has v_dot2c_i32_i16 instruction",
294 .dependencies = featureSet(&[_]Feature{}),
295 };
296 result[@intFromEnum(Feature.dot5_insts)] = .{
297 .llvm_name = "dot5-insts",
298 .description = "Has v_dot2c_f32_f16 instruction",
299 .dependencies = featureSet(&[_]Feature{}),
300 };
301 result[@intFromEnum(Feature.dot6_insts)] = .{
302 .llvm_name = "dot6-insts",
303 .description = "Has v_dot4c_i32_i8 instruction",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@intFromEnum(Feature.dot7_insts)] = .{
307 .llvm_name = "dot7-insts",
308 .description = "Has v_dot4_u32_u8, v_dot8_u32_u4 instructions",
309 .dependencies = featureSet(&[_]Feature{}),
310 };
311 result[@intFromEnum(Feature.dot8_insts)] = .{
312 .llvm_name = "dot8-insts",
313 .description = "Has v_dot4_i32_iu8, v_dot8_i32_iu4 instructions",
314 .dependencies = featureSet(&[_]Feature{}),
315 };
316 result[@intFromEnum(Feature.dot9_insts)] = .{
317 .llvm_name = "dot9-insts",
318 .description = "Has v_dot2_f16_f16, v_dot2_bf16_bf16, v_dot2_f32_bf16 instructions",
319 .dependencies = featureSet(&[_]Feature{}),
320 };
321 result[@intFromEnum(Feature.dpp)] = .{
322 .llvm_name = "dpp",
323 .description = "Support DPP (Data Parallel Primitives) extension",
324 .dependencies = featureSet(&[_]Feature{}),
325 };
326 result[@intFromEnum(Feature.dpp8)] = .{
327 .llvm_name = "dpp8",
328 .description = "Support DPP8 (Data Parallel Primitives) extension",
329 .dependencies = featureSet(&[_]Feature{}),
330 };
331 result[@intFromEnum(Feature.dpp_64bit)] = .{
332 .llvm_name = "dpp-64bit",
333 .description = "Support DPP (Data Parallel Primitives) extension",
334 .dependencies = featureSet(&[_]Feature{}),
335 };
336 result[@intFromEnum(Feature.ds128)] = .{
337 .llvm_name = "enable-ds128",
338 .description = "Use ds_{read|write}_b128",
339 .dependencies = featureSet(&[_]Feature{}),
340 };
341 result[@intFromEnum(Feature.ds_src2_insts)] = .{
342 .llvm_name = "ds-src2-insts",
343 .description = "Has ds_*_src2 instructions",
344 .dependencies = featureSet(&[_]Feature{}),
345 };
346 result[@intFromEnum(Feature.extended_image_insts)] = .{
347 .llvm_name = "extended-image-insts",
348 .description = "Support mips != 0, lod != 0, gather4, and get_lod",
349 .dependencies = featureSet(&[_]Feature{}),
350 };
351 result[@intFromEnum(Feature.fast_denormal_f32)] = .{
352 .llvm_name = "fast-denormal-f32",
353 .description = "Enabling denormals does not cause f32 instructions to run at f64 rates",
354 .dependencies = featureSet(&[_]Feature{}),
355 };
356 result[@intFromEnum(Feature.fast_fmaf)] = .{
357 .llvm_name = "fast-fmaf",
358 .description = "Assuming f32 fma is at least as fast as mul + add",
359 .dependencies = featureSet(&[_]Feature{}),
360 };
361 result[@intFromEnum(Feature.flat_address_space)] = .{
362 .llvm_name = "flat-address-space",
363 .description = "Support flat address space",
364 .dependencies = featureSet(&[_]Feature{}),
365 };
366 result[@intFromEnum(Feature.flat_atomic_fadd_f32_inst)] = .{
367 .llvm_name = "flat-atomic-fadd-f32-inst",
368 .description = "Has flat_atomic_add_f32 instruction",
369 .dependencies = featureSet(&[_]Feature{}),
370 };
371 result[@intFromEnum(Feature.flat_for_global)] = .{
372 .llvm_name = "flat-for-global",
373 .description = "Force to generate flat instruction for global",
374 .dependencies = featureSet(&[_]Feature{}),
375 };
376 result[@intFromEnum(Feature.flat_global_insts)] = .{
377 .llvm_name = "flat-global-insts",
378 .description = "Have global_* flat memory instructions",
379 .dependencies = featureSet(&[_]Feature{}),
380 };
381 result[@intFromEnum(Feature.flat_inst_offsets)] = .{
382 .llvm_name = "flat-inst-offsets",
383 .description = "Flat instructions have immediate offset addressing mode",
384 .dependencies = featureSet(&[_]Feature{}),
385 };
386 result[@intFromEnum(Feature.flat_scratch)] = .{
387 .llvm_name = "enable-flat-scratch",
388 .description = "Use scratch_* flat memory instructions to access scratch",
389 .dependencies = featureSet(&[_]Feature{}),
390 };
391 result[@intFromEnum(Feature.flat_scratch_insts)] = .{
392 .llvm_name = "flat-scratch-insts",
393 .description = "Have scratch_* flat memory instructions",
394 .dependencies = featureSet(&[_]Feature{}),
395 };
396 result[@intFromEnum(Feature.flat_segment_offset_bug)] = .{
397 .llvm_name = "flat-segment-offset-bug",
398 .description = "GFX10 bug where inst_offset is ignored when flat instructions access global memory",
399 .dependencies = featureSet(&[_]Feature{}),
400 };
401 result[@intFromEnum(Feature.fma_mix_insts)] = .{
402 .llvm_name = "fma-mix-insts",
403 .description = "Has v_fma_mix_f32, v_fma_mixlo_f16, v_fma_mixhi_f16 instructions",
404 .dependencies = featureSet(&[_]Feature{}),
405 };
406 result[@intFromEnum(Feature.fmacf64_inst)] = .{
407 .llvm_name = "fmacf64-inst",
408 .description = "Has v_fmac_f64 instruction",
409 .dependencies = featureSet(&[_]Feature{}),
410 };
411 result[@intFromEnum(Feature.fmaf)] = .{
412 .llvm_name = "fmaf",
413 .description = "Enable single precision FMA (not as fast as mul+add, but fused)",
414 .dependencies = featureSet(&[_]Feature{}),
415 };
416 result[@intFromEnum(Feature.force_store_sc0_sc1)] = .{
417 .llvm_name = "force-store-sc0-sc1",
418 .description = "Has SC0 and SC1 on stores",
419 .dependencies = featureSet(&[_]Feature{}),
420 };
421 result[@intFromEnum(Feature.fp64)] = .{
422 .llvm_name = "fp64",
423 .description = "Enable double precision operations",
424 .dependencies = featureSet(&[_]Feature{}),
425 };
426 result[@intFromEnum(Feature.fp8_insts)] = .{
427 .llvm_name = "fp8-insts",
428 .description = "Has fp8 and bf8 instructions",
429 .dependencies = featureSet(&[_]Feature{}),
430 };
431 result[@intFromEnum(Feature.full_rate_64_ops)] = .{
432 .llvm_name = "full-rate-64-ops",
433 .description = "Most fp64 instructions are full rate",
434 .dependencies = featureSet(&[_]Feature{}),
435 };
436 result[@intFromEnum(Feature.g16)] = .{
437 .llvm_name = "g16",
438 .description = "Support G16 for 16-bit gradient image operands",
439 .dependencies = featureSet(&[_]Feature{}),
440 };
441 result[@intFromEnum(Feature.gcn3_encoding)] = .{
442 .llvm_name = "gcn3-encoding",
443 .description = "Encoding format for VI",
444 .dependencies = featureSet(&[_]Feature{}),
445 };
446 result[@intFromEnum(Feature.get_wave_id_inst)] = .{
447 .llvm_name = "get-wave-id-inst",
448 .description = "Has s_get_waveid_in_workgroup instruction",
449 .dependencies = featureSet(&[_]Feature{}),
450 };
451 result[@intFromEnum(Feature.gfx10)] = .{
452 .llvm_name = "gfx10",
453 .description = "GFX10 GPU generation",
454 .dependencies = featureSet(&[_]Feature{
455 .@"16_bit_insts",
456 .a16,
457 .add_no_carry_insts,
458 .aperture_regs,
459 .ci_insts,
460 .dpp,
461 .dpp8,
462 .extended_image_insts,
463 .fast_denormal_f32,
464 .fast_fmaf,
465 .flat_address_space,
466 .flat_global_insts,
467 .flat_inst_offsets,
468 .flat_scratch_insts,
469 .fma_mix_insts,
470 .fp64,
471 .g16,
472 .gfx10_insts,
473 .gfx8_insts,
474 .gfx9_insts,
475 .image_insts,
476 .int_clamp_insts,
477 .inv_2pi_inline_imm,
478 .localmemorysize65536,
479 .mimg_r128,
480 .movrel,
481 .no_data_dep_hazard,
482 .no_sdst_cmpx,
483 .pk_fmac_f16_inst,
484 .s_memrealtime,
485 .s_memtime_inst,
486 .sdwa,
487 .sdwa_omod,
488 .sdwa_scalar,
489 .sdwa_sdst,
490 .unaligned_buffer_access,
491 .unaligned_ds_access,
492 .vop3_literal,
493 .vop3p,
494 .vscnt,
495 }),
496 };
497 result[@intFromEnum(Feature.gfx10_3_insts)] = .{
498 .llvm_name = "gfx10-3-insts",
499 .description = "Additional instructions for GFX10.3",
500 .dependencies = featureSet(&[_]Feature{}),
501 };
502 result[@intFromEnum(Feature.gfx10_a_encoding)] = .{
503 .llvm_name = "gfx10_a-encoding",
504 .description = "Has BVH ray tracing instructions",
505 .dependencies = featureSet(&[_]Feature{}),
506 };
507 result[@intFromEnum(Feature.gfx10_b_encoding)] = .{
508 .llvm_name = "gfx10_b-encoding",
509 .description = "Encoding format GFX10_B",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@intFromEnum(Feature.gfx10_insts)] = .{
513 .llvm_name = "gfx10-insts",
514 .description = "Additional instructions for GFX10+",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@intFromEnum(Feature.gfx11)] = .{
518 .llvm_name = "gfx11",
519 .description = "GFX11 GPU generation",
520 .dependencies = featureSet(&[_]Feature{
521 .@"16_bit_insts",
522 .a16,
523 .add_no_carry_insts,
524 .aperture_regs,
525 .ci_insts,
526 .dpp,
527 .dpp8,
528 .extended_image_insts,
529 .fast_denormal_f32,
530 .fast_fmaf,
531 .flat_address_space,
532 .flat_global_insts,
533 .flat_inst_offsets,
534 .flat_scratch_insts,
535 .fma_mix_insts,
536 .fp64,
537 .g16,
538 .gfx10_3_insts,
539 .gfx10_a_encoding,
540 .gfx10_b_encoding,
541 .gfx10_insts,
542 .gfx11_insts,
543 .gfx8_insts,
544 .gfx9_insts,
545 .int_clamp_insts,
546 .inv_2pi_inline_imm,
547 .localmemorysize65536,
548 .mimg_r128,
549 .movrel,
550 .no_data_dep_hazard,
551 .no_sdst_cmpx,
552 .pk_fmac_f16_inst,
553 .true16,
554 .unaligned_buffer_access,
555 .unaligned_ds_access,
556 .vop3_literal,
557 .vop3p,
558 .vopd,
559 .vscnt,
560 }),
561 };
562 result[@intFromEnum(Feature.gfx11_full_vgprs)] = .{
563 .llvm_name = "gfx11-full-vgprs",
564 .description = "GFX11 with 50% more physical VGPRs and 50% larger allocation granule than GFX10",
565 .dependencies = featureSet(&[_]Feature{}),
566 };
567 result[@intFromEnum(Feature.gfx11_insts)] = .{
568 .llvm_name = "gfx11-insts",
569 .description = "Additional instructions for GFX11+",
570 .dependencies = featureSet(&[_]Feature{}),
571 };
572 result[@intFromEnum(Feature.gfx7_gfx8_gfx9_insts)] = .{
573 .llvm_name = "gfx7-gfx8-gfx9-insts",
574 .description = "Instructions shared in GFX7, GFX8, GFX9",
575 .dependencies = featureSet(&[_]Feature{}),
576 };
577 result[@intFromEnum(Feature.gfx8_insts)] = .{
578 .llvm_name = "gfx8-insts",
579 .description = "Additional instructions for GFX8+",
580 .dependencies = featureSet(&[_]Feature{}),
581 };
582 result[@intFromEnum(Feature.gfx9)] = .{
583 .llvm_name = "gfx9",
584 .description = "GFX9 GPU generation",
585 .dependencies = featureSet(&[_]Feature{
586 .@"16_bit_insts",
587 .a16,
588 .add_no_carry_insts,
589 .aperture_regs,
590 .ci_insts,
591 .dpp,
592 .fast_denormal_f32,
593 .fast_fmaf,
594 .flat_address_space,
595 .flat_global_insts,
596 .flat_inst_offsets,
597 .flat_scratch_insts,
598 .fp64,
599 .gcn3_encoding,
600 .gfx7_gfx8_gfx9_insts,
601 .gfx8_insts,
602 .gfx9_insts,
603 .int_clamp_insts,
604 .inv_2pi_inline_imm,
605 .localmemorysize65536,
606 .negative_scratch_offset_bug,
607 .r128_a16,
608 .s_memrealtime,
609 .s_memtime_inst,
610 .scalar_atomics,
611 .scalar_flat_scratch_insts,
612 .scalar_stores,
613 .sdwa,
614 .sdwa_omod,
615 .sdwa_scalar,
616 .sdwa_sdst,
617 .unaligned_buffer_access,
618 .unaligned_ds_access,
619 .vgpr_index_mode,
620 .vop3p,
621 .wavefrontsize64,
622 .xnack_support,
623 }),
624 };
625 result[@intFromEnum(Feature.gfx90a_insts)] = .{
626 .llvm_name = "gfx90a-insts",
627 .description = "Additional instructions for GFX90A+",
628 .dependencies = featureSet(&[_]Feature{}),
629 };
630 result[@intFromEnum(Feature.gfx940_insts)] = .{
631 .llvm_name = "gfx940-insts",
632 .description = "Additional instructions for GFX940+",
633 .dependencies = featureSet(&[_]Feature{}),
634 };
635 result[@intFromEnum(Feature.gfx9_insts)] = .{
636 .llvm_name = "gfx9-insts",
637 .description = "Additional instructions for GFX9+",
638 .dependencies = featureSet(&[_]Feature{}),
639 };
640 result[@intFromEnum(Feature.half_rate_64_ops)] = .{
641 .llvm_name = "half-rate-64-ops",
642 .description = "Most fp64 instructions are half rate instead of quarter",
643 .dependencies = featureSet(&[_]Feature{}),
644 };
645 result[@intFromEnum(Feature.image_gather4_d16_bug)] = .{
646 .llvm_name = "image-gather4-d16-bug",
647 .description = "Image Gather4 D16 hardware bug",
648 .dependencies = featureSet(&[_]Feature{}),
649 };
650 result[@intFromEnum(Feature.image_insts)] = .{
651 .llvm_name = "image-insts",
652 .description = "Support image instructions",
653 .dependencies = featureSet(&[_]Feature{}),
654 };
655 result[@intFromEnum(Feature.image_store_d16_bug)] = .{
656 .llvm_name = "image-store-d16-bug",
657 .description = "Image Store D16 hardware bug",
658 .dependencies = featureSet(&[_]Feature{}),
659 };
660 result[@intFromEnum(Feature.inst_fwd_prefetch_bug)] = .{
661 .llvm_name = "inst-fwd-prefetch-bug",
662 .description = "S_INST_PREFETCH instruction causes shader to hang",
663 .dependencies = featureSet(&[_]Feature{}),
664 };
665 result[@intFromEnum(Feature.int_clamp_insts)] = .{
666 .llvm_name = "int-clamp-insts",
667 .description = "Support clamp for integer destination",
668 .dependencies = featureSet(&[_]Feature{}),
669 };
670 result[@intFromEnum(Feature.inv_2pi_inline_imm)] = .{
671 .llvm_name = "inv-2pi-inline-imm",
672 .description = "Has 1 / (2 * pi) as inline immediate",
673 .dependencies = featureSet(&[_]Feature{}),
674 };
675 result[@intFromEnum(Feature.lds_branch_vmem_war_hazard)] = .{
676 .llvm_name = "lds-branch-vmem-war-hazard",
677 .description = "Switching between LDS and VMEM-tex not waiting VM_VSRC=0",
678 .dependencies = featureSet(&[_]Feature{}),
679 };
680 result[@intFromEnum(Feature.lds_misaligned_bug)] = .{
681 .llvm_name = "lds-misaligned-bug",
682 .description = "Some GFX10 bug with multi-dword LDS and flat access that is not naturally aligned in WGP mode",
683 .dependencies = featureSet(&[_]Feature{}),
684 };
685 result[@intFromEnum(Feature.ldsbankcount16)] = .{
686 .llvm_name = "ldsbankcount16",
687 .description = "The number of LDS banks per compute unit.",
688 .dependencies = featureSet(&[_]Feature{}),
689 };
690 result[@intFromEnum(Feature.ldsbankcount32)] = .{
691 .llvm_name = "ldsbankcount32",
692 .description = "The number of LDS banks per compute unit.",
693 .dependencies = featureSet(&[_]Feature{}),
694 };
695 result[@intFromEnum(Feature.load_store_opt)] = .{
696 .llvm_name = "load-store-opt",
697 .description = "Enable SI load/store optimizer pass",
698 .dependencies = featureSet(&[_]Feature{}),
699 };
700 result[@intFromEnum(Feature.localmemorysize32768)] = .{
701 .llvm_name = "localmemorysize32768",
702 .description = "The size of local memory in bytes",
703 .dependencies = featureSet(&[_]Feature{}),
704 };
705 result[@intFromEnum(Feature.localmemorysize65536)] = .{
706 .llvm_name = "localmemorysize65536",
707 .description = "The size of local memory in bytes",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.mad_intra_fwd_bug)] = .{
711 .llvm_name = "mad-intra-fwd-bug",
712 .description = "MAD_U64/I64 intra instruction forwarding bug",
713 .dependencies = featureSet(&[_]Feature{}),
714 };
715 result[@intFromEnum(Feature.mad_mac_f32_insts)] = .{
716 .llvm_name = "mad-mac-f32-insts",
717 .description = "Has v_mad_f32/v_mac_f32/v_madak_f32/v_madmk_f32 instructions",
718 .dependencies = featureSet(&[_]Feature{}),
719 };
720 result[@intFromEnum(Feature.mad_mix_insts)] = .{
721 .llvm_name = "mad-mix-insts",
722 .description = "Has v_mad_mix_f32, v_mad_mixlo_f16, v_mad_mixhi_f16 instructions",
723 .dependencies = featureSet(&[_]Feature{}),
724 };
725 result[@intFromEnum(Feature.mai_insts)] = .{
726 .llvm_name = "mai-insts",
727 .description = "Has mAI instructions",
728 .dependencies = featureSet(&[_]Feature{}),
729 };
730 result[@intFromEnum(Feature.max_private_element_size_16)] = .{
731 .llvm_name = "max-private-element-size-16",
732 .description = "Maximum private access size may be 16",
733 .dependencies = featureSet(&[_]Feature{}),
734 };
735 result[@intFromEnum(Feature.max_private_element_size_4)] = .{
736 .llvm_name = "max-private-element-size-4",
737 .description = "Maximum private access size may be 4",
738 .dependencies = featureSet(&[_]Feature{}),
739 };
740 result[@intFromEnum(Feature.max_private_element_size_8)] = .{
741 .llvm_name = "max-private-element-size-8",
742 .description = "Maximum private access size may be 8",
743 .dependencies = featureSet(&[_]Feature{}),
744 };
745 result[@intFromEnum(Feature.mfma_inline_literal_bug)] = .{
746 .llvm_name = "mfma-inline-literal-bug",
747 .description = "MFMA cannot use inline literal as SrcC",
748 .dependencies = featureSet(&[_]Feature{}),
749 };
750 result[@intFromEnum(Feature.mimg_r128)] = .{
751 .llvm_name = "mimg-r128",
752 .description = "Support 128-bit texture resources",
753 .dependencies = featureSet(&[_]Feature{}),
754 };
755 result[@intFromEnum(Feature.movrel)] = .{
756 .llvm_name = "movrel",
757 .description = "Has v_movrel*_b32 instructions",
758 .dependencies = featureSet(&[_]Feature{}),
759 };
760 result[@intFromEnum(Feature.negative_scratch_offset_bug)] = .{
761 .llvm_name = "negative-scratch-offset-bug",
762 .description = "Negative immediate offsets in scratch instructions with an SGPR offset page fault on GFX9",
763 .dependencies = featureSet(&[_]Feature{}),
764 };
765 result[@intFromEnum(Feature.negative_unaligned_scratch_offset_bug)] = .{
766 .llvm_name = "negative-unaligned-scratch-offset-bug",
767 .description = "Scratch instructions with a VGPR offset and a negative immediate offset that is not a multiple of 4 read wrong memory on GFX10",
768 .dependencies = featureSet(&[_]Feature{}),
769 };
770 result[@intFromEnum(Feature.no_data_dep_hazard)] = .{
771 .llvm_name = "no-data-dep-hazard",
772 .description = "Does not need SW waitstates",
773 .dependencies = featureSet(&[_]Feature{}),
774 };
775 result[@intFromEnum(Feature.no_sdst_cmpx)] = .{
776 .llvm_name = "no-sdst-cmpx",
777 .description = "V_CMPX does not write VCC/SGPR in addition to EXEC",
778 .dependencies = featureSet(&[_]Feature{}),
779 };
780 result[@intFromEnum(Feature.nsa_clause_bug)] = .{
781 .llvm_name = "nsa-clause-bug",
782 .description = "MIMG-NSA in a hard clause has unpredictable results on GFX10.1",
783 .dependencies = featureSet(&[_]Feature{}),
784 };
785 result[@intFromEnum(Feature.nsa_encoding)] = .{
786 .llvm_name = "nsa-encoding",
787 .description = "Support NSA encoding for image instructions",
788 .dependencies = featureSet(&[_]Feature{}),
789 };
790 result[@intFromEnum(Feature.nsa_to_vmem_bug)] = .{
791 .llvm_name = "nsa-to-vmem-bug",
792 .description = "MIMG-NSA followed by VMEM fail if EXEC_LO or EXEC_HI equals zero",
793 .dependencies = featureSet(&[_]Feature{}),
794 };
795 result[@intFromEnum(Feature.offset_3f_bug)] = .{
796 .llvm_name = "offset-3f-bug",
797 .description = "Branch offset of 3f hardware bug",
798 .dependencies = featureSet(&[_]Feature{}),
799 };
800 result[@intFromEnum(Feature.packed_fp32_ops)] = .{
801 .llvm_name = "packed-fp32-ops",
802 .description = "Support packed fp32 instructions",
803 .dependencies = featureSet(&[_]Feature{}),
804 };
805 result[@intFromEnum(Feature.packed_tid)] = .{
806 .llvm_name = "packed-tid",
807 .description = "Workitem IDs are packed into v0 at kernel launch",
808 .dependencies = featureSet(&[_]Feature{}),
809 };
810 result[@intFromEnum(Feature.partial_nsa_encoding)] = .{
811 .llvm_name = "partial-nsa-encoding",
812 .description = "Support partial NSA encoding for image instructions",
813 .dependencies = featureSet(&[_]Feature{}),
814 };
815 result[@intFromEnum(Feature.pk_fmac_f16_inst)] = .{
816 .llvm_name = "pk-fmac-f16-inst",
817 .description = "Has v_pk_fmac_f16 instruction",
818 .dependencies = featureSet(&[_]Feature{}),
819 };
820 result[@intFromEnum(Feature.promote_alloca)] = .{
821 .llvm_name = "promote-alloca",
822 .description = "Enable promote alloca pass",
823 .dependencies = featureSet(&[_]Feature{}),
824 };
825 result[@intFromEnum(Feature.prt_strict_null)] = .{
826 .llvm_name = "enable-prt-strict-null",
827 .description = "Enable zeroing of result registers for sparse texture fetches",
828 .dependencies = featureSet(&[_]Feature{}),
829 };
830 result[@intFromEnum(Feature.r128_a16)] = .{
831 .llvm_name = "r128-a16",
832 .description = "Support gfx9-style A16 for 16-bit coordinates/gradients/lod/clamp/mip image operands, where a16 is aliased with r128",
833 .dependencies = featureSet(&[_]Feature{}),
834 };
835 result[@intFromEnum(Feature.s_memrealtime)] = .{
836 .llvm_name = "s-memrealtime",
837 .description = "Has s_memrealtime instruction",
838 .dependencies = featureSet(&[_]Feature{}),
839 };
840 result[@intFromEnum(Feature.s_memtime_inst)] = .{
841 .llvm_name = "s-memtime-inst",
842 .description = "Has s_memtime instruction",
843 .dependencies = featureSet(&[_]Feature{}),
844 };
845 result[@intFromEnum(Feature.scalar_atomics)] = .{
846 .llvm_name = "scalar-atomics",
847 .description = "Has atomic scalar memory instructions",
848 .dependencies = featureSet(&[_]Feature{}),
849 };
850 result[@intFromEnum(Feature.scalar_flat_scratch_insts)] = .{
851 .llvm_name = "scalar-flat-scratch-insts",
852 .description = "Have s_scratch_* flat memory instructions",
853 .dependencies = featureSet(&[_]Feature{}),
854 };
855 result[@intFromEnum(Feature.scalar_stores)] = .{
856 .llvm_name = "scalar-stores",
857 .description = "Has store scalar memory instructions",
858 .dependencies = featureSet(&[_]Feature{}),
859 };
860 result[@intFromEnum(Feature.sdwa)] = .{
861 .llvm_name = "sdwa",
862 .description = "Support SDWA (Sub-DWORD Addressing) extension",
863 .dependencies = featureSet(&[_]Feature{}),
864 };
865 result[@intFromEnum(Feature.sdwa_mav)] = .{
866 .llvm_name = "sdwa-mav",
867 .description = "Support v_mac_f32/f16 with SDWA (Sub-DWORD Addressing) extension",
868 .dependencies = featureSet(&[_]Feature{}),
869 };
870 result[@intFromEnum(Feature.sdwa_omod)] = .{
871 .llvm_name = "sdwa-omod",
872 .description = "Support OMod with SDWA (Sub-DWORD Addressing) extension",
873 .dependencies = featureSet(&[_]Feature{}),
874 };
875 result[@intFromEnum(Feature.sdwa_out_mods_vopc)] = .{
876 .llvm_name = "sdwa-out-mods-vopc",
877 .description = "Support clamp for VOPC with SDWA (Sub-DWORD Addressing) extension",
878 .dependencies = featureSet(&[_]Feature{}),
879 };
880 result[@intFromEnum(Feature.sdwa_scalar)] = .{
881 .llvm_name = "sdwa-scalar",
882 .description = "Support scalar register with SDWA (Sub-DWORD Addressing) extension",
883 .dependencies = featureSet(&[_]Feature{}),
884 };
885 result[@intFromEnum(Feature.sdwa_sdst)] = .{
886 .llvm_name = "sdwa-sdst",
887 .description = "Support scalar dst for VOPC with SDWA (Sub-DWORD Addressing) extension",
888 .dependencies = featureSet(&[_]Feature{}),
889 };
890 result[@intFromEnum(Feature.sea_islands)] = .{
891 .llvm_name = "sea-islands",
892 .description = "SEA_ISLANDS GPU generation",
893 .dependencies = featureSet(&[_]Feature{
894 .ci_insts,
895 .ds_src2_insts,
896 .extended_image_insts,
897 .flat_address_space,
898 .fp64,
899 .gfx7_gfx8_gfx9_insts,
900 .image_insts,
901 .localmemorysize65536,
902 .mad_mac_f32_insts,
903 .mimg_r128,
904 .movrel,
905 .s_memtime_inst,
906 .trig_reduced_range,
907 .unaligned_buffer_access,
908 .wavefrontsize64,
909 }),
910 };
911 result[@intFromEnum(Feature.sgpr_init_bug)] = .{
912 .llvm_name = "sgpr-init-bug",
913 .description = "VI SGPR initialization bug requiring a fixed SGPR allocation size",
914 .dependencies = featureSet(&[_]Feature{}),
915 };
916 result[@intFromEnum(Feature.shader_cycles_register)] = .{
917 .llvm_name = "shader-cycles-register",
918 .description = "Has SHADER_CYCLES hardware register",
919 .dependencies = featureSet(&[_]Feature{}),
920 };
921 result[@intFromEnum(Feature.si_scheduler)] = .{
922 .llvm_name = "si-scheduler",
923 .description = "Enable SI Machine Scheduler",
924 .dependencies = featureSet(&[_]Feature{}),
925 };
926 result[@intFromEnum(Feature.smem_to_vector_write_hazard)] = .{
927 .llvm_name = "smem-to-vector-write-hazard",
928 .description = "s_load_dword followed by v_cmp page faults",
929 .dependencies = featureSet(&[_]Feature{}),
930 };
931 result[@intFromEnum(Feature.southern_islands)] = .{
932 .llvm_name = "southern-islands",
933 .description = "SOUTHERN_ISLANDS GPU generation",
934 .dependencies = featureSet(&[_]Feature{
935 .ds_src2_insts,
936 .extended_image_insts,
937 .fp64,
938 .image_insts,
939 .ldsbankcount32,
940 .localmemorysize32768,
941 .mad_mac_f32_insts,
942 .mimg_r128,
943 .movrel,
944 .s_memtime_inst,
945 .trig_reduced_range,
946 .wavefrontsize64,
947 }),
948 };
949 result[@intFromEnum(Feature.sramecc)] = .{
950 .llvm_name = "sramecc",
951 .description = "Enable SRAMECC",
952 .dependencies = featureSet(&[_]Feature{}),
953 };
954 result[@intFromEnum(Feature.sramecc_support)] = .{
955 .llvm_name = "sramecc-support",
956 .description = "Hardware supports SRAMECC",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.tgsplit)] = .{
960 .llvm_name = "tgsplit",
961 .description = "Enable threadgroup split execution",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.trap_handler)] = .{
965 .llvm_name = "trap-handler",
966 .description = "Trap handler support",
967 .dependencies = featureSet(&[_]Feature{}),
968 };
969 result[@intFromEnum(Feature.trig_reduced_range)] = .{
970 .llvm_name = "trig-reduced-range",
971 .description = "Requires use of fract on arguments to trig instructions",
972 .dependencies = featureSet(&[_]Feature{}),
973 };
974 result[@intFromEnum(Feature.true16)] = .{
975 .llvm_name = "true16",
976 .description = "True 16-bit operand instructions",
977 .dependencies = featureSet(&[_]Feature{}),
978 };
979 result[@intFromEnum(Feature.unaligned_access_mode)] = .{
980 .llvm_name = "unaligned-access-mode",
981 .description = "Enable unaligned global, local and region loads and stores if the hardware supports it",
982 .dependencies = featureSet(&[_]Feature{}),
983 };
984 result[@intFromEnum(Feature.unaligned_buffer_access)] = .{
985 .llvm_name = "unaligned-buffer-access",
986 .description = "Hardware supports unaligned global loads and stores",
987 .dependencies = featureSet(&[_]Feature{}),
988 };
989 result[@intFromEnum(Feature.unaligned_ds_access)] = .{
990 .llvm_name = "unaligned-ds-access",
991 .description = "Hardware supports unaligned local and region loads and stores",
992 .dependencies = featureSet(&[_]Feature{}),
993 };
994 result[@intFromEnum(Feature.unaligned_scratch_access)] = .{
995 .llvm_name = "unaligned-scratch-access",
996 .description = "Support unaligned scratch loads and stores",
997 .dependencies = featureSet(&[_]Feature{}),
998 };
999 result[@intFromEnum(Feature.unpacked_d16_vmem)] = .{
1000 .llvm_name = "unpacked-d16-vmem",
1001 .description = "Has unpacked d16 vmem instructions",
1002 .dependencies = featureSet(&[_]Feature{}),
1003 };
1004 result[@intFromEnum(Feature.unsafe_ds_offset_folding)] = .{
1005 .llvm_name = "unsafe-ds-offset-folding",
1006 .description = "Force using DS instruction immediate offsets on SI",
1007 .dependencies = featureSet(&[_]Feature{}),
1008 };
1009 result[@intFromEnum(Feature.user_sgpr_init16_bug)] = .{
1010 .llvm_name = "user-sgpr-init16-bug",
1011 .description = "Bug requiring at least 16 user+system SGPRs to be enabled",
1012 .dependencies = featureSet(&[_]Feature{}),
1013 };
1014 result[@intFromEnum(Feature.valu_trans_use_hazard)] = .{
1015 .llvm_name = "valu-trans-use-hazard",
1016 .description = "Hazard when TRANS instructions are closely followed by a use of the result",
1017 .dependencies = featureSet(&[_]Feature{}),
1018 };
1019 result[@intFromEnum(Feature.vcmpx_exec_war_hazard)] = .{
1020 .llvm_name = "vcmpx-exec-war-hazard",
1021 .description = "V_CMPX WAR hazard on EXEC (V_CMPX issue ONLY)",
1022 .dependencies = featureSet(&[_]Feature{}),
1023 };
1024 result[@intFromEnum(Feature.vcmpx_permlane_hazard)] = .{
1025 .llvm_name = "vcmpx-permlane-hazard",
1026 .description = "TODO: describe me",
1027 .dependencies = featureSet(&[_]Feature{}),
1028 };
1029 result[@intFromEnum(Feature.vgpr_index_mode)] = .{
1030 .llvm_name = "vgpr-index-mode",
1031 .description = "Has VGPR mode register indexing",
1032 .dependencies = featureSet(&[_]Feature{}),
1033 };
1034 result[@intFromEnum(Feature.vmem_to_scalar_write_hazard)] = .{
1035 .llvm_name = "vmem-to-scalar-write-hazard",
1036 .description = "VMEM instruction followed by scalar writing to EXEC mask, M0 or SGPR leads to incorrect execution.",
1037 .dependencies = featureSet(&[_]Feature{}),
1038 };
1039 result[@intFromEnum(Feature.volcanic_islands)] = .{
1040 .llvm_name = "volcanic-islands",
1041 .description = "VOLCANIC_ISLANDS GPU generation",
1042 .dependencies = featureSet(&[_]Feature{
1043 .@"16_bit_insts",
1044 .ci_insts,
1045 .dpp,
1046 .ds_src2_insts,
1047 .extended_image_insts,
1048 .fast_denormal_f32,
1049 .flat_address_space,
1050 .fp64,
1051 .gcn3_encoding,
1052 .gfx7_gfx8_gfx9_insts,
1053 .gfx8_insts,
1054 .image_insts,
1055 .int_clamp_insts,
1056 .inv_2pi_inline_imm,
1057 .localmemorysize65536,
1058 .mad_mac_f32_insts,
1059 .mimg_r128,
1060 .movrel,
1061 .s_memrealtime,
1062 .s_memtime_inst,
1063 .scalar_stores,
1064 .sdwa,
1065 .sdwa_mav,
1066 .sdwa_out_mods_vopc,
1067 .trig_reduced_range,
1068 .unaligned_buffer_access,
1069 .vgpr_index_mode,
1070 .wavefrontsize64,
1071 }),
1072 };
1073 result[@intFromEnum(Feature.vop3_literal)] = .{
1074 .llvm_name = "vop3-literal",
1075 .description = "Can use one literal in VOP3",
1076 .dependencies = featureSet(&[_]Feature{}),
1077 };
1078 result[@intFromEnum(Feature.vop3p)] = .{
1079 .llvm_name = "vop3p",
1080 .description = "Has VOP3P packed instructions",
1081 .dependencies = featureSet(&[_]Feature{}),
1082 };
1083 result[@intFromEnum(Feature.vopd)] = .{
1084 .llvm_name = "vopd",
1085 .description = "Has VOPD dual issue wave32 instructions",
1086 .dependencies = featureSet(&[_]Feature{}),
1087 };
1088 result[@intFromEnum(Feature.vscnt)] = .{
1089 .llvm_name = "vscnt",
1090 .description = "Has separate store vscnt counter",
1091 .dependencies = featureSet(&[_]Feature{}),
1092 };
1093 result[@intFromEnum(Feature.wavefrontsize16)] = .{
1094 .llvm_name = "wavefrontsize16",
1095 .description = "The number of threads per wavefront",
1096 .dependencies = featureSet(&[_]Feature{}),
1097 };
1098 result[@intFromEnum(Feature.wavefrontsize32)] = .{
1099 .llvm_name = "wavefrontsize32",
1100 .description = "The number of threads per wavefront",
1101 .dependencies = featureSet(&[_]Feature{}),
1102 };
1103 result[@intFromEnum(Feature.wavefrontsize64)] = .{
1104 .llvm_name = "wavefrontsize64",
1105 .description = "The number of threads per wavefront",
1106 .dependencies = featureSet(&[_]Feature{}),
1107 };
1108 result[@intFromEnum(Feature.xnack)] = .{
1109 .llvm_name = "xnack",
1110 .description = "Enable XNACK support",
1111 .dependencies = featureSet(&[_]Feature{}),
1112 };
1113 result[@intFromEnum(Feature.xnack_support)] = .{
1114 .llvm_name = "xnack-support",
1115 .description = "Hardware supports XNACK",
1116 .dependencies = featureSet(&[_]Feature{}),
1117 };
1118 const ti = @typeInfo(Feature);
1119 for (&result, 0..) |*elem, i| {
1120 elem.index = i;
1121 elem.name = ti.Enum.fields[i].name;
1122 }
1123 break :blk result;
1124};
1125
1126pub const cpu = struct {
1127 pub const bonaire = CpuModel{
1128 .name = "bonaire",
1129 .llvm_name = "bonaire",
1130 .features = featureSet(&[_]Feature{
1131 .ldsbankcount32,
1132 .sea_islands,
1133 }),
1134 };
1135 pub const carrizo = CpuModel{
1136 .name = "carrizo",
1137 .llvm_name = "carrizo",
1138 .features = featureSet(&[_]Feature{
1139 .fast_fmaf,
1140 .half_rate_64_ops,
1141 .ldsbankcount32,
1142 .unpacked_d16_vmem,
1143 .volcanic_islands,
1144 .xnack_support,
1145 }),
1146 };
1147 pub const fiji = CpuModel{
1148 .name = "fiji",
1149 .llvm_name = "fiji",
1150 .features = featureSet(&[_]Feature{
1151 .ldsbankcount32,
1152 .unpacked_d16_vmem,
1153 .volcanic_islands,
1154 }),
1155 };
1156 pub const generic = CpuModel{
1157 .name = "generic",
1158 .llvm_name = "generic",
1159 .features = featureSet(&[_]Feature{
1160 .wavefrontsize64,
1161 }),
1162 };
1163 pub const generic_hsa = CpuModel{
1164 .name = "generic_hsa",
1165 .llvm_name = "generic-hsa",
1166 .features = featureSet(&[_]Feature{
1167 .flat_address_space,
1168 .wavefrontsize64,
1169 }),
1170 };
1171 pub const gfx1010 = CpuModel{
1172 .name = "gfx1010",
1173 .llvm_name = "gfx1010",
1174 .features = featureSet(&[_]Feature{
1175 .back_off_barrier,
1176 .dl_insts,
1177 .ds_src2_insts,
1178 .flat_segment_offset_bug,
1179 .get_wave_id_inst,
1180 .gfx10,
1181 .inst_fwd_prefetch_bug,
1182 .lds_branch_vmem_war_hazard,
1183 .lds_misaligned_bug,
1184 .ldsbankcount32,
1185 .mad_mac_f32_insts,
1186 .negative_unaligned_scratch_offset_bug,
1187 .nsa_clause_bug,
1188 .nsa_encoding,
1189 .nsa_to_vmem_bug,
1190 .offset_3f_bug,
1191 .scalar_atomics,
1192 .scalar_flat_scratch_insts,
1193 .scalar_stores,
1194 .smem_to_vector_write_hazard,
1195 .vcmpx_exec_war_hazard,
1196 .vcmpx_permlane_hazard,
1197 .vmem_to_scalar_write_hazard,
1198 .wavefrontsize32,
1199 .xnack_support,
1200 }),
1201 };
1202 pub const gfx1011 = CpuModel{
1203 .name = "gfx1011",
1204 .llvm_name = "gfx1011",
1205 .features = featureSet(&[_]Feature{
1206 .back_off_barrier,
1207 .dl_insts,
1208 .dot10_insts,
1209 .dot1_insts,
1210 .dot2_insts,
1211 .dot5_insts,
1212 .dot6_insts,
1213 .dot7_insts,
1214 .ds_src2_insts,
1215 .flat_segment_offset_bug,
1216 .get_wave_id_inst,
1217 .gfx10,
1218 .inst_fwd_prefetch_bug,
1219 .lds_branch_vmem_war_hazard,
1220 .lds_misaligned_bug,
1221 .ldsbankcount32,
1222 .mad_mac_f32_insts,
1223 .negative_unaligned_scratch_offset_bug,
1224 .nsa_clause_bug,
1225 .nsa_encoding,
1226 .nsa_to_vmem_bug,
1227 .offset_3f_bug,
1228 .scalar_atomics,
1229 .scalar_flat_scratch_insts,
1230 .scalar_stores,
1231 .smem_to_vector_write_hazard,
1232 .vcmpx_exec_war_hazard,
1233 .vcmpx_permlane_hazard,
1234 .vmem_to_scalar_write_hazard,
1235 .wavefrontsize32,
1236 .xnack_support,
1237 }),
1238 };
1239 pub const gfx1012 = CpuModel{
1240 .name = "gfx1012",
1241 .llvm_name = "gfx1012",
1242 .features = featureSet(&[_]Feature{
1243 .back_off_barrier,
1244 .dl_insts,
1245 .dot10_insts,
1246 .dot1_insts,
1247 .dot2_insts,
1248 .dot5_insts,
1249 .dot6_insts,
1250 .dot7_insts,
1251 .ds_src2_insts,
1252 .flat_segment_offset_bug,
1253 .get_wave_id_inst,
1254 .gfx10,
1255 .inst_fwd_prefetch_bug,
1256 .lds_branch_vmem_war_hazard,
1257 .lds_misaligned_bug,
1258 .ldsbankcount32,
1259 .mad_mac_f32_insts,
1260 .negative_unaligned_scratch_offset_bug,
1261 .nsa_clause_bug,
1262 .nsa_encoding,
1263 .nsa_to_vmem_bug,
1264 .offset_3f_bug,
1265 .scalar_atomics,
1266 .scalar_flat_scratch_insts,
1267 .scalar_stores,
1268 .smem_to_vector_write_hazard,
1269 .vcmpx_exec_war_hazard,
1270 .vcmpx_permlane_hazard,
1271 .vmem_to_scalar_write_hazard,
1272 .wavefrontsize32,
1273 .xnack_support,
1274 }),
1275 };
1276 pub const gfx1013 = CpuModel{
1277 .name = "gfx1013",
1278 .llvm_name = "gfx1013",
1279 .features = featureSet(&[_]Feature{
1280 .back_off_barrier,
1281 .dl_insts,
1282 .ds_src2_insts,
1283 .flat_segment_offset_bug,
1284 .get_wave_id_inst,
1285 .gfx10,
1286 .gfx10_a_encoding,
1287 .inst_fwd_prefetch_bug,
1288 .lds_branch_vmem_war_hazard,
1289 .lds_misaligned_bug,
1290 .ldsbankcount32,
1291 .mad_mac_f32_insts,
1292 .negative_unaligned_scratch_offset_bug,
1293 .nsa_clause_bug,
1294 .nsa_encoding,
1295 .nsa_to_vmem_bug,
1296 .offset_3f_bug,
1297 .scalar_atomics,
1298 .scalar_flat_scratch_insts,
1299 .scalar_stores,
1300 .smem_to_vector_write_hazard,
1301 .vcmpx_exec_war_hazard,
1302 .vcmpx_permlane_hazard,
1303 .vmem_to_scalar_write_hazard,
1304 .wavefrontsize32,
1305 .xnack_support,
1306 }),
1307 };
1308 pub const gfx1030 = CpuModel{
1309 .name = "gfx1030",
1310 .llvm_name = "gfx1030",
1311 .features = featureSet(&[_]Feature{
1312 .back_off_barrier,
1313 .dl_insts,
1314 .dot10_insts,
1315 .dot1_insts,
1316 .dot2_insts,
1317 .dot5_insts,
1318 .dot6_insts,
1319 .dot7_insts,
1320 .gfx10,
1321 .gfx10_3_insts,
1322 .gfx10_a_encoding,
1323 .gfx10_b_encoding,
1324 .ldsbankcount32,
1325 .nsa_encoding,
1326 .shader_cycles_register,
1327 .wavefrontsize32,
1328 }),
1329 };
1330 pub const gfx1031 = CpuModel{
1331 .name = "gfx1031",
1332 .llvm_name = "gfx1031",
1333 .features = featureSet(&[_]Feature{
1334 .back_off_barrier,
1335 .dl_insts,
1336 .dot10_insts,
1337 .dot1_insts,
1338 .dot2_insts,
1339 .dot5_insts,
1340 .dot6_insts,
1341 .dot7_insts,
1342 .gfx10,
1343 .gfx10_3_insts,
1344 .gfx10_a_encoding,
1345 .gfx10_b_encoding,
1346 .ldsbankcount32,
1347 .nsa_encoding,
1348 .shader_cycles_register,
1349 .wavefrontsize32,
1350 }),
1351 };
1352 pub const gfx1032 = CpuModel{
1353 .name = "gfx1032",
1354 .llvm_name = "gfx1032",
1355 .features = featureSet(&[_]Feature{
1356 .back_off_barrier,
1357 .dl_insts,
1358 .dot10_insts,
1359 .dot1_insts,
1360 .dot2_insts,
1361 .dot5_insts,
1362 .dot6_insts,
1363 .dot7_insts,
1364 .gfx10,
1365 .gfx10_3_insts,
1366 .gfx10_a_encoding,
1367 .gfx10_b_encoding,
1368 .ldsbankcount32,
1369 .nsa_encoding,
1370 .shader_cycles_register,
1371 .wavefrontsize32,
1372 }),
1373 };
1374 pub const gfx1033 = CpuModel{
1375 .name = "gfx1033",
1376 .llvm_name = "gfx1033",
1377 .features = featureSet(&[_]Feature{
1378 .back_off_barrier,
1379 .dl_insts,
1380 .dot10_insts,
1381 .dot1_insts,
1382 .dot2_insts,
1383 .dot5_insts,
1384 .dot6_insts,
1385 .dot7_insts,
1386 .gfx10,
1387 .gfx10_3_insts,
1388 .gfx10_a_encoding,
1389 .gfx10_b_encoding,
1390 .ldsbankcount32,
1391 .nsa_encoding,
1392 .shader_cycles_register,
1393 .wavefrontsize32,
1394 }),
1395 };
1396 pub const gfx1034 = CpuModel{
1397 .name = "gfx1034",
1398 .llvm_name = "gfx1034",
1399 .features = featureSet(&[_]Feature{
1400 .back_off_barrier,
1401 .dl_insts,
1402 .dot10_insts,
1403 .dot1_insts,
1404 .dot2_insts,
1405 .dot5_insts,
1406 .dot6_insts,
1407 .dot7_insts,
1408 .gfx10,
1409 .gfx10_3_insts,
1410 .gfx10_a_encoding,
1411 .gfx10_b_encoding,
1412 .ldsbankcount32,
1413 .nsa_encoding,
1414 .shader_cycles_register,
1415 .wavefrontsize32,
1416 }),
1417 };
1418 pub const gfx1035 = CpuModel{
1419 .name = "gfx1035",
1420 .llvm_name = "gfx1035",
1421 .features = featureSet(&[_]Feature{
1422 .back_off_barrier,
1423 .dl_insts,
1424 .dot10_insts,
1425 .dot1_insts,
1426 .dot2_insts,
1427 .dot5_insts,
1428 .dot6_insts,
1429 .dot7_insts,
1430 .gfx10,
1431 .gfx10_3_insts,
1432 .gfx10_a_encoding,
1433 .gfx10_b_encoding,
1434 .ldsbankcount32,
1435 .nsa_encoding,
1436 .shader_cycles_register,
1437 .wavefrontsize32,
1438 }),
1439 };
1440 pub const gfx1036 = CpuModel{
1441 .name = "gfx1036",
1442 .llvm_name = "gfx1036",
1443 .features = featureSet(&[_]Feature{
1444 .back_off_barrier,
1445 .dl_insts,
1446 .dot10_insts,
1447 .dot1_insts,
1448 .dot2_insts,
1449 .dot5_insts,
1450 .dot6_insts,
1451 .dot7_insts,
1452 .gfx10,
1453 .gfx10_3_insts,
1454 .gfx10_a_encoding,
1455 .gfx10_b_encoding,
1456 .ldsbankcount32,
1457 .nsa_encoding,
1458 .shader_cycles_register,
1459 .wavefrontsize32,
1460 }),
1461 };
1462 pub const gfx1100 = CpuModel{
1463 .name = "gfx1100",
1464 .llvm_name = "gfx1100",
1465 .features = featureSet(&[_]Feature{
1466 .architected_flat_scratch,
1467 .atomic_fadd_no_rtn_insts,
1468 .atomic_fadd_rtn_insts,
1469 .dl_insts,
1470 .dot10_insts,
1471 .dot5_insts,
1472 .dot7_insts,
1473 .dot8_insts,
1474 .dot9_insts,
1475 .flat_atomic_fadd_f32_inst,
1476 .gfx11,
1477 .gfx11_full_vgprs,
1478 .image_insts,
1479 .ldsbankcount32,
1480 .mad_intra_fwd_bug,
1481 .nsa_encoding,
1482 .packed_tid,
1483 .partial_nsa_encoding,
1484 .shader_cycles_register,
1485 .user_sgpr_init16_bug,
1486 .valu_trans_use_hazard,
1487 .vcmpx_permlane_hazard,
1488 .wavefrontsize32,
1489 }),
1490 };
1491 pub const gfx1101 = CpuModel{
1492 .name = "gfx1101",
1493 .llvm_name = "gfx1101",
1494 .features = featureSet(&[_]Feature{
1495 .architected_flat_scratch,
1496 .atomic_fadd_no_rtn_insts,
1497 .atomic_fadd_rtn_insts,
1498 .dl_insts,
1499 .dot10_insts,
1500 .dot5_insts,
1501 .dot7_insts,
1502 .dot8_insts,
1503 .dot9_insts,
1504 .flat_atomic_fadd_f32_inst,
1505 .gfx11,
1506 .gfx11_full_vgprs,
1507 .image_insts,
1508 .ldsbankcount32,
1509 .mad_intra_fwd_bug,
1510 .nsa_encoding,
1511 .packed_tid,
1512 .partial_nsa_encoding,
1513 .shader_cycles_register,
1514 .valu_trans_use_hazard,
1515 .vcmpx_permlane_hazard,
1516 .wavefrontsize32,
1517 }),
1518 };
1519 pub const gfx1102 = CpuModel{
1520 .name = "gfx1102",
1521 .llvm_name = "gfx1102",
1522 .features = featureSet(&[_]Feature{
1523 .architected_flat_scratch,
1524 .atomic_fadd_no_rtn_insts,
1525 .atomic_fadd_rtn_insts,
1526 .dl_insts,
1527 .dot10_insts,
1528 .dot5_insts,
1529 .dot7_insts,
1530 .dot8_insts,
1531 .dot9_insts,
1532 .flat_atomic_fadd_f32_inst,
1533 .gfx11,
1534 .image_insts,
1535 .ldsbankcount32,
1536 .mad_intra_fwd_bug,
1537 .nsa_encoding,
1538 .packed_tid,
1539 .partial_nsa_encoding,
1540 .shader_cycles_register,
1541 .user_sgpr_init16_bug,
1542 .valu_trans_use_hazard,
1543 .vcmpx_permlane_hazard,
1544 .wavefrontsize32,
1545 }),
1546 };
1547 pub const gfx1103 = CpuModel{
1548 .name = "gfx1103",
1549 .llvm_name = "gfx1103",
1550 .features = featureSet(&[_]Feature{
1551 .architected_flat_scratch,
1552 .atomic_fadd_no_rtn_insts,
1553 .atomic_fadd_rtn_insts,
1554 .dl_insts,
1555 .dot10_insts,
1556 .dot5_insts,
1557 .dot7_insts,
1558 .dot8_insts,
1559 .dot9_insts,
1560 .flat_atomic_fadd_f32_inst,
1561 .gfx11,
1562 .image_insts,
1563 .ldsbankcount32,
1564 .mad_intra_fwd_bug,
1565 .nsa_encoding,
1566 .packed_tid,
1567 .partial_nsa_encoding,
1568 .shader_cycles_register,
1569 .valu_trans_use_hazard,
1570 .vcmpx_permlane_hazard,
1571 .wavefrontsize32,
1572 }),
1573 };
1574 pub const gfx1150 = CpuModel{
1575 .name = "gfx1150",
1576 .llvm_name = "gfx1150",
1577 .features = featureSet(&[_]Feature{
1578 .architected_flat_scratch,
1579 .atomic_fadd_no_rtn_insts,
1580 .atomic_fadd_rtn_insts,
1581 .dl_insts,
1582 .dot10_insts,
1583 .dot5_insts,
1584 .dot7_insts,
1585 .dot8_insts,
1586 .dot9_insts,
1587 .flat_atomic_fadd_f32_inst,
1588 .gfx11,
1589 .image_insts,
1590 .ldsbankcount32,
1591 .mad_intra_fwd_bug,
1592 .nsa_encoding,
1593 .packed_tid,
1594 .partial_nsa_encoding,
1595 .shader_cycles_register,
1596 .vcmpx_permlane_hazard,
1597 .wavefrontsize32,
1598 }),
1599 };
1600 pub const gfx1151 = CpuModel{
1601 .name = "gfx1151",
1602 .llvm_name = "gfx1151",
1603 .features = featureSet(&[_]Feature{
1604 .architected_flat_scratch,
1605 .atomic_fadd_no_rtn_insts,
1606 .atomic_fadd_rtn_insts,
1607 .dl_insts,
1608 .dot10_insts,
1609 .dot5_insts,
1610 .dot7_insts,
1611 .dot8_insts,
1612 .dot9_insts,
1613 .flat_atomic_fadd_f32_inst,
1614 .gfx11,
1615 .gfx11_full_vgprs,
1616 .image_insts,
1617 .ldsbankcount32,
1618 .mad_intra_fwd_bug,
1619 .nsa_encoding,
1620 .packed_tid,
1621 .partial_nsa_encoding,
1622 .shader_cycles_register,
1623 .vcmpx_permlane_hazard,
1624 .wavefrontsize32,
1625 }),
1626 };
1627 pub const gfx600 = CpuModel{
1628 .name = "gfx600",
1629 .llvm_name = "gfx600",
1630 .features = featureSet(&[_]Feature{
1631 .fast_fmaf,
1632 .half_rate_64_ops,
1633 .southern_islands,
1634 }),
1635 };
1636 pub const gfx601 = CpuModel{
1637 .name = "gfx601",
1638 .llvm_name = "gfx601",
1639 .features = featureSet(&[_]Feature{
1640 .southern_islands,
1641 }),
1642 };
1643 pub const gfx602 = CpuModel{
1644 .name = "gfx602",
1645 .llvm_name = "gfx602",
1646 .features = featureSet(&[_]Feature{
1647 .southern_islands,
1648 }),
1649 };
1650 pub const gfx700 = CpuModel{
1651 .name = "gfx700",
1652 .llvm_name = "gfx700",
1653 .features = featureSet(&[_]Feature{
1654 .ldsbankcount32,
1655 .sea_islands,
1656 }),
1657 };
1658 pub const gfx701 = CpuModel{
1659 .name = "gfx701",
1660 .llvm_name = "gfx701",
1661 .features = featureSet(&[_]Feature{
1662 .fast_fmaf,
1663 .half_rate_64_ops,
1664 .ldsbankcount32,
1665 .sea_islands,
1666 }),
1667 };
1668 pub const gfx702 = CpuModel{
1669 .name = "gfx702",
1670 .llvm_name = "gfx702",
1671 .features = featureSet(&[_]Feature{
1672 .fast_fmaf,
1673 .ldsbankcount16,
1674 .sea_islands,
1675 }),
1676 };
1677 pub const gfx703 = CpuModel{
1678 .name = "gfx703",
1679 .llvm_name = "gfx703",
1680 .features = featureSet(&[_]Feature{
1681 .ldsbankcount16,
1682 .sea_islands,
1683 }),
1684 };
1685 pub const gfx704 = CpuModel{
1686 .name = "gfx704",
1687 .llvm_name = "gfx704",
1688 .features = featureSet(&[_]Feature{
1689 .ldsbankcount32,
1690 .sea_islands,
1691 }),
1692 };
1693 pub const gfx705 = CpuModel{
1694 .name = "gfx705",
1695 .llvm_name = "gfx705",
1696 .features = featureSet(&[_]Feature{
1697 .ldsbankcount16,
1698 .sea_islands,
1699 }),
1700 };
1701 pub const gfx801 = CpuModel{
1702 .name = "gfx801",
1703 .llvm_name = "gfx801",
1704 .features = featureSet(&[_]Feature{
1705 .fast_fmaf,
1706 .half_rate_64_ops,
1707 .ldsbankcount32,
1708 .unpacked_d16_vmem,
1709 .volcanic_islands,
1710 .xnack_support,
1711 }),
1712 };
1713 pub const gfx802 = CpuModel{
1714 .name = "gfx802",
1715 .llvm_name = "gfx802",
1716 .features = featureSet(&[_]Feature{
1717 .ldsbankcount32,
1718 .sgpr_init_bug,
1719 .unpacked_d16_vmem,
1720 .volcanic_islands,
1721 }),
1722 };
1723 pub const gfx803 = CpuModel{
1724 .name = "gfx803",
1725 .llvm_name = "gfx803",
1726 .features = featureSet(&[_]Feature{
1727 .ldsbankcount32,
1728 .unpacked_d16_vmem,
1729 .volcanic_islands,
1730 }),
1731 };
1732 pub const gfx805 = CpuModel{
1733 .name = "gfx805",
1734 .llvm_name = "gfx805",
1735 .features = featureSet(&[_]Feature{
1736 .ldsbankcount32,
1737 .sgpr_init_bug,
1738 .unpacked_d16_vmem,
1739 .volcanic_islands,
1740 }),
1741 };
1742 pub const gfx810 = CpuModel{
1743 .name = "gfx810",
1744 .llvm_name = "gfx810",
1745 .features = featureSet(&[_]Feature{
1746 .image_gather4_d16_bug,
1747 .image_store_d16_bug,
1748 .ldsbankcount16,
1749 .volcanic_islands,
1750 .xnack_support,
1751 }),
1752 };
1753 pub const gfx900 = CpuModel{
1754 .name = "gfx900",
1755 .llvm_name = "gfx900",
1756 .features = featureSet(&[_]Feature{
1757 .ds_src2_insts,
1758 .extended_image_insts,
1759 .gfx9,
1760 .image_gather4_d16_bug,
1761 .image_insts,
1762 .ldsbankcount32,
1763 .mad_mac_f32_insts,
1764 .mad_mix_insts,
1765 }),
1766 };
1767 pub const gfx902 = CpuModel{
1768 .name = "gfx902",
1769 .llvm_name = "gfx902",
1770 .features = featureSet(&[_]Feature{
1771 .ds_src2_insts,
1772 .extended_image_insts,
1773 .gfx9,
1774 .image_gather4_d16_bug,
1775 .image_insts,
1776 .ldsbankcount32,
1777 .mad_mac_f32_insts,
1778 .mad_mix_insts,
1779 }),
1780 };
1781 pub const gfx904 = CpuModel{
1782 .name = "gfx904",
1783 .llvm_name = "gfx904",
1784 .features = featureSet(&[_]Feature{
1785 .ds_src2_insts,
1786 .extended_image_insts,
1787 .fma_mix_insts,
1788 .gfx9,
1789 .image_gather4_d16_bug,
1790 .image_insts,
1791 .ldsbankcount32,
1792 .mad_mac_f32_insts,
1793 }),
1794 };
1795 pub const gfx906 = CpuModel{
1796 .name = "gfx906",
1797 .llvm_name = "gfx906",
1798 .features = featureSet(&[_]Feature{
1799 .dl_insts,
1800 .dot10_insts,
1801 .dot1_insts,
1802 .dot2_insts,
1803 .dot7_insts,
1804 .ds_src2_insts,
1805 .extended_image_insts,
1806 .fma_mix_insts,
1807 .gfx9,
1808 .half_rate_64_ops,
1809 .image_gather4_d16_bug,
1810 .image_insts,
1811 .ldsbankcount32,
1812 .mad_mac_f32_insts,
1813 .sramecc_support,
1814 }),
1815 };
1816 pub const gfx908 = CpuModel{
1817 .name = "gfx908",
1818 .llvm_name = "gfx908",
1819 .features = featureSet(&[_]Feature{
1820 .atomic_buffer_global_pk_add_f16_no_rtn_insts,
1821 .atomic_fadd_no_rtn_insts,
1822 .dl_insts,
1823 .dot10_insts,
1824 .dot1_insts,
1825 .dot2_insts,
1826 .dot3_insts,
1827 .dot4_insts,
1828 .dot5_insts,
1829 .dot6_insts,
1830 .dot7_insts,
1831 .ds_src2_insts,
1832 .extended_image_insts,
1833 .fma_mix_insts,
1834 .gfx9,
1835 .half_rate_64_ops,
1836 .image_gather4_d16_bug,
1837 .image_insts,
1838 .ldsbankcount32,
1839 .mad_mac_f32_insts,
1840 .mai_insts,
1841 .mfma_inline_literal_bug,
1842 .pk_fmac_f16_inst,
1843 .sramecc_support,
1844 }),
1845 };
1846 pub const gfx909 = CpuModel{
1847 .name = "gfx909",
1848 .llvm_name = "gfx909",
1849 .features = featureSet(&[_]Feature{
1850 .ds_src2_insts,
1851 .extended_image_insts,
1852 .gfx9,
1853 .image_gather4_d16_bug,
1854 .image_insts,
1855 .ldsbankcount32,
1856 .mad_mac_f32_insts,
1857 .mad_mix_insts,
1858 }),
1859 };
1860 pub const gfx90a = CpuModel{
1861 .name = "gfx90a",
1862 .llvm_name = "gfx90a",
1863 .features = featureSet(&[_]Feature{
1864 .atomic_buffer_global_pk_add_f16_insts,
1865 .atomic_fadd_no_rtn_insts,
1866 .atomic_fadd_rtn_insts,
1867 .back_off_barrier,
1868 .dl_insts,
1869 .dot10_insts,
1870 .dot1_insts,
1871 .dot2_insts,
1872 .dot3_insts,
1873 .dot4_insts,
1874 .dot5_insts,
1875 .dot6_insts,
1876 .dot7_insts,
1877 .dpp_64bit,
1878 .fma_mix_insts,
1879 .fmacf64_inst,
1880 .full_rate_64_ops,
1881 .gfx9,
1882 .gfx90a_insts,
1883 .image_insts,
1884 .ldsbankcount32,
1885 .mad_mac_f32_insts,
1886 .mai_insts,
1887 .packed_fp32_ops,
1888 .packed_tid,
1889 .pk_fmac_f16_inst,
1890 .sramecc_support,
1891 }),
1892 };
1893 pub const gfx90c = CpuModel{
1894 .name = "gfx90c",
1895 .llvm_name = "gfx90c",
1896 .features = featureSet(&[_]Feature{
1897 .ds_src2_insts,
1898 .extended_image_insts,
1899 .gfx9,
1900 .image_gather4_d16_bug,
1901 .image_insts,
1902 .ldsbankcount32,
1903 .mad_mac_f32_insts,
1904 .mad_mix_insts,
1905 }),
1906 };
1907 pub const gfx940 = CpuModel{
1908 .name = "gfx940",
1909 .llvm_name = "gfx940",
1910 .features = featureSet(&[_]Feature{
1911 .architected_flat_scratch,
1912 .atomic_buffer_global_pk_add_f16_insts,
1913 .atomic_ds_pk_add_16_insts,
1914 .atomic_fadd_no_rtn_insts,
1915 .atomic_fadd_rtn_insts,
1916 .atomic_flat_pk_add_16_insts,
1917 .atomic_global_pk_add_bf16_inst,
1918 .back_off_barrier,
1919 .dl_insts,
1920 .dot10_insts,
1921 .dot1_insts,
1922 .dot2_insts,
1923 .dot3_insts,
1924 .dot4_insts,
1925 .dot5_insts,
1926 .dot6_insts,
1927 .dot7_insts,
1928 .dpp_64bit,
1929 .flat_atomic_fadd_f32_inst,
1930 .fma_mix_insts,
1931 .fmacf64_inst,
1932 .force_store_sc0_sc1,
1933 .fp8_insts,
1934 .full_rate_64_ops,
1935 .gfx9,
1936 .gfx90a_insts,
1937 .gfx940_insts,
1938 .ldsbankcount32,
1939 .mai_insts,
1940 .packed_fp32_ops,
1941 .packed_tid,
1942 .pk_fmac_f16_inst,
1943 .sramecc_support,
1944 }),
1945 };
1946 pub const gfx941 = CpuModel{
1947 .name = "gfx941",
1948 .llvm_name = "gfx941",
1949 .features = featureSet(&[_]Feature{
1950 .architected_flat_scratch,
1951 .atomic_buffer_global_pk_add_f16_insts,
1952 .atomic_ds_pk_add_16_insts,
1953 .atomic_fadd_no_rtn_insts,
1954 .atomic_fadd_rtn_insts,
1955 .atomic_flat_pk_add_16_insts,
1956 .atomic_global_pk_add_bf16_inst,
1957 .back_off_barrier,
1958 .dl_insts,
1959 .dot10_insts,
1960 .dot1_insts,
1961 .dot2_insts,
1962 .dot3_insts,
1963 .dot4_insts,
1964 .dot5_insts,
1965 .dot6_insts,
1966 .dot7_insts,
1967 .dpp_64bit,
1968 .flat_atomic_fadd_f32_inst,
1969 .fma_mix_insts,
1970 .fmacf64_inst,
1971 .force_store_sc0_sc1,
1972 .fp8_insts,
1973 .full_rate_64_ops,
1974 .gfx9,
1975 .gfx90a_insts,
1976 .gfx940_insts,
1977 .ldsbankcount32,
1978 .mai_insts,
1979 .packed_fp32_ops,
1980 .packed_tid,
1981 .pk_fmac_f16_inst,
1982 .sramecc_support,
1983 }),
1984 };
1985 pub const gfx942 = CpuModel{
1986 .name = "gfx942",
1987 .llvm_name = "gfx942",
1988 .features = featureSet(&[_]Feature{
1989 .architected_flat_scratch,
1990 .atomic_buffer_global_pk_add_f16_insts,
1991 .atomic_ds_pk_add_16_insts,
1992 .atomic_fadd_no_rtn_insts,
1993 .atomic_fadd_rtn_insts,
1994 .atomic_flat_pk_add_16_insts,
1995 .atomic_global_pk_add_bf16_inst,
1996 .back_off_barrier,
1997 .dl_insts,
1998 .dot10_insts,
1999 .dot1_insts,
2000 .dot2_insts,
2001 .dot3_insts,
2002 .dot4_insts,
2003 .dot5_insts,
2004 .dot6_insts,
2005 .dot7_insts,
2006 .dpp_64bit,
2007 .flat_atomic_fadd_f32_inst,
2008 .fma_mix_insts,
2009 .fmacf64_inst,
2010 .fp8_insts,
2011 .full_rate_64_ops,
2012 .gfx9,
2013 .gfx90a_insts,
2014 .gfx940_insts,
2015 .ldsbankcount32,
2016 .mai_insts,
2017 .packed_fp32_ops,
2018 .packed_tid,
2019 .pk_fmac_f16_inst,
2020 .sramecc_support,
2021 }),
2022 };
2023 pub const hainan = CpuModel{
2024 .name = "hainan",
2025 .llvm_name = "hainan",
2026 .features = featureSet(&[_]Feature{
2027 .southern_islands,
2028 }),
2029 };
2030 pub const hawaii = CpuModel{
2031 .name = "hawaii",
2032 .llvm_name = "hawaii",
2033 .features = featureSet(&[_]Feature{
2034 .fast_fmaf,
2035 .half_rate_64_ops,
2036 .ldsbankcount32,
2037 .sea_islands,
2038 }),
2039 };
2040 pub const iceland = CpuModel{
2041 .name = "iceland",
2042 .llvm_name = "iceland",
2043 .features = featureSet(&[_]Feature{
2044 .ldsbankcount32,
2045 .sgpr_init_bug,
2046 .unpacked_d16_vmem,
2047 .volcanic_islands,
2048 }),
2049 };
2050 pub const kabini = CpuModel{
2051 .name = "kabini",
2052 .llvm_name = "kabini",
2053 .features = featureSet(&[_]Feature{
2054 .ldsbankcount16,
2055 .sea_islands,
2056 }),
2057 };
2058 pub const kaveri = CpuModel{
2059 .name = "kaveri",
2060 .llvm_name = "kaveri",
2061 .features = featureSet(&[_]Feature{
2062 .ldsbankcount32,
2063 .sea_islands,
2064 }),
2065 };
2066 pub const mullins = CpuModel{
2067 .name = "mullins",
2068 .llvm_name = "mullins",
2069 .features = featureSet(&[_]Feature{
2070 .ldsbankcount16,
2071 .sea_islands,
2072 }),
2073 };
2074 pub const oland = CpuModel{
2075 .name = "oland",
2076 .llvm_name = "oland",
2077 .features = featureSet(&[_]Feature{
2078 .southern_islands,
2079 }),
2080 };
2081 pub const pitcairn = CpuModel{
2082 .name = "pitcairn",
2083 .llvm_name = "pitcairn",
2084 .features = featureSet(&[_]Feature{
2085 .southern_islands,
2086 }),
2087 };
2088 pub const polaris10 = CpuModel{
2089 .name = "polaris10",
2090 .llvm_name = "polaris10",
2091 .features = featureSet(&[_]Feature{
2092 .ldsbankcount32,
2093 .unpacked_d16_vmem,
2094 .volcanic_islands,
2095 }),
2096 };
2097 pub const polaris11 = CpuModel{
2098 .name = "polaris11",
2099 .llvm_name = "polaris11",
2100 .features = featureSet(&[_]Feature{
2101 .ldsbankcount32,
2102 .unpacked_d16_vmem,
2103 .volcanic_islands,
2104 }),
2105 };
2106 pub const stoney = CpuModel{
2107 .name = "stoney",
2108 .llvm_name = "stoney",
2109 .features = featureSet(&[_]Feature{
2110 .image_gather4_d16_bug,
2111 .image_store_d16_bug,
2112 .ldsbankcount16,
2113 .volcanic_islands,
2114 .xnack_support,
2115 }),
2116 };
2117 pub const tahiti = CpuModel{
2118 .name = "tahiti",
2119 .llvm_name = "tahiti",
2120 .features = featureSet(&[_]Feature{
2121 .fast_fmaf,
2122 .half_rate_64_ops,
2123 .southern_islands,
2124 }),
2125 };
2126 pub const tonga = CpuModel{
2127 .name = "tonga",
2128 .llvm_name = "tonga",
2129 .features = featureSet(&[_]Feature{
2130 .ldsbankcount32,
2131 .sgpr_init_bug,
2132 .unpacked_d16_vmem,
2133 .volcanic_islands,
2134 }),
2135 };
2136 pub const tongapro = CpuModel{
2137 .name = "tongapro",
2138 .llvm_name = "tongapro",
2139 .features = featureSet(&[_]Feature{
2140 .ldsbankcount32,
2141 .sgpr_init_bug,
2142 .unpacked_d16_vmem,
2143 .volcanic_islands,
2144 }),
2145 };
2146 pub const verde = CpuModel{
2147 .name = "verde",
2148 .llvm_name = "verde",
2149 .features = featureSet(&[_]Feature{
2150 .southern_islands,
2151 }),
2152 };
2153};
lib/std/target/arc.zig deleted-39
......@@ -1,39 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 norm,
9};
10
11pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
12pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
13pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
14pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
15
16pub const all_features = blk: {
17 const len = @typeInfo(Feature).Enum.fields.len;
18 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
19 var result: [len]CpuFeature = undefined;
20 result[@intFromEnum(Feature.norm)] = .{
21 .llvm_name = "norm",
22 .description = "Enable support for norm instruction.",
23 .dependencies = featureSet(&[_]Feature{}),
24 };
25 const ti = @typeInfo(Feature);
26 for (&result, 0..) |*elem, i| {
27 elem.index = i;
28 elem.name = ti.Enum.fields[i].name;
29 }
30 break :blk result;
31};
32
33pub const cpu = struct {
34 pub const generic = CpuModel{
35 .name = "generic",
36 .llvm_name = "generic",
37 .features = featureSet(&[_]Feature{}),
38 };
39};
lib/std/target/arm.zig deleted-2604
......@@ -1,2604 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"32bit",
9 @"8msecext",
10 a76,
11 aapcs_frame_chain,
12 aapcs_frame_chain_leaf,
13 aclass,
14 acquire_release,
15 aes,
16 atomics_32,
17 avoid_movs_shop,
18 avoid_partial_cpsr,
19 bf16,
20 big_endian_instructions,
21 cde,
22 cdecp0,
23 cdecp1,
24 cdecp2,
25 cdecp3,
26 cdecp4,
27 cdecp5,
28 cdecp6,
29 cdecp7,
30 cheap_predicable_cpsr,
31 clrbhb,
32 crc,
33 crypto,
34 d32,
35 db,
36 dfb,
37 disable_postra_scheduler,
38 dont_widen_vmovs,
39 dotprod,
40 dsp,
41 execute_only,
42 expand_fp_mlx,
43 exynos,
44 fix_cmse_cve_2021_35465,
45 fix_cortex_a57_aes_1742098,
46 fp16,
47 fp16fml,
48 fp64,
49 fp_armv8,
50 fp_armv8d16,
51 fp_armv8d16sp,
52 fp_armv8sp,
53 fpao,
54 fpregs,
55 fpregs16,
56 fpregs64,
57 fullfp16,
58 fuse_aes,
59 fuse_literals,
60 harden_sls_blr,
61 harden_sls_nocomdat,
62 harden_sls_retbr,
63 has_v4t,
64 has_v5t,
65 has_v5te,
66 has_v6,
67 has_v6k,
68 has_v6m,
69 has_v6t2,
70 has_v7,
71 has_v7clrex,
72 has_v8,
73 has_v8_1a,
74 has_v8_1m_main,
75 has_v8_2a,
76 has_v8_3a,
77 has_v8_4a,
78 has_v8_5a,
79 has_v8_6a,
80 has_v8_7a,
81 has_v8_8a,
82 has_v8_9a,
83 has_v8m,
84 has_v8m_main,
85 has_v9_1a,
86 has_v9_2a,
87 has_v9_3a,
88 has_v9_4a,
89 has_v9a,
90 hwdiv,
91 hwdiv_arm,
92 i8mm,
93 iwmmxt,
94 iwmmxt2,
95 lob,
96 long_calls,
97 loop_align,
98 m3,
99 mclass,
100 mp,
101 muxed_units,
102 mve,
103 mve1beat,
104 mve2beat,
105 mve4beat,
106 mve_fp,
107 nacl_trap,
108 neon,
109 neon_fpmovs,
110 neonfp,
111 no_branch_predictor,
112 no_bti_at_return_twice,
113 no_movt,
114 no_neg_immediates,
115 noarm,
116 nonpipelined_vfp,
117 pacbti,
118 perfmon,
119 prefer_ishst,
120 prefer_vmovsr,
121 prof_unpr,
122 r4,
123 ras,
124 rclass,
125 read_tp_tpidrprw,
126 read_tp_tpidruro,
127 read_tp_tpidrurw,
128 reserve_r9,
129 ret_addr_stack,
130 sb,
131 sha2,
132 slow_fp_brcc,
133 slow_load_D_subreg,
134 slow_odd_reg,
135 slow_vdup32,
136 slow_vgetlni32,
137 slowfpvfmx,
138 slowfpvmlx,
139 soft_float,
140 splat_vfp_neon,
141 strict_align,
142 swift,
143 thumb2,
144 thumb_mode,
145 trustzone,
146 use_mipipeliner,
147 use_misched,
148 v2,
149 v2a,
150 v3,
151 v3m,
152 v4,
153 v4t,
154 v5t,
155 v5te,
156 v5tej,
157 v6,
158 v6j,
159 v6k,
160 v6kz,
161 v6m,
162 v6sm,
163 v6t2,
164 v7a,
165 v7em,
166 v7k,
167 v7m,
168 v7r,
169 v7s,
170 v7ve,
171 v8_1a,
172 v8_1m_main,
173 v8_2a,
174 v8_3a,
175 v8_4a,
176 v8_5a,
177 v8_6a,
178 v8_7a,
179 v8_8a,
180 v8_9a,
181 v8a,
182 v8m,
183 v8m_main,
184 v8r,
185 v9_1a,
186 v9_2a,
187 v9_3a,
188 v9_4a,
189 v9a,
190 vfp2,
191 vfp2sp,
192 vfp3,
193 vfp3d16,
194 vfp3d16sp,
195 vfp3sp,
196 vfp4,
197 vfp4d16,
198 vfp4d16sp,
199 vfp4sp,
200 virtualization,
201 vldn_align,
202 vmlx_forwarding,
203 vmlx_hazards,
204 wide_stride_vfp,
205 xscale,
206 zcz,
207};
208
209pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
210pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
211pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
212pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
213
214pub const all_features = blk: {
215 @setEvalBranchQuota(10000);
216 const len = @typeInfo(Feature).Enum.fields.len;
217 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
218 var result: [len]CpuFeature = undefined;
219 result[@intFromEnum(Feature.@"32bit")] = .{
220 .llvm_name = "32bit",
221 .description = "Prefer 32-bit Thumb instrs",
222 .dependencies = featureSet(&[_]Feature{}),
223 };
224 result[@intFromEnum(Feature.@"8msecext")] = .{
225 .llvm_name = "8msecext",
226 .description = "Enable support for ARMv8-M Security Extensions",
227 .dependencies = featureSet(&[_]Feature{}),
228 };
229 result[@intFromEnum(Feature.a76)] = .{
230 .llvm_name = "a76",
231 .description = "Cortex-A76 ARM processors",
232 .dependencies = featureSet(&[_]Feature{}),
233 };
234 result[@intFromEnum(Feature.aapcs_frame_chain)] = .{
235 .llvm_name = "aapcs-frame-chain",
236 .description = "Create an AAPCS compliant frame chain",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.aapcs_frame_chain_leaf)] = .{
240 .llvm_name = "aapcs-frame-chain-leaf",
241 .description = "Create an AAPCS compliant frame chain for leaf functions",
242 .dependencies = featureSet(&[_]Feature{
243 .aapcs_frame_chain,
244 }),
245 };
246 result[@intFromEnum(Feature.aclass)] = .{
247 .llvm_name = "aclass",
248 .description = "Is application profile ('A' series)",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.acquire_release)] = .{
252 .llvm_name = "acquire-release",
253 .description = "Has v8 acquire/release (lda/ldaex etc) instructions",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.aes)] = .{
257 .llvm_name = "aes",
258 .description = "Enable AES support",
259 .dependencies = featureSet(&[_]Feature{
260 .neon,
261 }),
262 };
263 result[@intFromEnum(Feature.atomics_32)] = .{
264 .llvm_name = "atomics-32",
265 .description = "Assume that lock-free 32-bit atomics are available",
266 .dependencies = featureSet(&[_]Feature{}),
267 };
268 result[@intFromEnum(Feature.avoid_movs_shop)] = .{
269 .llvm_name = "avoid-movs-shop",
270 .description = "Avoid movs instructions with shifter operand",
271 .dependencies = featureSet(&[_]Feature{}),
272 };
273 result[@intFromEnum(Feature.avoid_partial_cpsr)] = .{
274 .llvm_name = "avoid-partial-cpsr",
275 .description = "Avoid CPSR partial update for OOO execution",
276 .dependencies = featureSet(&[_]Feature{}),
277 };
278 result[@intFromEnum(Feature.bf16)] = .{
279 .llvm_name = "bf16",
280 .description = "Enable support for BFloat16 instructions",
281 .dependencies = featureSet(&[_]Feature{
282 .neon,
283 }),
284 };
285 result[@intFromEnum(Feature.big_endian_instructions)] = .{
286 .llvm_name = "big-endian-instructions",
287 .description = "Expect instructions to be stored big-endian.",
288 .dependencies = featureSet(&[_]Feature{}),
289 };
290 result[@intFromEnum(Feature.cde)] = .{
291 .llvm_name = "cde",
292 .description = "Support CDE instructions",
293 .dependencies = featureSet(&[_]Feature{
294 .has_v8m_main,
295 }),
296 };
297 result[@intFromEnum(Feature.cdecp0)] = .{
298 .llvm_name = "cdecp0",
299 .description = "Coprocessor 0 ISA is CDEv1",
300 .dependencies = featureSet(&[_]Feature{
301 .cde,
302 }),
303 };
304 result[@intFromEnum(Feature.cdecp1)] = .{
305 .llvm_name = "cdecp1",
306 .description = "Coprocessor 1 ISA is CDEv1",
307 .dependencies = featureSet(&[_]Feature{
308 .cde,
309 }),
310 };
311 result[@intFromEnum(Feature.cdecp2)] = .{
312 .llvm_name = "cdecp2",
313 .description = "Coprocessor 2 ISA is CDEv1",
314 .dependencies = featureSet(&[_]Feature{
315 .cde,
316 }),
317 };
318 result[@intFromEnum(Feature.cdecp3)] = .{
319 .llvm_name = "cdecp3",
320 .description = "Coprocessor 3 ISA is CDEv1",
321 .dependencies = featureSet(&[_]Feature{
322 .cde,
323 }),
324 };
325 result[@intFromEnum(Feature.cdecp4)] = .{
326 .llvm_name = "cdecp4",
327 .description = "Coprocessor 4 ISA is CDEv1",
328 .dependencies = featureSet(&[_]Feature{
329 .cde,
330 }),
331 };
332 result[@intFromEnum(Feature.cdecp5)] = .{
333 .llvm_name = "cdecp5",
334 .description = "Coprocessor 5 ISA is CDEv1",
335 .dependencies = featureSet(&[_]Feature{
336 .cde,
337 }),
338 };
339 result[@intFromEnum(Feature.cdecp6)] = .{
340 .llvm_name = "cdecp6",
341 .description = "Coprocessor 6 ISA is CDEv1",
342 .dependencies = featureSet(&[_]Feature{
343 .cde,
344 }),
345 };
346 result[@intFromEnum(Feature.cdecp7)] = .{
347 .llvm_name = "cdecp7",
348 .description = "Coprocessor 7 ISA is CDEv1",
349 .dependencies = featureSet(&[_]Feature{
350 .cde,
351 }),
352 };
353 result[@intFromEnum(Feature.cheap_predicable_cpsr)] = .{
354 .llvm_name = "cheap-predicable-cpsr",
355 .description = "Disable +1 predication cost for instructions updating CPSR",
356 .dependencies = featureSet(&[_]Feature{}),
357 };
358 result[@intFromEnum(Feature.clrbhb)] = .{
359 .llvm_name = "clrbhb",
360 .description = "Enable Clear BHB instruction",
361 .dependencies = featureSet(&[_]Feature{}),
362 };
363 result[@intFromEnum(Feature.crc)] = .{
364 .llvm_name = "crc",
365 .description = "Enable support for CRC instructions",
366 .dependencies = featureSet(&[_]Feature{}),
367 };
368 result[@intFromEnum(Feature.crypto)] = .{
369 .llvm_name = "crypto",
370 .description = "Enable support for Cryptography extensions",
371 .dependencies = featureSet(&[_]Feature{
372 .aes,
373 .sha2,
374 }),
375 };
376 result[@intFromEnum(Feature.d32)] = .{
377 .llvm_name = "d32",
378 .description = "Extend FP to 32 double registers",
379 .dependencies = featureSet(&[_]Feature{}),
380 };
381 result[@intFromEnum(Feature.db)] = .{
382 .llvm_name = "db",
383 .description = "Has data barrier (dmb/dsb) instructions",
384 .dependencies = featureSet(&[_]Feature{}),
385 };
386 result[@intFromEnum(Feature.dfb)] = .{
387 .llvm_name = "dfb",
388 .description = "Has full data barrier (dfb) instruction",
389 .dependencies = featureSet(&[_]Feature{}),
390 };
391 result[@intFromEnum(Feature.disable_postra_scheduler)] = .{
392 .llvm_name = "disable-postra-scheduler",
393 .description = "Don't schedule again after register allocation",
394 .dependencies = featureSet(&[_]Feature{}),
395 };
396 result[@intFromEnum(Feature.dont_widen_vmovs)] = .{
397 .llvm_name = "dont-widen-vmovs",
398 .description = "Don't widen VMOVS to VMOVD",
399 .dependencies = featureSet(&[_]Feature{}),
400 };
401 result[@intFromEnum(Feature.dotprod)] = .{
402 .llvm_name = "dotprod",
403 .description = "Enable support for dot product instructions",
404 .dependencies = featureSet(&[_]Feature{
405 .neon,
406 }),
407 };
408 result[@intFromEnum(Feature.dsp)] = .{
409 .llvm_name = "dsp",
410 .description = "Supports DSP instructions in ARM and/or Thumb2",
411 .dependencies = featureSet(&[_]Feature{}),
412 };
413 result[@intFromEnum(Feature.execute_only)] = .{
414 .llvm_name = "execute-only",
415 .description = "Enable the generation of execute only code.",
416 .dependencies = featureSet(&[_]Feature{}),
417 };
418 result[@intFromEnum(Feature.expand_fp_mlx)] = .{
419 .llvm_name = "expand-fp-mlx",
420 .description = "Expand VFP/NEON MLA/MLS instructions",
421 .dependencies = featureSet(&[_]Feature{}),
422 };
423 result[@intFromEnum(Feature.exynos)] = .{
424 .llvm_name = "exynos",
425 .description = "Samsung Exynos processors",
426 .dependencies = featureSet(&[_]Feature{
427 .crc,
428 .crypto,
429 .expand_fp_mlx,
430 .fuse_aes,
431 .fuse_literals,
432 .hwdiv,
433 .hwdiv_arm,
434 .prof_unpr,
435 .ret_addr_stack,
436 .slow_fp_brcc,
437 .slow_vdup32,
438 .slow_vgetlni32,
439 .slowfpvfmx,
440 .slowfpvmlx,
441 .splat_vfp_neon,
442 .wide_stride_vfp,
443 .zcz,
444 }),
445 };
446 result[@intFromEnum(Feature.fix_cmse_cve_2021_35465)] = .{
447 .llvm_name = "fix-cmse-cve-2021-35465",
448 .description = "Mitigate against the cve-2021-35465 security vulnurability",
449 .dependencies = featureSet(&[_]Feature{}),
450 };
451 result[@intFromEnum(Feature.fix_cortex_a57_aes_1742098)] = .{
452 .llvm_name = "fix-cortex-a57-aes-1742098",
453 .description = "Work around Cortex-A57 Erratum 1742098 / Cortex-A72 Erratum 1655431 (AES)",
454 .dependencies = featureSet(&[_]Feature{}),
455 };
456 result[@intFromEnum(Feature.fp16)] = .{
457 .llvm_name = "fp16",
458 .description = "Enable half-precision floating point",
459 .dependencies = featureSet(&[_]Feature{}),
460 };
461 result[@intFromEnum(Feature.fp16fml)] = .{
462 .llvm_name = "fp16fml",
463 .description = "Enable full half-precision floating point fml instructions",
464 .dependencies = featureSet(&[_]Feature{
465 .fullfp16,
466 }),
467 };
468 result[@intFromEnum(Feature.fp64)] = .{
469 .llvm_name = "fp64",
470 .description = "Floating point unit supports double precision",
471 .dependencies = featureSet(&[_]Feature{
472 .fpregs64,
473 }),
474 };
475 result[@intFromEnum(Feature.fp_armv8)] = .{
476 .llvm_name = "fp-armv8",
477 .description = "Enable ARMv8 FP",
478 .dependencies = featureSet(&[_]Feature{
479 .fp_armv8d16,
480 .fp_armv8sp,
481 .vfp4,
482 }),
483 };
484 result[@intFromEnum(Feature.fp_armv8d16)] = .{
485 .llvm_name = "fp-armv8d16",
486 .description = "Enable ARMv8 FP with only 16 d-registers",
487 .dependencies = featureSet(&[_]Feature{
488 .fp_armv8d16sp,
489 .vfp4d16,
490 }),
491 };
492 result[@intFromEnum(Feature.fp_armv8d16sp)] = .{
493 .llvm_name = "fp-armv8d16sp",
494 .description = "Enable ARMv8 FP with only 16 d-registers and no double precision",
495 .dependencies = featureSet(&[_]Feature{
496 .vfp4d16sp,
497 }),
498 };
499 result[@intFromEnum(Feature.fp_armv8sp)] = .{
500 .llvm_name = "fp-armv8sp",
501 .description = "Enable ARMv8 FP with no double precision",
502 .dependencies = featureSet(&[_]Feature{
503 .fp_armv8d16sp,
504 .vfp4sp,
505 }),
506 };
507 result[@intFromEnum(Feature.fpao)] = .{
508 .llvm_name = "fpao",
509 .description = "Enable fast computation of positive address offsets",
510 .dependencies = featureSet(&[_]Feature{}),
511 };
512 result[@intFromEnum(Feature.fpregs)] = .{
513 .llvm_name = "fpregs",
514 .description = "Enable FP registers",
515 .dependencies = featureSet(&[_]Feature{}),
516 };
517 result[@intFromEnum(Feature.fpregs16)] = .{
518 .llvm_name = "fpregs16",
519 .description = "Enable 16-bit FP registers",
520 .dependencies = featureSet(&[_]Feature{
521 .fpregs,
522 }),
523 };
524 result[@intFromEnum(Feature.fpregs64)] = .{
525 .llvm_name = "fpregs64",
526 .description = "Enable 64-bit FP registers",
527 .dependencies = featureSet(&[_]Feature{
528 .fpregs,
529 }),
530 };
531 result[@intFromEnum(Feature.fullfp16)] = .{
532 .llvm_name = "fullfp16",
533 .description = "Enable full half-precision floating point",
534 .dependencies = featureSet(&[_]Feature{
535 .fp_armv8d16sp,
536 .fpregs16,
537 }),
538 };
539 result[@intFromEnum(Feature.fuse_aes)] = .{
540 .llvm_name = "fuse-aes",
541 .description = "CPU fuses AES crypto operations",
542 .dependencies = featureSet(&[_]Feature{}),
543 };
544 result[@intFromEnum(Feature.fuse_literals)] = .{
545 .llvm_name = "fuse-literals",
546 .description = "CPU fuses literal generation operations",
547 .dependencies = featureSet(&[_]Feature{}),
548 };
549 result[@intFromEnum(Feature.harden_sls_blr)] = .{
550 .llvm_name = "harden-sls-blr",
551 .description = "Harden against straight line speculation across indirect calls",
552 .dependencies = featureSet(&[_]Feature{}),
553 };
554 result[@intFromEnum(Feature.harden_sls_nocomdat)] = .{
555 .llvm_name = "harden-sls-nocomdat",
556 .description = "Generate thunk code for SLS mitigation in the normal text section",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
559 result[@intFromEnum(Feature.harden_sls_retbr)] = .{
560 .llvm_name = "harden-sls-retbr",
561 .description = "Harden against straight line speculation across RETurn and BranchRegister instructions",
562 .dependencies = featureSet(&[_]Feature{}),
563 };
564 result[@intFromEnum(Feature.has_v4t)] = .{
565 .llvm_name = "v4t",
566 .description = "Support ARM v4T instructions",
567 .dependencies = featureSet(&[_]Feature{}),
568 };
569 result[@intFromEnum(Feature.has_v5t)] = .{
570 .llvm_name = "v5t",
571 .description = "Support ARM v5T instructions",
572 .dependencies = featureSet(&[_]Feature{
573 .has_v4t,
574 }),
575 };
576 result[@intFromEnum(Feature.has_v5te)] = .{
577 .llvm_name = "v5te",
578 .description = "Support ARM v5TE, v5TEj, and v5TExp instructions",
579 .dependencies = featureSet(&[_]Feature{
580 .has_v5t,
581 }),
582 };
583 result[@intFromEnum(Feature.has_v6)] = .{
584 .llvm_name = "v6",
585 .description = "Support ARM v6 instructions",
586 .dependencies = featureSet(&[_]Feature{
587 .has_v5te,
588 }),
589 };
590 result[@intFromEnum(Feature.has_v6k)] = .{
591 .llvm_name = "v6k",
592 .description = "Support ARM v6k instructions",
593 .dependencies = featureSet(&[_]Feature{
594 .has_v6,
595 }),
596 };
597 result[@intFromEnum(Feature.has_v6m)] = .{
598 .llvm_name = "v6m",
599 .description = "Support ARM v6M instructions",
600 .dependencies = featureSet(&[_]Feature{
601 .has_v6,
602 }),
603 };
604 result[@intFromEnum(Feature.has_v6t2)] = .{
605 .llvm_name = "v6t2",
606 .description = "Support ARM v6t2 instructions",
607 .dependencies = featureSet(&[_]Feature{
608 .has_v6k,
609 .has_v8m,
610 .thumb2,
611 }),
612 };
613 result[@intFromEnum(Feature.has_v7)] = .{
614 .llvm_name = "v7",
615 .description = "Support ARM v7 instructions",
616 .dependencies = featureSet(&[_]Feature{
617 .has_v6t2,
618 .has_v7clrex,
619 }),
620 };
621 result[@intFromEnum(Feature.has_v7clrex)] = .{
622 .llvm_name = "v7clrex",
623 .description = "Has v7 clrex instruction",
624 .dependencies = featureSet(&[_]Feature{}),
625 };
626 result[@intFromEnum(Feature.has_v8)] = .{
627 .llvm_name = "v8",
628 .description = "Support ARM v8 instructions",
629 .dependencies = featureSet(&[_]Feature{
630 .acquire_release,
631 .has_v7,
632 .perfmon,
633 }),
634 };
635 result[@intFromEnum(Feature.has_v8_1a)] = .{
636 .llvm_name = "v8.1a",
637 .description = "Support ARM v8.1a instructions",
638 .dependencies = featureSet(&[_]Feature{
639 .has_v8,
640 }),
641 };
642 result[@intFromEnum(Feature.has_v8_1m_main)] = .{
643 .llvm_name = "v8.1m.main",
644 .description = "Support ARM v8-1M Mainline instructions",
645 .dependencies = featureSet(&[_]Feature{
646 .has_v8m_main,
647 }),
648 };
649 result[@intFromEnum(Feature.has_v8_2a)] = .{
650 .llvm_name = "v8.2a",
651 .description = "Support ARM v8.2a instructions",
652 .dependencies = featureSet(&[_]Feature{
653 .has_v8_1a,
654 }),
655 };
656 result[@intFromEnum(Feature.has_v8_3a)] = .{
657 .llvm_name = "v8.3a",
658 .description = "Support ARM v8.3a instructions",
659 .dependencies = featureSet(&[_]Feature{
660 .has_v8_2a,
661 }),
662 };
663 result[@intFromEnum(Feature.has_v8_4a)] = .{
664 .llvm_name = "v8.4a",
665 .description = "Support ARM v8.4a instructions",
666 .dependencies = featureSet(&[_]Feature{
667 .dotprod,
668 .has_v8_3a,
669 }),
670 };
671 result[@intFromEnum(Feature.has_v8_5a)] = .{
672 .llvm_name = "v8.5a",
673 .description = "Support ARM v8.5a instructions",
674 .dependencies = featureSet(&[_]Feature{
675 .has_v8_4a,
676 .sb,
677 }),
678 };
679 result[@intFromEnum(Feature.has_v8_6a)] = .{
680 .llvm_name = "v8.6a",
681 .description = "Support ARM v8.6a instructions",
682 .dependencies = featureSet(&[_]Feature{
683 .bf16,
684 .has_v8_5a,
685 .i8mm,
686 }),
687 };
688 result[@intFromEnum(Feature.has_v8_7a)] = .{
689 .llvm_name = "v8.7a",
690 .description = "Support ARM v8.7a instructions",
691 .dependencies = featureSet(&[_]Feature{
692 .has_v8_6a,
693 }),
694 };
695 result[@intFromEnum(Feature.has_v8_8a)] = .{
696 .llvm_name = "v8.8a",
697 .description = "Support ARM v8.8a instructions",
698 .dependencies = featureSet(&[_]Feature{
699 .has_v8_7a,
700 }),
701 };
702 result[@intFromEnum(Feature.has_v8_9a)] = .{
703 .llvm_name = "v8.9a",
704 .description = "Support ARM v8.9a instructions",
705 .dependencies = featureSet(&[_]Feature{
706 .clrbhb,
707 .has_v8_8a,
708 }),
709 };
710 result[@intFromEnum(Feature.has_v8m)] = .{
711 .llvm_name = "v8m",
712 .description = "Support ARM v8M Baseline instructions",
713 .dependencies = featureSet(&[_]Feature{
714 .has_v6m,
715 }),
716 };
717 result[@intFromEnum(Feature.has_v8m_main)] = .{
718 .llvm_name = "v8m.main",
719 .description = "Support ARM v8M Mainline instructions",
720 .dependencies = featureSet(&[_]Feature{
721 .has_v7,
722 }),
723 };
724 result[@intFromEnum(Feature.has_v9_1a)] = .{
725 .llvm_name = "v9.1a",
726 .description = "Support ARM v9.1a instructions",
727 .dependencies = featureSet(&[_]Feature{
728 .has_v8_6a,
729 .has_v9a,
730 }),
731 };
732 result[@intFromEnum(Feature.has_v9_2a)] = .{
733 .llvm_name = "v9.2a",
734 .description = "Support ARM v9.2a instructions",
735 .dependencies = featureSet(&[_]Feature{
736 .has_v8_7a,
737 .has_v9_1a,
738 }),
739 };
740 result[@intFromEnum(Feature.has_v9_3a)] = .{
741 .llvm_name = "v9.3a",
742 .description = "Support ARM v9.3a instructions",
743 .dependencies = featureSet(&[_]Feature{
744 .has_v8_8a,
745 .has_v9_2a,
746 }),
747 };
748 result[@intFromEnum(Feature.has_v9_4a)] = .{
749 .llvm_name = "v9.4a",
750 .description = "Support ARM v9.4a instructions",
751 .dependencies = featureSet(&[_]Feature{
752 .has_v8_9a,
753 .has_v9_3a,
754 }),
755 };
756 result[@intFromEnum(Feature.has_v9a)] = .{
757 .llvm_name = "v9a",
758 .description = "Support ARM v9a instructions",
759 .dependencies = featureSet(&[_]Feature{
760 .has_v8_5a,
761 }),
762 };
763 result[@intFromEnum(Feature.hwdiv)] = .{
764 .llvm_name = "hwdiv",
765 .description = "Enable divide instructions in Thumb",
766 .dependencies = featureSet(&[_]Feature{}),
767 };
768 result[@intFromEnum(Feature.hwdiv_arm)] = .{
769 .llvm_name = "hwdiv-arm",
770 .description = "Enable divide instructions in ARM mode",
771 .dependencies = featureSet(&[_]Feature{}),
772 };
773 result[@intFromEnum(Feature.i8mm)] = .{
774 .llvm_name = "i8mm",
775 .description = "Enable Matrix Multiply Int8 Extension",
776 .dependencies = featureSet(&[_]Feature{
777 .neon,
778 }),
779 };
780 result[@intFromEnum(Feature.iwmmxt)] = .{
781 .llvm_name = "iwmmxt",
782 .description = "ARMv5te architecture",
783 .dependencies = featureSet(&[_]Feature{
784 .v5te,
785 }),
786 };
787 result[@intFromEnum(Feature.iwmmxt2)] = .{
788 .llvm_name = "iwmmxt2",
789 .description = "ARMv5te architecture",
790 .dependencies = featureSet(&[_]Feature{
791 .v5te,
792 }),
793 };
794 result[@intFromEnum(Feature.lob)] = .{
795 .llvm_name = "lob",
796 .description = "Enable Low Overhead Branch extensions",
797 .dependencies = featureSet(&[_]Feature{}),
798 };
799 result[@intFromEnum(Feature.long_calls)] = .{
800 .llvm_name = "long-calls",
801 .description = "Generate calls via indirect call instructions",
802 .dependencies = featureSet(&[_]Feature{}),
803 };
804 result[@intFromEnum(Feature.loop_align)] = .{
805 .llvm_name = "loop-align",
806 .description = "Prefer 32-bit alignment for loops",
807 .dependencies = featureSet(&[_]Feature{}),
808 };
809 result[@intFromEnum(Feature.m3)] = .{
810 .llvm_name = "m3",
811 .description = "Cortex-M3 ARM processors",
812 .dependencies = featureSet(&[_]Feature{}),
813 };
814 result[@intFromEnum(Feature.mclass)] = .{
815 .llvm_name = "mclass",
816 .description = "Is microcontroller profile ('M' series)",
817 .dependencies = featureSet(&[_]Feature{}),
818 };
819 result[@intFromEnum(Feature.mp)] = .{
820 .llvm_name = "mp",
821 .description = "Supports Multiprocessing extension",
822 .dependencies = featureSet(&[_]Feature{}),
823 };
824 result[@intFromEnum(Feature.muxed_units)] = .{
825 .llvm_name = "muxed-units",
826 .description = "Has muxed AGU and NEON/FPU",
827 .dependencies = featureSet(&[_]Feature{}),
828 };
829 result[@intFromEnum(Feature.mve)] = .{
830 .llvm_name = "mve",
831 .description = "Support M-Class Vector Extension with integer ops",
832 .dependencies = featureSet(&[_]Feature{
833 .dsp,
834 .fpregs16,
835 .fpregs64,
836 .has_v8_1m_main,
837 }),
838 };
839 result[@intFromEnum(Feature.mve1beat)] = .{
840 .llvm_name = "mve1beat",
841 .description = "Model MVE instructions as a 1 beat per tick architecture",
842 .dependencies = featureSet(&[_]Feature{}),
843 };
844 result[@intFromEnum(Feature.mve2beat)] = .{
845 .llvm_name = "mve2beat",
846 .description = "Model MVE instructions as a 2 beats per tick architecture",
847 .dependencies = featureSet(&[_]Feature{}),
848 };
849 result[@intFromEnum(Feature.mve4beat)] = .{
850 .llvm_name = "mve4beat",
851 .description = "Model MVE instructions as a 4 beats per tick architecture",
852 .dependencies = featureSet(&[_]Feature{}),
853 };
854 result[@intFromEnum(Feature.mve_fp)] = .{
855 .llvm_name = "mve.fp",
856 .description = "Support M-Class Vector Extension with integer and floating ops",
857 .dependencies = featureSet(&[_]Feature{
858 .fullfp16,
859 .mve,
860 }),
861 };
862 result[@intFromEnum(Feature.nacl_trap)] = .{
863 .llvm_name = "nacl-trap",
864 .description = "NaCl trap",
865 .dependencies = featureSet(&[_]Feature{}),
866 };
867 result[@intFromEnum(Feature.neon)] = .{
868 .llvm_name = "neon",
869 .description = "Enable NEON instructions",
870 .dependencies = featureSet(&[_]Feature{
871 .vfp3,
872 }),
873 };
874 result[@intFromEnum(Feature.neon_fpmovs)] = .{
875 .llvm_name = "neon-fpmovs",
876 .description = "Convert VMOVSR, VMOVRS, VMOVS to NEON",
877 .dependencies = featureSet(&[_]Feature{}),
878 };
879 result[@intFromEnum(Feature.neonfp)] = .{
880 .llvm_name = "neonfp",
881 .description = "Use NEON for single precision FP",
882 .dependencies = featureSet(&[_]Feature{}),
883 };
884 result[@intFromEnum(Feature.no_branch_predictor)] = .{
885 .llvm_name = "no-branch-predictor",
886 .description = "Has no branch predictor",
887 .dependencies = featureSet(&[_]Feature{}),
888 };
889 result[@intFromEnum(Feature.no_bti_at_return_twice)] = .{
890 .llvm_name = "no-bti-at-return-twice",
891 .description = "Don't place a BTI instruction after a return-twice",
892 .dependencies = featureSet(&[_]Feature{}),
893 };
894 result[@intFromEnum(Feature.no_movt)] = .{
895 .llvm_name = "no-movt",
896 .description = "Don't use movt/movw pairs for 32-bit imms",
897 .dependencies = featureSet(&[_]Feature{}),
898 };
899 result[@intFromEnum(Feature.no_neg_immediates)] = .{
900 .llvm_name = "no-neg-immediates",
901 .description = "Convert immediates and instructions to their negated or complemented equivalent when the immediate does not fit in the encoding.",
902 .dependencies = featureSet(&[_]Feature{}),
903 };
904 result[@intFromEnum(Feature.noarm)] = .{
905 .llvm_name = "noarm",
906 .description = "Does not support ARM mode execution",
907 .dependencies = featureSet(&[_]Feature{}),
908 };
909 result[@intFromEnum(Feature.nonpipelined_vfp)] = .{
910 .llvm_name = "nonpipelined-vfp",
911 .description = "VFP instructions are not pipelined",
912 .dependencies = featureSet(&[_]Feature{}),
913 };
914 result[@intFromEnum(Feature.pacbti)] = .{
915 .llvm_name = "pacbti",
916 .description = "Enable Pointer Authentication and Branch Target Identification",
917 .dependencies = featureSet(&[_]Feature{}),
918 };
919 result[@intFromEnum(Feature.perfmon)] = .{
920 .llvm_name = "perfmon",
921 .description = "Enable support for Performance Monitor extensions",
922 .dependencies = featureSet(&[_]Feature{}),
923 };
924 result[@intFromEnum(Feature.prefer_ishst)] = .{
925 .llvm_name = "prefer-ishst",
926 .description = "Prefer ISHST barriers",
927 .dependencies = featureSet(&[_]Feature{}),
928 };
929 result[@intFromEnum(Feature.prefer_vmovsr)] = .{
930 .llvm_name = "prefer-vmovsr",
931 .description = "Prefer VMOVSR",
932 .dependencies = featureSet(&[_]Feature{}),
933 };
934 result[@intFromEnum(Feature.prof_unpr)] = .{
935 .llvm_name = "prof-unpr",
936 .description = "Is profitable to unpredicate",
937 .dependencies = featureSet(&[_]Feature{}),
938 };
939 result[@intFromEnum(Feature.r4)] = .{
940 .llvm_name = "r4",
941 .description = "Cortex-R4 ARM processors",
942 .dependencies = featureSet(&[_]Feature{}),
943 };
944 result[@intFromEnum(Feature.ras)] = .{
945 .llvm_name = "ras",
946 .description = "Enable Reliability, Availability and Serviceability extensions",
947 .dependencies = featureSet(&[_]Feature{}),
948 };
949 result[@intFromEnum(Feature.rclass)] = .{
950 .llvm_name = "rclass",
951 .description = "Is realtime profile ('R' series)",
952 .dependencies = featureSet(&[_]Feature{}),
953 };
954 result[@intFromEnum(Feature.read_tp_tpidrprw)] = .{
955 .llvm_name = "read-tp-tpidrprw",
956 .description = "Reading thread pointer from TPIDRPRW register",
957 .dependencies = featureSet(&[_]Feature{}),
958 };
959 result[@intFromEnum(Feature.read_tp_tpidruro)] = .{
960 .llvm_name = "read-tp-tpidruro",
961 .description = "Reading thread pointer from TPIDRURO register",
962 .dependencies = featureSet(&[_]Feature{}),
963 };
964 result[@intFromEnum(Feature.read_tp_tpidrurw)] = .{
965 .llvm_name = "read-tp-tpidrurw",
966 .description = "Reading thread pointer from TPIDRURW register",
967 .dependencies = featureSet(&[_]Feature{}),
968 };
969 result[@intFromEnum(Feature.reserve_r9)] = .{
970 .llvm_name = "reserve-r9",
971 .description = "Reserve R9, making it unavailable as GPR",
972 .dependencies = featureSet(&[_]Feature{}),
973 };
974 result[@intFromEnum(Feature.ret_addr_stack)] = .{
975 .llvm_name = "ret-addr-stack",
976 .description = "Has return address stack",
977 .dependencies = featureSet(&[_]Feature{}),
978 };
979 result[@intFromEnum(Feature.sb)] = .{
980 .llvm_name = "sb",
981 .description = "Enable v8.5a Speculation Barrier",
982 .dependencies = featureSet(&[_]Feature{}),
983 };
984 result[@intFromEnum(Feature.sha2)] = .{
985 .llvm_name = "sha2",
986 .description = "Enable SHA1 and SHA256 support",
987 .dependencies = featureSet(&[_]Feature{
988 .neon,
989 }),
990 };
991 result[@intFromEnum(Feature.slow_fp_brcc)] = .{
992 .llvm_name = "slow-fp-brcc",
993 .description = "FP compare + branch is slow",
994 .dependencies = featureSet(&[_]Feature{}),
995 };
996 result[@intFromEnum(Feature.slow_load_D_subreg)] = .{
997 .llvm_name = "slow-load-D-subreg",
998 .description = "Loading into D subregs is slow",
999 .dependencies = featureSet(&[_]Feature{}),
1000 };
1001 result[@intFromEnum(Feature.slow_odd_reg)] = .{
1002 .llvm_name = "slow-odd-reg",
1003 .description = "VLDM/VSTM starting with an odd register is slow",
1004 .dependencies = featureSet(&[_]Feature{}),
1005 };
1006 result[@intFromEnum(Feature.slow_vdup32)] = .{
1007 .llvm_name = "slow-vdup32",
1008 .description = "Has slow VDUP32 - prefer VMOV",
1009 .dependencies = featureSet(&[_]Feature{}),
1010 };
1011 result[@intFromEnum(Feature.slow_vgetlni32)] = .{
1012 .llvm_name = "slow-vgetlni32",
1013 .description = "Has slow VGETLNi32 - prefer VMOV",
1014 .dependencies = featureSet(&[_]Feature{}),
1015 };
1016 result[@intFromEnum(Feature.slowfpvfmx)] = .{
1017 .llvm_name = "slowfpvfmx",
1018 .description = "Disable VFP / NEON FMA instructions",
1019 .dependencies = featureSet(&[_]Feature{}),
1020 };
1021 result[@intFromEnum(Feature.slowfpvmlx)] = .{
1022 .llvm_name = "slowfpvmlx",
1023 .description = "Disable VFP / NEON MAC instructions",
1024 .dependencies = featureSet(&[_]Feature{}),
1025 };
1026 result[@intFromEnum(Feature.soft_float)] = .{
1027 .llvm_name = "soft-float",
1028 .description = "Use software floating point features.",
1029 .dependencies = featureSet(&[_]Feature{}),
1030 };
1031 result[@intFromEnum(Feature.splat_vfp_neon)] = .{
1032 .llvm_name = "splat-vfp-neon",
1033 .description = "Splat register from VFP to NEON",
1034 .dependencies = featureSet(&[_]Feature{
1035 .dont_widen_vmovs,
1036 }),
1037 };
1038 result[@intFromEnum(Feature.strict_align)] = .{
1039 .llvm_name = "strict-align",
1040 .description = "Disallow all unaligned memory access",
1041 .dependencies = featureSet(&[_]Feature{}),
1042 };
1043 result[@intFromEnum(Feature.swift)] = .{
1044 .llvm_name = "swift",
1045 .description = "Swift ARM processors",
1046 .dependencies = featureSet(&[_]Feature{}),
1047 };
1048 result[@intFromEnum(Feature.thumb2)] = .{
1049 .llvm_name = "thumb2",
1050 .description = "Enable Thumb2 instructions",
1051 .dependencies = featureSet(&[_]Feature{}),
1052 };
1053 result[@intFromEnum(Feature.thumb_mode)] = .{
1054 .llvm_name = "thumb-mode",
1055 .description = "Thumb mode",
1056 .dependencies = featureSet(&[_]Feature{}),
1057 };
1058 result[@intFromEnum(Feature.trustzone)] = .{
1059 .llvm_name = "trustzone",
1060 .description = "Enable support for TrustZone security extensions",
1061 .dependencies = featureSet(&[_]Feature{}),
1062 };
1063 result[@intFromEnum(Feature.use_mipipeliner)] = .{
1064 .llvm_name = "use-mipipeliner",
1065 .description = "Use the MachinePipeliner",
1066 .dependencies = featureSet(&[_]Feature{}),
1067 };
1068 result[@intFromEnum(Feature.use_misched)] = .{
1069 .llvm_name = "use-misched",
1070 .description = "Use the MachineScheduler",
1071 .dependencies = featureSet(&[_]Feature{}),
1072 };
1073 result[@intFromEnum(Feature.v2)] = .{
1074 .llvm_name = null,
1075 .description = "ARMv2 architecture",
1076 .dependencies = featureSet(&[_]Feature{
1077 .strict_align,
1078 }),
1079 };
1080 result[@intFromEnum(Feature.v2a)] = .{
1081 .llvm_name = null,
1082 .description = "ARMv2a architecture",
1083 .dependencies = featureSet(&[_]Feature{
1084 .strict_align,
1085 }),
1086 };
1087 result[@intFromEnum(Feature.v3)] = .{
1088 .llvm_name = null,
1089 .description = "ARMv3 architecture",
1090 .dependencies = featureSet(&[_]Feature{
1091 .strict_align,
1092 }),
1093 };
1094 result[@intFromEnum(Feature.v3m)] = .{
1095 .llvm_name = null,
1096 .description = "ARMv3m architecture",
1097 .dependencies = featureSet(&[_]Feature{
1098 .strict_align,
1099 }),
1100 };
1101 result[@intFromEnum(Feature.v4)] = .{
1102 .llvm_name = "armv4",
1103 .description = "ARMv4 architecture",
1104 .dependencies = featureSet(&[_]Feature{
1105 .strict_align,
1106 }),
1107 };
1108 result[@intFromEnum(Feature.v4t)] = .{
1109 .llvm_name = "armv4t",
1110 .description = "ARMv4t architecture",
1111 .dependencies = featureSet(&[_]Feature{
1112 .has_v4t,
1113 .strict_align,
1114 }),
1115 };
1116 result[@intFromEnum(Feature.v5t)] = .{
1117 .llvm_name = "armv5t",
1118 .description = "ARMv5t architecture",
1119 .dependencies = featureSet(&[_]Feature{
1120 .has_v5t,
1121 .strict_align,
1122 }),
1123 };
1124 result[@intFromEnum(Feature.v5te)] = .{
1125 .llvm_name = "armv5te",
1126 .description = "ARMv5te architecture",
1127 .dependencies = featureSet(&[_]Feature{
1128 .has_v5te,
1129 .strict_align,
1130 }),
1131 };
1132 result[@intFromEnum(Feature.v5tej)] = .{
1133 .llvm_name = "armv5tej",
1134 .description = "ARMv5tej architecture",
1135 .dependencies = featureSet(&[_]Feature{
1136 .has_v5te,
1137 .strict_align,
1138 }),
1139 };
1140 result[@intFromEnum(Feature.v6)] = .{
1141 .llvm_name = "armv6",
1142 .description = "ARMv6 architecture",
1143 .dependencies = featureSet(&[_]Feature{
1144 .dsp,
1145 .has_v6,
1146 }),
1147 };
1148 result[@intFromEnum(Feature.v6j)] = .{
1149 .llvm_name = "armv6j",
1150 .description = "ARMv7a architecture",
1151 .dependencies = featureSet(&[_]Feature{
1152 .v6,
1153 }),
1154 };
1155 result[@intFromEnum(Feature.v6k)] = .{
1156 .llvm_name = "armv6k",
1157 .description = "ARMv6k architecture",
1158 .dependencies = featureSet(&[_]Feature{
1159 .has_v6k,
1160 }),
1161 };
1162 result[@intFromEnum(Feature.v6kz)] = .{
1163 .llvm_name = "armv6kz",
1164 .description = "ARMv6kz architecture",
1165 .dependencies = featureSet(&[_]Feature{
1166 .has_v6k,
1167 .trustzone,
1168 }),
1169 };
1170 result[@intFromEnum(Feature.v6m)] = .{
1171 .llvm_name = "armv6-m",
1172 .description = "ARMv6m architecture",
1173 .dependencies = featureSet(&[_]Feature{
1174 .db,
1175 .has_v6m,
1176 .mclass,
1177 .noarm,
1178 .strict_align,
1179 .thumb_mode,
1180 }),
1181 };
1182 result[@intFromEnum(Feature.v6sm)] = .{
1183 .llvm_name = "armv6s-m",
1184 .description = "ARMv6sm architecture",
1185 .dependencies = featureSet(&[_]Feature{
1186 .db,
1187 .has_v6m,
1188 .mclass,
1189 .noarm,
1190 .strict_align,
1191 .thumb_mode,
1192 }),
1193 };
1194 result[@intFromEnum(Feature.v6t2)] = .{
1195 .llvm_name = "armv6t2",
1196 .description = "ARMv6t2 architecture",
1197 .dependencies = featureSet(&[_]Feature{
1198 .dsp,
1199 .has_v6t2,
1200 }),
1201 };
1202 result[@intFromEnum(Feature.v7a)] = .{
1203 .llvm_name = "armv7-a",
1204 .description = "ARMv7a architecture",
1205 .dependencies = featureSet(&[_]Feature{
1206 .aclass,
1207 .db,
1208 .dsp,
1209 .has_v7,
1210 .neon,
1211 .perfmon,
1212 }),
1213 };
1214 result[@intFromEnum(Feature.v7em)] = .{
1215 .llvm_name = "armv7e-m",
1216 .description = "ARMv7em architecture",
1217 .dependencies = featureSet(&[_]Feature{
1218 .db,
1219 .dsp,
1220 .has_v7,
1221 .hwdiv,
1222 .mclass,
1223 .noarm,
1224 .thumb_mode,
1225 }),
1226 };
1227 result[@intFromEnum(Feature.v7k)] = .{
1228 .llvm_name = "armv7k",
1229 .description = "ARMv7a architecture",
1230 .dependencies = featureSet(&[_]Feature{
1231 .v7a,
1232 }),
1233 };
1234 result[@intFromEnum(Feature.v7m)] = .{
1235 .llvm_name = "armv7-m",
1236 .description = "ARMv7m architecture",
1237 .dependencies = featureSet(&[_]Feature{
1238 .db,
1239 .has_v7,
1240 .hwdiv,
1241 .mclass,
1242 .noarm,
1243 .thumb_mode,
1244 }),
1245 };
1246 result[@intFromEnum(Feature.v7r)] = .{
1247 .llvm_name = "armv7-r",
1248 .description = "ARMv7r architecture",
1249 .dependencies = featureSet(&[_]Feature{
1250 .db,
1251 .dsp,
1252 .has_v7,
1253 .hwdiv,
1254 .perfmon,
1255 .rclass,
1256 }),
1257 };
1258 result[@intFromEnum(Feature.v7s)] = .{
1259 .llvm_name = "armv7s",
1260 .description = "ARMv7a architecture",
1261 .dependencies = featureSet(&[_]Feature{
1262 .v7a,
1263 }),
1264 };
1265 result[@intFromEnum(Feature.v7ve)] = .{
1266 .llvm_name = "armv7ve",
1267 .description = "ARMv7ve architecture",
1268 .dependencies = featureSet(&[_]Feature{
1269 .aclass,
1270 .db,
1271 .dsp,
1272 .has_v7,
1273 .mp,
1274 .neon,
1275 .perfmon,
1276 .trustzone,
1277 .virtualization,
1278 }),
1279 };
1280 result[@intFromEnum(Feature.v8_1a)] = .{
1281 .llvm_name = "armv8.1-a",
1282 .description = "ARMv81a architecture",
1283 .dependencies = featureSet(&[_]Feature{
1284 .aclass,
1285 .crc,
1286 .crypto,
1287 .db,
1288 .dsp,
1289 .fp_armv8,
1290 .has_v8_1a,
1291 .mp,
1292 .trustzone,
1293 .virtualization,
1294 }),
1295 };
1296 result[@intFromEnum(Feature.v8_1m_main)] = .{
1297 .llvm_name = "armv8.1-m.main",
1298 .description = "ARMv81mMainline architecture",
1299 .dependencies = featureSet(&[_]Feature{
1300 .@"8msecext",
1301 .acquire_release,
1302 .db,
1303 .has_v8_1m_main,
1304 .hwdiv,
1305 .lob,
1306 .mclass,
1307 .noarm,
1308 .ras,
1309 .thumb_mode,
1310 }),
1311 };
1312 result[@intFromEnum(Feature.v8_2a)] = .{
1313 .llvm_name = "armv8.2-a",
1314 .description = "ARMv82a architecture",
1315 .dependencies = featureSet(&[_]Feature{
1316 .aclass,
1317 .crc,
1318 .crypto,
1319 .db,
1320 .dsp,
1321 .fp_armv8,
1322 .has_v8_2a,
1323 .mp,
1324 .ras,
1325 .trustzone,
1326 .virtualization,
1327 }),
1328 };
1329 result[@intFromEnum(Feature.v8_3a)] = .{
1330 .llvm_name = "armv8.3-a",
1331 .description = "ARMv83a architecture",
1332 .dependencies = featureSet(&[_]Feature{
1333 .aclass,
1334 .crc,
1335 .crypto,
1336 .db,
1337 .dsp,
1338 .fp_armv8,
1339 .has_v8_3a,
1340 .mp,
1341 .ras,
1342 .trustzone,
1343 .virtualization,
1344 }),
1345 };
1346 result[@intFromEnum(Feature.v8_4a)] = .{
1347 .llvm_name = "armv8.4-a",
1348 .description = "ARMv84a architecture",
1349 .dependencies = featureSet(&[_]Feature{
1350 .aclass,
1351 .crc,
1352 .crypto,
1353 .db,
1354 .dsp,
1355 .fp_armv8,
1356 .has_v8_4a,
1357 .mp,
1358 .ras,
1359 .trustzone,
1360 .virtualization,
1361 }),
1362 };
1363 result[@intFromEnum(Feature.v8_5a)] = .{
1364 .llvm_name = "armv8.5-a",
1365 .description = "ARMv85a architecture",
1366 .dependencies = featureSet(&[_]Feature{
1367 .aclass,
1368 .crc,
1369 .crypto,
1370 .db,
1371 .dsp,
1372 .fp_armv8,
1373 .has_v8_5a,
1374 .mp,
1375 .ras,
1376 .trustzone,
1377 .virtualization,
1378 }),
1379 };
1380 result[@intFromEnum(Feature.v8_6a)] = .{
1381 .llvm_name = "armv8.6-a",
1382 .description = "ARMv86a architecture",
1383 .dependencies = featureSet(&[_]Feature{
1384 .aclass,
1385 .crc,
1386 .crypto,
1387 .db,
1388 .dsp,
1389 .fp_armv8,
1390 .has_v8_6a,
1391 .mp,
1392 .ras,
1393 .trustzone,
1394 .virtualization,
1395 }),
1396 };
1397 result[@intFromEnum(Feature.v8_7a)] = .{
1398 .llvm_name = "armv8.7-a",
1399 .description = "ARMv87a architecture",
1400 .dependencies = featureSet(&[_]Feature{
1401 .aclass,
1402 .crc,
1403 .crypto,
1404 .db,
1405 .dsp,
1406 .fp_armv8,
1407 .has_v8_7a,
1408 .mp,
1409 .ras,
1410 .trustzone,
1411 .virtualization,
1412 }),
1413 };
1414 result[@intFromEnum(Feature.v8_8a)] = .{
1415 .llvm_name = "armv8.8-a",
1416 .description = "ARMv88a architecture",
1417 .dependencies = featureSet(&[_]Feature{
1418 .aclass,
1419 .crc,
1420 .crypto,
1421 .db,
1422 .dsp,
1423 .fp_armv8,
1424 .has_v8_8a,
1425 .mp,
1426 .ras,
1427 .trustzone,
1428 .virtualization,
1429 }),
1430 };
1431 result[@intFromEnum(Feature.v8_9a)] = .{
1432 .llvm_name = "armv8.9-a",
1433 .description = "ARMv89a architecture",
1434 .dependencies = featureSet(&[_]Feature{
1435 .aclass,
1436 .crc,
1437 .crypto,
1438 .db,
1439 .dsp,
1440 .fp_armv8,
1441 .has_v8_9a,
1442 .mp,
1443 .ras,
1444 .trustzone,
1445 .virtualization,
1446 }),
1447 };
1448 result[@intFromEnum(Feature.v8a)] = .{
1449 .llvm_name = "armv8-a",
1450 .description = "ARMv8a architecture",
1451 .dependencies = featureSet(&[_]Feature{
1452 .aclass,
1453 .crc,
1454 .crypto,
1455 .db,
1456 .dsp,
1457 .fp_armv8,
1458 .has_v8,
1459 .mp,
1460 .trustzone,
1461 .virtualization,
1462 }),
1463 };
1464 result[@intFromEnum(Feature.v8m)] = .{
1465 .llvm_name = "armv8-m.base",
1466 .description = "ARMv8mBaseline architecture",
1467 .dependencies = featureSet(&[_]Feature{
1468 .@"8msecext",
1469 .acquire_release,
1470 .db,
1471 .has_v7clrex,
1472 .has_v8m,
1473 .hwdiv,
1474 .mclass,
1475 .noarm,
1476 .strict_align,
1477 .thumb_mode,
1478 }),
1479 };
1480 result[@intFromEnum(Feature.v8m_main)] = .{
1481 .llvm_name = "armv8-m.main",
1482 .description = "ARMv8mMainline architecture",
1483 .dependencies = featureSet(&[_]Feature{
1484 .@"8msecext",
1485 .acquire_release,
1486 .db,
1487 .has_v8m_main,
1488 .hwdiv,
1489 .mclass,
1490 .noarm,
1491 .thumb_mode,
1492 }),
1493 };
1494 result[@intFromEnum(Feature.v8r)] = .{
1495 .llvm_name = "armv8-r",
1496 .description = "ARMv8r architecture",
1497 .dependencies = featureSet(&[_]Feature{
1498 .crc,
1499 .db,
1500 .dfb,
1501 .dsp,
1502 .fp_armv8,
1503 .has_v8,
1504 .mp,
1505 .neon,
1506 .rclass,
1507 .virtualization,
1508 }),
1509 };
1510 result[@intFromEnum(Feature.v9_1a)] = .{
1511 .llvm_name = "armv9.1-a",
1512 .description = "ARMv91a architecture",
1513 .dependencies = featureSet(&[_]Feature{
1514 .aclass,
1515 .crc,
1516 .db,
1517 .dsp,
1518 .fp_armv8,
1519 .has_v9_1a,
1520 .mp,
1521 .ras,
1522 .trustzone,
1523 .virtualization,
1524 }),
1525 };
1526 result[@intFromEnum(Feature.v9_2a)] = .{
1527 .llvm_name = "armv9.2-a",
1528 .description = "ARMv92a architecture",
1529 .dependencies = featureSet(&[_]Feature{
1530 .aclass,
1531 .crc,
1532 .db,
1533 .dsp,
1534 .fp_armv8,
1535 .has_v9_2a,
1536 .mp,
1537 .ras,
1538 .trustzone,
1539 .virtualization,
1540 }),
1541 };
1542 result[@intFromEnum(Feature.v9_3a)] = .{
1543 .llvm_name = "armv9.3-a",
1544 .description = "ARMv93a architecture",
1545 .dependencies = featureSet(&[_]Feature{
1546 .aclass,
1547 .crc,
1548 .crypto,
1549 .db,
1550 .dsp,
1551 .fp_armv8,
1552 .has_v9_3a,
1553 .mp,
1554 .ras,
1555 .trustzone,
1556 .virtualization,
1557 }),
1558 };
1559 result[@intFromEnum(Feature.v9_4a)] = .{
1560 .llvm_name = "armv9.4-a",
1561 .description = "ARMv94a architecture",
1562 .dependencies = featureSet(&[_]Feature{
1563 .aclass,
1564 .crc,
1565 .db,
1566 .dsp,
1567 .fp_armv8,
1568 .has_v9_4a,
1569 .mp,
1570 .ras,
1571 .trustzone,
1572 .virtualization,
1573 }),
1574 };
1575 result[@intFromEnum(Feature.v9a)] = .{
1576 .llvm_name = "armv9-a",
1577 .description = "ARMv9a architecture",
1578 .dependencies = featureSet(&[_]Feature{
1579 .aclass,
1580 .crc,
1581 .db,
1582 .dsp,
1583 .fp_armv8,
1584 .has_v9a,
1585 .mp,
1586 .ras,
1587 .trustzone,
1588 .virtualization,
1589 }),
1590 };
1591 result[@intFromEnum(Feature.vfp2)] = .{
1592 .llvm_name = "vfp2",
1593 .description = "Enable VFP2 instructions",
1594 .dependencies = featureSet(&[_]Feature{
1595 .fp64,
1596 .vfp2sp,
1597 }),
1598 };
1599 result[@intFromEnum(Feature.vfp2sp)] = .{
1600 .llvm_name = "vfp2sp",
1601 .description = "Enable VFP2 instructions with no double precision",
1602 .dependencies = featureSet(&[_]Feature{
1603 .fpregs,
1604 }),
1605 };
1606 result[@intFromEnum(Feature.vfp3)] = .{
1607 .llvm_name = "vfp3",
1608 .description = "Enable VFP3 instructions",
1609 .dependencies = featureSet(&[_]Feature{
1610 .vfp3d16,
1611 .vfp3sp,
1612 }),
1613 };
1614 result[@intFromEnum(Feature.vfp3d16)] = .{
1615 .llvm_name = "vfp3d16",
1616 .description = "Enable VFP3 instructions with only 16 d-registers",
1617 .dependencies = featureSet(&[_]Feature{
1618 .vfp2,
1619 .vfp3d16sp,
1620 }),
1621 };
1622 result[@intFromEnum(Feature.vfp3d16sp)] = .{
1623 .llvm_name = "vfp3d16sp",
1624 .description = "Enable VFP3 instructions with only 16 d-registers and no double precision",
1625 .dependencies = featureSet(&[_]Feature{
1626 .vfp2sp,
1627 }),
1628 };
1629 result[@intFromEnum(Feature.vfp3sp)] = .{
1630 .llvm_name = "vfp3sp",
1631 .description = "Enable VFP3 instructions with no double precision",
1632 .dependencies = featureSet(&[_]Feature{
1633 .d32,
1634 .vfp3d16sp,
1635 }),
1636 };
1637 result[@intFromEnum(Feature.vfp4)] = .{
1638 .llvm_name = "vfp4",
1639 .description = "Enable VFP4 instructions",
1640 .dependencies = featureSet(&[_]Feature{
1641 .vfp3,
1642 .vfp4d16,
1643 .vfp4sp,
1644 }),
1645 };
1646 result[@intFromEnum(Feature.vfp4d16)] = .{
1647 .llvm_name = "vfp4d16",
1648 .description = "Enable VFP4 instructions with only 16 d-registers",
1649 .dependencies = featureSet(&[_]Feature{
1650 .vfp3d16,
1651 .vfp4d16sp,
1652 }),
1653 };
1654 result[@intFromEnum(Feature.vfp4d16sp)] = .{
1655 .llvm_name = "vfp4d16sp",
1656 .description = "Enable VFP4 instructions with only 16 d-registers and no double precision",
1657 .dependencies = featureSet(&[_]Feature{
1658 .fp16,
1659 .vfp3d16sp,
1660 }),
1661 };
1662 result[@intFromEnum(Feature.vfp4sp)] = .{
1663 .llvm_name = "vfp4sp",
1664 .description = "Enable VFP4 instructions with no double precision",
1665 .dependencies = featureSet(&[_]Feature{
1666 .vfp3sp,
1667 .vfp4d16sp,
1668 }),
1669 };
1670 result[@intFromEnum(Feature.virtualization)] = .{
1671 .llvm_name = "virtualization",
1672 .description = "Supports Virtualization extension",
1673 .dependencies = featureSet(&[_]Feature{
1674 .hwdiv,
1675 .hwdiv_arm,
1676 }),
1677 };
1678 result[@intFromEnum(Feature.vldn_align)] = .{
1679 .llvm_name = "vldn-align",
1680 .description = "Check for VLDn unaligned access",
1681 .dependencies = featureSet(&[_]Feature{}),
1682 };
1683 result[@intFromEnum(Feature.vmlx_forwarding)] = .{
1684 .llvm_name = "vmlx-forwarding",
1685 .description = "Has multiplier accumulator forwarding",
1686 .dependencies = featureSet(&[_]Feature{}),
1687 };
1688 result[@intFromEnum(Feature.vmlx_hazards)] = .{
1689 .llvm_name = "vmlx-hazards",
1690 .description = "Has VMLx hazards",
1691 .dependencies = featureSet(&[_]Feature{}),
1692 };
1693 result[@intFromEnum(Feature.wide_stride_vfp)] = .{
1694 .llvm_name = "wide-stride-vfp",
1695 .description = "Use a wide stride when allocating VFP registers",
1696 .dependencies = featureSet(&[_]Feature{}),
1697 };
1698 result[@intFromEnum(Feature.xscale)] = .{
1699 .llvm_name = "xscale",
1700 .description = "ARMv5te architecture",
1701 .dependencies = featureSet(&[_]Feature{
1702 .v5te,
1703 }),
1704 };
1705 result[@intFromEnum(Feature.zcz)] = .{
1706 .llvm_name = "zcz",
1707 .description = "Has zero-cycle zeroing instructions",
1708 .dependencies = featureSet(&[_]Feature{}),
1709 };
1710 const ti = @typeInfo(Feature);
1711 for (&result, 0..) |*elem, i| {
1712 elem.index = i;
1713 elem.name = ti.Enum.fields[i].name;
1714 }
1715 break :blk result;
1716};
1717
1718pub const cpu = struct {
1719 pub const arm1020e = CpuModel{
1720 .name = "arm1020e",
1721 .llvm_name = "arm1020e",
1722 .features = featureSet(&[_]Feature{
1723 .v5te,
1724 }),
1725 };
1726 pub const arm1020t = CpuModel{
1727 .name = "arm1020t",
1728 .llvm_name = "arm1020t",
1729 .features = featureSet(&[_]Feature{
1730 .v5t,
1731 }),
1732 };
1733 pub const arm1022e = CpuModel{
1734 .name = "arm1022e",
1735 .llvm_name = "arm1022e",
1736 .features = featureSet(&[_]Feature{
1737 .v5te,
1738 }),
1739 };
1740 pub const arm10e = CpuModel{
1741 .name = "arm10e",
1742 .llvm_name = "arm10e",
1743 .features = featureSet(&[_]Feature{
1744 .v5te,
1745 }),
1746 };
1747 pub const arm10tdmi = CpuModel{
1748 .name = "arm10tdmi",
1749 .llvm_name = "arm10tdmi",
1750 .features = featureSet(&[_]Feature{
1751 .v5t,
1752 }),
1753 };
1754 pub const arm1136j_s = CpuModel{
1755 .name = "arm1136j_s",
1756 .llvm_name = "arm1136j-s",
1757 .features = featureSet(&[_]Feature{
1758 .v6,
1759 }),
1760 };
1761 pub const arm1136jf_s = CpuModel{
1762 .name = "arm1136jf_s",
1763 .llvm_name = "arm1136jf-s",
1764 .features = featureSet(&[_]Feature{
1765 .slowfpvmlx,
1766 .v6,
1767 .vfp2,
1768 }),
1769 };
1770 pub const arm1156t2_s = CpuModel{
1771 .name = "arm1156t2_s",
1772 .llvm_name = "arm1156t2-s",
1773 .features = featureSet(&[_]Feature{
1774 .v6t2,
1775 }),
1776 };
1777 pub const arm1156t2f_s = CpuModel{
1778 .name = "arm1156t2f_s",
1779 .llvm_name = "arm1156t2f-s",
1780 .features = featureSet(&[_]Feature{
1781 .slowfpvmlx,
1782 .v6t2,
1783 .vfp2,
1784 }),
1785 };
1786 pub const arm1176jz_s = CpuModel{
1787 .name = "arm1176jz_s",
1788 .llvm_name = "arm1176jz-s",
1789 .features = featureSet(&[_]Feature{
1790 .v6kz,
1791 }),
1792 };
1793 pub const arm1176jzf_s = CpuModel{
1794 .name = "arm1176jzf_s",
1795 .llvm_name = "arm1176jzf-s",
1796 .features = featureSet(&[_]Feature{
1797 .slowfpvmlx,
1798 .v6kz,
1799 .vfp2,
1800 }),
1801 };
1802 pub const arm710t = CpuModel{
1803 .name = "arm710t",
1804 .llvm_name = "arm710t",
1805 .features = featureSet(&[_]Feature{
1806 .v4t,
1807 }),
1808 };
1809 pub const arm720t = CpuModel{
1810 .name = "arm720t",
1811 .llvm_name = "arm720t",
1812 .features = featureSet(&[_]Feature{
1813 .v4t,
1814 }),
1815 };
1816 pub const arm7tdmi = CpuModel{
1817 .name = "arm7tdmi",
1818 .llvm_name = "arm7tdmi",
1819 .features = featureSet(&[_]Feature{
1820 .v4t,
1821 }),
1822 };
1823 pub const arm7tdmi_s = CpuModel{
1824 .name = "arm7tdmi_s",
1825 .llvm_name = "arm7tdmi-s",
1826 .features = featureSet(&[_]Feature{
1827 .v4t,
1828 }),
1829 };
1830 pub const arm8 = CpuModel{
1831 .name = "arm8",
1832 .llvm_name = "arm8",
1833 .features = featureSet(&[_]Feature{
1834 .v4,
1835 }),
1836 };
1837 pub const arm810 = CpuModel{
1838 .name = "arm810",
1839 .llvm_name = "arm810",
1840 .features = featureSet(&[_]Feature{
1841 .v4,
1842 }),
1843 };
1844 pub const arm9 = CpuModel{
1845 .name = "arm9",
1846 .llvm_name = "arm9",
1847 .features = featureSet(&[_]Feature{
1848 .v4t,
1849 }),
1850 };
1851 pub const arm920 = CpuModel{
1852 .name = "arm920",
1853 .llvm_name = "arm920",
1854 .features = featureSet(&[_]Feature{
1855 .v4t,
1856 }),
1857 };
1858 pub const arm920t = CpuModel{
1859 .name = "arm920t",
1860 .llvm_name = "arm920t",
1861 .features = featureSet(&[_]Feature{
1862 .v4t,
1863 }),
1864 };
1865 pub const arm922t = CpuModel{
1866 .name = "arm922t",
1867 .llvm_name = "arm922t",
1868 .features = featureSet(&[_]Feature{
1869 .v4t,
1870 }),
1871 };
1872 pub const arm926ej_s = CpuModel{
1873 .name = "arm926ej_s",
1874 .llvm_name = "arm926ej-s",
1875 .features = featureSet(&[_]Feature{
1876 .v5te,
1877 }),
1878 };
1879 pub const arm940t = CpuModel{
1880 .name = "arm940t",
1881 .llvm_name = "arm940t",
1882 .features = featureSet(&[_]Feature{
1883 .v4t,
1884 }),
1885 };
1886 pub const arm946e_s = CpuModel{
1887 .name = "arm946e_s",
1888 .llvm_name = "arm946e-s",
1889 .features = featureSet(&[_]Feature{
1890 .v5te,
1891 }),
1892 };
1893 pub const arm966e_s = CpuModel{
1894 .name = "arm966e_s",
1895 .llvm_name = "arm966e-s",
1896 .features = featureSet(&[_]Feature{
1897 .v5te,
1898 }),
1899 };
1900 pub const arm968e_s = CpuModel{
1901 .name = "arm968e_s",
1902 .llvm_name = "arm968e-s",
1903 .features = featureSet(&[_]Feature{
1904 .v5te,
1905 }),
1906 };
1907 pub const arm9e = CpuModel{
1908 .name = "arm9e",
1909 .llvm_name = "arm9e",
1910 .features = featureSet(&[_]Feature{
1911 .v5te,
1912 }),
1913 };
1914 pub const arm9tdmi = CpuModel{
1915 .name = "arm9tdmi",
1916 .llvm_name = "arm9tdmi",
1917 .features = featureSet(&[_]Feature{
1918 .v4t,
1919 }),
1920 };
1921 pub const baseline = CpuModel{
1922 .name = "baseline",
1923 .llvm_name = "generic",
1924 .features = featureSet(&[_]Feature{
1925 .v7a,
1926 }),
1927 };
1928 pub const cortex_a12 = CpuModel{
1929 .name = "cortex_a12",
1930 .llvm_name = "cortex-a12",
1931 .features = featureSet(&[_]Feature{
1932 .avoid_partial_cpsr,
1933 .mp,
1934 .ret_addr_stack,
1935 .trustzone,
1936 .v7a,
1937 .vfp4,
1938 .virtualization,
1939 .vmlx_forwarding,
1940 }),
1941 };
1942 pub const cortex_a15 = CpuModel{
1943 .name = "cortex_a15",
1944 .llvm_name = "cortex-a15",
1945 .features = featureSet(&[_]Feature{
1946 .avoid_partial_cpsr,
1947 .mp,
1948 .muxed_units,
1949 .ret_addr_stack,
1950 .splat_vfp_neon,
1951 .trustzone,
1952 .v7a,
1953 .vfp4,
1954 .virtualization,
1955 .vldn_align,
1956 }),
1957 };
1958 pub const cortex_a17 = CpuModel{
1959 .name = "cortex_a17",
1960 .llvm_name = "cortex-a17",
1961 .features = featureSet(&[_]Feature{
1962 .avoid_partial_cpsr,
1963 .mp,
1964 .ret_addr_stack,
1965 .trustzone,
1966 .v7a,
1967 .vfp4,
1968 .virtualization,
1969 .vmlx_forwarding,
1970 }),
1971 };
1972 pub const cortex_a32 = CpuModel{
1973 .name = "cortex_a32",
1974 .llvm_name = "cortex-a32",
1975 .features = featureSet(&[_]Feature{
1976 .v8a,
1977 }),
1978 };
1979 pub const cortex_a35 = CpuModel{
1980 .name = "cortex_a35",
1981 .llvm_name = "cortex-a35",
1982 .features = featureSet(&[_]Feature{
1983 .v8a,
1984 }),
1985 };
1986 pub const cortex_a5 = CpuModel{
1987 .name = "cortex_a5",
1988 .llvm_name = "cortex-a5",
1989 .features = featureSet(&[_]Feature{
1990 .mp,
1991 .ret_addr_stack,
1992 .slow_fp_brcc,
1993 .slowfpvfmx,
1994 .slowfpvmlx,
1995 .trustzone,
1996 .v7a,
1997 .vfp4,
1998 .vmlx_forwarding,
1999 }),
2000 };
2001 pub const cortex_a53 = CpuModel{
2002 .name = "cortex_a53",
2003 .llvm_name = "cortex-a53",
2004 .features = featureSet(&[_]Feature{
2005 .fpao,
2006 .v8a,
2007 }),
2008 };
2009 pub const cortex_a55 = CpuModel{
2010 .name = "cortex_a55",
2011 .llvm_name = "cortex-a55",
2012 .features = featureSet(&[_]Feature{
2013 .dotprod,
2014 .v8_2a,
2015 }),
2016 };
2017 pub const cortex_a57 = CpuModel{
2018 .name = "cortex_a57",
2019 .llvm_name = "cortex-a57",
2020 .features = featureSet(&[_]Feature{
2021 .avoid_partial_cpsr,
2022 .cheap_predicable_cpsr,
2023 .fix_cortex_a57_aes_1742098,
2024 .fpao,
2025 .v8a,
2026 }),
2027 };
2028 pub const cortex_a7 = CpuModel{
2029 .name = "cortex_a7",
2030 .llvm_name = "cortex-a7",
2031 .features = featureSet(&[_]Feature{
2032 .mp,
2033 .ret_addr_stack,
2034 .slow_fp_brcc,
2035 .slowfpvfmx,
2036 .slowfpvmlx,
2037 .trustzone,
2038 .v7a,
2039 .vfp4,
2040 .virtualization,
2041 .vmlx_forwarding,
2042 .vmlx_hazards,
2043 }),
2044 };
2045 pub const cortex_a710 = CpuModel{
2046 .name = "cortex_a710",
2047 .llvm_name = "cortex-a710",
2048 .features = featureSet(&[_]Feature{
2049 .bf16,
2050 .fp16fml,
2051 .i8mm,
2052 .v9a,
2053 }),
2054 };
2055 pub const cortex_a72 = CpuModel{
2056 .name = "cortex_a72",
2057 .llvm_name = "cortex-a72",
2058 .features = featureSet(&[_]Feature{
2059 .fix_cortex_a57_aes_1742098,
2060 .v8a,
2061 }),
2062 };
2063 pub const cortex_a73 = CpuModel{
2064 .name = "cortex_a73",
2065 .llvm_name = "cortex-a73",
2066 .features = featureSet(&[_]Feature{
2067 .v8a,
2068 }),
2069 };
2070 pub const cortex_a75 = CpuModel{
2071 .name = "cortex_a75",
2072 .llvm_name = "cortex-a75",
2073 .features = featureSet(&[_]Feature{
2074 .dotprod,
2075 .v8_2a,
2076 }),
2077 };
2078 pub const cortex_a76 = CpuModel{
2079 .name = "cortex_a76",
2080 .llvm_name = "cortex-a76",
2081 .features = featureSet(&[_]Feature{
2082 .a76,
2083 .dotprod,
2084 .fullfp16,
2085 .v8_2a,
2086 }),
2087 };
2088 pub const cortex_a76ae = CpuModel{
2089 .name = "cortex_a76ae",
2090 .llvm_name = "cortex-a76ae",
2091 .features = featureSet(&[_]Feature{
2092 .a76,
2093 .dotprod,
2094 .fullfp16,
2095 .v8_2a,
2096 }),
2097 };
2098 pub const cortex_a77 = CpuModel{
2099 .name = "cortex_a77",
2100 .llvm_name = "cortex-a77",
2101 .features = featureSet(&[_]Feature{
2102 .dotprod,
2103 .fullfp16,
2104 .v8_2a,
2105 }),
2106 };
2107 pub const cortex_a78 = CpuModel{
2108 .name = "cortex_a78",
2109 .llvm_name = "cortex-a78",
2110 .features = featureSet(&[_]Feature{
2111 .dotprod,
2112 .fullfp16,
2113 .v8_2a,
2114 }),
2115 };
2116 pub const cortex_a78c = CpuModel{
2117 .name = "cortex_a78c",
2118 .llvm_name = "cortex-a78c",
2119 .features = featureSet(&[_]Feature{
2120 .dotprod,
2121 .fullfp16,
2122 .v8_2a,
2123 }),
2124 };
2125 pub const cortex_a8 = CpuModel{
2126 .name = "cortex_a8",
2127 .llvm_name = "cortex-a8",
2128 .features = featureSet(&[_]Feature{
2129 .nonpipelined_vfp,
2130 .ret_addr_stack,
2131 .slow_fp_brcc,
2132 .slowfpvfmx,
2133 .slowfpvmlx,
2134 .trustzone,
2135 .v7a,
2136 .vmlx_forwarding,
2137 .vmlx_hazards,
2138 }),
2139 };
2140 pub const cortex_a9 = CpuModel{
2141 .name = "cortex_a9",
2142 .llvm_name = "cortex-a9",
2143 .features = featureSet(&[_]Feature{
2144 .avoid_partial_cpsr,
2145 .expand_fp_mlx,
2146 .fp16,
2147 .mp,
2148 .muxed_units,
2149 .neon_fpmovs,
2150 .prefer_vmovsr,
2151 .ret_addr_stack,
2152 .trustzone,
2153 .v7a,
2154 .vldn_align,
2155 .vmlx_forwarding,
2156 .vmlx_hazards,
2157 }),
2158 };
2159 pub const cortex_m0 = CpuModel{
2160 .name = "cortex_m0",
2161 .llvm_name = "cortex-m0",
2162 .features = featureSet(&[_]Feature{
2163 .no_branch_predictor,
2164 .v6m,
2165 }),
2166 };
2167 pub const cortex_m0plus = CpuModel{
2168 .name = "cortex_m0plus",
2169 .llvm_name = "cortex-m0plus",
2170 .features = featureSet(&[_]Feature{
2171 .no_branch_predictor,
2172 .v6m,
2173 }),
2174 };
2175 pub const cortex_m1 = CpuModel{
2176 .name = "cortex_m1",
2177 .llvm_name = "cortex-m1",
2178 .features = featureSet(&[_]Feature{
2179 .no_branch_predictor,
2180 .v6m,
2181 }),
2182 };
2183 pub const cortex_m23 = CpuModel{
2184 .name = "cortex_m23",
2185 .llvm_name = "cortex-m23",
2186 .features = featureSet(&[_]Feature{
2187 .no_branch_predictor,
2188 .no_movt,
2189 .v8m,
2190 }),
2191 };
2192 pub const cortex_m3 = CpuModel{
2193 .name = "cortex_m3",
2194 .llvm_name = "cortex-m3",
2195 .features = featureSet(&[_]Feature{
2196 .loop_align,
2197 .m3,
2198 .no_branch_predictor,
2199 .use_misched,
2200 .v7m,
2201 }),
2202 };
2203 pub const cortex_m33 = CpuModel{
2204 .name = "cortex_m33",
2205 .llvm_name = "cortex-m33",
2206 .features = featureSet(&[_]Feature{
2207 .dsp,
2208 .fix_cmse_cve_2021_35465,
2209 .fp_armv8d16sp,
2210 .loop_align,
2211 .no_branch_predictor,
2212 .slowfpvfmx,
2213 .slowfpvmlx,
2214 .use_misched,
2215 .v8m_main,
2216 }),
2217 };
2218 pub const cortex_m35p = CpuModel{
2219 .name = "cortex_m35p",
2220 .llvm_name = "cortex-m35p",
2221 .features = featureSet(&[_]Feature{
2222 .dsp,
2223 .fix_cmse_cve_2021_35465,
2224 .fp_armv8d16sp,
2225 .loop_align,
2226 .no_branch_predictor,
2227 .slowfpvfmx,
2228 .slowfpvmlx,
2229 .use_misched,
2230 .v8m_main,
2231 }),
2232 };
2233 pub const cortex_m4 = CpuModel{
2234 .name = "cortex_m4",
2235 .llvm_name = "cortex-m4",
2236 .features = featureSet(&[_]Feature{
2237 .loop_align,
2238 .no_branch_predictor,
2239 .slowfpvfmx,
2240 .slowfpvmlx,
2241 .use_misched,
2242 .v7em,
2243 .vfp4d16sp,
2244 }),
2245 };
2246 pub const cortex_m55 = CpuModel{
2247 .name = "cortex_m55",
2248 .llvm_name = "cortex-m55",
2249 .features = featureSet(&[_]Feature{
2250 .fix_cmse_cve_2021_35465,
2251 .fp_armv8d16,
2252 .loop_align,
2253 .mve_fp,
2254 .no_branch_predictor,
2255 .slowfpvmlx,
2256 .use_misched,
2257 .v8_1m_main,
2258 }),
2259 };
2260 pub const cortex_m7 = CpuModel{
2261 .name = "cortex_m7",
2262 .llvm_name = "cortex-m7",
2263 .features = featureSet(&[_]Feature{
2264 .fp_armv8d16,
2265 .use_mipipeliner,
2266 .use_misched,
2267 .v7em,
2268 }),
2269 };
2270 pub const cortex_m85 = CpuModel{
2271 .name = "cortex_m85",
2272 .llvm_name = "cortex-m85",
2273 .features = featureSet(&[_]Feature{
2274 .fp_armv8d16,
2275 .mve_fp,
2276 .pacbti,
2277 .use_misched,
2278 .v8_1m_main,
2279 }),
2280 };
2281 pub const cortex_r4 = CpuModel{
2282 .name = "cortex_r4",
2283 .llvm_name = "cortex-r4",
2284 .features = featureSet(&[_]Feature{
2285 .avoid_partial_cpsr,
2286 .r4,
2287 .ret_addr_stack,
2288 .v7r,
2289 }),
2290 };
2291 pub const cortex_r4f = CpuModel{
2292 .name = "cortex_r4f",
2293 .llvm_name = "cortex-r4f",
2294 .features = featureSet(&[_]Feature{
2295 .avoid_partial_cpsr,
2296 .r4,
2297 .ret_addr_stack,
2298 .slow_fp_brcc,
2299 .slowfpvfmx,
2300 .slowfpvmlx,
2301 .v7r,
2302 .vfp3d16,
2303 }),
2304 };
2305 pub const cortex_r5 = CpuModel{
2306 .name = "cortex_r5",
2307 .llvm_name = "cortex-r5",
2308 .features = featureSet(&[_]Feature{
2309 .avoid_partial_cpsr,
2310 .hwdiv_arm,
2311 .ret_addr_stack,
2312 .slow_fp_brcc,
2313 .slowfpvfmx,
2314 .slowfpvmlx,
2315 .v7r,
2316 .vfp3d16,
2317 }),
2318 };
2319 pub const cortex_r52 = CpuModel{
2320 .name = "cortex_r52",
2321 .llvm_name = "cortex-r52",
2322 .features = featureSet(&[_]Feature{
2323 .fpao,
2324 .use_misched,
2325 .v8r,
2326 }),
2327 };
2328 pub const cortex_r7 = CpuModel{
2329 .name = "cortex_r7",
2330 .llvm_name = "cortex-r7",
2331 .features = featureSet(&[_]Feature{
2332 .avoid_partial_cpsr,
2333 .fp16,
2334 .hwdiv_arm,
2335 .mp,
2336 .ret_addr_stack,
2337 .slow_fp_brcc,
2338 .slowfpvfmx,
2339 .slowfpvmlx,
2340 .v7r,
2341 .vfp3d16,
2342 }),
2343 };
2344 pub const cortex_r8 = CpuModel{
2345 .name = "cortex_r8",
2346 .llvm_name = "cortex-r8",
2347 .features = featureSet(&[_]Feature{
2348 .avoid_partial_cpsr,
2349 .fp16,
2350 .hwdiv_arm,
2351 .mp,
2352 .ret_addr_stack,
2353 .slow_fp_brcc,
2354 .slowfpvfmx,
2355 .slowfpvmlx,
2356 .v7r,
2357 .vfp3d16,
2358 }),
2359 };
2360 pub const cortex_x1 = CpuModel{
2361 .name = "cortex_x1",
2362 .llvm_name = "cortex-x1",
2363 .features = featureSet(&[_]Feature{
2364 .dotprod,
2365 .fullfp16,
2366 .v8_2a,
2367 }),
2368 };
2369 pub const cortex_x1c = CpuModel{
2370 .name = "cortex_x1c",
2371 .llvm_name = "cortex-x1c",
2372 .features = featureSet(&[_]Feature{
2373 .dotprod,
2374 .fullfp16,
2375 .v8_2a,
2376 }),
2377 };
2378 pub const cyclone = CpuModel{
2379 .name = "cyclone",
2380 .llvm_name = "cyclone",
2381 .features = featureSet(&[_]Feature{
2382 .avoid_movs_shop,
2383 .avoid_partial_cpsr,
2384 .disable_postra_scheduler,
2385 .neonfp,
2386 .ret_addr_stack,
2387 .slowfpvfmx,
2388 .slowfpvmlx,
2389 .swift,
2390 .use_misched,
2391 .v8a,
2392 .zcz,
2393 }),
2394 };
2395 pub const ep9312 = CpuModel{
2396 .name = "ep9312",
2397 .llvm_name = "ep9312",
2398 .features = featureSet(&[_]Feature{
2399 .v4t,
2400 }),
2401 };
2402 pub const exynos_m1 = CpuModel{
2403 .name = "exynos_m1",
2404 .llvm_name = null,
2405 .features = featureSet(&[_]Feature{
2406 .exynos,
2407 .v8a,
2408 }),
2409 };
2410 pub const exynos_m2 = CpuModel{
2411 .name = "exynos_m2",
2412 .llvm_name = null,
2413 .features = featureSet(&[_]Feature{
2414 .exynos,
2415 .v8a,
2416 }),
2417 };
2418 pub const exynos_m3 = CpuModel{
2419 .name = "exynos_m3",
2420 .llvm_name = "exynos-m3",
2421 .features = featureSet(&[_]Feature{
2422 .exynos,
2423 .v8a,
2424 }),
2425 };
2426 pub const exynos_m4 = CpuModel{
2427 .name = "exynos_m4",
2428 .llvm_name = "exynos-m4",
2429 .features = featureSet(&[_]Feature{
2430 .dotprod,
2431 .exynos,
2432 .fullfp16,
2433 .v8_2a,
2434 }),
2435 };
2436 pub const exynos_m5 = CpuModel{
2437 .name = "exynos_m5",
2438 .llvm_name = "exynos-m5",
2439 .features = featureSet(&[_]Feature{
2440 .dotprod,
2441 .exynos,
2442 .fullfp16,
2443 .v8_2a,
2444 }),
2445 };
2446 pub const generic = CpuModel{
2447 .name = "generic",
2448 .llvm_name = "generic",
2449 .features = featureSet(&[_]Feature{}),
2450 };
2451 pub const iwmmxt = CpuModel{
2452 .name = "iwmmxt",
2453 .llvm_name = "iwmmxt",
2454 .features = featureSet(&[_]Feature{
2455 .v5te,
2456 }),
2457 };
2458 pub const krait = CpuModel{
2459 .name = "krait",
2460 .llvm_name = "krait",
2461 .features = featureSet(&[_]Feature{
2462 .avoid_partial_cpsr,
2463 .hwdiv,
2464 .hwdiv_arm,
2465 .muxed_units,
2466 .ret_addr_stack,
2467 .v7a,
2468 .vfp4,
2469 .vldn_align,
2470 .vmlx_forwarding,
2471 }),
2472 };
2473 pub const kryo = CpuModel{
2474 .name = "kryo",
2475 .llvm_name = "kryo",
2476 .features = featureSet(&[_]Feature{
2477 .v8a,
2478 }),
2479 };
2480 pub const mpcore = CpuModel{
2481 .name = "mpcore",
2482 .llvm_name = "mpcore",
2483 .features = featureSet(&[_]Feature{
2484 .slowfpvmlx,
2485 .v6k,
2486 .vfp2,
2487 }),
2488 };
2489 pub const mpcorenovfp = CpuModel{
2490 .name = "mpcorenovfp",
2491 .llvm_name = "mpcorenovfp",
2492 .features = featureSet(&[_]Feature{
2493 .v6k,
2494 }),
2495 };
2496 pub const neoverse_n1 = CpuModel{
2497 .name = "neoverse_n1",
2498 .llvm_name = "neoverse-n1",
2499 .features = featureSet(&[_]Feature{
2500 .dotprod,
2501 .v8_2a,
2502 }),
2503 };
2504 pub const neoverse_n2 = CpuModel{
2505 .name = "neoverse_n2",
2506 .llvm_name = "neoverse-n2",
2507 .features = featureSet(&[_]Feature{
2508 .bf16,
2509 .i8mm,
2510 .v8_5a,
2511 }),
2512 };
2513 pub const neoverse_v1 = CpuModel{
2514 .name = "neoverse_v1",
2515 .llvm_name = "neoverse-v1",
2516 .features = featureSet(&[_]Feature{
2517 .bf16,
2518 .fullfp16,
2519 .i8mm,
2520 .v8_4a,
2521 }),
2522 };
2523 pub const sc000 = CpuModel{
2524 .name = "sc000",
2525 .llvm_name = "sc000",
2526 .features = featureSet(&[_]Feature{
2527 .no_branch_predictor,
2528 .v6m,
2529 }),
2530 };
2531 pub const sc300 = CpuModel{
2532 .name = "sc300",
2533 .llvm_name = "sc300",
2534 .features = featureSet(&[_]Feature{
2535 .m3,
2536 .no_branch_predictor,
2537 .use_misched,
2538 .v7m,
2539 }),
2540 };
2541 pub const strongarm = CpuModel{
2542 .name = "strongarm",
2543 .llvm_name = "strongarm",
2544 .features = featureSet(&[_]Feature{
2545 .v4,
2546 }),
2547 };
2548 pub const strongarm110 = CpuModel{
2549 .name = "strongarm110",
2550 .llvm_name = "strongarm110",
2551 .features = featureSet(&[_]Feature{
2552 .v4,
2553 }),
2554 };
2555 pub const strongarm1100 = CpuModel{
2556 .name = "strongarm1100",
2557 .llvm_name = "strongarm1100",
2558 .features = featureSet(&[_]Feature{
2559 .v4,
2560 }),
2561 };
2562 pub const strongarm1110 = CpuModel{
2563 .name = "strongarm1110",
2564 .llvm_name = "strongarm1110",
2565 .features = featureSet(&[_]Feature{
2566 .v4,
2567 }),
2568 };
2569 pub const swift = CpuModel{
2570 .name = "swift",
2571 .llvm_name = "swift",
2572 .features = featureSet(&[_]Feature{
2573 .avoid_movs_shop,
2574 .avoid_partial_cpsr,
2575 .disable_postra_scheduler,
2576 .hwdiv,
2577 .hwdiv_arm,
2578 .mp,
2579 .neonfp,
2580 .prefer_ishst,
2581 .prof_unpr,
2582 .ret_addr_stack,
2583 .slow_load_D_subreg,
2584 .slow_odd_reg,
2585 .slow_vdup32,
2586 .slow_vgetlni32,
2587 .slowfpvfmx,
2588 .slowfpvmlx,
2589 .swift,
2590 .use_misched,
2591 .v7a,
2592 .vfp4,
2593 .vmlx_hazards,
2594 .wide_stride_vfp,
2595 }),
2596 };
2597 pub const xscale = CpuModel{
2598 .name = "xscale",
2599 .llvm_name = "xscale",
2600 .features = featureSet(&[_]Feature{
2601 .v5te,
2602 }),
2603 };
2604};
lib/std/target/avr.zig deleted-2607
......@@ -1,2607 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 addsubiw,
9 avr0,
10 avr1,
11 avr2,
12 avr25,
13 avr3,
14 avr31,
15 avr35,
16 avr4,
17 avr5,
18 avr51,
19 avr6,
20 avrtiny,
21 @"break",
22 des,
23 eijmpcall,
24 elpm,
25 elpmx,
26 ijmpcall,
27 jmpcall,
28 lowbytefirst,
29 lpm,
30 lpmx,
31 memmappedregs,
32 movw,
33 mul,
34 rmw,
35 smallstack,
36 special,
37 spm,
38 spmx,
39 sram,
40 tinyencoding,
41 xmega,
42 xmega3,
43 xmegau,
44};
45
46pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
47pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
48pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
49pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
50
51pub const all_features = blk: {
52 const len = @typeInfo(Feature).Enum.fields.len;
53 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
54 var result: [len]CpuFeature = undefined;
55 result[@intFromEnum(Feature.addsubiw)] = .{
56 .llvm_name = "addsubiw",
57 .description = "Enable 16-bit register-immediate addition and subtraction instructions",
58 .dependencies = featureSet(&[_]Feature{}),
59 };
60 result[@intFromEnum(Feature.avr0)] = .{
61 .llvm_name = "avr0",
62 .description = "The device is a part of the avr0 family",
63 .dependencies = featureSet(&[_]Feature{}),
64 };
65 result[@intFromEnum(Feature.avr1)] = .{
66 .llvm_name = "avr1",
67 .description = "The device is a part of the avr1 family",
68 .dependencies = featureSet(&[_]Feature{
69 .avr0,
70 .lpm,
71 .memmappedregs,
72 }),
73 };
74 result[@intFromEnum(Feature.avr2)] = .{
75 .llvm_name = "avr2",
76 .description = "The device is a part of the avr2 family",
77 .dependencies = featureSet(&[_]Feature{
78 .addsubiw,
79 .avr1,
80 .ijmpcall,
81 .sram,
82 }),
83 };
84 result[@intFromEnum(Feature.avr25)] = .{
85 .llvm_name = "avr25",
86 .description = "The device is a part of the avr25 family",
87 .dependencies = featureSet(&[_]Feature{
88 .avr2,
89 .@"break",
90 .lpmx,
91 .movw,
92 .spm,
93 }),
94 };
95 result[@intFromEnum(Feature.avr3)] = .{
96 .llvm_name = "avr3",
97 .description = "The device is a part of the avr3 family",
98 .dependencies = featureSet(&[_]Feature{
99 .avr2,
100 .jmpcall,
101 }),
102 };
103 result[@intFromEnum(Feature.avr31)] = .{
104 .llvm_name = "avr31",
105 .description = "The device is a part of the avr31 family",
106 .dependencies = featureSet(&[_]Feature{
107 .avr3,
108 .elpm,
109 }),
110 };
111 result[@intFromEnum(Feature.avr35)] = .{
112 .llvm_name = "avr35",
113 .description = "The device is a part of the avr35 family",
114 .dependencies = featureSet(&[_]Feature{
115 .avr3,
116 .@"break",
117 .lpmx,
118 .movw,
119 .spm,
120 }),
121 };
122 result[@intFromEnum(Feature.avr4)] = .{
123 .llvm_name = "avr4",
124 .description = "The device is a part of the avr4 family",
125 .dependencies = featureSet(&[_]Feature{
126 .avr2,
127 .@"break",
128 .lpmx,
129 .movw,
130 .mul,
131 .spm,
132 }),
133 };
134 result[@intFromEnum(Feature.avr5)] = .{
135 .llvm_name = "avr5",
136 .description = "The device is a part of the avr5 family",
137 .dependencies = featureSet(&[_]Feature{
138 .avr3,
139 .@"break",
140 .lpmx,
141 .movw,
142 .mul,
143 .spm,
144 }),
145 };
146 result[@intFromEnum(Feature.avr51)] = .{
147 .llvm_name = "avr51",
148 .description = "The device is a part of the avr51 family",
149 .dependencies = featureSet(&[_]Feature{
150 .avr5,
151 .elpm,
152 .elpmx,
153 }),
154 };
155 result[@intFromEnum(Feature.avr6)] = .{
156 .llvm_name = "avr6",
157 .description = "The device is a part of the avr6 family",
158 .dependencies = featureSet(&[_]Feature{
159 .avr51,
160 .eijmpcall,
161 }),
162 };
163 result[@intFromEnum(Feature.avrtiny)] = .{
164 .llvm_name = "avrtiny",
165 .description = "The device is a part of the avrtiny family",
166 .dependencies = featureSet(&[_]Feature{
167 .avr0,
168 .@"break",
169 .smallstack,
170 .sram,
171 .tinyencoding,
172 }),
173 };
174 result[@intFromEnum(Feature.@"break")] = .{
175 .llvm_name = "break",
176 .description = "The device supports the `BREAK` debugging instruction",
177 .dependencies = featureSet(&[_]Feature{}),
178 };
179 result[@intFromEnum(Feature.des)] = .{
180 .llvm_name = "des",
181 .description = "The device supports the `DES k` encryption instruction",
182 .dependencies = featureSet(&[_]Feature{}),
183 };
184 result[@intFromEnum(Feature.eijmpcall)] = .{
185 .llvm_name = "eijmpcall",
186 .description = "The device supports the `EIJMP`/`EICALL` instructions",
187 .dependencies = featureSet(&[_]Feature{}),
188 };
189 result[@intFromEnum(Feature.elpm)] = .{
190 .llvm_name = "elpm",
191 .description = "The device supports the ELPM instruction",
192 .dependencies = featureSet(&[_]Feature{}),
193 };
194 result[@intFromEnum(Feature.elpmx)] = .{
195 .llvm_name = "elpmx",
196 .description = "The device supports the `ELPM Rd, Z[+]` instructions",
197 .dependencies = featureSet(&[_]Feature{}),
198 };
199 result[@intFromEnum(Feature.ijmpcall)] = .{
200 .llvm_name = "ijmpcall",
201 .description = "The device supports `IJMP`/`ICALL`instructions",
202 .dependencies = featureSet(&[_]Feature{}),
203 };
204 result[@intFromEnum(Feature.jmpcall)] = .{
205 .llvm_name = "jmpcall",
206 .description = "The device supports the `JMP` and `CALL` instructions",
207 .dependencies = featureSet(&[_]Feature{}),
208 };
209 result[@intFromEnum(Feature.lowbytefirst)] = .{
210 .llvm_name = "lowbytefirst",
211 .description = "Do the low byte first when writing a 16-bit port or storing a 16-bit word",
212 .dependencies = featureSet(&[_]Feature{}),
213 };
214 result[@intFromEnum(Feature.lpm)] = .{
215 .llvm_name = "lpm",
216 .description = "The device supports the `LPM` instruction",
217 .dependencies = featureSet(&[_]Feature{}),
218 };
219 result[@intFromEnum(Feature.lpmx)] = .{
220 .llvm_name = "lpmx",
221 .description = "The device supports the `LPM Rd, Z[+]` instruction",
222 .dependencies = featureSet(&[_]Feature{}),
223 };
224 result[@intFromEnum(Feature.memmappedregs)] = .{
225 .llvm_name = "memmappedregs",
226 .description = "The device has CPU registers mapped in data address space",
227 .dependencies = featureSet(&[_]Feature{}),
228 };
229 result[@intFromEnum(Feature.movw)] = .{
230 .llvm_name = "movw",
231 .description = "The device supports the 16-bit MOVW instruction",
232 .dependencies = featureSet(&[_]Feature{}),
233 };
234 result[@intFromEnum(Feature.mul)] = .{
235 .llvm_name = "mul",
236 .description = "The device supports the multiplication instructions",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.rmw)] = .{
240 .llvm_name = "rmw",
241 .description = "The device supports the read-write-modify instructions: XCH, LAS, LAC, LAT",
242 .dependencies = featureSet(&[_]Feature{}),
243 };
244 result[@intFromEnum(Feature.smallstack)] = .{
245 .llvm_name = "smallstack",
246 .description = "The device has an 8-bit stack pointer",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@intFromEnum(Feature.special)] = .{
250 .llvm_name = "special",
251 .description = "Enable use of the entire instruction set - used for debugging",
252 .dependencies = featureSet(&[_]Feature{
253 .addsubiw,
254 .@"break",
255 .des,
256 .eijmpcall,
257 .elpm,
258 .elpmx,
259 .ijmpcall,
260 .jmpcall,
261 .lpm,
262 .lpmx,
263 .memmappedregs,
264 .movw,
265 .mul,
266 .rmw,
267 .spm,
268 .spmx,
269 .sram,
270 }),
271 };
272 result[@intFromEnum(Feature.spm)] = .{
273 .llvm_name = "spm",
274 .description = "The device supports the `SPM` instruction",
275 .dependencies = featureSet(&[_]Feature{}),
276 };
277 result[@intFromEnum(Feature.spmx)] = .{
278 .llvm_name = "spmx",
279 .description = "The device supports the `SPM Z+` instruction",
280 .dependencies = featureSet(&[_]Feature{}),
281 };
282 result[@intFromEnum(Feature.sram)] = .{
283 .llvm_name = "sram",
284 .description = "The device has random access memory",
285 .dependencies = featureSet(&[_]Feature{}),
286 };
287 result[@intFromEnum(Feature.tinyencoding)] = .{
288 .llvm_name = "tinyencoding",
289 .description = "The device has Tiny core specific instruction encodings",
290 .dependencies = featureSet(&[_]Feature{}),
291 };
292 result[@intFromEnum(Feature.xmega)] = .{
293 .llvm_name = "xmega",
294 .description = "The device is a part of the xmega family",
295 .dependencies = featureSet(&[_]Feature{
296 .addsubiw,
297 .avr0,
298 .@"break",
299 .des,
300 .eijmpcall,
301 .elpm,
302 .elpmx,
303 .ijmpcall,
304 .jmpcall,
305 .lowbytefirst,
306 .lpm,
307 .lpmx,
308 .movw,
309 .mul,
310 .spm,
311 .spmx,
312 .sram,
313 }),
314 };
315 result[@intFromEnum(Feature.xmega3)] = .{
316 .llvm_name = "xmega3",
317 .description = "The device is a part of the xmega3 family",
318 .dependencies = featureSet(&[_]Feature{
319 .addsubiw,
320 .avr0,
321 .@"break",
322 .ijmpcall,
323 .jmpcall,
324 .lowbytefirst,
325 .lpm,
326 .lpmx,
327 .movw,
328 .mul,
329 .sram,
330 }),
331 };
332 result[@intFromEnum(Feature.xmegau)] = .{
333 .llvm_name = "xmegau",
334 .description = "The device is a part of the xmegau family",
335 .dependencies = featureSet(&[_]Feature{
336 .rmw,
337 .xmega,
338 }),
339 };
340 const ti = @typeInfo(Feature);
341 for (&result, 0..) |*elem, i| {
342 elem.index = i;
343 elem.name = ti.Enum.fields[i].name;
344 }
345 break :blk result;
346};
347
348pub const cpu = struct {
349 pub const at43usb320 = CpuModel{
350 .name = "at43usb320",
351 .llvm_name = "at43usb320",
352 .features = featureSet(&[_]Feature{
353 .avr31,
354 }),
355 };
356 pub const at43usb355 = CpuModel{
357 .name = "at43usb355",
358 .llvm_name = "at43usb355",
359 .features = featureSet(&[_]Feature{
360 .avr3,
361 }),
362 };
363 pub const at76c711 = CpuModel{
364 .name = "at76c711",
365 .llvm_name = "at76c711",
366 .features = featureSet(&[_]Feature{
367 .avr3,
368 }),
369 };
370 pub const at86rf401 = CpuModel{
371 .name = "at86rf401",
372 .llvm_name = "at86rf401",
373 .features = featureSet(&[_]Feature{
374 .avr2,
375 .lpmx,
376 .movw,
377 }),
378 };
379 pub const at90c8534 = CpuModel{
380 .name = "at90c8534",
381 .llvm_name = "at90c8534",
382 .features = featureSet(&[_]Feature{
383 .avr2,
384 }),
385 };
386 pub const at90can128 = CpuModel{
387 .name = "at90can128",
388 .llvm_name = "at90can128",
389 .features = featureSet(&[_]Feature{
390 .avr51,
391 }),
392 };
393 pub const at90can32 = CpuModel{
394 .name = "at90can32",
395 .llvm_name = "at90can32",
396 .features = featureSet(&[_]Feature{
397 .avr5,
398 }),
399 };
400 pub const at90can64 = CpuModel{
401 .name = "at90can64",
402 .llvm_name = "at90can64",
403 .features = featureSet(&[_]Feature{
404 .avr5,
405 }),
406 };
407 pub const at90pwm1 = CpuModel{
408 .name = "at90pwm1",
409 .llvm_name = "at90pwm1",
410 .features = featureSet(&[_]Feature{
411 .avr4,
412 }),
413 };
414 pub const at90pwm161 = CpuModel{
415 .name = "at90pwm161",
416 .llvm_name = "at90pwm161",
417 .features = featureSet(&[_]Feature{
418 .avr5,
419 }),
420 };
421 pub const at90pwm2 = CpuModel{
422 .name = "at90pwm2",
423 .llvm_name = "at90pwm2",
424 .features = featureSet(&[_]Feature{
425 .avr4,
426 }),
427 };
428 pub const at90pwm216 = CpuModel{
429 .name = "at90pwm216",
430 .llvm_name = "at90pwm216",
431 .features = featureSet(&[_]Feature{
432 .avr5,
433 }),
434 };
435 pub const at90pwm2b = CpuModel{
436 .name = "at90pwm2b",
437 .llvm_name = "at90pwm2b",
438 .features = featureSet(&[_]Feature{
439 .avr4,
440 }),
441 };
442 pub const at90pwm3 = CpuModel{
443 .name = "at90pwm3",
444 .llvm_name = "at90pwm3",
445 .features = featureSet(&[_]Feature{
446 .avr4,
447 }),
448 };
449 pub const at90pwm316 = CpuModel{
450 .name = "at90pwm316",
451 .llvm_name = "at90pwm316",
452 .features = featureSet(&[_]Feature{
453 .avr5,
454 }),
455 };
456 pub const at90pwm3b = CpuModel{
457 .name = "at90pwm3b",
458 .llvm_name = "at90pwm3b",
459 .features = featureSet(&[_]Feature{
460 .avr4,
461 }),
462 };
463 pub const at90pwm81 = CpuModel{
464 .name = "at90pwm81",
465 .llvm_name = "at90pwm81",
466 .features = featureSet(&[_]Feature{
467 .avr4,
468 }),
469 };
470 pub const at90s1200 = CpuModel{
471 .name = "at90s1200",
472 .llvm_name = "at90s1200",
473 .features = featureSet(&[_]Feature{
474 .avr0,
475 .smallstack,
476 }),
477 };
478 pub const at90s2313 = CpuModel{
479 .name = "at90s2313",
480 .llvm_name = "at90s2313",
481 .features = featureSet(&[_]Feature{
482 .avr2,
483 .smallstack,
484 }),
485 };
486 pub const at90s2323 = CpuModel{
487 .name = "at90s2323",
488 .llvm_name = "at90s2323",
489 .features = featureSet(&[_]Feature{
490 .avr2,
491 .smallstack,
492 }),
493 };
494 pub const at90s2333 = CpuModel{
495 .name = "at90s2333",
496 .llvm_name = "at90s2333",
497 .features = featureSet(&[_]Feature{
498 .avr2,
499 .smallstack,
500 }),
501 };
502 pub const at90s2343 = CpuModel{
503 .name = "at90s2343",
504 .llvm_name = "at90s2343",
505 .features = featureSet(&[_]Feature{
506 .avr2,
507 .smallstack,
508 }),
509 };
510 pub const at90s4414 = CpuModel{
511 .name = "at90s4414",
512 .llvm_name = "at90s4414",
513 .features = featureSet(&[_]Feature{
514 .avr2,
515 .smallstack,
516 }),
517 };
518 pub const at90s4433 = CpuModel{
519 .name = "at90s4433",
520 .llvm_name = "at90s4433",
521 .features = featureSet(&[_]Feature{
522 .avr2,
523 .smallstack,
524 }),
525 };
526 pub const at90s4434 = CpuModel{
527 .name = "at90s4434",
528 .llvm_name = "at90s4434",
529 .features = featureSet(&[_]Feature{
530 .avr2,
531 .smallstack,
532 }),
533 };
534 pub const at90s8515 = CpuModel{
535 .name = "at90s8515",
536 .llvm_name = "at90s8515",
537 .features = featureSet(&[_]Feature{
538 .avr2,
539 }),
540 };
541 pub const at90s8535 = CpuModel{
542 .name = "at90s8535",
543 .llvm_name = "at90s8535",
544 .features = featureSet(&[_]Feature{
545 .avr2,
546 }),
547 };
548 pub const at90scr100 = CpuModel{
549 .name = "at90scr100",
550 .llvm_name = "at90scr100",
551 .features = featureSet(&[_]Feature{
552 .avr5,
553 }),
554 };
555 pub const at90usb1286 = CpuModel{
556 .name = "at90usb1286",
557 .llvm_name = "at90usb1286",
558 .features = featureSet(&[_]Feature{
559 .avr51,
560 }),
561 };
562 pub const at90usb1287 = CpuModel{
563 .name = "at90usb1287",
564 .llvm_name = "at90usb1287",
565 .features = featureSet(&[_]Feature{
566 .avr51,
567 }),
568 };
569 pub const at90usb162 = CpuModel{
570 .name = "at90usb162",
571 .llvm_name = "at90usb162",
572 .features = featureSet(&[_]Feature{
573 .avr35,
574 }),
575 };
576 pub const at90usb646 = CpuModel{
577 .name = "at90usb646",
578 .llvm_name = "at90usb646",
579 .features = featureSet(&[_]Feature{
580 .avr5,
581 }),
582 };
583 pub const at90usb647 = CpuModel{
584 .name = "at90usb647",
585 .llvm_name = "at90usb647",
586 .features = featureSet(&[_]Feature{
587 .avr5,
588 }),
589 };
590 pub const at90usb82 = CpuModel{
591 .name = "at90usb82",
592 .llvm_name = "at90usb82",
593 .features = featureSet(&[_]Feature{
594 .avr35,
595 }),
596 };
597 pub const at94k = CpuModel{
598 .name = "at94k",
599 .llvm_name = "at94k",
600 .features = featureSet(&[_]Feature{
601 .avr3,
602 .lpmx,
603 .movw,
604 .mul,
605 }),
606 };
607 pub const ata5272 = CpuModel{
608 .name = "ata5272",
609 .llvm_name = "ata5272",
610 .features = featureSet(&[_]Feature{
611 .avr25,
612 }),
613 };
614 pub const ata5505 = CpuModel{
615 .name = "ata5505",
616 .llvm_name = "ata5505",
617 .features = featureSet(&[_]Feature{
618 .avr35,
619 }),
620 };
621 pub const ata5702m322 = CpuModel{
622 .name = "ata5702m322",
623 .llvm_name = "ata5702m322",
624 .features = featureSet(&[_]Feature{
625 .avr5,
626 }),
627 };
628 pub const ata5782 = CpuModel{
629 .name = "ata5782",
630 .llvm_name = "ata5782",
631 .features = featureSet(&[_]Feature{
632 .avr5,
633 }),
634 };
635 pub const ata5790 = CpuModel{
636 .name = "ata5790",
637 .llvm_name = "ata5790",
638 .features = featureSet(&[_]Feature{
639 .avr5,
640 }),
641 };
642 pub const ata5790n = CpuModel{
643 .name = "ata5790n",
644 .llvm_name = "ata5790n",
645 .features = featureSet(&[_]Feature{
646 .avr5,
647 }),
648 };
649 pub const ata5791 = CpuModel{
650 .name = "ata5791",
651 .llvm_name = "ata5791",
652 .features = featureSet(&[_]Feature{
653 .avr5,
654 }),
655 };
656 pub const ata5795 = CpuModel{
657 .name = "ata5795",
658 .llvm_name = "ata5795",
659 .features = featureSet(&[_]Feature{
660 .avr5,
661 }),
662 };
663 pub const ata5831 = CpuModel{
664 .name = "ata5831",
665 .llvm_name = "ata5831",
666 .features = featureSet(&[_]Feature{
667 .avr5,
668 }),
669 };
670 pub const ata6285 = CpuModel{
671 .name = "ata6285",
672 .llvm_name = "ata6285",
673 .features = featureSet(&[_]Feature{
674 .avr4,
675 }),
676 };
677 pub const ata6286 = CpuModel{
678 .name = "ata6286",
679 .llvm_name = "ata6286",
680 .features = featureSet(&[_]Feature{
681 .avr4,
682 }),
683 };
684 pub const ata6289 = CpuModel{
685 .name = "ata6289",
686 .llvm_name = "ata6289",
687 .features = featureSet(&[_]Feature{
688 .avr4,
689 }),
690 };
691 pub const ata6612c = CpuModel{
692 .name = "ata6612c",
693 .llvm_name = "ata6612c",
694 .features = featureSet(&[_]Feature{
695 .avr4,
696 }),
697 };
698 pub const ata6613c = CpuModel{
699 .name = "ata6613c",
700 .llvm_name = "ata6613c",
701 .features = featureSet(&[_]Feature{
702 .avr5,
703 }),
704 };
705 pub const ata6614q = CpuModel{
706 .name = "ata6614q",
707 .llvm_name = "ata6614q",
708 .features = featureSet(&[_]Feature{
709 .avr5,
710 }),
711 };
712 pub const ata6616c = CpuModel{
713 .name = "ata6616c",
714 .llvm_name = "ata6616c",
715 .features = featureSet(&[_]Feature{
716 .avr25,
717 }),
718 };
719 pub const ata6617c = CpuModel{
720 .name = "ata6617c",
721 .llvm_name = "ata6617c",
722 .features = featureSet(&[_]Feature{
723 .avr35,
724 }),
725 };
726 pub const ata664251 = CpuModel{
727 .name = "ata664251",
728 .llvm_name = "ata664251",
729 .features = featureSet(&[_]Feature{
730 .avr35,
731 }),
732 };
733 pub const ata8210 = CpuModel{
734 .name = "ata8210",
735 .llvm_name = "ata8210",
736 .features = featureSet(&[_]Feature{
737 .avr5,
738 }),
739 };
740 pub const ata8510 = CpuModel{
741 .name = "ata8510",
742 .llvm_name = "ata8510",
743 .features = featureSet(&[_]Feature{
744 .avr5,
745 }),
746 };
747 pub const atmega103 = CpuModel{
748 .name = "atmega103",
749 .llvm_name = "atmega103",
750 .features = featureSet(&[_]Feature{
751 .avr31,
752 }),
753 };
754 pub const atmega128 = CpuModel{
755 .name = "atmega128",
756 .llvm_name = "atmega128",
757 .features = featureSet(&[_]Feature{
758 .avr51,
759 }),
760 };
761 pub const atmega1280 = CpuModel{
762 .name = "atmega1280",
763 .llvm_name = "atmega1280",
764 .features = featureSet(&[_]Feature{
765 .avr51,
766 }),
767 };
768 pub const atmega1281 = CpuModel{
769 .name = "atmega1281",
770 .llvm_name = "atmega1281",
771 .features = featureSet(&[_]Feature{
772 .avr51,
773 }),
774 };
775 pub const atmega1284 = CpuModel{
776 .name = "atmega1284",
777 .llvm_name = "atmega1284",
778 .features = featureSet(&[_]Feature{
779 .avr51,
780 }),
781 };
782 pub const atmega1284p = CpuModel{
783 .name = "atmega1284p",
784 .llvm_name = "atmega1284p",
785 .features = featureSet(&[_]Feature{
786 .avr51,
787 }),
788 };
789 pub const atmega1284rfr2 = CpuModel{
790 .name = "atmega1284rfr2",
791 .llvm_name = "atmega1284rfr2",
792 .features = featureSet(&[_]Feature{
793 .avr51,
794 }),
795 };
796 pub const atmega128a = CpuModel{
797 .name = "atmega128a",
798 .llvm_name = "atmega128a",
799 .features = featureSet(&[_]Feature{
800 .avr51,
801 }),
802 };
803 pub const atmega128rfa1 = CpuModel{
804 .name = "atmega128rfa1",
805 .llvm_name = "atmega128rfa1",
806 .features = featureSet(&[_]Feature{
807 .avr51,
808 }),
809 };
810 pub const atmega128rfr2 = CpuModel{
811 .name = "atmega128rfr2",
812 .llvm_name = "atmega128rfr2",
813 .features = featureSet(&[_]Feature{
814 .avr51,
815 }),
816 };
817 pub const atmega16 = CpuModel{
818 .name = "atmega16",
819 .llvm_name = "atmega16",
820 .features = featureSet(&[_]Feature{
821 .avr5,
822 }),
823 };
824 pub const atmega1608 = CpuModel{
825 .name = "atmega1608",
826 .llvm_name = "atmega1608",
827 .features = featureSet(&[_]Feature{
828 .xmega3,
829 }),
830 };
831 pub const atmega1609 = CpuModel{
832 .name = "atmega1609",
833 .llvm_name = "atmega1609",
834 .features = featureSet(&[_]Feature{
835 .xmega3,
836 }),
837 };
838 pub const atmega161 = CpuModel{
839 .name = "atmega161",
840 .llvm_name = "atmega161",
841 .features = featureSet(&[_]Feature{
842 .avr3,
843 .lpmx,
844 .movw,
845 .mul,
846 .spm,
847 }),
848 };
849 pub const atmega162 = CpuModel{
850 .name = "atmega162",
851 .llvm_name = "atmega162",
852 .features = featureSet(&[_]Feature{
853 .avr5,
854 }),
855 };
856 pub const atmega163 = CpuModel{
857 .name = "atmega163",
858 .llvm_name = "atmega163",
859 .features = featureSet(&[_]Feature{
860 .avr3,
861 .lpmx,
862 .movw,
863 .mul,
864 .spm,
865 }),
866 };
867 pub const atmega164a = CpuModel{
868 .name = "atmega164a",
869 .llvm_name = "atmega164a",
870 .features = featureSet(&[_]Feature{
871 .avr5,
872 }),
873 };
874 pub const atmega164p = CpuModel{
875 .name = "atmega164p",
876 .llvm_name = "atmega164p",
877 .features = featureSet(&[_]Feature{
878 .avr5,
879 }),
880 };
881 pub const atmega164pa = CpuModel{
882 .name = "atmega164pa",
883 .llvm_name = "atmega164pa",
884 .features = featureSet(&[_]Feature{
885 .avr5,
886 }),
887 };
888 pub const atmega165 = CpuModel{
889 .name = "atmega165",
890 .llvm_name = "atmega165",
891 .features = featureSet(&[_]Feature{
892 .avr5,
893 }),
894 };
895 pub const atmega165a = CpuModel{
896 .name = "atmega165a",
897 .llvm_name = "atmega165a",
898 .features = featureSet(&[_]Feature{
899 .avr5,
900 }),
901 };
902 pub const atmega165p = CpuModel{
903 .name = "atmega165p",
904 .llvm_name = "atmega165p",
905 .features = featureSet(&[_]Feature{
906 .avr5,
907 }),
908 };
909 pub const atmega165pa = CpuModel{
910 .name = "atmega165pa",
911 .llvm_name = "atmega165pa",
912 .features = featureSet(&[_]Feature{
913 .avr5,
914 }),
915 };
916 pub const atmega168 = CpuModel{
917 .name = "atmega168",
918 .llvm_name = "atmega168",
919 .features = featureSet(&[_]Feature{
920 .avr5,
921 }),
922 };
923 pub const atmega168a = CpuModel{
924 .name = "atmega168a",
925 .llvm_name = "atmega168a",
926 .features = featureSet(&[_]Feature{
927 .avr5,
928 }),
929 };
930 pub const atmega168p = CpuModel{
931 .name = "atmega168p",
932 .llvm_name = "atmega168p",
933 .features = featureSet(&[_]Feature{
934 .avr5,
935 }),
936 };
937 pub const atmega168pa = CpuModel{
938 .name = "atmega168pa",
939 .llvm_name = "atmega168pa",
940 .features = featureSet(&[_]Feature{
941 .avr5,
942 }),
943 };
944 pub const atmega168pb = CpuModel{
945 .name = "atmega168pb",
946 .llvm_name = "atmega168pb",
947 .features = featureSet(&[_]Feature{
948 .avr5,
949 }),
950 };
951 pub const atmega169 = CpuModel{
952 .name = "atmega169",
953 .llvm_name = "atmega169",
954 .features = featureSet(&[_]Feature{
955 .avr5,
956 }),
957 };
958 pub const atmega169a = CpuModel{
959 .name = "atmega169a",
960 .llvm_name = "atmega169a",
961 .features = featureSet(&[_]Feature{
962 .avr5,
963 }),
964 };
965 pub const atmega169p = CpuModel{
966 .name = "atmega169p",
967 .llvm_name = "atmega169p",
968 .features = featureSet(&[_]Feature{
969 .avr5,
970 }),
971 };
972 pub const atmega169pa = CpuModel{
973 .name = "atmega169pa",
974 .llvm_name = "atmega169pa",
975 .features = featureSet(&[_]Feature{
976 .avr5,
977 }),
978 };
979 pub const atmega16a = CpuModel{
980 .name = "atmega16a",
981 .llvm_name = "atmega16a",
982 .features = featureSet(&[_]Feature{
983 .avr5,
984 }),
985 };
986 pub const atmega16hva = CpuModel{
987 .name = "atmega16hva",
988 .llvm_name = "atmega16hva",
989 .features = featureSet(&[_]Feature{
990 .avr5,
991 }),
992 };
993 pub const atmega16hva2 = CpuModel{
994 .name = "atmega16hva2",
995 .llvm_name = "atmega16hva2",
996 .features = featureSet(&[_]Feature{
997 .avr5,
998 }),
999 };
1000 pub const atmega16hvb = CpuModel{
1001 .name = "atmega16hvb",
1002 .llvm_name = "atmega16hvb",
1003 .features = featureSet(&[_]Feature{
1004 .avr5,
1005 }),
1006 };
1007 pub const atmega16hvbrevb = CpuModel{
1008 .name = "atmega16hvbrevb",
1009 .llvm_name = "atmega16hvbrevb",
1010 .features = featureSet(&[_]Feature{
1011 .avr5,
1012 }),
1013 };
1014 pub const atmega16m1 = CpuModel{
1015 .name = "atmega16m1",
1016 .llvm_name = "atmega16m1",
1017 .features = featureSet(&[_]Feature{
1018 .avr5,
1019 }),
1020 };
1021 pub const atmega16u2 = CpuModel{
1022 .name = "atmega16u2",
1023 .llvm_name = "atmega16u2",
1024 .features = featureSet(&[_]Feature{
1025 .avr35,
1026 }),
1027 };
1028 pub const atmega16u4 = CpuModel{
1029 .name = "atmega16u4",
1030 .llvm_name = "atmega16u4",
1031 .features = featureSet(&[_]Feature{
1032 .avr5,
1033 }),
1034 };
1035 pub const atmega2560 = CpuModel{
1036 .name = "atmega2560",
1037 .llvm_name = "atmega2560",
1038 .features = featureSet(&[_]Feature{
1039 .avr6,
1040 }),
1041 };
1042 pub const atmega2561 = CpuModel{
1043 .name = "atmega2561",
1044 .llvm_name = "atmega2561",
1045 .features = featureSet(&[_]Feature{
1046 .avr6,
1047 }),
1048 };
1049 pub const atmega2564rfr2 = CpuModel{
1050 .name = "atmega2564rfr2",
1051 .llvm_name = "atmega2564rfr2",
1052 .features = featureSet(&[_]Feature{
1053 .avr6,
1054 }),
1055 };
1056 pub const atmega256rfr2 = CpuModel{
1057 .name = "atmega256rfr2",
1058 .llvm_name = "atmega256rfr2",
1059 .features = featureSet(&[_]Feature{
1060 .avr6,
1061 }),
1062 };
1063 pub const atmega32 = CpuModel{
1064 .name = "atmega32",
1065 .llvm_name = "atmega32",
1066 .features = featureSet(&[_]Feature{
1067 .avr5,
1068 }),
1069 };
1070 pub const atmega3208 = CpuModel{
1071 .name = "atmega3208",
1072 .llvm_name = "atmega3208",
1073 .features = featureSet(&[_]Feature{
1074 .xmega3,
1075 }),
1076 };
1077 pub const atmega3209 = CpuModel{
1078 .name = "atmega3209",
1079 .llvm_name = "atmega3209",
1080 .features = featureSet(&[_]Feature{
1081 .xmega3,
1082 }),
1083 };
1084 pub const atmega323 = CpuModel{
1085 .name = "atmega323",
1086 .llvm_name = "atmega323",
1087 .features = featureSet(&[_]Feature{
1088 .avr5,
1089 }),
1090 };
1091 pub const atmega324a = CpuModel{
1092 .name = "atmega324a",
1093 .llvm_name = "atmega324a",
1094 .features = featureSet(&[_]Feature{
1095 .avr5,
1096 }),
1097 };
1098 pub const atmega324p = CpuModel{
1099 .name = "atmega324p",
1100 .llvm_name = "atmega324p",
1101 .features = featureSet(&[_]Feature{
1102 .avr5,
1103 }),
1104 };
1105 pub const atmega324pa = CpuModel{
1106 .name = "atmega324pa",
1107 .llvm_name = "atmega324pa",
1108 .features = featureSet(&[_]Feature{
1109 .avr5,
1110 }),
1111 };
1112 pub const atmega324pb = CpuModel{
1113 .name = "atmega324pb",
1114 .llvm_name = "atmega324pb",
1115 .features = featureSet(&[_]Feature{
1116 .avr5,
1117 }),
1118 };
1119 pub const atmega325 = CpuModel{
1120 .name = "atmega325",
1121 .llvm_name = "atmega325",
1122 .features = featureSet(&[_]Feature{
1123 .avr5,
1124 }),
1125 };
1126 pub const atmega3250 = CpuModel{
1127 .name = "atmega3250",
1128 .llvm_name = "atmega3250",
1129 .features = featureSet(&[_]Feature{
1130 .avr5,
1131 }),
1132 };
1133 pub const atmega3250a = CpuModel{
1134 .name = "atmega3250a",
1135 .llvm_name = "atmega3250a",
1136 .features = featureSet(&[_]Feature{
1137 .avr5,
1138 }),
1139 };
1140 pub const atmega3250p = CpuModel{
1141 .name = "atmega3250p",
1142 .llvm_name = "atmega3250p",
1143 .features = featureSet(&[_]Feature{
1144 .avr5,
1145 }),
1146 };
1147 pub const atmega3250pa = CpuModel{
1148 .name = "atmega3250pa",
1149 .llvm_name = "atmega3250pa",
1150 .features = featureSet(&[_]Feature{
1151 .avr5,
1152 }),
1153 };
1154 pub const atmega325a = CpuModel{
1155 .name = "atmega325a",
1156 .llvm_name = "atmega325a",
1157 .features = featureSet(&[_]Feature{
1158 .avr5,
1159 }),
1160 };
1161 pub const atmega325p = CpuModel{
1162 .name = "atmega325p",
1163 .llvm_name = "atmega325p",
1164 .features = featureSet(&[_]Feature{
1165 .avr5,
1166 }),
1167 };
1168 pub const atmega325pa = CpuModel{
1169 .name = "atmega325pa",
1170 .llvm_name = "atmega325pa",
1171 .features = featureSet(&[_]Feature{
1172 .avr5,
1173 }),
1174 };
1175 pub const atmega328 = CpuModel{
1176 .name = "atmega328",
1177 .llvm_name = "atmega328",
1178 .features = featureSet(&[_]Feature{
1179 .avr5,
1180 }),
1181 };
1182 pub const atmega328p = CpuModel{
1183 .name = "atmega328p",
1184 .llvm_name = "atmega328p",
1185 .features = featureSet(&[_]Feature{
1186 .avr5,
1187 }),
1188 };
1189 pub const atmega328pb = CpuModel{
1190 .name = "atmega328pb",
1191 .llvm_name = "atmega328pb",
1192 .features = featureSet(&[_]Feature{
1193 .avr5,
1194 }),
1195 };
1196 pub const atmega329 = CpuModel{
1197 .name = "atmega329",
1198 .llvm_name = "atmega329",
1199 .features = featureSet(&[_]Feature{
1200 .avr5,
1201 }),
1202 };
1203 pub const atmega3290 = CpuModel{
1204 .name = "atmega3290",
1205 .llvm_name = "atmega3290",
1206 .features = featureSet(&[_]Feature{
1207 .avr5,
1208 }),
1209 };
1210 pub const atmega3290a = CpuModel{
1211 .name = "atmega3290a",
1212 .llvm_name = "atmega3290a",
1213 .features = featureSet(&[_]Feature{
1214 .avr5,
1215 }),
1216 };
1217 pub const atmega3290p = CpuModel{
1218 .name = "atmega3290p",
1219 .llvm_name = "atmega3290p",
1220 .features = featureSet(&[_]Feature{
1221 .avr5,
1222 }),
1223 };
1224 pub const atmega3290pa = CpuModel{
1225 .name = "atmega3290pa",
1226 .llvm_name = "atmega3290pa",
1227 .features = featureSet(&[_]Feature{
1228 .avr5,
1229 }),
1230 };
1231 pub const atmega329a = CpuModel{
1232 .name = "atmega329a",
1233 .llvm_name = "atmega329a",
1234 .features = featureSet(&[_]Feature{
1235 .avr5,
1236 }),
1237 };
1238 pub const atmega329p = CpuModel{
1239 .name = "atmega329p",
1240 .llvm_name = "atmega329p",
1241 .features = featureSet(&[_]Feature{
1242 .avr5,
1243 }),
1244 };
1245 pub const atmega329pa = CpuModel{
1246 .name = "atmega329pa",
1247 .llvm_name = "atmega329pa",
1248 .features = featureSet(&[_]Feature{
1249 .avr5,
1250 }),
1251 };
1252 pub const atmega32a = CpuModel{
1253 .name = "atmega32a",
1254 .llvm_name = "atmega32a",
1255 .features = featureSet(&[_]Feature{
1256 .avr5,
1257 }),
1258 };
1259 pub const atmega32c1 = CpuModel{
1260 .name = "atmega32c1",
1261 .llvm_name = "atmega32c1",
1262 .features = featureSet(&[_]Feature{
1263 .avr5,
1264 }),
1265 };
1266 pub const atmega32hvb = CpuModel{
1267 .name = "atmega32hvb",
1268 .llvm_name = "atmega32hvb",
1269 .features = featureSet(&[_]Feature{
1270 .avr5,
1271 }),
1272 };
1273 pub const atmega32hvbrevb = CpuModel{
1274 .name = "atmega32hvbrevb",
1275 .llvm_name = "atmega32hvbrevb",
1276 .features = featureSet(&[_]Feature{
1277 .avr5,
1278 }),
1279 };
1280 pub const atmega32m1 = CpuModel{
1281 .name = "atmega32m1",
1282 .llvm_name = "atmega32m1",
1283 .features = featureSet(&[_]Feature{
1284 .avr5,
1285 }),
1286 };
1287 pub const atmega32u2 = CpuModel{
1288 .name = "atmega32u2",
1289 .llvm_name = "atmega32u2",
1290 .features = featureSet(&[_]Feature{
1291 .avr35,
1292 }),
1293 };
1294 pub const atmega32u4 = CpuModel{
1295 .name = "atmega32u4",
1296 .llvm_name = "atmega32u4",
1297 .features = featureSet(&[_]Feature{
1298 .avr5,
1299 }),
1300 };
1301 pub const atmega32u6 = CpuModel{
1302 .name = "atmega32u6",
1303 .llvm_name = "atmega32u6",
1304 .features = featureSet(&[_]Feature{
1305 .avr5,
1306 }),
1307 };
1308 pub const atmega406 = CpuModel{
1309 .name = "atmega406",
1310 .llvm_name = "atmega406",
1311 .features = featureSet(&[_]Feature{
1312 .avr5,
1313 }),
1314 };
1315 pub const atmega48 = CpuModel{
1316 .name = "atmega48",
1317 .llvm_name = "atmega48",
1318 .features = featureSet(&[_]Feature{
1319 .avr4,
1320 }),
1321 };
1322 pub const atmega4808 = CpuModel{
1323 .name = "atmega4808",
1324 .llvm_name = "atmega4808",
1325 .features = featureSet(&[_]Feature{
1326 .xmega3,
1327 }),
1328 };
1329 pub const atmega4809 = CpuModel{
1330 .name = "atmega4809",
1331 .llvm_name = "atmega4809",
1332 .features = featureSet(&[_]Feature{
1333 .xmega3,
1334 }),
1335 };
1336 pub const atmega48a = CpuModel{
1337 .name = "atmega48a",
1338 .llvm_name = "atmega48a",
1339 .features = featureSet(&[_]Feature{
1340 .avr4,
1341 }),
1342 };
1343 pub const atmega48p = CpuModel{
1344 .name = "atmega48p",
1345 .llvm_name = "atmega48p",
1346 .features = featureSet(&[_]Feature{
1347 .avr4,
1348 }),
1349 };
1350 pub const atmega48pa = CpuModel{
1351 .name = "atmega48pa",
1352 .llvm_name = "atmega48pa",
1353 .features = featureSet(&[_]Feature{
1354 .avr4,
1355 }),
1356 };
1357 pub const atmega48pb = CpuModel{
1358 .name = "atmega48pb",
1359 .llvm_name = "atmega48pb",
1360 .features = featureSet(&[_]Feature{
1361 .avr4,
1362 }),
1363 };
1364 pub const atmega64 = CpuModel{
1365 .name = "atmega64",
1366 .llvm_name = "atmega64",
1367 .features = featureSet(&[_]Feature{
1368 .avr5,
1369 }),
1370 };
1371 pub const atmega640 = CpuModel{
1372 .name = "atmega640",
1373 .llvm_name = "atmega640",
1374 .features = featureSet(&[_]Feature{
1375 .avr5,
1376 }),
1377 };
1378 pub const atmega644 = CpuModel{
1379 .name = "atmega644",
1380 .llvm_name = "atmega644",
1381 .features = featureSet(&[_]Feature{
1382 .avr5,
1383 }),
1384 };
1385 pub const atmega644a = CpuModel{
1386 .name = "atmega644a",
1387 .llvm_name = "atmega644a",
1388 .features = featureSet(&[_]Feature{
1389 .avr5,
1390 }),
1391 };
1392 pub const atmega644p = CpuModel{
1393 .name = "atmega644p",
1394 .llvm_name = "atmega644p",
1395 .features = featureSet(&[_]Feature{
1396 .avr5,
1397 }),
1398 };
1399 pub const atmega644pa = CpuModel{
1400 .name = "atmega644pa",
1401 .llvm_name = "atmega644pa",
1402 .features = featureSet(&[_]Feature{
1403 .avr5,
1404 }),
1405 };
1406 pub const atmega644rfr2 = CpuModel{
1407 .name = "atmega644rfr2",
1408 .llvm_name = "atmega644rfr2",
1409 .features = featureSet(&[_]Feature{
1410 .avr5,
1411 }),
1412 };
1413 pub const atmega645 = CpuModel{
1414 .name = "atmega645",
1415 .llvm_name = "atmega645",
1416 .features = featureSet(&[_]Feature{
1417 .avr5,
1418 }),
1419 };
1420 pub const atmega6450 = CpuModel{
1421 .name = "atmega6450",
1422 .llvm_name = "atmega6450",
1423 .features = featureSet(&[_]Feature{
1424 .avr5,
1425 }),
1426 };
1427 pub const atmega6450a = CpuModel{
1428 .name = "atmega6450a",
1429 .llvm_name = "atmega6450a",
1430 .features = featureSet(&[_]Feature{
1431 .avr5,
1432 }),
1433 };
1434 pub const atmega6450p = CpuModel{
1435 .name = "atmega6450p",
1436 .llvm_name = "atmega6450p",
1437 .features = featureSet(&[_]Feature{
1438 .avr5,
1439 }),
1440 };
1441 pub const atmega645a = CpuModel{
1442 .name = "atmega645a",
1443 .llvm_name = "atmega645a",
1444 .features = featureSet(&[_]Feature{
1445 .avr5,
1446 }),
1447 };
1448 pub const atmega645p = CpuModel{
1449 .name = "atmega645p",
1450 .llvm_name = "atmega645p",
1451 .features = featureSet(&[_]Feature{
1452 .avr5,
1453 }),
1454 };
1455 pub const atmega649 = CpuModel{
1456 .name = "atmega649",
1457 .llvm_name = "atmega649",
1458 .features = featureSet(&[_]Feature{
1459 .avr5,
1460 }),
1461 };
1462 pub const atmega6490 = CpuModel{
1463 .name = "atmega6490",
1464 .llvm_name = "atmega6490",
1465 .features = featureSet(&[_]Feature{
1466 .avr5,
1467 }),
1468 };
1469 pub const atmega6490a = CpuModel{
1470 .name = "atmega6490a",
1471 .llvm_name = "atmega6490a",
1472 .features = featureSet(&[_]Feature{
1473 .avr5,
1474 }),
1475 };
1476 pub const atmega6490p = CpuModel{
1477 .name = "atmega6490p",
1478 .llvm_name = "atmega6490p",
1479 .features = featureSet(&[_]Feature{
1480 .avr5,
1481 }),
1482 };
1483 pub const atmega649a = CpuModel{
1484 .name = "atmega649a",
1485 .llvm_name = "atmega649a",
1486 .features = featureSet(&[_]Feature{
1487 .avr5,
1488 }),
1489 };
1490 pub const atmega649p = CpuModel{
1491 .name = "atmega649p",
1492 .llvm_name = "atmega649p",
1493 .features = featureSet(&[_]Feature{
1494 .avr5,
1495 }),
1496 };
1497 pub const atmega64a = CpuModel{
1498 .name = "atmega64a",
1499 .llvm_name = "atmega64a",
1500 .features = featureSet(&[_]Feature{
1501 .avr5,
1502 }),
1503 };
1504 pub const atmega64c1 = CpuModel{
1505 .name = "atmega64c1",
1506 .llvm_name = "atmega64c1",
1507 .features = featureSet(&[_]Feature{
1508 .avr5,
1509 }),
1510 };
1511 pub const atmega64hve = CpuModel{
1512 .name = "atmega64hve",
1513 .llvm_name = "atmega64hve",
1514 .features = featureSet(&[_]Feature{
1515 .avr5,
1516 }),
1517 };
1518 pub const atmega64hve2 = CpuModel{
1519 .name = "atmega64hve2",
1520 .llvm_name = "atmega64hve2",
1521 .features = featureSet(&[_]Feature{
1522 .avr5,
1523 }),
1524 };
1525 pub const atmega64m1 = CpuModel{
1526 .name = "atmega64m1",
1527 .llvm_name = "atmega64m1",
1528 .features = featureSet(&[_]Feature{
1529 .avr5,
1530 }),
1531 };
1532 pub const atmega64rfr2 = CpuModel{
1533 .name = "atmega64rfr2",
1534 .llvm_name = "atmega64rfr2",
1535 .features = featureSet(&[_]Feature{
1536 .avr5,
1537 }),
1538 };
1539 pub const atmega8 = CpuModel{
1540 .name = "atmega8",
1541 .llvm_name = "atmega8",
1542 .features = featureSet(&[_]Feature{
1543 .avr2,
1544 .lpmx,
1545 .movw,
1546 .mul,
1547 .spm,
1548 }),
1549 };
1550 pub const atmega808 = CpuModel{
1551 .name = "atmega808",
1552 .llvm_name = "atmega808",
1553 .features = featureSet(&[_]Feature{
1554 .xmega3,
1555 }),
1556 };
1557 pub const atmega809 = CpuModel{
1558 .name = "atmega809",
1559 .llvm_name = "atmega809",
1560 .features = featureSet(&[_]Feature{
1561 .xmega3,
1562 }),
1563 };
1564 pub const atmega8515 = CpuModel{
1565 .name = "atmega8515",
1566 .llvm_name = "atmega8515",
1567 .features = featureSet(&[_]Feature{
1568 .avr2,
1569 .lpmx,
1570 .movw,
1571 .mul,
1572 .spm,
1573 }),
1574 };
1575 pub const atmega8535 = CpuModel{
1576 .name = "atmega8535",
1577 .llvm_name = "atmega8535",
1578 .features = featureSet(&[_]Feature{
1579 .avr2,
1580 .lpmx,
1581 .movw,
1582 .mul,
1583 .spm,
1584 }),
1585 };
1586 pub const atmega88 = CpuModel{
1587 .name = "atmega88",
1588 .llvm_name = "atmega88",
1589 .features = featureSet(&[_]Feature{
1590 .avr4,
1591 }),
1592 };
1593 pub const atmega88a = CpuModel{
1594 .name = "atmega88a",
1595 .llvm_name = "atmega88a",
1596 .features = featureSet(&[_]Feature{
1597 .avr4,
1598 }),
1599 };
1600 pub const atmega88p = CpuModel{
1601 .name = "atmega88p",
1602 .llvm_name = "atmega88p",
1603 .features = featureSet(&[_]Feature{
1604 .avr4,
1605 }),
1606 };
1607 pub const atmega88pa = CpuModel{
1608 .name = "atmega88pa",
1609 .llvm_name = "atmega88pa",
1610 .features = featureSet(&[_]Feature{
1611 .avr4,
1612 }),
1613 };
1614 pub const atmega88pb = CpuModel{
1615 .name = "atmega88pb",
1616 .llvm_name = "atmega88pb",
1617 .features = featureSet(&[_]Feature{
1618 .avr4,
1619 }),
1620 };
1621 pub const atmega8a = CpuModel{
1622 .name = "atmega8a",
1623 .llvm_name = "atmega8a",
1624 .features = featureSet(&[_]Feature{
1625 .avr2,
1626 .lpmx,
1627 .movw,
1628 .mul,
1629 .spm,
1630 }),
1631 };
1632 pub const atmega8hva = CpuModel{
1633 .name = "atmega8hva",
1634 .llvm_name = "atmega8hva",
1635 .features = featureSet(&[_]Feature{
1636 .avr4,
1637 }),
1638 };
1639 pub const atmega8u2 = CpuModel{
1640 .name = "atmega8u2",
1641 .llvm_name = "atmega8u2",
1642 .features = featureSet(&[_]Feature{
1643 .avr35,
1644 }),
1645 };
1646 pub const attiny10 = CpuModel{
1647 .name = "attiny10",
1648 .llvm_name = "attiny10",
1649 .features = featureSet(&[_]Feature{
1650 .avrtiny,
1651 }),
1652 };
1653 pub const attiny102 = CpuModel{
1654 .name = "attiny102",
1655 .llvm_name = "attiny102",
1656 .features = featureSet(&[_]Feature{
1657 .avrtiny,
1658 }),
1659 };
1660 pub const attiny104 = CpuModel{
1661 .name = "attiny104",
1662 .llvm_name = "attiny104",
1663 .features = featureSet(&[_]Feature{
1664 .avrtiny,
1665 }),
1666 };
1667 pub const attiny11 = CpuModel{
1668 .name = "attiny11",
1669 .llvm_name = "attiny11",
1670 .features = featureSet(&[_]Feature{
1671 .avr1,
1672 .smallstack,
1673 }),
1674 };
1675 pub const attiny12 = CpuModel{
1676 .name = "attiny12",
1677 .llvm_name = "attiny12",
1678 .features = featureSet(&[_]Feature{
1679 .avr1,
1680 .smallstack,
1681 }),
1682 };
1683 pub const attiny13 = CpuModel{
1684 .name = "attiny13",
1685 .llvm_name = "attiny13",
1686 .features = featureSet(&[_]Feature{
1687 .avr25,
1688 .smallstack,
1689 }),
1690 };
1691 pub const attiny13a = CpuModel{
1692 .name = "attiny13a",
1693 .llvm_name = "attiny13a",
1694 .features = featureSet(&[_]Feature{
1695 .avr25,
1696 .smallstack,
1697 }),
1698 };
1699 pub const attiny15 = CpuModel{
1700 .name = "attiny15",
1701 .llvm_name = "attiny15",
1702 .features = featureSet(&[_]Feature{
1703 .avr1,
1704 .smallstack,
1705 }),
1706 };
1707 pub const attiny1604 = CpuModel{
1708 .name = "attiny1604",
1709 .llvm_name = "attiny1604",
1710 .features = featureSet(&[_]Feature{
1711 .xmega3,
1712 }),
1713 };
1714 pub const attiny1606 = CpuModel{
1715 .name = "attiny1606",
1716 .llvm_name = "attiny1606",
1717 .features = featureSet(&[_]Feature{
1718 .xmega3,
1719 }),
1720 };
1721 pub const attiny1607 = CpuModel{
1722 .name = "attiny1607",
1723 .llvm_name = "attiny1607",
1724 .features = featureSet(&[_]Feature{
1725 .xmega3,
1726 }),
1727 };
1728 pub const attiny1614 = CpuModel{
1729 .name = "attiny1614",
1730 .llvm_name = "attiny1614",
1731 .features = featureSet(&[_]Feature{
1732 .xmega3,
1733 }),
1734 };
1735 pub const attiny1616 = CpuModel{
1736 .name = "attiny1616",
1737 .llvm_name = "attiny1616",
1738 .features = featureSet(&[_]Feature{
1739 .xmega3,
1740 }),
1741 };
1742 pub const attiny1617 = CpuModel{
1743 .name = "attiny1617",
1744 .llvm_name = "attiny1617",
1745 .features = featureSet(&[_]Feature{
1746 .xmega3,
1747 }),
1748 };
1749 pub const attiny1624 = CpuModel{
1750 .name = "attiny1624",
1751 .llvm_name = "attiny1624",
1752 .features = featureSet(&[_]Feature{
1753 .xmega3,
1754 }),
1755 };
1756 pub const attiny1626 = CpuModel{
1757 .name = "attiny1626",
1758 .llvm_name = "attiny1626",
1759 .features = featureSet(&[_]Feature{
1760 .xmega3,
1761 }),
1762 };
1763 pub const attiny1627 = CpuModel{
1764 .name = "attiny1627",
1765 .llvm_name = "attiny1627",
1766 .features = featureSet(&[_]Feature{
1767 .xmega3,
1768 }),
1769 };
1770 pub const attiny1634 = CpuModel{
1771 .name = "attiny1634",
1772 .llvm_name = "attiny1634",
1773 .features = featureSet(&[_]Feature{
1774 .avr35,
1775 }),
1776 };
1777 pub const attiny167 = CpuModel{
1778 .name = "attiny167",
1779 .llvm_name = "attiny167",
1780 .features = featureSet(&[_]Feature{
1781 .avr35,
1782 }),
1783 };
1784 pub const attiny20 = CpuModel{
1785 .name = "attiny20",
1786 .llvm_name = "attiny20",
1787 .features = featureSet(&[_]Feature{
1788 .avrtiny,
1789 }),
1790 };
1791 pub const attiny202 = CpuModel{
1792 .name = "attiny202",
1793 .llvm_name = "attiny202",
1794 .features = featureSet(&[_]Feature{
1795 .xmega3,
1796 }),
1797 };
1798 pub const attiny204 = CpuModel{
1799 .name = "attiny204",
1800 .llvm_name = "attiny204",
1801 .features = featureSet(&[_]Feature{
1802 .xmega3,
1803 }),
1804 };
1805 pub const attiny212 = CpuModel{
1806 .name = "attiny212",
1807 .llvm_name = "attiny212",
1808 .features = featureSet(&[_]Feature{
1809 .xmega3,
1810 }),
1811 };
1812 pub const attiny214 = CpuModel{
1813 .name = "attiny214",
1814 .llvm_name = "attiny214",
1815 .features = featureSet(&[_]Feature{
1816 .xmega3,
1817 }),
1818 };
1819 pub const attiny22 = CpuModel{
1820 .name = "attiny22",
1821 .llvm_name = "attiny22",
1822 .features = featureSet(&[_]Feature{
1823 .avr2,
1824 .smallstack,
1825 }),
1826 };
1827 pub const attiny2313 = CpuModel{
1828 .name = "attiny2313",
1829 .llvm_name = "attiny2313",
1830 .features = featureSet(&[_]Feature{
1831 .avr25,
1832 .smallstack,
1833 }),
1834 };
1835 pub const attiny2313a = CpuModel{
1836 .name = "attiny2313a",
1837 .llvm_name = "attiny2313a",
1838 .features = featureSet(&[_]Feature{
1839 .avr25,
1840 .smallstack,
1841 }),
1842 };
1843 pub const attiny24 = CpuModel{
1844 .name = "attiny24",
1845 .llvm_name = "attiny24",
1846 .features = featureSet(&[_]Feature{
1847 .avr25,
1848 .smallstack,
1849 }),
1850 };
1851 pub const attiny24a = CpuModel{
1852 .name = "attiny24a",
1853 .llvm_name = "attiny24a",
1854 .features = featureSet(&[_]Feature{
1855 .avr25,
1856 .smallstack,
1857 }),
1858 };
1859 pub const attiny25 = CpuModel{
1860 .name = "attiny25",
1861 .llvm_name = "attiny25",
1862 .features = featureSet(&[_]Feature{
1863 .avr25,
1864 .smallstack,
1865 }),
1866 };
1867 pub const attiny26 = CpuModel{
1868 .name = "attiny26",
1869 .llvm_name = "attiny26",
1870 .features = featureSet(&[_]Feature{
1871 .avr2,
1872 .lpmx,
1873 .smallstack,
1874 }),
1875 };
1876 pub const attiny261 = CpuModel{
1877 .name = "attiny261",
1878 .llvm_name = "attiny261",
1879 .features = featureSet(&[_]Feature{
1880 .avr25,
1881 .smallstack,
1882 }),
1883 };
1884 pub const attiny261a = CpuModel{
1885 .name = "attiny261a",
1886 .llvm_name = "attiny261a",
1887 .features = featureSet(&[_]Feature{
1888 .avr25,
1889 .smallstack,
1890 }),
1891 };
1892 pub const attiny28 = CpuModel{
1893 .name = "attiny28",
1894 .llvm_name = "attiny28",
1895 .features = featureSet(&[_]Feature{
1896 .avr1,
1897 .smallstack,
1898 }),
1899 };
1900 pub const attiny3216 = CpuModel{
1901 .name = "attiny3216",
1902 .llvm_name = "attiny3216",
1903 .features = featureSet(&[_]Feature{
1904 .xmega3,
1905 }),
1906 };
1907 pub const attiny3217 = CpuModel{
1908 .name = "attiny3217",
1909 .llvm_name = "attiny3217",
1910 .features = featureSet(&[_]Feature{
1911 .xmega3,
1912 }),
1913 };
1914 pub const attiny4 = CpuModel{
1915 .name = "attiny4",
1916 .llvm_name = "attiny4",
1917 .features = featureSet(&[_]Feature{
1918 .avrtiny,
1919 }),
1920 };
1921 pub const attiny40 = CpuModel{
1922 .name = "attiny40",
1923 .llvm_name = "attiny40",
1924 .features = featureSet(&[_]Feature{
1925 .avrtiny,
1926 }),
1927 };
1928 pub const attiny402 = CpuModel{
1929 .name = "attiny402",
1930 .llvm_name = "attiny402",
1931 .features = featureSet(&[_]Feature{
1932 .xmega3,
1933 }),
1934 };
1935 pub const attiny404 = CpuModel{
1936 .name = "attiny404",
1937 .llvm_name = "attiny404",
1938 .features = featureSet(&[_]Feature{
1939 .xmega3,
1940 }),
1941 };
1942 pub const attiny406 = CpuModel{
1943 .name = "attiny406",
1944 .llvm_name = "attiny406",
1945 .features = featureSet(&[_]Feature{
1946 .xmega3,
1947 }),
1948 };
1949 pub const attiny412 = CpuModel{
1950 .name = "attiny412",
1951 .llvm_name = "attiny412",
1952 .features = featureSet(&[_]Feature{
1953 .xmega3,
1954 }),
1955 };
1956 pub const attiny414 = CpuModel{
1957 .name = "attiny414",
1958 .llvm_name = "attiny414",
1959 .features = featureSet(&[_]Feature{
1960 .xmega3,
1961 }),
1962 };
1963 pub const attiny416 = CpuModel{
1964 .name = "attiny416",
1965 .llvm_name = "attiny416",
1966 .features = featureSet(&[_]Feature{
1967 .xmega3,
1968 }),
1969 };
1970 pub const attiny417 = CpuModel{
1971 .name = "attiny417",
1972 .llvm_name = "attiny417",
1973 .features = featureSet(&[_]Feature{
1974 .xmega3,
1975 }),
1976 };
1977 pub const attiny4313 = CpuModel{
1978 .name = "attiny4313",
1979 .llvm_name = "attiny4313",
1980 .features = featureSet(&[_]Feature{
1981 .avr25,
1982 }),
1983 };
1984 pub const attiny43u = CpuModel{
1985 .name = "attiny43u",
1986 .llvm_name = "attiny43u",
1987 .features = featureSet(&[_]Feature{
1988 .avr25,
1989 }),
1990 };
1991 pub const attiny44 = CpuModel{
1992 .name = "attiny44",
1993 .llvm_name = "attiny44",
1994 .features = featureSet(&[_]Feature{
1995 .avr25,
1996 }),
1997 };
1998 pub const attiny441 = CpuModel{
1999 .name = "attiny441",
2000 .llvm_name = "attiny441",
2001 .features = featureSet(&[_]Feature{
2002 .avr25,
2003 }),
2004 };
2005 pub const attiny44a = CpuModel{
2006 .name = "attiny44a",
2007 .llvm_name = "attiny44a",
2008 .features = featureSet(&[_]Feature{
2009 .avr25,
2010 }),
2011 };
2012 pub const attiny45 = CpuModel{
2013 .name = "attiny45",
2014 .llvm_name = "attiny45",
2015 .features = featureSet(&[_]Feature{
2016 .avr25,
2017 }),
2018 };
2019 pub const attiny461 = CpuModel{
2020 .name = "attiny461",
2021 .llvm_name = "attiny461",
2022 .features = featureSet(&[_]Feature{
2023 .avr25,
2024 }),
2025 };
2026 pub const attiny461a = CpuModel{
2027 .name = "attiny461a",
2028 .llvm_name = "attiny461a",
2029 .features = featureSet(&[_]Feature{
2030 .avr25,
2031 }),
2032 };
2033 pub const attiny48 = CpuModel{
2034 .name = "attiny48",
2035 .llvm_name = "attiny48",
2036 .features = featureSet(&[_]Feature{
2037 .avr25,
2038 }),
2039 };
2040 pub const attiny5 = CpuModel{
2041 .name = "attiny5",
2042 .llvm_name = "attiny5",
2043 .features = featureSet(&[_]Feature{
2044 .avrtiny,
2045 }),
2046 };
2047 pub const attiny804 = CpuModel{
2048 .name = "attiny804",
2049 .llvm_name = "attiny804",
2050 .features = featureSet(&[_]Feature{
2051 .xmega3,
2052 }),
2053 };
2054 pub const attiny806 = CpuModel{
2055 .name = "attiny806",
2056 .llvm_name = "attiny806",
2057 .features = featureSet(&[_]Feature{
2058 .xmega3,
2059 }),
2060 };
2061 pub const attiny807 = CpuModel{
2062 .name = "attiny807",
2063 .llvm_name = "attiny807",
2064 .features = featureSet(&[_]Feature{
2065 .xmega3,
2066 }),
2067 };
2068 pub const attiny814 = CpuModel{
2069 .name = "attiny814",
2070 .llvm_name = "attiny814",
2071 .features = featureSet(&[_]Feature{
2072 .xmega3,
2073 }),
2074 };
2075 pub const attiny816 = CpuModel{
2076 .name = "attiny816",
2077 .llvm_name = "attiny816",
2078 .features = featureSet(&[_]Feature{
2079 .xmega3,
2080 }),
2081 };
2082 pub const attiny817 = CpuModel{
2083 .name = "attiny817",
2084 .llvm_name = "attiny817",
2085 .features = featureSet(&[_]Feature{
2086 .xmega3,
2087 }),
2088 };
2089 pub const attiny828 = CpuModel{
2090 .name = "attiny828",
2091 .llvm_name = "attiny828",
2092 .features = featureSet(&[_]Feature{
2093 .avr25,
2094 }),
2095 };
2096 pub const attiny84 = CpuModel{
2097 .name = "attiny84",
2098 .llvm_name = "attiny84",
2099 .features = featureSet(&[_]Feature{
2100 .avr25,
2101 }),
2102 };
2103 pub const attiny841 = CpuModel{
2104 .name = "attiny841",
2105 .llvm_name = "attiny841",
2106 .features = featureSet(&[_]Feature{
2107 .avr25,
2108 }),
2109 };
2110 pub const attiny84a = CpuModel{
2111 .name = "attiny84a",
2112 .llvm_name = "attiny84a",
2113 .features = featureSet(&[_]Feature{
2114 .avr25,
2115 }),
2116 };
2117 pub const attiny85 = CpuModel{
2118 .name = "attiny85",
2119 .llvm_name = "attiny85",
2120 .features = featureSet(&[_]Feature{
2121 .avr25,
2122 }),
2123 };
2124 pub const attiny861 = CpuModel{
2125 .name = "attiny861",
2126 .llvm_name = "attiny861",
2127 .features = featureSet(&[_]Feature{
2128 .avr25,
2129 }),
2130 };
2131 pub const attiny861a = CpuModel{
2132 .name = "attiny861a",
2133 .llvm_name = "attiny861a",
2134 .features = featureSet(&[_]Feature{
2135 .avr25,
2136 }),
2137 };
2138 pub const attiny87 = CpuModel{
2139 .name = "attiny87",
2140 .llvm_name = "attiny87",
2141 .features = featureSet(&[_]Feature{
2142 .avr25,
2143 }),
2144 };
2145 pub const attiny88 = CpuModel{
2146 .name = "attiny88",
2147 .llvm_name = "attiny88",
2148 .features = featureSet(&[_]Feature{
2149 .avr25,
2150 }),
2151 };
2152 pub const attiny9 = CpuModel{
2153 .name = "attiny9",
2154 .llvm_name = "attiny9",
2155 .features = featureSet(&[_]Feature{
2156 .avrtiny,
2157 }),
2158 };
2159 pub const atxmega128a1 = CpuModel{
2160 .name = "atxmega128a1",
2161 .llvm_name = "atxmega128a1",
2162 .features = featureSet(&[_]Feature{
2163 .xmega,
2164 }),
2165 };
2166 pub const atxmega128a1u = CpuModel{
2167 .name = "atxmega128a1u",
2168 .llvm_name = "atxmega128a1u",
2169 .features = featureSet(&[_]Feature{
2170 .xmegau,
2171 }),
2172 };
2173 pub const atxmega128a3 = CpuModel{
2174 .name = "atxmega128a3",
2175 .llvm_name = "atxmega128a3",
2176 .features = featureSet(&[_]Feature{
2177 .xmega,
2178 }),
2179 };
2180 pub const atxmega128a3u = CpuModel{
2181 .name = "atxmega128a3u",
2182 .llvm_name = "atxmega128a3u",
2183 .features = featureSet(&[_]Feature{
2184 .xmegau,
2185 }),
2186 };
2187 pub const atxmega128a4u = CpuModel{
2188 .name = "atxmega128a4u",
2189 .llvm_name = "atxmega128a4u",
2190 .features = featureSet(&[_]Feature{
2191 .xmegau,
2192 }),
2193 };
2194 pub const atxmega128b1 = CpuModel{
2195 .name = "atxmega128b1",
2196 .llvm_name = "atxmega128b1",
2197 .features = featureSet(&[_]Feature{
2198 .xmegau,
2199 }),
2200 };
2201 pub const atxmega128b3 = CpuModel{
2202 .name = "atxmega128b3",
2203 .llvm_name = "atxmega128b3",
2204 .features = featureSet(&[_]Feature{
2205 .xmegau,
2206 }),
2207 };
2208 pub const atxmega128c3 = CpuModel{
2209 .name = "atxmega128c3",
2210 .llvm_name = "atxmega128c3",
2211 .features = featureSet(&[_]Feature{
2212 .xmegau,
2213 }),
2214 };
2215 pub const atxmega128d3 = CpuModel{
2216 .name = "atxmega128d3",
2217 .llvm_name = "atxmega128d3",
2218 .features = featureSet(&[_]Feature{
2219 .xmega,
2220 }),
2221 };
2222 pub const atxmega128d4 = CpuModel{
2223 .name = "atxmega128d4",
2224 .llvm_name = "atxmega128d4",
2225 .features = featureSet(&[_]Feature{
2226 .xmega,
2227 }),
2228 };
2229 pub const atxmega16a4 = CpuModel{
2230 .name = "atxmega16a4",
2231 .llvm_name = "atxmega16a4",
2232 .features = featureSet(&[_]Feature{
2233 .xmega,
2234 }),
2235 };
2236 pub const atxmega16a4u = CpuModel{
2237 .name = "atxmega16a4u",
2238 .llvm_name = "atxmega16a4u",
2239 .features = featureSet(&[_]Feature{
2240 .xmegau,
2241 }),
2242 };
2243 pub const atxmega16c4 = CpuModel{
2244 .name = "atxmega16c4",
2245 .llvm_name = "atxmega16c4",
2246 .features = featureSet(&[_]Feature{
2247 .xmegau,
2248 }),
2249 };
2250 pub const atxmega16d4 = CpuModel{
2251 .name = "atxmega16d4",
2252 .llvm_name = "atxmega16d4",
2253 .features = featureSet(&[_]Feature{
2254 .xmega,
2255 }),
2256 };
2257 pub const atxmega16e5 = CpuModel{
2258 .name = "atxmega16e5",
2259 .llvm_name = "atxmega16e5",
2260 .features = featureSet(&[_]Feature{
2261 .xmegau,
2262 }),
2263 };
2264 pub const atxmega192a3 = CpuModel{
2265 .name = "atxmega192a3",
2266 .llvm_name = "atxmega192a3",
2267 .features = featureSet(&[_]Feature{
2268 .xmega,
2269 }),
2270 };
2271 pub const atxmega192a3u = CpuModel{
2272 .name = "atxmega192a3u",
2273 .llvm_name = "atxmega192a3u",
2274 .features = featureSet(&[_]Feature{
2275 .xmegau,
2276 }),
2277 };
2278 pub const atxmega192c3 = CpuModel{
2279 .name = "atxmega192c3",
2280 .llvm_name = "atxmega192c3",
2281 .features = featureSet(&[_]Feature{
2282 .xmegau,
2283 }),
2284 };
2285 pub const atxmega192d3 = CpuModel{
2286 .name = "atxmega192d3",
2287 .llvm_name = "atxmega192d3",
2288 .features = featureSet(&[_]Feature{
2289 .xmega,
2290 }),
2291 };
2292 pub const atxmega256a3 = CpuModel{
2293 .name = "atxmega256a3",
2294 .llvm_name = "atxmega256a3",
2295 .features = featureSet(&[_]Feature{
2296 .xmega,
2297 }),
2298 };
2299 pub const atxmega256a3b = CpuModel{
2300 .name = "atxmega256a3b",
2301 .llvm_name = "atxmega256a3b",
2302 .features = featureSet(&[_]Feature{
2303 .xmega,
2304 }),
2305 };
2306 pub const atxmega256a3bu = CpuModel{
2307 .name = "atxmega256a3bu",
2308 .llvm_name = "atxmega256a3bu",
2309 .features = featureSet(&[_]Feature{
2310 .xmegau,
2311 }),
2312 };
2313 pub const atxmega256a3u = CpuModel{
2314 .name = "atxmega256a3u",
2315 .llvm_name = "atxmega256a3u",
2316 .features = featureSet(&[_]Feature{
2317 .xmegau,
2318 }),
2319 };
2320 pub const atxmega256c3 = CpuModel{
2321 .name = "atxmega256c3",
2322 .llvm_name = "atxmega256c3",
2323 .features = featureSet(&[_]Feature{
2324 .xmegau,
2325 }),
2326 };
2327 pub const atxmega256d3 = CpuModel{
2328 .name = "atxmega256d3",
2329 .llvm_name = "atxmega256d3",
2330 .features = featureSet(&[_]Feature{
2331 .xmega,
2332 }),
2333 };
2334 pub const atxmega32a4 = CpuModel{
2335 .name = "atxmega32a4",
2336 .llvm_name = "atxmega32a4",
2337 .features = featureSet(&[_]Feature{
2338 .xmega,
2339 }),
2340 };
2341 pub const atxmega32a4u = CpuModel{
2342 .name = "atxmega32a4u",
2343 .llvm_name = "atxmega32a4u",
2344 .features = featureSet(&[_]Feature{
2345 .xmegau,
2346 }),
2347 };
2348 pub const atxmega32c3 = CpuModel{
2349 .name = "atxmega32c3",
2350 .llvm_name = "atxmega32c3",
2351 .features = featureSet(&[_]Feature{
2352 .xmegau,
2353 }),
2354 };
2355 pub const atxmega32c4 = CpuModel{
2356 .name = "atxmega32c4",
2357 .llvm_name = "atxmega32c4",
2358 .features = featureSet(&[_]Feature{
2359 .xmegau,
2360 }),
2361 };
2362 pub const atxmega32d3 = CpuModel{
2363 .name = "atxmega32d3",
2364 .llvm_name = "atxmega32d3",
2365 .features = featureSet(&[_]Feature{
2366 .xmega,
2367 }),
2368 };
2369 pub const atxmega32d4 = CpuModel{
2370 .name = "atxmega32d4",
2371 .llvm_name = "atxmega32d4",
2372 .features = featureSet(&[_]Feature{
2373 .xmega,
2374 }),
2375 };
2376 pub const atxmega32e5 = CpuModel{
2377 .name = "atxmega32e5",
2378 .llvm_name = "atxmega32e5",
2379 .features = featureSet(&[_]Feature{
2380 .xmegau,
2381 }),
2382 };
2383 pub const atxmega384c3 = CpuModel{
2384 .name = "atxmega384c3",
2385 .llvm_name = "atxmega384c3",
2386 .features = featureSet(&[_]Feature{
2387 .xmegau,
2388 }),
2389 };
2390 pub const atxmega384d3 = CpuModel{
2391 .name = "atxmega384d3",
2392 .llvm_name = "atxmega384d3",
2393 .features = featureSet(&[_]Feature{
2394 .xmega,
2395 }),
2396 };
2397 pub const atxmega64a1 = CpuModel{
2398 .name = "atxmega64a1",
2399 .llvm_name = "atxmega64a1",
2400 .features = featureSet(&[_]Feature{
2401 .xmega,
2402 }),
2403 };
2404 pub const atxmega64a1u = CpuModel{
2405 .name = "atxmega64a1u",
2406 .llvm_name = "atxmega64a1u",
2407 .features = featureSet(&[_]Feature{
2408 .xmegau,
2409 }),
2410 };
2411 pub const atxmega64a3 = CpuModel{
2412 .name = "atxmega64a3",
2413 .llvm_name = "atxmega64a3",
2414 .features = featureSet(&[_]Feature{
2415 .xmega,
2416 }),
2417 };
2418 pub const atxmega64a3u = CpuModel{
2419 .name = "atxmega64a3u",
2420 .llvm_name = "atxmega64a3u",
2421 .features = featureSet(&[_]Feature{
2422 .xmegau,
2423 }),
2424 };
2425 pub const atxmega64a4u = CpuModel{
2426 .name = "atxmega64a4u",
2427 .llvm_name = "atxmega64a4u",
2428 .features = featureSet(&[_]Feature{
2429 .xmegau,
2430 }),
2431 };
2432 pub const atxmega64b1 = CpuModel{
2433 .name = "atxmega64b1",
2434 .llvm_name = "atxmega64b1",
2435 .features = featureSet(&[_]Feature{
2436 .xmegau,
2437 }),
2438 };
2439 pub const atxmega64b3 = CpuModel{
2440 .name = "atxmega64b3",
2441 .llvm_name = "atxmega64b3",
2442 .features = featureSet(&[_]Feature{
2443 .xmegau,
2444 }),
2445 };
2446 pub const atxmega64c3 = CpuModel{
2447 .name = "atxmega64c3",
2448 .llvm_name = "atxmega64c3",
2449 .features = featureSet(&[_]Feature{
2450 .xmegau,
2451 }),
2452 };
2453 pub const atxmega64d3 = CpuModel{
2454 .name = "atxmega64d3",
2455 .llvm_name = "atxmega64d3",
2456 .features = featureSet(&[_]Feature{
2457 .xmega,
2458 }),
2459 };
2460 pub const atxmega64d4 = CpuModel{
2461 .name = "atxmega64d4",
2462 .llvm_name = "atxmega64d4",
2463 .features = featureSet(&[_]Feature{
2464 .xmega,
2465 }),
2466 };
2467 pub const atxmega8e5 = CpuModel{
2468 .name = "atxmega8e5",
2469 .llvm_name = "atxmega8e5",
2470 .features = featureSet(&[_]Feature{
2471 .xmegau,
2472 }),
2473 };
2474 pub const avr1 = CpuModel{
2475 .name = "avr1",
2476 .llvm_name = "avr1",
2477 .features = featureSet(&[_]Feature{
2478 .avr1,
2479 }),
2480 };
2481 pub const avr2 = CpuModel{
2482 .name = "avr2",
2483 .llvm_name = "avr2",
2484 .features = featureSet(&[_]Feature{
2485 .avr2,
2486 }),
2487 };
2488 pub const avr25 = CpuModel{
2489 .name = "avr25",
2490 .llvm_name = "avr25",
2491 .features = featureSet(&[_]Feature{
2492 .avr25,
2493 }),
2494 };
2495 pub const avr3 = CpuModel{
2496 .name = "avr3",
2497 .llvm_name = "avr3",
2498 .features = featureSet(&[_]Feature{
2499 .avr3,
2500 }),
2501 };
2502 pub const avr31 = CpuModel{
2503 .name = "avr31",
2504 .llvm_name = "avr31",
2505 .features = featureSet(&[_]Feature{
2506 .avr31,
2507 }),
2508 };
2509 pub const avr35 = CpuModel{
2510 .name = "avr35",
2511 .llvm_name = "avr35",
2512 .features = featureSet(&[_]Feature{
2513 .avr35,
2514 }),
2515 };
2516 pub const avr4 = CpuModel{
2517 .name = "avr4",
2518 .llvm_name = "avr4",
2519 .features = featureSet(&[_]Feature{
2520 .avr4,
2521 }),
2522 };
2523 pub const avr5 = CpuModel{
2524 .name = "avr5",
2525 .llvm_name = "avr5",
2526 .features = featureSet(&[_]Feature{
2527 .avr5,
2528 }),
2529 };
2530 pub const avr51 = CpuModel{
2531 .name = "avr51",
2532 .llvm_name = "avr51",
2533 .features = featureSet(&[_]Feature{
2534 .avr51,
2535 }),
2536 };
2537 pub const avr6 = CpuModel{
2538 .name = "avr6",
2539 .llvm_name = "avr6",
2540 .features = featureSet(&[_]Feature{
2541 .avr6,
2542 }),
2543 };
2544 pub const avrtiny = CpuModel{
2545 .name = "avrtiny",
2546 .llvm_name = "avrtiny",
2547 .features = featureSet(&[_]Feature{
2548 .avrtiny,
2549 }),
2550 };
2551 pub const avrxmega1 = CpuModel{
2552 .name = "avrxmega1",
2553 .llvm_name = "avrxmega1",
2554 .features = featureSet(&[_]Feature{
2555 .xmega,
2556 }),
2557 };
2558 pub const avrxmega2 = CpuModel{
2559 .name = "avrxmega2",
2560 .llvm_name = "avrxmega2",
2561 .features = featureSet(&[_]Feature{
2562 .xmega,
2563 }),
2564 };
2565 pub const avrxmega3 = CpuModel{
2566 .name = "avrxmega3",
2567 .llvm_name = "avrxmega3",
2568 .features = featureSet(&[_]Feature{
2569 .xmega3,
2570 }),
2571 };
2572 pub const avrxmega4 = CpuModel{
2573 .name = "avrxmega4",
2574 .llvm_name = "avrxmega4",
2575 .features = featureSet(&[_]Feature{
2576 .xmega,
2577 }),
2578 };
2579 pub const avrxmega5 = CpuModel{
2580 .name = "avrxmega5",
2581 .llvm_name = "avrxmega5",
2582 .features = featureSet(&[_]Feature{
2583 .xmega,
2584 }),
2585 };
2586 pub const avrxmega6 = CpuModel{
2587 .name = "avrxmega6",
2588 .llvm_name = "avrxmega6",
2589 .features = featureSet(&[_]Feature{
2590 .xmega,
2591 }),
2592 };
2593 pub const avrxmega7 = CpuModel{
2594 .name = "avrxmega7",
2595 .llvm_name = "avrxmega7",
2596 .features = featureSet(&[_]Feature{
2597 .xmega,
2598 }),
2599 };
2600 pub const m3000 = CpuModel{
2601 .name = "m3000",
2602 .llvm_name = "m3000",
2603 .features = featureSet(&[_]Feature{
2604 .avr5,
2605 }),
2606 };
2607};
lib/std/target/bpf.zig deleted-73
......@@ -1,73 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 alu32,
9 dummy,
10 dwarfris,
11};
12
13pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
14pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
15pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
16pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
17
18pub const all_features = blk: {
19 const len = @typeInfo(Feature).Enum.fields.len;
20 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
21 var result: [len]CpuFeature = undefined;
22 result[@intFromEnum(Feature.alu32)] = .{
23 .llvm_name = "alu32",
24 .description = "Enable ALU32 instructions",
25 .dependencies = featureSet(&[_]Feature{}),
26 };
27 result[@intFromEnum(Feature.dummy)] = .{
28 .llvm_name = "dummy",
29 .description = "unused feature",
30 .dependencies = featureSet(&[_]Feature{}),
31 };
32 result[@intFromEnum(Feature.dwarfris)] = .{
33 .llvm_name = "dwarfris",
34 .description = "Disable MCAsmInfo DwarfUsesRelocationsAcrossSections",
35 .dependencies = featureSet(&[_]Feature{}),
36 };
37 const ti = @typeInfo(Feature);
38 for (&result, 0..) |*elem, i| {
39 elem.index = i;
40 elem.name = ti.Enum.fields[i].name;
41 }
42 break :blk result;
43};
44
45pub const cpu = struct {
46 pub const generic = CpuModel{
47 .name = "generic",
48 .llvm_name = "generic",
49 .features = featureSet(&[_]Feature{}),
50 };
51 pub const probe = CpuModel{
52 .name = "probe",
53 .llvm_name = "probe",
54 .features = featureSet(&[_]Feature{}),
55 };
56 pub const v1 = CpuModel{
57 .name = "v1",
58 .llvm_name = "v1",
59 .features = featureSet(&[_]Feature{}),
60 };
61 pub const v2 = CpuModel{
62 .name = "v2",
63 .llvm_name = "v2",
64 .features = featureSet(&[_]Feature{}),
65 };
66 pub const v3 = CpuModel{
67 .name = "v3",
68 .llvm_name = "v3",
69 .features = featureSet(&[_]Feature{
70 .alu32,
71 }),
72 };
73};
lib/std/target/csky.zig deleted-3214
......@@ -1,3214 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"10e60",
9 @"2e3",
10 @"3e3r1",
11 @"3e3r2",
12 @"3e3r3",
13 @"3e7",
14 @"7e10",
15 btst16,
16 cache,
17 ccrt,
18 ck801,
19 ck802,
20 ck803,
21 ck803s,
22 ck804,
23 ck805,
24 ck807,
25 ck810,
26 ck810v,
27 ck860,
28 ck860v,
29 constpool,
30 doloop,
31 dsp1e2,
32 dsp_silan,
33 dspe60,
34 dspv2,
35 e1,
36 e2,
37 edsp,
38 elrw,
39 fdivdu,
40 float1e2,
41 float1e3,
42 float3e4,
43 float7e60,
44 floate1,
45 fpuv2_df,
46 fpuv2_sf,
47 fpuv3_df,
48 fpuv3_hf,
49 fpuv3_hi,
50 fpuv3_sf,
51 hard_float,
52 hard_float_abi,
53 hard_tp,
54 high_registers,
55 hwdiv,
56 istack,
57 java,
58 mp,
59 mp1e2,
60 multiple_stld,
61 nvic,
62 pushpop,
63 smart,
64 soft_tp,
65 stack_size,
66 trust,
67 vdsp2e3,
68 vdsp2e60f,
69 vdspv1,
70 vdspv2,
71};
72
73pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
74pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
75pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
76pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
77
78pub const all_features = blk: {
79 const len = @typeInfo(Feature).Enum.fields.len;
80 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
81 var result: [len]CpuFeature = undefined;
82 result[@intFromEnum(Feature.@"10e60")] = .{
83 .llvm_name = "10e60",
84 .description = "Support CSKY 10e60 instructions",
85 .dependencies = featureSet(&[_]Feature{
86 .@"7e10",
87 }),
88 };
89 result[@intFromEnum(Feature.@"2e3")] = .{
90 .llvm_name = "2e3",
91 .description = "Support CSKY 2e3 instructions",
92 .dependencies = featureSet(&[_]Feature{
93 .e2,
94 }),
95 };
96 result[@intFromEnum(Feature.@"3e3r1")] = .{
97 .llvm_name = "3e3r1",
98 .description = "Support CSKY 3e3r1 instructions",
99 .dependencies = featureSet(&[_]Feature{}),
100 };
101 result[@intFromEnum(Feature.@"3e3r2")] = .{
102 .llvm_name = "3e3r2",
103 .description = "Support CSKY 3e3r2 instructions",
104 .dependencies = featureSet(&[_]Feature{
105 .@"3e3r1",
106 .doloop,
107 }),
108 };
109 result[@intFromEnum(Feature.@"3e3r3")] = .{
110 .llvm_name = "3e3r3",
111 .description = "Support CSKY 3e3r3 instructions",
112 .dependencies = featureSet(&[_]Feature{
113 .doloop,
114 }),
115 };
116 result[@intFromEnum(Feature.@"3e7")] = .{
117 .llvm_name = "3e7",
118 .description = "Support CSKY 3e7 instructions",
119 .dependencies = featureSet(&[_]Feature{
120 .@"2e3",
121 }),
122 };
123 result[@intFromEnum(Feature.@"7e10")] = .{
124 .llvm_name = "7e10",
125 .description = "Support CSKY 7e10 instructions",
126 .dependencies = featureSet(&[_]Feature{
127 .@"3e7",
128 }),
129 };
130 result[@intFromEnum(Feature.btst16)] = .{
131 .llvm_name = "btst16",
132 .description = "Use the 16-bit btsti instruction",
133 .dependencies = featureSet(&[_]Feature{}),
134 };
135 result[@intFromEnum(Feature.cache)] = .{
136 .llvm_name = "cache",
137 .description = "Enable cache",
138 .dependencies = featureSet(&[_]Feature{}),
139 };
140 result[@intFromEnum(Feature.ccrt)] = .{
141 .llvm_name = "ccrt",
142 .description = "Use CSKY compiler runtime",
143 .dependencies = featureSet(&[_]Feature{}),
144 };
145 result[@intFromEnum(Feature.ck801)] = .{
146 .llvm_name = "ck801",
147 .description = "CSKY ck801 processors",
148 .dependencies = featureSet(&[_]Feature{}),
149 };
150 result[@intFromEnum(Feature.ck802)] = .{
151 .llvm_name = "ck802",
152 .description = "CSKY ck802 processors",
153 .dependencies = featureSet(&[_]Feature{}),
154 };
155 result[@intFromEnum(Feature.ck803)] = .{
156 .llvm_name = "ck803",
157 .description = "CSKY ck803 processors",
158 .dependencies = featureSet(&[_]Feature{}),
159 };
160 result[@intFromEnum(Feature.ck803s)] = .{
161 .llvm_name = "ck803s",
162 .description = "CSKY ck803s processors",
163 .dependencies = featureSet(&[_]Feature{}),
164 };
165 result[@intFromEnum(Feature.ck804)] = .{
166 .llvm_name = "ck804",
167 .description = "CSKY ck804 processors",
168 .dependencies = featureSet(&[_]Feature{}),
169 };
170 result[@intFromEnum(Feature.ck805)] = .{
171 .llvm_name = "ck805",
172 .description = "CSKY ck805 processors",
173 .dependencies = featureSet(&[_]Feature{}),
174 };
175 result[@intFromEnum(Feature.ck807)] = .{
176 .llvm_name = "ck807",
177 .description = "CSKY ck807 processors",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.ck810)] = .{
181 .llvm_name = "ck810",
182 .description = "CSKY ck810 processors",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.ck810v)] = .{
186 .llvm_name = "ck810v",
187 .description = "CSKY ck810v processors",
188 .dependencies = featureSet(&[_]Feature{}),
189 };
190 result[@intFromEnum(Feature.ck860)] = .{
191 .llvm_name = "ck860",
192 .description = "CSKY ck860 processors",
193 .dependencies = featureSet(&[_]Feature{}),
194 };
195 result[@intFromEnum(Feature.ck860v)] = .{
196 .llvm_name = "ck860v",
197 .description = "CSKY ck860v processors",
198 .dependencies = featureSet(&[_]Feature{}),
199 };
200 result[@intFromEnum(Feature.constpool)] = .{
201 .llvm_name = "constpool",
202 .description = "Dump the constant pool by compiler",
203 .dependencies = featureSet(&[_]Feature{}),
204 };
205 result[@intFromEnum(Feature.doloop)] = .{
206 .llvm_name = "doloop",
207 .description = "Enable doloop instructions",
208 .dependencies = featureSet(&[_]Feature{}),
209 };
210 result[@intFromEnum(Feature.dsp1e2)] = .{
211 .llvm_name = "dsp1e2",
212 .description = "Support CSKY dsp1e2 instructions",
213 .dependencies = featureSet(&[_]Feature{}),
214 };
215 result[@intFromEnum(Feature.dsp_silan)] = .{
216 .llvm_name = "dsp_silan",
217 .description = "Enable DSP Silan instrutions",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
220 result[@intFromEnum(Feature.dspe60)] = .{
221 .llvm_name = "dspe60",
222 .description = "Support CSKY dspe60 instructions",
223 .dependencies = featureSet(&[_]Feature{}),
224 };
225 result[@intFromEnum(Feature.dspv2)] = .{
226 .llvm_name = "dspv2",
227 .description = "Enable DSP V2.0 instrutions",
228 .dependencies = featureSet(&[_]Feature{}),
229 };
230 result[@intFromEnum(Feature.e1)] = .{
231 .llvm_name = "e1",
232 .description = "Support CSKY e1 instructions",
233 .dependencies = featureSet(&[_]Feature{
234 .elrw,
235 }),
236 };
237 result[@intFromEnum(Feature.e2)] = .{
238 .llvm_name = "e2",
239 .description = "Support CSKY e2 instructions",
240 .dependencies = featureSet(&[_]Feature{
241 .e1,
242 }),
243 };
244 result[@intFromEnum(Feature.edsp)] = .{
245 .llvm_name = "edsp",
246 .description = "Enable DSP instrutions",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@intFromEnum(Feature.elrw)] = .{
250 .llvm_name = "elrw",
251 .description = "Use the extend LRW instruction",
252 .dependencies = featureSet(&[_]Feature{}),
253 };
254 result[@intFromEnum(Feature.fdivdu)] = .{
255 .llvm_name = "fdivdu",
256 .description = "Enable float divide instructions",
257 .dependencies = featureSet(&[_]Feature{}),
258 };
259 result[@intFromEnum(Feature.float1e2)] = .{
260 .llvm_name = "float1e2",
261 .description = "Support CSKY float1e2 instructions",
262 .dependencies = featureSet(&[_]Feature{}),
263 };
264 result[@intFromEnum(Feature.float1e3)] = .{
265 .llvm_name = "float1e3",
266 .description = "Support CSKY float1e3 instructions",
267 .dependencies = featureSet(&[_]Feature{}),
268 };
269 result[@intFromEnum(Feature.float3e4)] = .{
270 .llvm_name = "float3e4",
271 .description = "Support CSKY float3e4 instructions",
272 .dependencies = featureSet(&[_]Feature{}),
273 };
274 result[@intFromEnum(Feature.float7e60)] = .{
275 .llvm_name = "float7e60",
276 .description = "Support CSKY float7e60 instructions",
277 .dependencies = featureSet(&[_]Feature{}),
278 };
279 result[@intFromEnum(Feature.floate1)] = .{
280 .llvm_name = "floate1",
281 .description = "Support CSKY floate1 instructions",
282 .dependencies = featureSet(&[_]Feature{}),
283 };
284 result[@intFromEnum(Feature.fpuv2_df)] = .{
285 .llvm_name = "fpuv2_df",
286 .description = "Enable FPUv2 double float instructions",
287 .dependencies = featureSet(&[_]Feature{}),
288 };
289 result[@intFromEnum(Feature.fpuv2_sf)] = .{
290 .llvm_name = "fpuv2_sf",
291 .description = "Enable FPUv2 single float instructions",
292 .dependencies = featureSet(&[_]Feature{}),
293 };
294 result[@intFromEnum(Feature.fpuv3_df)] = .{
295 .llvm_name = "fpuv3_df",
296 .description = "Enable FPUv3 double float instructions",
297 .dependencies = featureSet(&[_]Feature{}),
298 };
299 result[@intFromEnum(Feature.fpuv3_hf)] = .{
300 .llvm_name = "fpuv3_hf",
301 .description = "Enable FPUv3 half precision operate instructions",
302 .dependencies = featureSet(&[_]Feature{}),
303 };
304 result[@intFromEnum(Feature.fpuv3_hi)] = .{
305 .llvm_name = "fpuv3_hi",
306 .description = "Enable FPUv3 half word converting instructions",
307 .dependencies = featureSet(&[_]Feature{}),
308 };
309 result[@intFromEnum(Feature.fpuv3_sf)] = .{
310 .llvm_name = "fpuv3_sf",
311 .description = "Enable FPUv3 single float instructions",
312 .dependencies = featureSet(&[_]Feature{}),
313 };
314 result[@intFromEnum(Feature.hard_float)] = .{
315 .llvm_name = "hard-float",
316 .description = "Use hard floating point features",
317 .dependencies = featureSet(&[_]Feature{}),
318 };
319 result[@intFromEnum(Feature.hard_float_abi)] = .{
320 .llvm_name = "hard-float-abi",
321 .description = "Use hard floating point ABI to pass args",
322 .dependencies = featureSet(&[_]Feature{}),
323 };
324 result[@intFromEnum(Feature.hard_tp)] = .{
325 .llvm_name = "hard-tp",
326 .description = "Enable TLS Pointer register",
327 .dependencies = featureSet(&[_]Feature{}),
328 };
329 result[@intFromEnum(Feature.high_registers)] = .{
330 .llvm_name = "high-registers",
331 .description = "Enable r16-r31 registers",
332 .dependencies = featureSet(&[_]Feature{}),
333 };
334 result[@intFromEnum(Feature.hwdiv)] = .{
335 .llvm_name = "hwdiv",
336 .description = "Enable divide instrutions",
337 .dependencies = featureSet(&[_]Feature{}),
338 };
339 result[@intFromEnum(Feature.istack)] = .{
340 .llvm_name = "istack",
341 .description = "Enable interrput attribute",
342 .dependencies = featureSet(&[_]Feature{}),
343 };
344 result[@intFromEnum(Feature.java)] = .{
345 .llvm_name = "java",
346 .description = "Enable java instructions",
347 .dependencies = featureSet(&[_]Feature{}),
348 };
349 result[@intFromEnum(Feature.mp)] = .{
350 .llvm_name = "mp",
351 .description = "Support CSKY mp instructions",
352 .dependencies = featureSet(&[_]Feature{
353 .@"2e3",
354 }),
355 };
356 result[@intFromEnum(Feature.mp1e2)] = .{
357 .llvm_name = "mp1e2",
358 .description = "Support CSKY mp1e2 instructions",
359 .dependencies = featureSet(&[_]Feature{
360 .@"3e7",
361 }),
362 };
363 result[@intFromEnum(Feature.multiple_stld)] = .{
364 .llvm_name = "multiple_stld",
365 .description = "Enable multiple load/store instrutions",
366 .dependencies = featureSet(&[_]Feature{}),
367 };
368 result[@intFromEnum(Feature.nvic)] = .{
369 .llvm_name = "nvic",
370 .description = "Enable NVIC",
371 .dependencies = featureSet(&[_]Feature{}),
372 };
373 result[@intFromEnum(Feature.pushpop)] = .{
374 .llvm_name = "pushpop",
375 .description = "Enable push/pop instrutions",
376 .dependencies = featureSet(&[_]Feature{}),
377 };
378 result[@intFromEnum(Feature.smart)] = .{
379 .llvm_name = "smart",
380 .description = "Let CPU work in Smart Mode",
381 .dependencies = featureSet(&[_]Feature{}),
382 };
383 result[@intFromEnum(Feature.soft_tp)] = .{
384 .llvm_name = "soft-tp",
385 .description = "Disable TLS Pointer register",
386 .dependencies = featureSet(&[_]Feature{}),
387 };
388 result[@intFromEnum(Feature.stack_size)] = .{
389 .llvm_name = "stack-size",
390 .description = "Output stack size information",
391 .dependencies = featureSet(&[_]Feature{}),
392 };
393 result[@intFromEnum(Feature.trust)] = .{
394 .llvm_name = "trust",
395 .description = "Enable trust instructions",
396 .dependencies = featureSet(&[_]Feature{}),
397 };
398 result[@intFromEnum(Feature.vdsp2e3)] = .{
399 .llvm_name = "vdsp2e3",
400 .description = "Support CSKY vdsp2e3 instructions",
401 .dependencies = featureSet(&[_]Feature{}),
402 };
403 result[@intFromEnum(Feature.vdsp2e60f)] = .{
404 .llvm_name = "vdsp2e60f",
405 .description = "Support CSKY vdsp2e60f instructions",
406 .dependencies = featureSet(&[_]Feature{}),
407 };
408 result[@intFromEnum(Feature.vdspv1)] = .{
409 .llvm_name = "vdspv1",
410 .description = "Enable 128bit vdsp-v1 instructions",
411 .dependencies = featureSet(&[_]Feature{}),
412 };
413 result[@intFromEnum(Feature.vdspv2)] = .{
414 .llvm_name = "vdspv2",
415 .description = "Enable vdsp-v2 instructions",
416 .dependencies = featureSet(&[_]Feature{}),
417 };
418 const ti = @typeInfo(Feature);
419 for (&result, 0..) |*elem, i| {
420 elem.index = i;
421 elem.name = ti.Enum.fields[i].name;
422 }
423 break :blk result;
424};
425
426pub const cpu = struct {
427 pub const c807 = CpuModel{
428 .name = "c807",
429 .llvm_name = "c807",
430 .features = featureSet(&[_]Feature{
431 .cache,
432 .ck807,
433 .dsp1e2,
434 .dspe60,
435 .edsp,
436 .hard_tp,
437 .high_registers,
438 .hwdiv,
439 .mp,
440 .mp1e2,
441 .nvic,
442 .trust,
443 }),
444 };
445 pub const c807f = CpuModel{
446 .name = "c807f",
447 .llvm_name = "c807f",
448 .features = featureSet(&[_]Feature{
449 .cache,
450 .ck807,
451 .dsp1e2,
452 .dspe60,
453 .edsp,
454 .fdivdu,
455 .float1e2,
456 .float1e3,
457 .float3e4,
458 .floate1,
459 .fpuv2_df,
460 .fpuv2_sf,
461 .hard_tp,
462 .high_registers,
463 .hwdiv,
464 .mp,
465 .mp1e2,
466 .nvic,
467 .trust,
468 }),
469 };
470 pub const c810 = CpuModel{
471 .name = "c810",
472 .llvm_name = "c810",
473 .features = featureSet(&[_]Feature{
474 .@"7e10",
475 .cache,
476 .ck810,
477 .dsp1e2,
478 .dspe60,
479 .edsp,
480 .fdivdu,
481 .float1e2,
482 .floate1,
483 .fpuv2_df,
484 .fpuv2_sf,
485 .hard_tp,
486 .high_registers,
487 .hwdiv,
488 .mp,
489 .mp1e2,
490 .nvic,
491 .trust,
492 }),
493 };
494 pub const c810t = CpuModel{
495 .name = "c810t",
496 .llvm_name = "c810t",
497 .features = featureSet(&[_]Feature{
498 .@"7e10",
499 .cache,
500 .ck810,
501 .dsp1e2,
502 .dspe60,
503 .edsp,
504 .fdivdu,
505 .float1e2,
506 .floate1,
507 .fpuv2_df,
508 .fpuv2_sf,
509 .hard_tp,
510 .high_registers,
511 .hwdiv,
512 .mp,
513 .mp1e2,
514 .nvic,
515 .trust,
516 }),
517 };
518 pub const c810tv = CpuModel{
519 .name = "c810tv",
520 .llvm_name = "c810tv",
521 .features = featureSet(&[_]Feature{
522 .@"7e10",
523 .cache,
524 .ck810,
525 .ck810v,
526 .dsp1e2,
527 .dspe60,
528 .edsp,
529 .fdivdu,
530 .float1e2,
531 .floate1,
532 .fpuv2_df,
533 .fpuv2_sf,
534 .hard_tp,
535 .high_registers,
536 .hwdiv,
537 .mp,
538 .mp1e2,
539 .nvic,
540 .trust,
541 .vdspv1,
542 }),
543 };
544 pub const c810v = CpuModel{
545 .name = "c810v",
546 .llvm_name = "c810v",
547 .features = featureSet(&[_]Feature{
548 .@"7e10",
549 .cache,
550 .ck810,
551 .ck810v,
552 .dsp1e2,
553 .dspe60,
554 .edsp,
555 .fdivdu,
556 .float1e2,
557 .floate1,
558 .fpuv2_df,
559 .fpuv2_sf,
560 .hard_tp,
561 .high_registers,
562 .hwdiv,
563 .mp,
564 .mp1e2,
565 .nvic,
566 .trust,
567 .vdspv1,
568 }),
569 };
570 pub const c860 = CpuModel{
571 .name = "c860",
572 .llvm_name = "c860",
573 .features = featureSet(&[_]Feature{
574 .@"10e60",
575 .@"3e3r2",
576 .@"3e3r3",
577 .btst16,
578 .cache,
579 .ck860,
580 .dspe60,
581 .float7e60,
582 .fpuv3_df,
583 .fpuv3_hf,
584 .fpuv3_hi,
585 .fpuv3_sf,
586 .hard_tp,
587 .high_registers,
588 .hwdiv,
589 .mp,
590 .mp1e2,
591 .nvic,
592 .trust,
593 }),
594 };
595 pub const c860v = CpuModel{
596 .name = "c860v",
597 .llvm_name = "c860v",
598 .features = featureSet(&[_]Feature{
599 .@"10e60",
600 .@"3e3r2",
601 .@"3e3r3",
602 .btst16,
603 .cache,
604 .ck860,
605 .ck860v,
606 .dspe60,
607 .float7e60,
608 .fpuv3_df,
609 .fpuv3_hf,
610 .fpuv3_hi,
611 .fpuv3_sf,
612 .hard_tp,
613 .high_registers,
614 .hwdiv,
615 .mp,
616 .mp1e2,
617 .nvic,
618 .trust,
619 .vdsp2e60f,
620 .vdspv2,
621 }),
622 };
623 pub const ck801 = CpuModel{
624 .name = "ck801",
625 .llvm_name = "ck801",
626 .features = featureSet(&[_]Feature{
627 .btst16,
628 .ck801,
629 .e1,
630 .trust,
631 }),
632 };
633 pub const ck801t = CpuModel{
634 .name = "ck801t",
635 .llvm_name = "ck801t",
636 .features = featureSet(&[_]Feature{
637 .btst16,
638 .ck801,
639 .e1,
640 .trust,
641 }),
642 };
643 pub const ck802 = CpuModel{
644 .name = "ck802",
645 .llvm_name = "ck802",
646 .features = featureSet(&[_]Feature{
647 .btst16,
648 .ck802,
649 .e2,
650 .nvic,
651 .trust,
652 }),
653 };
654 pub const ck802j = CpuModel{
655 .name = "ck802j",
656 .llvm_name = "ck802j",
657 .features = featureSet(&[_]Feature{
658 .btst16,
659 .ck802,
660 .e2,
661 .java,
662 .nvic,
663 .trust,
664 }),
665 };
666 pub const ck802t = CpuModel{
667 .name = "ck802t",
668 .llvm_name = "ck802t",
669 .features = featureSet(&[_]Feature{
670 .btst16,
671 .ck802,
672 .e2,
673 .nvic,
674 .trust,
675 }),
676 };
677 pub const ck803 = CpuModel{
678 .name = "ck803",
679 .llvm_name = "ck803",
680 .features = featureSet(&[_]Feature{
681 .btst16,
682 .ck803,
683 .hwdiv,
684 .mp,
685 .nvic,
686 .trust,
687 }),
688 };
689 pub const ck803e = CpuModel{
690 .name = "ck803e",
691 .llvm_name = "ck803e",
692 .features = featureSet(&[_]Feature{
693 .btst16,
694 .ck803,
695 .dsp1e2,
696 .dspe60,
697 .edsp,
698 .hwdiv,
699 .mp,
700 .nvic,
701 .trust,
702 }),
703 };
704 pub const ck803ef = CpuModel{
705 .name = "ck803ef",
706 .llvm_name = "ck803ef",
707 .features = featureSet(&[_]Feature{
708 .btst16,
709 .ck803,
710 .dsp1e2,
711 .dspe60,
712 .edsp,
713 .float1e3,
714 .floate1,
715 .fpuv2_sf,
716 .hwdiv,
717 .mp,
718 .nvic,
719 .trust,
720 }),
721 };
722 pub const ck803efh = CpuModel{
723 .name = "ck803efh",
724 .llvm_name = "ck803efh",
725 .features = featureSet(&[_]Feature{
726 .btst16,
727 .ck803,
728 .dsp1e2,
729 .dspe60,
730 .edsp,
731 .float1e3,
732 .floate1,
733 .fpuv2_sf,
734 .hwdiv,
735 .mp,
736 .nvic,
737 .trust,
738 }),
739 };
740 pub const ck803efhr1 = CpuModel{
741 .name = "ck803efhr1",
742 .llvm_name = "ck803efhr1",
743 .features = featureSet(&[_]Feature{
744 .@"3e3r1",
745 .btst16,
746 .ck803,
747 .dsp1e2,
748 .dspe60,
749 .dspv2,
750 .edsp,
751 .float1e3,
752 .floate1,
753 .fpuv2_sf,
754 .high_registers,
755 .hwdiv,
756 .mp,
757 .nvic,
758 .trust,
759 }),
760 };
761 pub const ck803efhr2 = CpuModel{
762 .name = "ck803efhr2",
763 .llvm_name = "ck803efhr2",
764 .features = featureSet(&[_]Feature{
765 .@"3e3r2",
766 .@"3e3r3",
767 .btst16,
768 .ck803,
769 .dsp1e2,
770 .dspe60,
771 .dspv2,
772 .edsp,
773 .float1e3,
774 .floate1,
775 .fpuv2_sf,
776 .high_registers,
777 .hwdiv,
778 .mp,
779 .nvic,
780 .trust,
781 }),
782 };
783 pub const ck803efhr3 = CpuModel{
784 .name = "ck803efhr3",
785 .llvm_name = "ck803efhr3",
786 .features = featureSet(&[_]Feature{
787 .@"3e3r2",
788 .@"3e3r3",
789 .btst16,
790 .ck803,
791 .dsp1e2,
792 .dspe60,
793 .dspv2,
794 .edsp,
795 .float1e3,
796 .floate1,
797 .fpuv2_sf,
798 .high_registers,
799 .hwdiv,
800 .mp,
801 .nvic,
802 .trust,
803 }),
804 };
805 pub const ck803efht = CpuModel{
806 .name = "ck803efht",
807 .llvm_name = "ck803efht",
808 .features = featureSet(&[_]Feature{
809 .btst16,
810 .ck803,
811 .dsp1e2,
812 .dspe60,
813 .edsp,
814 .float1e3,
815 .floate1,
816 .fpuv2_sf,
817 .hwdiv,
818 .mp,
819 .nvic,
820 .trust,
821 }),
822 };
823 pub const ck803efhtr1 = CpuModel{
824 .name = "ck803efhtr1",
825 .llvm_name = "ck803efhtr1",
826 .features = featureSet(&[_]Feature{
827 .@"3e3r1",
828 .btst16,
829 .ck803,
830 .dsp1e2,
831 .dspe60,
832 .dspv2,
833 .edsp,
834 .float1e3,
835 .floate1,
836 .fpuv2_sf,
837 .high_registers,
838 .hwdiv,
839 .mp,
840 .nvic,
841 .trust,
842 }),
843 };
844 pub const ck803efhtr2 = CpuModel{
845 .name = "ck803efhtr2",
846 .llvm_name = "ck803efhtr2",
847 .features = featureSet(&[_]Feature{
848 .@"3e3r2",
849 .@"3e3r3",
850 .btst16,
851 .ck803,
852 .dsp1e2,
853 .dspe60,
854 .dspv2,
855 .edsp,
856 .float1e3,
857 .floate1,
858 .fpuv2_sf,
859 .high_registers,
860 .hwdiv,
861 .mp,
862 .nvic,
863 .trust,
864 }),
865 };
866 pub const ck803efhtr3 = CpuModel{
867 .name = "ck803efhtr3",
868 .llvm_name = "ck803efhtr3",
869 .features = featureSet(&[_]Feature{
870 .@"3e3r2",
871 .@"3e3r3",
872 .btst16,
873 .ck803,
874 .dsp1e2,
875 .dspe60,
876 .dspv2,
877 .edsp,
878 .float1e3,
879 .floate1,
880 .fpuv2_sf,
881 .high_registers,
882 .hwdiv,
883 .mp,
884 .nvic,
885 .trust,
886 }),
887 };
888 pub const ck803efr1 = CpuModel{
889 .name = "ck803efr1",
890 .llvm_name = "ck803efr1",
891 .features = featureSet(&[_]Feature{
892 .@"3e3r1",
893 .btst16,
894 .ck803,
895 .dsp1e2,
896 .dspe60,
897 .dspv2,
898 .edsp,
899 .float1e3,
900 .floate1,
901 .fpuv2_sf,
902 .high_registers,
903 .hwdiv,
904 .mp,
905 .nvic,
906 .trust,
907 }),
908 };
909 pub const ck803efr2 = CpuModel{
910 .name = "ck803efr2",
911 .llvm_name = "ck803efr2",
912 .features = featureSet(&[_]Feature{
913 .@"3e3r2",
914 .@"3e3r3",
915 .btst16,
916 .ck803,
917 .dsp1e2,
918 .dspe60,
919 .dspv2,
920 .edsp,
921 .float1e3,
922 .floate1,
923 .fpuv2_sf,
924 .high_registers,
925 .hwdiv,
926 .mp,
927 .nvic,
928 .trust,
929 }),
930 };
931 pub const ck803efr3 = CpuModel{
932 .name = "ck803efr3",
933 .llvm_name = "ck803efr3",
934 .features = featureSet(&[_]Feature{
935 .@"3e3r2",
936 .@"3e3r3",
937 .btst16,
938 .ck803,
939 .dsp1e2,
940 .dspe60,
941 .dspv2,
942 .edsp,
943 .float1e3,
944 .floate1,
945 .fpuv2_sf,
946 .high_registers,
947 .hwdiv,
948 .mp,
949 .nvic,
950 .trust,
951 }),
952 };
953 pub const ck803eft = CpuModel{
954 .name = "ck803eft",
955 .llvm_name = "ck803eft",
956 .features = featureSet(&[_]Feature{
957 .btst16,
958 .ck803,
959 .dsp1e2,
960 .dspe60,
961 .edsp,
962 .float1e3,
963 .floate1,
964 .fpuv2_sf,
965 .hwdiv,
966 .mp,
967 .nvic,
968 .trust,
969 }),
970 };
971 pub const ck803eftr1 = CpuModel{
972 .name = "ck803eftr1",
973 .llvm_name = "ck803eftr1",
974 .features = featureSet(&[_]Feature{
975 .@"3e3r1",
976 .btst16,
977 .ck803,
978 .dsp1e2,
979 .dspe60,
980 .dspv2,
981 .edsp,
982 .float1e3,
983 .floate1,
984 .fpuv2_sf,
985 .high_registers,
986 .hwdiv,
987 .mp,
988 .nvic,
989 .trust,
990 }),
991 };
992 pub const ck803eftr2 = CpuModel{
993 .name = "ck803eftr2",
994 .llvm_name = "ck803eftr2",
995 .features = featureSet(&[_]Feature{
996 .@"3e3r2",
997 .@"3e3r3",
998 .btst16,
999 .ck803,
1000 .dsp1e2,
1001 .dspe60,
1002 .dspv2,
1003 .edsp,
1004 .float1e3,
1005 .floate1,
1006 .fpuv2_sf,
1007 .high_registers,
1008 .hwdiv,
1009 .mp,
1010 .nvic,
1011 .trust,
1012 }),
1013 };
1014 pub const ck803eftr3 = CpuModel{
1015 .name = "ck803eftr3",
1016 .llvm_name = "ck803eftr3",
1017 .features = featureSet(&[_]Feature{
1018 .@"3e3r2",
1019 .@"3e3r3",
1020 .btst16,
1021 .ck803,
1022 .dsp1e2,
1023 .dspe60,
1024 .dspv2,
1025 .edsp,
1026 .float1e3,
1027 .floate1,
1028 .fpuv2_sf,
1029 .high_registers,
1030 .hwdiv,
1031 .mp,
1032 .nvic,
1033 .trust,
1034 }),
1035 };
1036 pub const ck803eh = CpuModel{
1037 .name = "ck803eh",
1038 .llvm_name = "ck803eh",
1039 .features = featureSet(&[_]Feature{
1040 .btst16,
1041 .ck803,
1042 .dsp1e2,
1043 .dspe60,
1044 .edsp,
1045 .hwdiv,
1046 .mp,
1047 .nvic,
1048 .trust,
1049 }),
1050 };
1051 pub const ck803ehr1 = CpuModel{
1052 .name = "ck803ehr1",
1053 .llvm_name = "ck803ehr1",
1054 .features = featureSet(&[_]Feature{
1055 .@"3e3r1",
1056 .@"3e3r3",
1057 .btst16,
1058 .ck803,
1059 .dsp1e2,
1060 .dspe60,
1061 .dspv2,
1062 .edsp,
1063 .high_registers,
1064 .hwdiv,
1065 .mp,
1066 .nvic,
1067 .trust,
1068 }),
1069 };
1070 pub const ck803ehr2 = CpuModel{
1071 .name = "ck803ehr2",
1072 .llvm_name = "ck803ehr2",
1073 .features = featureSet(&[_]Feature{
1074 .@"3e3r2",
1075 .@"3e3r3",
1076 .btst16,
1077 .ck803,
1078 .dsp1e2,
1079 .dspe60,
1080 .dspv2,
1081 .edsp,
1082 .high_registers,
1083 .hwdiv,
1084 .mp,
1085 .nvic,
1086 .trust,
1087 }),
1088 };
1089 pub const ck803ehr3 = CpuModel{
1090 .name = "ck803ehr3",
1091 .llvm_name = "ck803ehr3",
1092 .features = featureSet(&[_]Feature{
1093 .@"3e3r2",
1094 .@"3e3r3",
1095 .btst16,
1096 .ck803,
1097 .dsp1e2,
1098 .dspe60,
1099 .dspv2,
1100 .edsp,
1101 .high_registers,
1102 .hwdiv,
1103 .mp,
1104 .nvic,
1105 .trust,
1106 }),
1107 };
1108 pub const ck803eht = CpuModel{
1109 .name = "ck803eht",
1110 .llvm_name = "ck803eht",
1111 .features = featureSet(&[_]Feature{
1112 .btst16,
1113 .ck803,
1114 .dsp1e2,
1115 .dspe60,
1116 .edsp,
1117 .hwdiv,
1118 .mp,
1119 .nvic,
1120 .trust,
1121 }),
1122 };
1123 pub const ck803ehtr1 = CpuModel{
1124 .name = "ck803ehtr1",
1125 .llvm_name = "ck803ehtr1",
1126 .features = featureSet(&[_]Feature{
1127 .@"3e3r1",
1128 .@"3e3r3",
1129 .btst16,
1130 .ck803,
1131 .dsp1e2,
1132 .dspe60,
1133 .dspv2,
1134 .edsp,
1135 .high_registers,
1136 .hwdiv,
1137 .mp,
1138 .nvic,
1139 .trust,
1140 }),
1141 };
1142 pub const ck803ehtr2 = CpuModel{
1143 .name = "ck803ehtr2",
1144 .llvm_name = "ck803ehtr2",
1145 .features = featureSet(&[_]Feature{
1146 .@"3e3r2",
1147 .@"3e3r3",
1148 .btst16,
1149 .ck803,
1150 .dsp1e2,
1151 .dspe60,
1152 .dspv2,
1153 .edsp,
1154 .high_registers,
1155 .hwdiv,
1156 .mp,
1157 .nvic,
1158 .trust,
1159 }),
1160 };
1161 pub const ck803ehtr3 = CpuModel{
1162 .name = "ck803ehtr3",
1163 .llvm_name = "ck803ehtr3",
1164 .features = featureSet(&[_]Feature{
1165 .@"3e3r2",
1166 .@"3e3r3",
1167 .btst16,
1168 .ck803,
1169 .dsp1e2,
1170 .dspe60,
1171 .dspv2,
1172 .edsp,
1173 .high_registers,
1174 .hwdiv,
1175 .mp,
1176 .nvic,
1177 .trust,
1178 }),
1179 };
1180 pub const ck803er1 = CpuModel{
1181 .name = "ck803er1",
1182 .llvm_name = "ck803er1",
1183 .features = featureSet(&[_]Feature{
1184 .@"3e3r1",
1185 .@"3e3r3",
1186 .btst16,
1187 .ck803,
1188 .dsp1e2,
1189 .dspe60,
1190 .dspv2,
1191 .edsp,
1192 .high_registers,
1193 .hwdiv,
1194 .mp,
1195 .nvic,
1196 .trust,
1197 }),
1198 };
1199 pub const ck803er2 = CpuModel{
1200 .name = "ck803er2",
1201 .llvm_name = "ck803er2",
1202 .features = featureSet(&[_]Feature{
1203 .@"3e3r2",
1204 .@"3e3r3",
1205 .btst16,
1206 .ck803,
1207 .dsp1e2,
1208 .dspe60,
1209 .dspv2,
1210 .edsp,
1211 .high_registers,
1212 .hwdiv,
1213 .mp,
1214 .nvic,
1215 .trust,
1216 }),
1217 };
1218 pub const ck803er3 = CpuModel{
1219 .name = "ck803er3",
1220 .llvm_name = "ck803er3",
1221 .features = featureSet(&[_]Feature{
1222 .@"3e3r2",
1223 .@"3e3r3",
1224 .btst16,
1225 .ck803,
1226 .dsp1e2,
1227 .dspe60,
1228 .dspv2,
1229 .edsp,
1230 .high_registers,
1231 .hwdiv,
1232 .mp,
1233 .nvic,
1234 .trust,
1235 }),
1236 };
1237 pub const ck803et = CpuModel{
1238 .name = "ck803et",
1239 .llvm_name = "ck803et",
1240 .features = featureSet(&[_]Feature{
1241 .btst16,
1242 .ck803,
1243 .dsp1e2,
1244 .dspe60,
1245 .edsp,
1246 .hwdiv,
1247 .mp,
1248 .nvic,
1249 .trust,
1250 }),
1251 };
1252 pub const ck803etr1 = CpuModel{
1253 .name = "ck803etr1",
1254 .llvm_name = "ck803etr1",
1255 .features = featureSet(&[_]Feature{
1256 .@"3e3r1",
1257 .@"3e3r3",
1258 .btst16,
1259 .ck803,
1260 .dsp1e2,
1261 .dspe60,
1262 .dspv2,
1263 .edsp,
1264 .high_registers,
1265 .hwdiv,
1266 .mp,
1267 .nvic,
1268 .trust,
1269 }),
1270 };
1271 pub const ck803etr2 = CpuModel{
1272 .name = "ck803etr2",
1273 .llvm_name = "ck803etr2",
1274 .features = featureSet(&[_]Feature{
1275 .@"3e3r2",
1276 .@"3e3r3",
1277 .btst16,
1278 .ck803,
1279 .dsp1e2,
1280 .dspe60,
1281 .dspv2,
1282 .edsp,
1283 .high_registers,
1284 .hwdiv,
1285 .mp,
1286 .nvic,
1287 .trust,
1288 }),
1289 };
1290 pub const ck803etr3 = CpuModel{
1291 .name = "ck803etr3",
1292 .llvm_name = "ck803etr3",
1293 .features = featureSet(&[_]Feature{
1294 .@"3e3r2",
1295 .@"3e3r3",
1296 .btst16,
1297 .ck803,
1298 .dsp1e2,
1299 .dspe60,
1300 .dspv2,
1301 .edsp,
1302 .high_registers,
1303 .hwdiv,
1304 .mp,
1305 .nvic,
1306 .trust,
1307 }),
1308 };
1309 pub const ck803f = CpuModel{
1310 .name = "ck803f",
1311 .llvm_name = "ck803f",
1312 .features = featureSet(&[_]Feature{
1313 .btst16,
1314 .ck803,
1315 .float1e3,
1316 .floate1,
1317 .fpuv2_sf,
1318 .hwdiv,
1319 .mp,
1320 .nvic,
1321 .trust,
1322 }),
1323 };
1324 pub const ck803fh = CpuModel{
1325 .name = "ck803fh",
1326 .llvm_name = "ck803fh",
1327 .features = featureSet(&[_]Feature{
1328 .btst16,
1329 .ck803,
1330 .float1e3,
1331 .floate1,
1332 .fpuv2_sf,
1333 .hwdiv,
1334 .mp,
1335 .nvic,
1336 .trust,
1337 }),
1338 };
1339 pub const ck803fhr1 = CpuModel{
1340 .name = "ck803fhr1",
1341 .llvm_name = "ck803fhr1",
1342 .features = featureSet(&[_]Feature{
1343 .@"3e3r1",
1344 .@"3e3r3",
1345 .btst16,
1346 .ck803,
1347 .dspv2,
1348 .float1e3,
1349 .floate1,
1350 .fpuv2_sf,
1351 .hwdiv,
1352 .mp,
1353 .nvic,
1354 .trust,
1355 }),
1356 };
1357 pub const ck803fhr2 = CpuModel{
1358 .name = "ck803fhr2",
1359 .llvm_name = "ck803fhr2",
1360 .features = featureSet(&[_]Feature{
1361 .@"3e3r2",
1362 .@"3e3r3",
1363 .btst16,
1364 .ck803,
1365 .dspv2,
1366 .float1e3,
1367 .floate1,
1368 .fpuv2_sf,
1369 .hwdiv,
1370 .mp,
1371 .nvic,
1372 .trust,
1373 }),
1374 };
1375 pub const ck803fhr3 = CpuModel{
1376 .name = "ck803fhr3",
1377 .llvm_name = "ck803fhr3",
1378 .features = featureSet(&[_]Feature{
1379 .@"3e3r2",
1380 .@"3e3r3",
1381 .btst16,
1382 .ck803,
1383 .dspv2,
1384 .float1e3,
1385 .floate1,
1386 .fpuv2_sf,
1387 .hwdiv,
1388 .mp,
1389 .nvic,
1390 .trust,
1391 }),
1392 };
1393 pub const ck803fr1 = CpuModel{
1394 .name = "ck803fr1",
1395 .llvm_name = "ck803fr1",
1396 .features = featureSet(&[_]Feature{
1397 .@"3e3r1",
1398 .@"3e3r3",
1399 .btst16,
1400 .ck803,
1401 .dspv2,
1402 .float1e3,
1403 .floate1,
1404 .fpuv2_sf,
1405 .hwdiv,
1406 .mp,
1407 .nvic,
1408 .trust,
1409 }),
1410 };
1411 pub const ck803fr2 = CpuModel{
1412 .name = "ck803fr2",
1413 .llvm_name = "ck803fr2",
1414 .features = featureSet(&[_]Feature{
1415 .@"3e3r2",
1416 .@"3e3r3",
1417 .btst16,
1418 .ck803,
1419 .dspv2,
1420 .float1e3,
1421 .floate1,
1422 .fpuv2_sf,
1423 .hwdiv,
1424 .mp,
1425 .nvic,
1426 .trust,
1427 }),
1428 };
1429 pub const ck803fr3 = CpuModel{
1430 .name = "ck803fr3",
1431 .llvm_name = "ck803fr3",
1432 .features = featureSet(&[_]Feature{
1433 .@"3e3r2",
1434 .@"3e3r3",
1435 .btst16,
1436 .ck803,
1437 .dspv2,
1438 .float1e3,
1439 .floate1,
1440 .fpuv2_sf,
1441 .hwdiv,
1442 .mp,
1443 .nvic,
1444 .trust,
1445 }),
1446 };
1447 pub const ck803ft = CpuModel{
1448 .name = "ck803ft",
1449 .llvm_name = "ck803ft",
1450 .features = featureSet(&[_]Feature{
1451 .btst16,
1452 .ck803,
1453 .float1e3,
1454 .floate1,
1455 .fpuv2_sf,
1456 .hwdiv,
1457 .mp,
1458 .nvic,
1459 .trust,
1460 }),
1461 };
1462 pub const ck803ftr1 = CpuModel{
1463 .name = "ck803ftr1",
1464 .llvm_name = "ck803ftr1",
1465 .features = featureSet(&[_]Feature{
1466 .@"3e3r1",
1467 .btst16,
1468 .ck803,
1469 .dspv2,
1470 .float1e3,
1471 .floate1,
1472 .fpuv2_sf,
1473 .hwdiv,
1474 .mp,
1475 .nvic,
1476 .trust,
1477 }),
1478 };
1479 pub const ck803ftr2 = CpuModel{
1480 .name = "ck803ftr2",
1481 .llvm_name = "ck803ftr2",
1482 .features = featureSet(&[_]Feature{
1483 .@"3e3r2",
1484 .@"3e3r3",
1485 .btst16,
1486 .ck803,
1487 .dspv2,
1488 .float1e3,
1489 .floate1,
1490 .fpuv2_sf,
1491 .hwdiv,
1492 .mp,
1493 .nvic,
1494 .trust,
1495 }),
1496 };
1497 pub const ck803ftr3 = CpuModel{
1498 .name = "ck803ftr3",
1499 .llvm_name = "ck803ftr3",
1500 .features = featureSet(&[_]Feature{
1501 .@"3e3r2",
1502 .@"3e3r3",
1503 .btst16,
1504 .ck803,
1505 .dspv2,
1506 .float1e3,
1507 .floate1,
1508 .fpuv2_sf,
1509 .hwdiv,
1510 .mp,
1511 .nvic,
1512 .trust,
1513 }),
1514 };
1515 pub const ck803h = CpuModel{
1516 .name = "ck803h",
1517 .llvm_name = "ck803h",
1518 .features = featureSet(&[_]Feature{
1519 .btst16,
1520 .ck803,
1521 .hwdiv,
1522 .mp,
1523 .nvic,
1524 .trust,
1525 }),
1526 };
1527 pub const ck803hr1 = CpuModel{
1528 .name = "ck803hr1",
1529 .llvm_name = "ck803hr1",
1530 .features = featureSet(&[_]Feature{
1531 .@"3e3r1",
1532 .@"3e3r3",
1533 .btst16,
1534 .ck803,
1535 .dspv2,
1536 .hwdiv,
1537 .mp,
1538 .nvic,
1539 .trust,
1540 }),
1541 };
1542 pub const ck803hr2 = CpuModel{
1543 .name = "ck803hr2",
1544 .llvm_name = "ck803hr2",
1545 .features = featureSet(&[_]Feature{
1546 .@"3e3r2",
1547 .@"3e3r3",
1548 .btst16,
1549 .ck803,
1550 .dspv2,
1551 .hwdiv,
1552 .mp,
1553 .nvic,
1554 .trust,
1555 }),
1556 };
1557 pub const ck803hr3 = CpuModel{
1558 .name = "ck803hr3",
1559 .llvm_name = "ck803hr3",
1560 .features = featureSet(&[_]Feature{
1561 .@"3e3r2",
1562 .@"3e3r3",
1563 .btst16,
1564 .ck803,
1565 .dspv2,
1566 .hwdiv,
1567 .mp,
1568 .nvic,
1569 .trust,
1570 }),
1571 };
1572 pub const ck803ht = CpuModel{
1573 .name = "ck803ht",
1574 .llvm_name = "ck803ht",
1575 .features = featureSet(&[_]Feature{
1576 .btst16,
1577 .ck803,
1578 .hwdiv,
1579 .mp,
1580 .nvic,
1581 .trust,
1582 }),
1583 };
1584 pub const ck803htr1 = CpuModel{
1585 .name = "ck803htr1",
1586 .llvm_name = "ck803htr1",
1587 .features = featureSet(&[_]Feature{
1588 .@"3e3r1",
1589 .@"3e3r3",
1590 .btst16,
1591 .ck803,
1592 .dspv2,
1593 .hwdiv,
1594 .mp,
1595 .nvic,
1596 .trust,
1597 }),
1598 };
1599 pub const ck803htr2 = CpuModel{
1600 .name = "ck803htr2",
1601 .llvm_name = "ck803htr2",
1602 .features = featureSet(&[_]Feature{
1603 .@"3e3r2",
1604 .@"3e3r3",
1605 .btst16,
1606 .ck803,
1607 .dspv2,
1608 .hwdiv,
1609 .mp,
1610 .nvic,
1611 .trust,
1612 }),
1613 };
1614 pub const ck803htr3 = CpuModel{
1615 .name = "ck803htr3",
1616 .llvm_name = "ck803htr3",
1617 .features = featureSet(&[_]Feature{
1618 .@"3e3r2",
1619 .@"3e3r3",
1620 .btst16,
1621 .ck803,
1622 .dspv2,
1623 .hwdiv,
1624 .mp,
1625 .nvic,
1626 .trust,
1627 }),
1628 };
1629 pub const ck803r1 = CpuModel{
1630 .name = "ck803r1",
1631 .llvm_name = "ck803r1",
1632 .features = featureSet(&[_]Feature{
1633 .@"3e3r1",
1634 .@"3e3r3",
1635 .btst16,
1636 .ck803,
1637 .dspv2,
1638 .hwdiv,
1639 .mp,
1640 .nvic,
1641 .trust,
1642 }),
1643 };
1644 pub const ck803r2 = CpuModel{
1645 .name = "ck803r2",
1646 .llvm_name = "ck803r2",
1647 .features = featureSet(&[_]Feature{
1648 .@"3e3r2",
1649 .@"3e3r3",
1650 .btst16,
1651 .ck803,
1652 .dspv2,
1653 .hwdiv,
1654 .mp,
1655 .nvic,
1656 .trust,
1657 }),
1658 };
1659 pub const ck803r3 = CpuModel{
1660 .name = "ck803r3",
1661 .llvm_name = "ck803r3",
1662 .features = featureSet(&[_]Feature{
1663 .@"3e3r2",
1664 .@"3e3r3",
1665 .btst16,
1666 .ck803,
1667 .dspv2,
1668 .hwdiv,
1669 .mp,
1670 .nvic,
1671 .trust,
1672 }),
1673 };
1674 pub const ck803s = CpuModel{
1675 .name = "ck803s",
1676 .llvm_name = "ck803s",
1677 .features = featureSet(&[_]Feature{
1678 .@"3e3r1",
1679 .btst16,
1680 .ck803,
1681 .ck803s,
1682 .hwdiv,
1683 .mp,
1684 .nvic,
1685 .trust,
1686 }),
1687 };
1688 pub const ck803se = CpuModel{
1689 .name = "ck803se",
1690 .llvm_name = "ck803se",
1691 .features = featureSet(&[_]Feature{
1692 .@"3e3r1",
1693 .btst16,
1694 .ck803,
1695 .ck803s,
1696 .dsp1e2,
1697 .dspe60,
1698 .edsp,
1699 .hwdiv,
1700 .mp,
1701 .nvic,
1702 .trust,
1703 }),
1704 };
1705 pub const ck803sef = CpuModel{
1706 .name = "ck803sef",
1707 .llvm_name = "ck803sef",
1708 .features = featureSet(&[_]Feature{
1709 .@"3e3r1",
1710 .btst16,
1711 .ck803,
1712 .ck803s,
1713 .dsp1e2,
1714 .dspe60,
1715 .edsp,
1716 .float1e3,
1717 .floate1,
1718 .fpuv2_sf,
1719 .hwdiv,
1720 .mp,
1721 .nvic,
1722 .trust,
1723 }),
1724 };
1725 pub const ck803sefn = CpuModel{
1726 .name = "ck803sefn",
1727 .llvm_name = "ck803sefn",
1728 .features = featureSet(&[_]Feature{
1729 .@"3e3r1",
1730 .btst16,
1731 .ck803,
1732 .ck803s,
1733 .dsp1e2,
1734 .dsp_silan,
1735 .dspe60,
1736 .edsp,
1737 .float1e3,
1738 .floate1,
1739 .fpuv2_sf,
1740 .hwdiv,
1741 .mp,
1742 .nvic,
1743 .trust,
1744 }),
1745 };
1746 pub const ck803sefnt = CpuModel{
1747 .name = "ck803sefnt",
1748 .llvm_name = "ck803sefnt",
1749 .features = featureSet(&[_]Feature{
1750 .@"3e3r1",
1751 .btst16,
1752 .ck803,
1753 .ck803s,
1754 .dsp1e2,
1755 .dsp_silan,
1756 .dspe60,
1757 .edsp,
1758 .float1e3,
1759 .floate1,
1760 .fpuv2_sf,
1761 .hwdiv,
1762 .mp,
1763 .nvic,
1764 .trust,
1765 }),
1766 };
1767 pub const ck803seft = CpuModel{
1768 .name = "ck803seft",
1769 .llvm_name = "ck803seft",
1770 .features = featureSet(&[_]Feature{
1771 .@"3e3r1",
1772 .btst16,
1773 .ck803,
1774 .ck803s,
1775 .dsp1e2,
1776 .dspe60,
1777 .edsp,
1778 .float1e3,
1779 .floate1,
1780 .fpuv2_sf,
1781 .hwdiv,
1782 .mp,
1783 .nvic,
1784 .trust,
1785 }),
1786 };
1787 pub const ck803sen = CpuModel{
1788 .name = "ck803sen",
1789 .llvm_name = "ck803sen",
1790 .features = featureSet(&[_]Feature{
1791 .@"3e3r1",
1792 .btst16,
1793 .ck803,
1794 .ck803s,
1795 .dsp1e2,
1796 .dsp_silan,
1797 .dspe60,
1798 .edsp,
1799 .hwdiv,
1800 .mp,
1801 .nvic,
1802 .trust,
1803 }),
1804 };
1805 pub const ck803sf = CpuModel{
1806 .name = "ck803sf",
1807 .llvm_name = "ck803sf",
1808 .features = featureSet(&[_]Feature{
1809 .@"3e3r1",
1810 .btst16,
1811 .ck803,
1812 .ck803s,
1813 .float1e3,
1814 .floate1,
1815 .fpuv2_sf,
1816 .hwdiv,
1817 .mp,
1818 .nvic,
1819 .trust,
1820 }),
1821 };
1822 pub const ck803sfn = CpuModel{
1823 .name = "ck803sfn",
1824 .llvm_name = "ck803sfn",
1825 .features = featureSet(&[_]Feature{
1826 .@"3e3r1",
1827 .btst16,
1828 .ck803,
1829 .ck803s,
1830 .dsp_silan,
1831 .float1e3,
1832 .floate1,
1833 .fpuv2_sf,
1834 .hwdiv,
1835 .mp,
1836 .nvic,
1837 .trust,
1838 }),
1839 };
1840 pub const ck803sn = CpuModel{
1841 .name = "ck803sn",
1842 .llvm_name = "ck803sn",
1843 .features = featureSet(&[_]Feature{
1844 .@"3e3r1",
1845 .btst16,
1846 .ck803,
1847 .ck803s,
1848 .dsp_silan,
1849 .hwdiv,
1850 .mp,
1851 .nvic,
1852 .trust,
1853 }),
1854 };
1855 pub const ck803snt = CpuModel{
1856 .name = "ck803snt",
1857 .llvm_name = "ck803snt",
1858 .features = featureSet(&[_]Feature{
1859 .@"3e3r1",
1860 .btst16,
1861 .ck803,
1862 .ck803s,
1863 .dsp_silan,
1864 .hwdiv,
1865 .mp,
1866 .nvic,
1867 .trust,
1868 }),
1869 };
1870 pub const ck803st = CpuModel{
1871 .name = "ck803st",
1872 .llvm_name = "ck803st",
1873 .features = featureSet(&[_]Feature{
1874 .@"3e3r1",
1875 .btst16,
1876 .ck803,
1877 .ck803s,
1878 .hwdiv,
1879 .mp,
1880 .nvic,
1881 .trust,
1882 }),
1883 };
1884 pub const ck803t = CpuModel{
1885 .name = "ck803t",
1886 .llvm_name = "ck803t",
1887 .features = featureSet(&[_]Feature{
1888 .btst16,
1889 .ck803,
1890 .hwdiv,
1891 .mp,
1892 .nvic,
1893 .trust,
1894 }),
1895 };
1896 pub const ck803tr1 = CpuModel{
1897 .name = "ck803tr1",
1898 .llvm_name = "ck803tr1",
1899 .features = featureSet(&[_]Feature{
1900 .@"3e3r1",
1901 .@"3e3r3",
1902 .btst16,
1903 .ck803,
1904 .dspv2,
1905 .hwdiv,
1906 .mp,
1907 .nvic,
1908 .trust,
1909 }),
1910 };
1911 pub const ck803tr2 = CpuModel{
1912 .name = "ck803tr2",
1913 .llvm_name = "ck803tr2",
1914 .features = featureSet(&[_]Feature{
1915 .@"3e3r2",
1916 .@"3e3r3",
1917 .btst16,
1918 .ck803,
1919 .dspv2,
1920 .hwdiv,
1921 .mp,
1922 .nvic,
1923 .trust,
1924 }),
1925 };
1926 pub const ck803tr3 = CpuModel{
1927 .name = "ck803tr3",
1928 .llvm_name = "ck803tr3",
1929 .features = featureSet(&[_]Feature{
1930 .@"3e3r2",
1931 .@"3e3r3",
1932 .btst16,
1933 .ck803,
1934 .dspv2,
1935 .hwdiv,
1936 .mp,
1937 .nvic,
1938 .trust,
1939 }),
1940 };
1941 pub const ck804 = CpuModel{
1942 .name = "ck804",
1943 .llvm_name = "ck804",
1944 .features = featureSet(&[_]Feature{
1945 .@"3e3r2",
1946 .@"3e3r3",
1947 .btst16,
1948 .ck803,
1949 .ck804,
1950 .hwdiv,
1951 .mp,
1952 .nvic,
1953 .trust,
1954 }),
1955 };
1956 pub const ck804e = CpuModel{
1957 .name = "ck804e",
1958 .llvm_name = "ck804e",
1959 .features = featureSet(&[_]Feature{
1960 .@"3e3r2",
1961 .@"3e3r3",
1962 .btst16,
1963 .ck803,
1964 .ck804,
1965 .dspv2,
1966 .high_registers,
1967 .hwdiv,
1968 .mp,
1969 .nvic,
1970 .trust,
1971 }),
1972 };
1973 pub const ck804ef = CpuModel{
1974 .name = "ck804ef",
1975 .llvm_name = "ck804ef",
1976 .features = featureSet(&[_]Feature{
1977 .@"3e3r2",
1978 .@"3e3r3",
1979 .btst16,
1980 .ck803,
1981 .ck804,
1982 .dspv2,
1983 .float1e3,
1984 .floate1,
1985 .fpuv2_sf,
1986 .high_registers,
1987 .hwdiv,
1988 .mp,
1989 .nvic,
1990 .trust,
1991 }),
1992 };
1993 pub const ck804efh = CpuModel{
1994 .name = "ck804efh",
1995 .llvm_name = "ck804efh",
1996 .features = featureSet(&[_]Feature{
1997 .@"3e3r2",
1998 .@"3e3r3",
1999 .btst16,
2000 .ck803,
2001 .ck804,
2002 .dspv2,
2003 .float1e3,
2004 .floate1,
2005 .fpuv2_sf,
2006 .high_registers,
2007 .hwdiv,
2008 .mp,
2009 .nvic,
2010 .trust,
2011 }),
2012 };
2013 pub const ck804efht = CpuModel{
2014 .name = "ck804efht",
2015 .llvm_name = "ck804efht",
2016 .features = featureSet(&[_]Feature{
2017 .@"3e3r2",
2018 .@"3e3r3",
2019 .btst16,
2020 .ck803,
2021 .ck804,
2022 .dspv2,
2023 .float1e3,
2024 .floate1,
2025 .fpuv2_sf,
2026 .high_registers,
2027 .hwdiv,
2028 .mp,
2029 .nvic,
2030 .trust,
2031 }),
2032 };
2033 pub const ck804eft = CpuModel{
2034 .name = "ck804eft",
2035 .llvm_name = "ck804eft",
2036 .features = featureSet(&[_]Feature{
2037 .@"3e3r2",
2038 .@"3e3r3",
2039 .btst16,
2040 .ck803,
2041 .ck804,
2042 .dspv2,
2043 .float1e3,
2044 .floate1,
2045 .fpuv2_sf,
2046 .high_registers,
2047 .hwdiv,
2048 .mp,
2049 .nvic,
2050 .trust,
2051 }),
2052 };
2053 pub const ck804eh = CpuModel{
2054 .name = "ck804eh",
2055 .llvm_name = "ck804eh",
2056 .features = featureSet(&[_]Feature{
2057 .@"3e3r2",
2058 .@"3e3r3",
2059 .btst16,
2060 .ck803,
2061 .ck804,
2062 .dspv2,
2063 .high_registers,
2064 .hwdiv,
2065 .mp,
2066 .nvic,
2067 .trust,
2068 }),
2069 };
2070 pub const ck804eht = CpuModel{
2071 .name = "ck804eht",
2072 .llvm_name = "ck804eht",
2073 .features = featureSet(&[_]Feature{
2074 .@"3e3r2",
2075 .@"3e3r3",
2076 .btst16,
2077 .ck803,
2078 .ck804,
2079 .dspv2,
2080 .high_registers,
2081 .hwdiv,
2082 .mp,
2083 .nvic,
2084 .trust,
2085 }),
2086 };
2087 pub const ck804et = CpuModel{
2088 .name = "ck804et",
2089 .llvm_name = "ck804et",
2090 .features = featureSet(&[_]Feature{
2091 .@"3e3r2",
2092 .@"3e3r3",
2093 .btst16,
2094 .ck803,
2095 .ck804,
2096 .dspv2,
2097 .high_registers,
2098 .hwdiv,
2099 .mp,
2100 .nvic,
2101 .trust,
2102 }),
2103 };
2104 pub const ck804f = CpuModel{
2105 .name = "ck804f",
2106 .llvm_name = "ck804f",
2107 .features = featureSet(&[_]Feature{
2108 .@"3e3r2",
2109 .@"3e3r3",
2110 .btst16,
2111 .ck803,
2112 .ck804,
2113 .float1e3,
2114 .floate1,
2115 .fpuv2_sf,
2116 .hwdiv,
2117 .mp,
2118 .nvic,
2119 .trust,
2120 }),
2121 };
2122 pub const ck804fh = CpuModel{
2123 .name = "ck804fh",
2124 .llvm_name = "ck804fh",
2125 .features = featureSet(&[_]Feature{
2126 .@"3e3r2",
2127 .@"3e3r3",
2128 .btst16,
2129 .ck803,
2130 .ck804,
2131 .float1e3,
2132 .floate1,
2133 .fpuv2_sf,
2134 .hwdiv,
2135 .mp,
2136 .nvic,
2137 .trust,
2138 }),
2139 };
2140 pub const ck804ft = CpuModel{
2141 .name = "ck804ft",
2142 .llvm_name = "ck804ft",
2143 .features = featureSet(&[_]Feature{
2144 .@"3e3r2",
2145 .@"3e3r3",
2146 .btst16,
2147 .ck803,
2148 .ck804,
2149 .float1e3,
2150 .floate1,
2151 .fpuv2_sf,
2152 .hwdiv,
2153 .mp,
2154 .nvic,
2155 .trust,
2156 }),
2157 };
2158 pub const ck804h = CpuModel{
2159 .name = "ck804h",
2160 .llvm_name = "ck804h",
2161 .features = featureSet(&[_]Feature{
2162 .@"3e3r2",
2163 .@"3e3r3",
2164 .btst16,
2165 .ck803,
2166 .ck804,
2167 .hwdiv,
2168 .mp,
2169 .nvic,
2170 .trust,
2171 }),
2172 };
2173 pub const ck804ht = CpuModel{
2174 .name = "ck804ht",
2175 .llvm_name = "ck804ht",
2176 .features = featureSet(&[_]Feature{
2177 .@"3e3r2",
2178 .@"3e3r3",
2179 .btst16,
2180 .ck803,
2181 .ck804,
2182 .hwdiv,
2183 .mp,
2184 .nvic,
2185 .trust,
2186 }),
2187 };
2188 pub const ck804t = CpuModel{
2189 .name = "ck804t",
2190 .llvm_name = "ck804t",
2191 .features = featureSet(&[_]Feature{
2192 .@"3e3r2",
2193 .@"3e3r3",
2194 .btst16,
2195 .ck803,
2196 .ck804,
2197 .hwdiv,
2198 .mp,
2199 .nvic,
2200 .trust,
2201 }),
2202 };
2203 pub const ck805 = CpuModel{
2204 .name = "ck805",
2205 .llvm_name = "ck805",
2206 .features = featureSet(&[_]Feature{
2207 .@"3e3r2",
2208 .@"3e3r3",
2209 .btst16,
2210 .ck803,
2211 .ck805,
2212 .high_registers,
2213 .hwdiv,
2214 .mp,
2215 .nvic,
2216 .trust,
2217 .vdsp2e3,
2218 .vdspv2,
2219 }),
2220 };
2221 pub const ck805e = CpuModel{
2222 .name = "ck805e",
2223 .llvm_name = "ck805e",
2224 .features = featureSet(&[_]Feature{
2225 .@"3e3r2",
2226 .@"3e3r3",
2227 .btst16,
2228 .ck803,
2229 .ck805,
2230 .dspv2,
2231 .high_registers,
2232 .hwdiv,
2233 .mp,
2234 .nvic,
2235 .trust,
2236 .vdsp2e3,
2237 .vdspv2,
2238 }),
2239 };
2240 pub const ck805ef = CpuModel{
2241 .name = "ck805ef",
2242 .llvm_name = "ck805ef",
2243 .features = featureSet(&[_]Feature{
2244 .@"3e3r2",
2245 .@"3e3r3",
2246 .btst16,
2247 .ck803,
2248 .ck805,
2249 .dspv2,
2250 .float1e3,
2251 .floate1,
2252 .fpuv2_sf,
2253 .high_registers,
2254 .hwdiv,
2255 .mp,
2256 .nvic,
2257 .trust,
2258 .vdsp2e3,
2259 .vdspv2,
2260 }),
2261 };
2262 pub const ck805eft = CpuModel{
2263 .name = "ck805eft",
2264 .llvm_name = "ck805eft",
2265 .features = featureSet(&[_]Feature{
2266 .@"3e3r2",
2267 .@"3e3r3",
2268 .btst16,
2269 .ck803,
2270 .ck805,
2271 .dspv2,
2272 .float1e3,
2273 .floate1,
2274 .fpuv2_sf,
2275 .high_registers,
2276 .hwdiv,
2277 .mp,
2278 .nvic,
2279 .trust,
2280 .vdsp2e3,
2281 .vdspv2,
2282 }),
2283 };
2284 pub const ck805et = CpuModel{
2285 .name = "ck805et",
2286 .llvm_name = "ck805et",
2287 .features = featureSet(&[_]Feature{
2288 .@"3e3r2",
2289 .@"3e3r3",
2290 .btst16,
2291 .ck803,
2292 .ck805,
2293 .dspv2,
2294 .high_registers,
2295 .hwdiv,
2296 .mp,
2297 .nvic,
2298 .trust,
2299 .vdsp2e3,
2300 .vdspv2,
2301 }),
2302 };
2303 pub const ck805f = CpuModel{
2304 .name = "ck805f",
2305 .llvm_name = "ck805f",
2306 .features = featureSet(&[_]Feature{
2307 .@"3e3r2",
2308 .@"3e3r3",
2309 .btst16,
2310 .ck803,
2311 .ck805,
2312 .float1e3,
2313 .floate1,
2314 .fpuv2_sf,
2315 .high_registers,
2316 .hwdiv,
2317 .mp,
2318 .nvic,
2319 .trust,
2320 .vdsp2e3,
2321 .vdspv2,
2322 }),
2323 };
2324 pub const ck805ft = CpuModel{
2325 .name = "ck805ft",
2326 .llvm_name = "ck805ft",
2327 .features = featureSet(&[_]Feature{
2328 .@"3e3r2",
2329 .@"3e3r3",
2330 .btst16,
2331 .ck803,
2332 .ck805,
2333 .float1e3,
2334 .floate1,
2335 .fpuv2_sf,
2336 .high_registers,
2337 .hwdiv,
2338 .mp,
2339 .nvic,
2340 .trust,
2341 .vdsp2e3,
2342 .vdspv2,
2343 }),
2344 };
2345 pub const ck805t = CpuModel{
2346 .name = "ck805t",
2347 .llvm_name = "ck805t",
2348 .features = featureSet(&[_]Feature{
2349 .@"3e3r2",
2350 .@"3e3r3",
2351 .btst16,
2352 .ck803,
2353 .ck805,
2354 .high_registers,
2355 .hwdiv,
2356 .mp,
2357 .nvic,
2358 .trust,
2359 .vdsp2e3,
2360 .vdspv2,
2361 }),
2362 };
2363 pub const ck807 = CpuModel{
2364 .name = "ck807",
2365 .llvm_name = "ck807",
2366 .features = featureSet(&[_]Feature{
2367 .cache,
2368 .ck807,
2369 .dsp1e2,
2370 .dspe60,
2371 .edsp,
2372 .hard_tp,
2373 .high_registers,
2374 .hwdiv,
2375 .mp,
2376 .mp1e2,
2377 .nvic,
2378 .trust,
2379 }),
2380 };
2381 pub const ck807e = CpuModel{
2382 .name = "ck807e",
2383 .llvm_name = "ck807e",
2384 .features = featureSet(&[_]Feature{
2385 .cache,
2386 .ck807,
2387 .dsp1e2,
2388 .dspe60,
2389 .edsp,
2390 .hard_tp,
2391 .high_registers,
2392 .hwdiv,
2393 .mp,
2394 .mp1e2,
2395 .nvic,
2396 .trust,
2397 }),
2398 };
2399 pub const ck807ef = CpuModel{
2400 .name = "ck807ef",
2401 .llvm_name = "ck807ef",
2402 .features = featureSet(&[_]Feature{
2403 .cache,
2404 .ck807,
2405 .dsp1e2,
2406 .dspe60,
2407 .edsp,
2408 .fdivdu,
2409 .float1e2,
2410 .float1e3,
2411 .float3e4,
2412 .floate1,
2413 .fpuv2_df,
2414 .fpuv2_sf,
2415 .hard_tp,
2416 .high_registers,
2417 .hwdiv,
2418 .mp,
2419 .mp1e2,
2420 .nvic,
2421 .trust,
2422 }),
2423 };
2424 pub const ck807f = CpuModel{
2425 .name = "ck807f",
2426 .llvm_name = "ck807f",
2427 .features = featureSet(&[_]Feature{
2428 .cache,
2429 .ck807,
2430 .dsp1e2,
2431 .dspe60,
2432 .edsp,
2433 .fdivdu,
2434 .float1e2,
2435 .float1e3,
2436 .float3e4,
2437 .floate1,
2438 .fpuv2_df,
2439 .fpuv2_sf,
2440 .hard_tp,
2441 .high_registers,
2442 .hwdiv,
2443 .mp,
2444 .mp1e2,
2445 .nvic,
2446 .trust,
2447 }),
2448 };
2449 pub const ck810 = CpuModel{
2450 .name = "ck810",
2451 .llvm_name = "ck810",
2452 .features = featureSet(&[_]Feature{
2453 .@"7e10",
2454 .cache,
2455 .ck810,
2456 .dsp1e2,
2457 .dspe60,
2458 .edsp,
2459 .hard_tp,
2460 .high_registers,
2461 .hwdiv,
2462 .mp,
2463 .mp1e2,
2464 .nvic,
2465 .trust,
2466 }),
2467 };
2468 pub const ck810e = CpuModel{
2469 .name = "ck810e",
2470 .llvm_name = "ck810e",
2471 .features = featureSet(&[_]Feature{
2472 .@"7e10",
2473 .cache,
2474 .ck810,
2475 .dsp1e2,
2476 .dspe60,
2477 .edsp,
2478 .hard_tp,
2479 .high_registers,
2480 .hwdiv,
2481 .mp,
2482 .mp1e2,
2483 .nvic,
2484 .trust,
2485 }),
2486 };
2487 pub const ck810ef = CpuModel{
2488 .name = "ck810ef",
2489 .llvm_name = "ck810ef",
2490 .features = featureSet(&[_]Feature{
2491 .@"7e10",
2492 .cache,
2493 .ck810,
2494 .dsp1e2,
2495 .dspe60,
2496 .edsp,
2497 .fdivdu,
2498 .float1e2,
2499 .floate1,
2500 .fpuv2_df,
2501 .fpuv2_sf,
2502 .hard_tp,
2503 .high_registers,
2504 .hwdiv,
2505 .mp,
2506 .mp1e2,
2507 .nvic,
2508 .trust,
2509 }),
2510 };
2511 pub const ck810eft = CpuModel{
2512 .name = "ck810eft",
2513 .llvm_name = "ck810eft",
2514 .features = featureSet(&[_]Feature{
2515 .@"7e10",
2516 .cache,
2517 .ck810,
2518 .dsp1e2,
2519 .dspe60,
2520 .edsp,
2521 .fdivdu,
2522 .float1e2,
2523 .floate1,
2524 .fpuv2_df,
2525 .fpuv2_sf,
2526 .hard_tp,
2527 .high_registers,
2528 .hwdiv,
2529 .mp,
2530 .mp1e2,
2531 .nvic,
2532 .trust,
2533 }),
2534 };
2535 pub const ck810eftv = CpuModel{
2536 .name = "ck810eftv",
2537 .llvm_name = "ck810eftv",
2538 .features = featureSet(&[_]Feature{
2539 .@"7e10",
2540 .cache,
2541 .ck810,
2542 .ck810v,
2543 .dsp1e2,
2544 .dspe60,
2545 .edsp,
2546 .fdivdu,
2547 .float1e2,
2548 .floate1,
2549 .fpuv2_df,
2550 .fpuv2_sf,
2551 .hard_tp,
2552 .high_registers,
2553 .hwdiv,
2554 .mp,
2555 .mp1e2,
2556 .nvic,
2557 .trust,
2558 .vdspv1,
2559 }),
2560 };
2561 pub const ck810efv = CpuModel{
2562 .name = "ck810efv",
2563 .llvm_name = "ck810efv",
2564 .features = featureSet(&[_]Feature{
2565 .@"7e10",
2566 .cache,
2567 .ck810,
2568 .ck810v,
2569 .dsp1e2,
2570 .dspe60,
2571 .edsp,
2572 .fdivdu,
2573 .float1e2,
2574 .floate1,
2575 .fpuv2_df,
2576 .fpuv2_sf,
2577 .hard_tp,
2578 .high_registers,
2579 .hwdiv,
2580 .mp,
2581 .mp1e2,
2582 .nvic,
2583 .trust,
2584 .vdspv1,
2585 }),
2586 };
2587 pub const ck810et = CpuModel{
2588 .name = "ck810et",
2589 .llvm_name = "ck810et",
2590 .features = featureSet(&[_]Feature{
2591 .@"7e10",
2592 .cache,
2593 .ck810,
2594 .dsp1e2,
2595 .dspe60,
2596 .edsp,
2597 .hard_tp,
2598 .high_registers,
2599 .hwdiv,
2600 .mp,
2601 .mp1e2,
2602 .nvic,
2603 .trust,
2604 }),
2605 };
2606 pub const ck810etv = CpuModel{
2607 .name = "ck810etv",
2608 .llvm_name = "ck810etv",
2609 .features = featureSet(&[_]Feature{
2610 .@"7e10",
2611 .cache,
2612 .ck810,
2613 .ck810v,
2614 .dsp1e2,
2615 .dspe60,
2616 .edsp,
2617 .hard_tp,
2618 .high_registers,
2619 .hwdiv,
2620 .mp,
2621 .mp1e2,
2622 .nvic,
2623 .trust,
2624 .vdspv1,
2625 }),
2626 };
2627 pub const ck810ev = CpuModel{
2628 .name = "ck810ev",
2629 .llvm_name = "ck810ev",
2630 .features = featureSet(&[_]Feature{
2631 .@"7e10",
2632 .cache,
2633 .ck810,
2634 .ck810v,
2635 .dsp1e2,
2636 .dspe60,
2637 .edsp,
2638 .hard_tp,
2639 .high_registers,
2640 .hwdiv,
2641 .mp,
2642 .mp1e2,
2643 .nvic,
2644 .trust,
2645 .vdspv1,
2646 }),
2647 };
2648 pub const ck810f = CpuModel{
2649 .name = "ck810f",
2650 .llvm_name = "ck810f",
2651 .features = featureSet(&[_]Feature{
2652 .@"7e10",
2653 .cache,
2654 .ck810,
2655 .dsp1e2,
2656 .dspe60,
2657 .edsp,
2658 .fdivdu,
2659 .float1e2,
2660 .floate1,
2661 .fpuv2_df,
2662 .fpuv2_sf,
2663 .hard_tp,
2664 .high_registers,
2665 .hwdiv,
2666 .mp,
2667 .mp1e2,
2668 .nvic,
2669 .trust,
2670 }),
2671 };
2672 pub const ck810ft = CpuModel{
2673 .name = "ck810ft",
2674 .llvm_name = "ck810ft",
2675 .features = featureSet(&[_]Feature{
2676 .@"7e10",
2677 .cache,
2678 .ck810,
2679 .dsp1e2,
2680 .dspe60,
2681 .edsp,
2682 .fdivdu,
2683 .float1e2,
2684 .floate1,
2685 .fpuv2_df,
2686 .fpuv2_sf,
2687 .hard_tp,
2688 .high_registers,
2689 .hwdiv,
2690 .mp,
2691 .mp1e2,
2692 .nvic,
2693 .trust,
2694 }),
2695 };
2696 pub const ck810ftv = CpuModel{
2697 .name = "ck810ftv",
2698 .llvm_name = "ck810ftv",
2699 .features = featureSet(&[_]Feature{
2700 .@"7e10",
2701 .cache,
2702 .ck810,
2703 .ck810v,
2704 .dsp1e2,
2705 .dspe60,
2706 .edsp,
2707 .fdivdu,
2708 .float1e2,
2709 .floate1,
2710 .fpuv2_df,
2711 .fpuv2_sf,
2712 .hard_tp,
2713 .high_registers,
2714 .hwdiv,
2715 .mp,
2716 .mp1e2,
2717 .nvic,
2718 .trust,
2719 .vdspv1,
2720 }),
2721 };
2722 pub const ck810fv = CpuModel{
2723 .name = "ck810fv",
2724 .llvm_name = "ck810fv",
2725 .features = featureSet(&[_]Feature{
2726 .@"7e10",
2727 .cache,
2728 .ck810,
2729 .ck810v,
2730 .dsp1e2,
2731 .dspe60,
2732 .edsp,
2733 .fdivdu,
2734 .float1e2,
2735 .floate1,
2736 .fpuv2_df,
2737 .fpuv2_sf,
2738 .hard_tp,
2739 .high_registers,
2740 .hwdiv,
2741 .mp,
2742 .mp1e2,
2743 .nvic,
2744 .trust,
2745 .vdspv1,
2746 }),
2747 };
2748 pub const ck810t = CpuModel{
2749 .name = "ck810t",
2750 .llvm_name = "ck810t",
2751 .features = featureSet(&[_]Feature{
2752 .@"7e10",
2753 .cache,
2754 .ck810,
2755 .dsp1e2,
2756 .dspe60,
2757 .edsp,
2758 .hard_tp,
2759 .high_registers,
2760 .hwdiv,
2761 .mp,
2762 .mp1e2,
2763 .nvic,
2764 .trust,
2765 }),
2766 };
2767 pub const ck810tv = CpuModel{
2768 .name = "ck810tv",
2769 .llvm_name = "ck810tv",
2770 .features = featureSet(&[_]Feature{
2771 .@"7e10",
2772 .cache,
2773 .ck810,
2774 .ck810v,
2775 .dsp1e2,
2776 .dspe60,
2777 .edsp,
2778 .hard_tp,
2779 .high_registers,
2780 .hwdiv,
2781 .mp,
2782 .mp1e2,
2783 .nvic,
2784 .trust,
2785 .vdspv1,
2786 }),
2787 };
2788 pub const ck810v = CpuModel{
2789 .name = "ck810v",
2790 .llvm_name = "ck810v",
2791 .features = featureSet(&[_]Feature{
2792 .@"7e10",
2793 .cache,
2794 .ck810,
2795 .ck810v,
2796 .dsp1e2,
2797 .dspe60,
2798 .edsp,
2799 .hard_tp,
2800 .high_registers,
2801 .hwdiv,
2802 .mp,
2803 .mp1e2,
2804 .nvic,
2805 .trust,
2806 .vdspv1,
2807 }),
2808 };
2809 pub const ck860 = CpuModel{
2810 .name = "ck860",
2811 .llvm_name = "ck860",
2812 .features = featureSet(&[_]Feature{
2813 .@"10e60",
2814 .@"3e3r2",
2815 .@"3e3r3",
2816 .btst16,
2817 .cache,
2818 .ck860,
2819 .dspe60,
2820 .hard_tp,
2821 .high_registers,
2822 .hwdiv,
2823 .mp,
2824 .mp1e2,
2825 .nvic,
2826 .trust,
2827 }),
2828 };
2829 pub const ck860f = CpuModel{
2830 .name = "ck860f",
2831 .llvm_name = "ck860f",
2832 .features = featureSet(&[_]Feature{
2833 .@"10e60",
2834 .@"3e3r2",
2835 .@"3e3r3",
2836 .btst16,
2837 .cache,
2838 .ck860,
2839 .dspe60,
2840 .float7e60,
2841 .fpuv3_df,
2842 .fpuv3_hf,
2843 .fpuv3_hi,
2844 .fpuv3_sf,
2845 .hard_tp,
2846 .high_registers,
2847 .hwdiv,
2848 .mp,
2849 .mp1e2,
2850 .nvic,
2851 .trust,
2852 }),
2853 };
2854 pub const ck860fv = CpuModel{
2855 .name = "ck860fv",
2856 .llvm_name = "ck860fv",
2857 .features = featureSet(&[_]Feature{
2858 .@"10e60",
2859 .@"3e3r2",
2860 .@"3e3r3",
2861 .btst16,
2862 .cache,
2863 .ck860,
2864 .ck860v,
2865 .dspe60,
2866 .float7e60,
2867 .fpuv3_df,
2868 .fpuv3_hf,
2869 .fpuv3_hi,
2870 .fpuv3_sf,
2871 .hard_tp,
2872 .high_registers,
2873 .hwdiv,
2874 .mp,
2875 .mp1e2,
2876 .nvic,
2877 .trust,
2878 .vdsp2e60f,
2879 .vdspv2,
2880 }),
2881 };
2882 pub const ck860v = CpuModel{
2883 .name = "ck860v",
2884 .llvm_name = "ck860v",
2885 .features = featureSet(&[_]Feature{
2886 .@"10e60",
2887 .@"3e3r2",
2888 .@"3e3r3",
2889 .btst16,
2890 .cache,
2891 .ck860,
2892 .ck860v,
2893 .dspe60,
2894 .hard_tp,
2895 .high_registers,
2896 .hwdiv,
2897 .mp,
2898 .mp1e2,
2899 .nvic,
2900 .trust,
2901 .vdsp2e60f,
2902 .vdspv2,
2903 }),
2904 };
2905 pub const e801 = CpuModel{
2906 .name = "e801",
2907 .llvm_name = "e801",
2908 .features = featureSet(&[_]Feature{
2909 .btst16,
2910 .ck801,
2911 .e1,
2912 .trust,
2913 }),
2914 };
2915 pub const e802 = CpuModel{
2916 .name = "e802",
2917 .llvm_name = "e802",
2918 .features = featureSet(&[_]Feature{
2919 .btst16,
2920 .ck802,
2921 .e2,
2922 .nvic,
2923 .trust,
2924 }),
2925 };
2926 pub const e802t = CpuModel{
2927 .name = "e802t",
2928 .llvm_name = "e802t",
2929 .features = featureSet(&[_]Feature{
2930 .btst16,
2931 .ck802,
2932 .e2,
2933 .nvic,
2934 .trust,
2935 }),
2936 };
2937 pub const e803 = CpuModel{
2938 .name = "e803",
2939 .llvm_name = "e803",
2940 .features = featureSet(&[_]Feature{
2941 .@"3e3r2",
2942 .@"3e3r3",
2943 .btst16,
2944 .ck803,
2945 .hwdiv,
2946 .mp,
2947 .nvic,
2948 .trust,
2949 }),
2950 };
2951 pub const e803t = CpuModel{
2952 .name = "e803t",
2953 .llvm_name = "e803t",
2954 .features = featureSet(&[_]Feature{
2955 .@"3e3r2",
2956 .@"3e3r3",
2957 .btst16,
2958 .ck803,
2959 .hwdiv,
2960 .mp,
2961 .nvic,
2962 .trust,
2963 }),
2964 };
2965 pub const e804d = CpuModel{
2966 .name = "e804d",
2967 .llvm_name = "e804d",
2968 .features = featureSet(&[_]Feature{
2969 .@"3e3r2",
2970 .@"3e3r3",
2971 .btst16,
2972 .ck803,
2973 .ck804,
2974 .dspv2,
2975 .high_registers,
2976 .hwdiv,
2977 .mp,
2978 .nvic,
2979 .trust,
2980 }),
2981 };
2982 pub const e804df = CpuModel{
2983 .name = "e804df",
2984 .llvm_name = "e804df",
2985 .features = featureSet(&[_]Feature{
2986 .@"3e3r2",
2987 .@"3e3r3",
2988 .btst16,
2989 .ck803,
2990 .ck804,
2991 .dspv2,
2992 .float1e3,
2993 .floate1,
2994 .fpuv2_sf,
2995 .high_registers,
2996 .hwdiv,
2997 .mp,
2998 .nvic,
2999 .trust,
3000 }),
3001 };
3002 pub const e804dft = CpuModel{
3003 .name = "e804dft",
3004 .llvm_name = "e804dft",
3005 .features = featureSet(&[_]Feature{
3006 .@"3e3r2",
3007 .@"3e3r3",
3008 .btst16,
3009 .ck803,
3010 .ck804,
3011 .dspv2,
3012 .float1e3,
3013 .floate1,
3014 .fpuv2_sf,
3015 .high_registers,
3016 .hwdiv,
3017 .mp,
3018 .nvic,
3019 .trust,
3020 }),
3021 };
3022 pub const e804dt = CpuModel{
3023 .name = "e804dt",
3024 .llvm_name = "e804dt",
3025 .features = featureSet(&[_]Feature{
3026 .@"3e3r2",
3027 .@"3e3r3",
3028 .btst16,
3029 .ck803,
3030 .ck804,
3031 .dspv2,
3032 .high_registers,
3033 .hwdiv,
3034 .mp,
3035 .nvic,
3036 .trust,
3037 }),
3038 };
3039 pub const e804f = CpuModel{
3040 .name = "e804f",
3041 .llvm_name = "e804f",
3042 .features = featureSet(&[_]Feature{
3043 .@"3e3r2",
3044 .@"3e3r3",
3045 .btst16,
3046 .ck803,
3047 .ck804,
3048 .float1e3,
3049 .floate1,
3050 .fpuv2_sf,
3051 .hwdiv,
3052 .mp,
3053 .nvic,
3054 .trust,
3055 }),
3056 };
3057 pub const e804ft = CpuModel{
3058 .name = "e804ft",
3059 .llvm_name = "e804ft",
3060 .features = featureSet(&[_]Feature{
3061 .@"3e3r2",
3062 .@"3e3r3",
3063 .btst16,
3064 .ck803,
3065 .ck804,
3066 .float1e3,
3067 .floate1,
3068 .fpuv2_sf,
3069 .hwdiv,
3070 .mp,
3071 .nvic,
3072 .trust,
3073 }),
3074 };
3075 pub const generic = CpuModel{
3076 .name = "generic",
3077 .llvm_name = "generic",
3078 .features = featureSet(&[_]Feature{
3079 .btst16,
3080 }),
3081 };
3082 pub const @"i805" = CpuModel{
3083 .name = "i805",
3084 .llvm_name = "i805",
3085 .features = featureSet(&[_]Feature{
3086 .@"3e3r2",
3087 .@"3e3r3",
3088 .btst16,
3089 .ck803,
3090 .ck805,
3091 .high_registers,
3092 .hwdiv,
3093 .mp,
3094 .nvic,
3095 .trust,
3096 .vdsp2e3,
3097 .vdspv2,
3098 }),
3099 };
3100 pub const i805f = CpuModel{
3101 .name = "i805f",
3102 .llvm_name = "i805f",
3103 .features = featureSet(&[_]Feature{
3104 .@"3e3r2",
3105 .@"3e3r3",
3106 .btst16,
3107 .ck803,
3108 .ck805,
3109 .float1e3,
3110 .floate1,
3111 .fpuv2_sf,
3112 .high_registers,
3113 .hwdiv,
3114 .mp,
3115 .nvic,
3116 .trust,
3117 .vdsp2e3,
3118 .vdspv2,
3119 }),
3120 };
3121 pub const r807 = CpuModel{
3122 .name = "r807",
3123 .llvm_name = "r807",
3124 .features = featureSet(&[_]Feature{
3125 .cache,
3126 .ck807,
3127 .dsp1e2,
3128 .dspe60,
3129 .edsp,
3130 .hard_tp,
3131 .high_registers,
3132 .hwdiv,
3133 .mp,
3134 .mp1e2,
3135 .nvic,
3136 .trust,
3137 }),
3138 };
3139 pub const r807f = CpuModel{
3140 .name = "r807f",
3141 .llvm_name = "r807f",
3142 .features = featureSet(&[_]Feature{
3143 .cache,
3144 .ck807,
3145 .dsp1e2,
3146 .dspe60,
3147 .edsp,
3148 .fdivdu,
3149 .float1e2,
3150 .float1e3,
3151 .float3e4,
3152 .floate1,
3153 .fpuv2_df,
3154 .fpuv2_sf,
3155 .hard_tp,
3156 .high_registers,
3157 .hwdiv,
3158 .mp,
3159 .mp1e2,
3160 .nvic,
3161 .trust,
3162 }),
3163 };
3164 pub const s802 = CpuModel{
3165 .name = "s802",
3166 .llvm_name = "s802",
3167 .features = featureSet(&[_]Feature{
3168 .btst16,
3169 .ck802,
3170 .e2,
3171 .nvic,
3172 .trust,
3173 }),
3174 };
3175 pub const s802t = CpuModel{
3176 .name = "s802t",
3177 .llvm_name = "s802t",
3178 .features = featureSet(&[_]Feature{
3179 .btst16,
3180 .ck802,
3181 .e2,
3182 .nvic,
3183 .trust,
3184 }),
3185 };
3186 pub const s803 = CpuModel{
3187 .name = "s803",
3188 .llvm_name = "s803",
3189 .features = featureSet(&[_]Feature{
3190 .@"3e3r2",
3191 .@"3e3r3",
3192 .btst16,
3193 .ck803,
3194 .hwdiv,
3195 .mp,
3196 .nvic,
3197 .trust,
3198 }),
3199 };
3200 pub const s803t = CpuModel{
3201 .name = "s803t",
3202 .llvm_name = "s803t",
3203 .features = featureSet(&[_]Feature{
3204 .@"3e3r2",
3205 .@"3e3r3",
3206 .btst16,
3207 .ck803,
3208 .hwdiv,
3209 .mp,
3210 .nvic,
3211 .trust,
3212 }),
3213 };
3214};
lib/std/target/hexagon.zig deleted-586
......@@ -1,586 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 audio,
9 cabac,
10 compound,
11 duplex,
12 hvx,
13 hvx_ieee_fp,
14 hvx_length128b,
15 hvx_length64b,
16 hvx_qfloat,
17 hvxv60,
18 hvxv62,
19 hvxv65,
20 hvxv66,
21 hvxv67,
22 hvxv68,
23 hvxv69,
24 hvxv71,
25 hvxv73,
26 long_calls,
27 mem_noshuf,
28 memops,
29 noreturn_stack_elim,
30 nvj,
31 nvs,
32 packets,
33 prev65,
34 reserved_r19,
35 small_data,
36 tinycore,
37 unsafe_fp,
38 v5,
39 v55,
40 v60,
41 v62,
42 v65,
43 v66,
44 v67,
45 v68,
46 v69,
47 v71,
48 v73,
49 zreg,
50};
51
52pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
53pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
54pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
55pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
56
57pub const all_features = blk: {
58 const len = @typeInfo(Feature).Enum.fields.len;
59 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
60 var result: [len]CpuFeature = undefined;
61 result[@intFromEnum(Feature.audio)] = .{
62 .llvm_name = "audio",
63 .description = "Hexagon Audio extension instructions",
64 .dependencies = featureSet(&[_]Feature{}),
65 };
66 result[@intFromEnum(Feature.cabac)] = .{
67 .llvm_name = "cabac",
68 .description = "Emit the CABAC instruction",
69 .dependencies = featureSet(&[_]Feature{}),
70 };
71 result[@intFromEnum(Feature.compound)] = .{
72 .llvm_name = "compound",
73 .description = "Use compound instructions",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.duplex)] = .{
77 .llvm_name = "duplex",
78 .description = "Enable generation of duplex instruction",
79 .dependencies = featureSet(&[_]Feature{}),
80 };
81 result[@intFromEnum(Feature.hvx)] = .{
82 .llvm_name = "hvx",
83 .description = "Hexagon HVX instructions",
84 .dependencies = featureSet(&[_]Feature{}),
85 };
86 result[@intFromEnum(Feature.hvx_ieee_fp)] = .{
87 .llvm_name = "hvx-ieee-fp",
88 .description = "Hexagon HVX IEEE floating point instructions",
89 .dependencies = featureSet(&[_]Feature{}),
90 };
91 result[@intFromEnum(Feature.hvx_length128b)] = .{
92 .llvm_name = "hvx-length128b",
93 .description = "Hexagon HVX 128B instructions",
94 .dependencies = featureSet(&[_]Feature{
95 .hvx,
96 }),
97 };
98 result[@intFromEnum(Feature.hvx_length64b)] = .{
99 .llvm_name = "hvx-length64b",
100 .description = "Hexagon HVX 64B instructions",
101 .dependencies = featureSet(&[_]Feature{
102 .hvx,
103 }),
104 };
105 result[@intFromEnum(Feature.hvx_qfloat)] = .{
106 .llvm_name = "hvx-qfloat",
107 .description = "Hexagon HVX QFloating point instructions",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.hvxv60)] = .{
111 .llvm_name = "hvxv60",
112 .description = "Hexagon HVX instructions",
113 .dependencies = featureSet(&[_]Feature{
114 .hvx,
115 }),
116 };
117 result[@intFromEnum(Feature.hvxv62)] = .{
118 .llvm_name = "hvxv62",
119 .description = "Hexagon HVX instructions",
120 .dependencies = featureSet(&[_]Feature{
121 .hvxv60,
122 }),
123 };
124 result[@intFromEnum(Feature.hvxv65)] = .{
125 .llvm_name = "hvxv65",
126 .description = "Hexagon HVX instructions",
127 .dependencies = featureSet(&[_]Feature{
128 .hvxv62,
129 }),
130 };
131 result[@intFromEnum(Feature.hvxv66)] = .{
132 .llvm_name = "hvxv66",
133 .description = "Hexagon HVX instructions",
134 .dependencies = featureSet(&[_]Feature{
135 .hvxv65,
136 .zreg,
137 }),
138 };
139 result[@intFromEnum(Feature.hvxv67)] = .{
140 .llvm_name = "hvxv67",
141 .description = "Hexagon HVX instructions",
142 .dependencies = featureSet(&[_]Feature{
143 .hvxv66,
144 }),
145 };
146 result[@intFromEnum(Feature.hvxv68)] = .{
147 .llvm_name = "hvxv68",
148 .description = "Hexagon HVX instructions",
149 .dependencies = featureSet(&[_]Feature{
150 .hvxv67,
151 }),
152 };
153 result[@intFromEnum(Feature.hvxv69)] = .{
154 .llvm_name = "hvxv69",
155 .description = "Hexagon HVX instructions",
156 .dependencies = featureSet(&[_]Feature{
157 .hvxv68,
158 }),
159 };
160 result[@intFromEnum(Feature.hvxv71)] = .{
161 .llvm_name = "hvxv71",
162 .description = "Hexagon HVX instructions",
163 .dependencies = featureSet(&[_]Feature{
164 .hvxv69,
165 }),
166 };
167 result[@intFromEnum(Feature.hvxv73)] = .{
168 .llvm_name = "hvxv73",
169 .description = "Hexagon HVX instructions",
170 .dependencies = featureSet(&[_]Feature{
171 .hvxv71,
172 }),
173 };
174 result[@intFromEnum(Feature.long_calls)] = .{
175 .llvm_name = "long-calls",
176 .description = "Use constant-extended calls",
177 .dependencies = featureSet(&[_]Feature{}),
178 };
179 result[@intFromEnum(Feature.mem_noshuf)] = .{
180 .llvm_name = "mem_noshuf",
181 .description = "Supports mem_noshuf feature",
182 .dependencies = featureSet(&[_]Feature{}),
183 };
184 result[@intFromEnum(Feature.memops)] = .{
185 .llvm_name = "memops",
186 .description = "Use memop instructions",
187 .dependencies = featureSet(&[_]Feature{}),
188 };
189 result[@intFromEnum(Feature.noreturn_stack_elim)] = .{
190 .llvm_name = "noreturn-stack-elim",
191 .description = "Eliminate stack allocation in a noreturn function when possible",
192 .dependencies = featureSet(&[_]Feature{}),
193 };
194 result[@intFromEnum(Feature.nvj)] = .{
195 .llvm_name = "nvj",
196 .description = "Support for new-value jumps",
197 .dependencies = featureSet(&[_]Feature{
198 .packets,
199 }),
200 };
201 result[@intFromEnum(Feature.nvs)] = .{
202 .llvm_name = "nvs",
203 .description = "Support for new-value stores",
204 .dependencies = featureSet(&[_]Feature{
205 .packets,
206 }),
207 };
208 result[@intFromEnum(Feature.packets)] = .{
209 .llvm_name = "packets",
210 .description = "Support for instruction packets",
211 .dependencies = featureSet(&[_]Feature{}),
212 };
213 result[@intFromEnum(Feature.prev65)] = .{
214 .llvm_name = "prev65",
215 .description = "Support features deprecated in v65",
216 .dependencies = featureSet(&[_]Feature{}),
217 };
218 result[@intFromEnum(Feature.reserved_r19)] = .{
219 .llvm_name = "reserved-r19",
220 .description = "Reserve register R19",
221 .dependencies = featureSet(&[_]Feature{}),
222 };
223 result[@intFromEnum(Feature.small_data)] = .{
224 .llvm_name = "small-data",
225 .description = "Allow GP-relative addressing of global variables",
226 .dependencies = featureSet(&[_]Feature{}),
227 };
228 result[@intFromEnum(Feature.tinycore)] = .{
229 .llvm_name = "tinycore",
230 .description = "Hexagon Tiny Core",
231 .dependencies = featureSet(&[_]Feature{}),
232 };
233 result[@intFromEnum(Feature.unsafe_fp)] = .{
234 .llvm_name = "unsafe-fp",
235 .description = "Use unsafe FP math",
236 .dependencies = featureSet(&[_]Feature{}),
237 };
238 result[@intFromEnum(Feature.v5)] = .{
239 .llvm_name = "v5",
240 .description = "Enable Hexagon V5 architecture",
241 .dependencies = featureSet(&[_]Feature{}),
242 };
243 result[@intFromEnum(Feature.v55)] = .{
244 .llvm_name = "v55",
245 .description = "Enable Hexagon V55 architecture",
246 .dependencies = featureSet(&[_]Feature{}),
247 };
248 result[@intFromEnum(Feature.v60)] = .{
249 .llvm_name = "v60",
250 .description = "Enable Hexagon V60 architecture",
251 .dependencies = featureSet(&[_]Feature{}),
252 };
253 result[@intFromEnum(Feature.v62)] = .{
254 .llvm_name = "v62",
255 .description = "Enable Hexagon V62 architecture",
256 .dependencies = featureSet(&[_]Feature{}),
257 };
258 result[@intFromEnum(Feature.v65)] = .{
259 .llvm_name = "v65",
260 .description = "Enable Hexagon V65 architecture",
261 .dependencies = featureSet(&[_]Feature{}),
262 };
263 result[@intFromEnum(Feature.v66)] = .{
264 .llvm_name = "v66",
265 .description = "Enable Hexagon V66 architecture",
266 .dependencies = featureSet(&[_]Feature{}),
267 };
268 result[@intFromEnum(Feature.v67)] = .{
269 .llvm_name = "v67",
270 .description = "Enable Hexagon V67 architecture",
271 .dependencies = featureSet(&[_]Feature{}),
272 };
273 result[@intFromEnum(Feature.v68)] = .{
274 .llvm_name = "v68",
275 .description = "Enable Hexagon V68 architecture",
276 .dependencies = featureSet(&[_]Feature{}),
277 };
278 result[@intFromEnum(Feature.v69)] = .{
279 .llvm_name = "v69",
280 .description = "Enable Hexagon V69 architecture",
281 .dependencies = featureSet(&[_]Feature{}),
282 };
283 result[@intFromEnum(Feature.v71)] = .{
284 .llvm_name = "v71",
285 .description = "Enable Hexagon V71 architecture",
286 .dependencies = featureSet(&[_]Feature{}),
287 };
288 result[@intFromEnum(Feature.v73)] = .{
289 .llvm_name = "v73",
290 .description = "Enable Hexagon V73 architecture",
291 .dependencies = featureSet(&[_]Feature{}),
292 };
293 result[@intFromEnum(Feature.zreg)] = .{
294 .llvm_name = "zreg",
295 .description = "Hexagon ZReg extension instructions",
296 .dependencies = featureSet(&[_]Feature{}),
297 };
298 const ti = @typeInfo(Feature);
299 for (&result, 0..) |*elem, i| {
300 elem.index = i;
301 elem.name = ti.Enum.fields[i].name;
302 }
303 break :blk result;
304};
305
306pub const cpu = struct {
307 pub const generic = CpuModel{
308 .name = "generic",
309 .llvm_name = "generic",
310 .features = featureSet(&[_]Feature{
311 .cabac,
312 .compound,
313 .duplex,
314 .memops,
315 .nvj,
316 .nvs,
317 .prev65,
318 .small_data,
319 .v5,
320 .v55,
321 .v60,
322 }),
323 };
324 pub const hexagonv5 = CpuModel{
325 .name = "hexagonv5",
326 .llvm_name = "hexagonv5",
327 .features = featureSet(&[_]Feature{
328 .cabac,
329 .compound,
330 .duplex,
331 .memops,
332 .nvj,
333 .nvs,
334 .prev65,
335 .small_data,
336 .v5,
337 }),
338 };
339 pub const hexagonv55 = CpuModel{
340 .name = "hexagonv55",
341 .llvm_name = "hexagonv55",
342 .features = featureSet(&[_]Feature{
343 .cabac,
344 .compound,
345 .duplex,
346 .memops,
347 .nvj,
348 .nvs,
349 .prev65,
350 .small_data,
351 .v5,
352 .v55,
353 }),
354 };
355 pub const hexagonv60 = CpuModel{
356 .name = "hexagonv60",
357 .llvm_name = "hexagonv60",
358 .features = featureSet(&[_]Feature{
359 .cabac,
360 .compound,
361 .duplex,
362 .memops,
363 .nvj,
364 .nvs,
365 .prev65,
366 .small_data,
367 .v5,
368 .v55,
369 .v60,
370 }),
371 };
372 pub const hexagonv62 = CpuModel{
373 .name = "hexagonv62",
374 .llvm_name = "hexagonv62",
375 .features = featureSet(&[_]Feature{
376 .cabac,
377 .compound,
378 .duplex,
379 .memops,
380 .nvj,
381 .nvs,
382 .prev65,
383 .small_data,
384 .v5,
385 .v55,
386 .v60,
387 .v62,
388 }),
389 };
390 pub const hexagonv65 = CpuModel{
391 .name = "hexagonv65",
392 .llvm_name = "hexagonv65",
393 .features = featureSet(&[_]Feature{
394 .cabac,
395 .compound,
396 .duplex,
397 .mem_noshuf,
398 .memops,
399 .nvj,
400 .nvs,
401 .small_data,
402 .v5,
403 .v55,
404 .v60,
405 .v62,
406 .v65,
407 }),
408 };
409 pub const hexagonv66 = CpuModel{
410 .name = "hexagonv66",
411 .llvm_name = "hexagonv66",
412 .features = featureSet(&[_]Feature{
413 .cabac,
414 .compound,
415 .duplex,
416 .mem_noshuf,
417 .memops,
418 .nvj,
419 .nvs,
420 .small_data,
421 .v5,
422 .v55,
423 .v60,
424 .v62,
425 .v65,
426 .v66,
427 }),
428 };
429 pub const hexagonv67 = CpuModel{
430 .name = "hexagonv67",
431 .llvm_name = "hexagonv67",
432 .features = featureSet(&[_]Feature{
433 .cabac,
434 .compound,
435 .duplex,
436 .mem_noshuf,
437 .memops,
438 .nvj,
439 .nvs,
440 .small_data,
441 .v5,
442 .v55,
443 .v60,
444 .v62,
445 .v65,
446 .v66,
447 .v67,
448 }),
449 };
450 pub const hexagonv67t = CpuModel{
451 .name = "hexagonv67t",
452 .llvm_name = "hexagonv67t",
453 .features = featureSet(&[_]Feature{
454 .audio,
455 .compound,
456 .mem_noshuf,
457 .memops,
458 .nvs,
459 .small_data,
460 .tinycore,
461 .v5,
462 .v55,
463 .v60,
464 .v62,
465 .v65,
466 .v66,
467 .v67,
468 }),
469 };
470 pub const hexagonv68 = CpuModel{
471 .name = "hexagonv68",
472 .llvm_name = "hexagonv68",
473 .features = featureSet(&[_]Feature{
474 .cabac,
475 .compound,
476 .duplex,
477 .mem_noshuf,
478 .memops,
479 .nvj,
480 .nvs,
481 .small_data,
482 .v5,
483 .v55,
484 .v60,
485 .v62,
486 .v65,
487 .v66,
488 .v67,
489 .v68,
490 }),
491 };
492 pub const hexagonv69 = CpuModel{
493 .name = "hexagonv69",
494 .llvm_name = "hexagonv69",
495 .features = featureSet(&[_]Feature{
496 .cabac,
497 .compound,
498 .duplex,
499 .mem_noshuf,
500 .memops,
501 .nvj,
502 .nvs,
503 .small_data,
504 .v5,
505 .v55,
506 .v60,
507 .v62,
508 .v65,
509 .v66,
510 .v67,
511 .v68,
512 .v69,
513 }),
514 };
515 pub const hexagonv71 = CpuModel{
516 .name = "hexagonv71",
517 .llvm_name = "hexagonv71",
518 .features = featureSet(&[_]Feature{
519 .cabac,
520 .compound,
521 .duplex,
522 .mem_noshuf,
523 .memops,
524 .nvj,
525 .nvs,
526 .small_data,
527 .v5,
528 .v55,
529 .v60,
530 .v62,
531 .v65,
532 .v66,
533 .v67,
534 .v68,
535 .v69,
536 .v71,
537 }),
538 };
539 pub const hexagonv71t = CpuModel{
540 .name = "hexagonv71t",
541 .llvm_name = "hexagonv71t",
542 .features = featureSet(&[_]Feature{
543 .audio,
544 .compound,
545 .mem_noshuf,
546 .memops,
547 .nvs,
548 .small_data,
549 .tinycore,
550 .v5,
551 .v55,
552 .v60,
553 .v62,
554 .v65,
555 .v66,
556 .v67,
557 .v68,
558 .v69,
559 .v71,
560 }),
561 };
562 pub const hexagonv73 = CpuModel{
563 .name = "hexagonv73",
564 .llvm_name = "hexagonv73",
565 .features = featureSet(&[_]Feature{
566 .compound,
567 .duplex,
568 .mem_noshuf,
569 .memops,
570 .nvj,
571 .nvs,
572 .small_data,
573 .v5,
574 .v55,
575 .v60,
576 .v62,
577 .v65,
578 .v66,
579 .v67,
580 .v68,
581 .v69,
582 .v71,
583 .v73,
584 }),
585 };
586};
lib/std/target/loongarch.zig deleted-146
......@@ -1,146 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"32bit",
9 @"64bit",
10 d,
11 f,
12 la_global_with_abs,
13 la_global_with_pcrel,
14 la_local_with_abs,
15 lasx,
16 lbt,
17 lsx,
18 lvz,
19 ual,
20};
21
22pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
23pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
24pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
25pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
26
27pub const all_features = blk: {
28 const len = @typeInfo(Feature).Enum.fields.len;
29 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
30 var result: [len]CpuFeature = undefined;
31 result[@intFromEnum(Feature.@"32bit")] = .{
32 .llvm_name = "32bit",
33 .description = "LA32 Basic Integer and Privilege Instruction Set",
34 .dependencies = featureSet(&[_]Feature{}),
35 };
36 result[@intFromEnum(Feature.@"64bit")] = .{
37 .llvm_name = "64bit",
38 .description = "LA64 Basic Integer and Privilege Instruction Set",
39 .dependencies = featureSet(&[_]Feature{}),
40 };
41 result[@intFromEnum(Feature.d)] = .{
42 .llvm_name = "d",
43 .description = "'D' (Double-Precision Floating-Point)",
44 .dependencies = featureSet(&[_]Feature{
45 .f,
46 }),
47 };
48 result[@intFromEnum(Feature.f)] = .{
49 .llvm_name = "f",
50 .description = "'F' (Single-Precision Floating-Point)",
51 .dependencies = featureSet(&[_]Feature{}),
52 };
53 result[@intFromEnum(Feature.la_global_with_abs)] = .{
54 .llvm_name = "la-global-with-abs",
55 .description = "Expand la.global as la.abs",
56 .dependencies = featureSet(&[_]Feature{}),
57 };
58 result[@intFromEnum(Feature.la_global_with_pcrel)] = .{
59 .llvm_name = "la-global-with-pcrel",
60 .description = "Expand la.global as la.pcrel",
61 .dependencies = featureSet(&[_]Feature{}),
62 };
63 result[@intFromEnum(Feature.la_local_with_abs)] = .{
64 .llvm_name = "la-local-with-abs",
65 .description = "Expand la.local as la.abs",
66 .dependencies = featureSet(&[_]Feature{}),
67 };
68 result[@intFromEnum(Feature.lasx)] = .{
69 .llvm_name = "lasx",
70 .description = "'LASX' (Loongson Advanced SIMD Extension)",
71 .dependencies = featureSet(&[_]Feature{
72 .lsx,
73 }),
74 };
75 result[@intFromEnum(Feature.lbt)] = .{
76 .llvm_name = "lbt",
77 .description = "'LBT' (Loongson Binary Translation Extension)",
78 .dependencies = featureSet(&[_]Feature{}),
79 };
80 result[@intFromEnum(Feature.lsx)] = .{
81 .llvm_name = "lsx",
82 .description = "'LSX' (Loongson SIMD Extension)",
83 .dependencies = featureSet(&[_]Feature{
84 .d,
85 }),
86 };
87 result[@intFromEnum(Feature.lvz)] = .{
88 .llvm_name = "lvz",
89 .description = "'LVZ' (Loongson Virtualization Extension)",
90 .dependencies = featureSet(&[_]Feature{}),
91 };
92 result[@intFromEnum(Feature.ual)] = .{
93 .llvm_name = "ual",
94 .description = "Allow memory accesses to be unaligned",
95 .dependencies = featureSet(&[_]Feature{}),
96 };
97 const ti = @typeInfo(Feature);
98 for (&result, 0..) |*elem, i| {
99 elem.index = i;
100 elem.name = ti.Enum.fields[i].name;
101 }
102 break :blk result;
103};
104
105pub const cpu = struct {
106 pub const generic = CpuModel{
107 .name = "generic",
108 .llvm_name = "generic",
109 .features = featureSet(&[_]Feature{}),
110 };
111 pub const generic_la32 = CpuModel{
112 .name = "generic_la32",
113 .llvm_name = "generic-la32",
114 .features = featureSet(&[_]Feature{
115 .@"32bit",
116 }),
117 };
118 pub const generic_la64 = CpuModel{
119 .name = "generic_la64",
120 .llvm_name = "generic-la64",
121 .features = featureSet(&[_]Feature{
122 .@"64bit",
123 .ual,
124 }),
125 };
126 pub const la464 = CpuModel{
127 .name = "la464",
128 .llvm_name = "la464",
129 .features = featureSet(&[_]Feature{
130 .@"64bit",
131 .lasx,
132 .lbt,
133 .lvz,
134 .ual,
135 }),
136 };
137 pub const loongarch64 = CpuModel{
138 .name = "loongarch64",
139 .llvm_name = "loongarch64",
140 .features = featureSet(&[_]Feature{
141 .@"64bit",
142 .d,
143 .ual,
144 }),
145 };
146};
lib/std/target/m68k.zig deleted-228
......@@ -1,228 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 isa_68000,
9 isa_68010,
10 isa_68020,
11 isa_68030,
12 isa_68040,
13 isa_68060,
14 isa_68881,
15 isa_68882,
16 reserve_a0,
17 reserve_a1,
18 reserve_a2,
19 reserve_a3,
20 reserve_a4,
21 reserve_a5,
22 reserve_a6,
23 reserve_d0,
24 reserve_d1,
25 reserve_d2,
26 reserve_d3,
27 reserve_d4,
28 reserve_d5,
29 reserve_d6,
30 reserve_d7,
31};
32
33pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
34pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
35pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
36pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
37
38pub const all_features = blk: {
39 const len = @typeInfo(Feature).Enum.fields.len;
40 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
41 var result: [len]CpuFeature = undefined;
42 result[@intFromEnum(Feature.isa_68000)] = .{
43 .llvm_name = "isa-68000",
44 .description = "Is M68000 ISA supported",
45 .dependencies = featureSet(&[_]Feature{}),
46 };
47 result[@intFromEnum(Feature.isa_68010)] = .{
48 .llvm_name = "isa-68010",
49 .description = "Is M68010 ISA supported",
50 .dependencies = featureSet(&[_]Feature{
51 .isa_68000,
52 }),
53 };
54 result[@intFromEnum(Feature.isa_68020)] = .{
55 .llvm_name = "isa-68020",
56 .description = "Is M68020 ISA supported",
57 .dependencies = featureSet(&[_]Feature{
58 .isa_68010,
59 }),
60 };
61 result[@intFromEnum(Feature.isa_68030)] = .{
62 .llvm_name = "isa-68030",
63 .description = "Is M68030 ISA supported",
64 .dependencies = featureSet(&[_]Feature{
65 .isa_68020,
66 }),
67 };
68 result[@intFromEnum(Feature.isa_68040)] = .{
69 .llvm_name = "isa-68040",
70 .description = "Is M68040 ISA supported",
71 .dependencies = featureSet(&[_]Feature{
72 .isa_68030,
73 .isa_68882,
74 }),
75 };
76 result[@intFromEnum(Feature.isa_68060)] = .{
77 .llvm_name = "isa-68060",
78 .description = "Is M68060 ISA supported",
79 .dependencies = featureSet(&[_]Feature{
80 .isa_68040,
81 }),
82 };
83 result[@intFromEnum(Feature.isa_68881)] = .{
84 .llvm_name = "isa-68881",
85 .description = "Is M68881 (FPU) ISA supported",
86 .dependencies = featureSet(&[_]Feature{}),
87 };
88 result[@intFromEnum(Feature.isa_68882)] = .{
89 .llvm_name = "isa-68882",
90 .description = "Is M68882 (FPU) ISA supported",
91 .dependencies = featureSet(&[_]Feature{
92 .isa_68881,
93 }),
94 };
95 result[@intFromEnum(Feature.reserve_a0)] = .{
96 .llvm_name = "reserve-a0",
97 .description = "Reserve A0 register",
98 .dependencies = featureSet(&[_]Feature{}),
99 };
100 result[@intFromEnum(Feature.reserve_a1)] = .{
101 .llvm_name = "reserve-a1",
102 .description = "Reserve A1 register",
103 .dependencies = featureSet(&[_]Feature{}),
104 };
105 result[@intFromEnum(Feature.reserve_a2)] = .{
106 .llvm_name = "reserve-a2",
107 .description = "Reserve A2 register",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.reserve_a3)] = .{
111 .llvm_name = "reserve-a3",
112 .description = "Reserve A3 register",
113 .dependencies = featureSet(&[_]Feature{}),
114 };
115 result[@intFromEnum(Feature.reserve_a4)] = .{
116 .llvm_name = "reserve-a4",
117 .description = "Reserve A4 register",
118 .dependencies = featureSet(&[_]Feature{}),
119 };
120 result[@intFromEnum(Feature.reserve_a5)] = .{
121 .llvm_name = "reserve-a5",
122 .description = "Reserve A5 register",
123 .dependencies = featureSet(&[_]Feature{}),
124 };
125 result[@intFromEnum(Feature.reserve_a6)] = .{
126 .llvm_name = "reserve-a6",
127 .description = "Reserve A6 register",
128 .dependencies = featureSet(&[_]Feature{}),
129 };
130 result[@intFromEnum(Feature.reserve_d0)] = .{
131 .llvm_name = "reserve-d0",
132 .description = "Reserve D0 register",
133 .dependencies = featureSet(&[_]Feature{}),
134 };
135 result[@intFromEnum(Feature.reserve_d1)] = .{
136 .llvm_name = "reserve-d1",
137 .description = "Reserve D1 register",
138 .dependencies = featureSet(&[_]Feature{}),
139 };
140 result[@intFromEnum(Feature.reserve_d2)] = .{
141 .llvm_name = "reserve-d2",
142 .description = "Reserve D2 register",
143 .dependencies = featureSet(&[_]Feature{}),
144 };
145 result[@intFromEnum(Feature.reserve_d3)] = .{
146 .llvm_name = "reserve-d3",
147 .description = "Reserve D3 register",
148 .dependencies = featureSet(&[_]Feature{}),
149 };
150 result[@intFromEnum(Feature.reserve_d4)] = .{
151 .llvm_name = "reserve-d4",
152 .description = "Reserve D4 register",
153 .dependencies = featureSet(&[_]Feature{}),
154 };
155 result[@intFromEnum(Feature.reserve_d5)] = .{
156 .llvm_name = "reserve-d5",
157 .description = "Reserve D5 register",
158 .dependencies = featureSet(&[_]Feature{}),
159 };
160 result[@intFromEnum(Feature.reserve_d6)] = .{
161 .llvm_name = "reserve-d6",
162 .description = "Reserve D6 register",
163 .dependencies = featureSet(&[_]Feature{}),
164 };
165 result[@intFromEnum(Feature.reserve_d7)] = .{
166 .llvm_name = "reserve-d7",
167 .description = "Reserve D7 register",
168 .dependencies = featureSet(&[_]Feature{}),
169 };
170 const ti = @typeInfo(Feature);
171 for (&result, 0..) |*elem, i| {
172 elem.index = i;
173 elem.name = ti.Enum.fields[i].name;
174 }
175 break :blk result;
176};
177
178pub const cpu = struct {
179 pub const generic = CpuModel{
180 .name = "generic",
181 .llvm_name = "generic",
182 .features = featureSet(&[_]Feature{
183 .isa_68000,
184 }),
185 };
186 pub const M68000 = CpuModel{
187 .name = "M68000",
188 .llvm_name = "M68000",
189 .features = featureSet(&[_]Feature{
190 .isa_68000,
191 }),
192 };
193 pub const M68010 = CpuModel{
194 .name = "M68010",
195 .llvm_name = "M68010",
196 .features = featureSet(&[_]Feature{
197 .isa_68010,
198 }),
199 };
200 pub const M68020 = CpuModel{
201 .name = "M68020",
202 .llvm_name = "M68020",
203 .features = featureSet(&[_]Feature{
204 .isa_68020,
205 }),
206 };
207 pub const M68030 = CpuModel{
208 .name = "M68030",
209 .llvm_name = "M68030",
210 .features = featureSet(&[_]Feature{
211 .isa_68030,
212 }),
213 };
214 pub const M68040 = CpuModel{
215 .name = "M68040",
216 .llvm_name = "M68040",
217 .features = featureSet(&[_]Feature{
218 .isa_68040,
219 }),
220 };
221 pub const M68060 = CpuModel{
222 .name = "M68060",
223 .llvm_name = "M68060",
224 .features = featureSet(&[_]Feature{
225 .isa_68060,
226 }),
227 };
228};
lib/std/target/mips.zig deleted-531
......@@ -1,531 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 abs2008,
9 cnmips,
10 cnmipsp,
11 crc,
12 dsp,
13 dspr2,
14 dspr3,
15 eva,
16 fp64,
17 fpxx,
18 ginv,
19 gp64,
20 long_calls,
21 micromips,
22 mips1,
23 mips16,
24 mips2,
25 mips3,
26 mips32,
27 mips32r2,
28 mips32r3,
29 mips32r5,
30 mips32r6,
31 mips3_32,
32 mips3_32r2,
33 mips3d,
34 mips4,
35 mips4_32,
36 mips4_32r2,
37 mips5,
38 mips5_32r2,
39 mips64,
40 mips64r2,
41 mips64r3,
42 mips64r5,
43 mips64r6,
44 msa,
45 mt,
46 nan2008,
47 noabicalls,
48 nomadd4,
49 nooddspreg,
50 p5600,
51 ptr64,
52 single_float,
53 soft_float,
54 sym32,
55 use_indirect_jump_hazard,
56 use_tcc_in_div,
57 vfpu,
58 virt,
59 xgot,
60};
61
62pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
63pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
64pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
65pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
66
67pub const all_features = blk: {
68 const len = @typeInfo(Feature).Enum.fields.len;
69 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
70 var result: [len]CpuFeature = undefined;
71 result[@intFromEnum(Feature.abs2008)] = .{
72 .llvm_name = "abs2008",
73 .description = "Disable IEEE 754-2008 abs.fmt mode",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.cnmips)] = .{
77 .llvm_name = "cnmips",
78 .description = "Octeon cnMIPS Support",
79 .dependencies = featureSet(&[_]Feature{
80 .mips64r2,
81 }),
82 };
83 result[@intFromEnum(Feature.cnmipsp)] = .{
84 .llvm_name = "cnmipsp",
85 .description = "Octeon+ cnMIPS Support",
86 .dependencies = featureSet(&[_]Feature{
87 .cnmips,
88 }),
89 };
90 result[@intFromEnum(Feature.crc)] = .{
91 .llvm_name = "crc",
92 .description = "Mips R6 CRC ASE",
93 .dependencies = featureSet(&[_]Feature{}),
94 };
95 result[@intFromEnum(Feature.dsp)] = .{
96 .llvm_name = "dsp",
97 .description = "Mips DSP ASE",
98 .dependencies = featureSet(&[_]Feature{}),
99 };
100 result[@intFromEnum(Feature.dspr2)] = .{
101 .llvm_name = "dspr2",
102 .description = "Mips DSP-R2 ASE",
103 .dependencies = featureSet(&[_]Feature{
104 .dsp,
105 }),
106 };
107 result[@intFromEnum(Feature.dspr3)] = .{
108 .llvm_name = "dspr3",
109 .description = "Mips DSP-R3 ASE",
110 .dependencies = featureSet(&[_]Feature{
111 .dspr2,
112 }),
113 };
114 result[@intFromEnum(Feature.eva)] = .{
115 .llvm_name = "eva",
116 .description = "Mips EVA ASE",
117 .dependencies = featureSet(&[_]Feature{}),
118 };
119 result[@intFromEnum(Feature.fp64)] = .{
120 .llvm_name = "fp64",
121 .description = "Support 64-bit FP registers",
122 .dependencies = featureSet(&[_]Feature{}),
123 };
124 result[@intFromEnum(Feature.fpxx)] = .{
125 .llvm_name = "fpxx",
126 .description = "Support for FPXX",
127 .dependencies = featureSet(&[_]Feature{}),
128 };
129 result[@intFromEnum(Feature.ginv)] = .{
130 .llvm_name = "ginv",
131 .description = "Mips Global Invalidate ASE",
132 .dependencies = featureSet(&[_]Feature{}),
133 };
134 result[@intFromEnum(Feature.gp64)] = .{
135 .llvm_name = "gp64",
136 .description = "General Purpose Registers are 64-bit wide",
137 .dependencies = featureSet(&[_]Feature{}),
138 };
139 result[@intFromEnum(Feature.long_calls)] = .{
140 .llvm_name = "long-calls",
141 .description = "Disable use of the jal instruction",
142 .dependencies = featureSet(&[_]Feature{}),
143 };
144 result[@intFromEnum(Feature.micromips)] = .{
145 .llvm_name = "micromips",
146 .description = "microMips mode",
147 .dependencies = featureSet(&[_]Feature{}),
148 };
149 result[@intFromEnum(Feature.mips1)] = .{
150 .llvm_name = "mips1",
151 .description = "Mips I ISA Support [highly experimental]",
152 .dependencies = featureSet(&[_]Feature{}),
153 };
154 result[@intFromEnum(Feature.mips16)] = .{
155 .llvm_name = "mips16",
156 .description = "Mips16 mode",
157 .dependencies = featureSet(&[_]Feature{}),
158 };
159 result[@intFromEnum(Feature.mips2)] = .{
160 .llvm_name = "mips2",
161 .description = "Mips II ISA Support [highly experimental]",
162 .dependencies = featureSet(&[_]Feature{
163 .mips1,
164 }),
165 };
166 result[@intFromEnum(Feature.mips3)] = .{
167 .llvm_name = "mips3",
168 .description = "MIPS III ISA Support [highly experimental]",
169 .dependencies = featureSet(&[_]Feature{
170 .fp64,
171 .gp64,
172 .mips2,
173 .mips3_32,
174 .mips3_32r2,
175 }),
176 };
177 result[@intFromEnum(Feature.mips32)] = .{
178 .llvm_name = "mips32",
179 .description = "Mips32 ISA Support",
180 .dependencies = featureSet(&[_]Feature{
181 .mips2,
182 .mips3_32,
183 .mips4_32,
184 }),
185 };
186 result[@intFromEnum(Feature.mips32r2)] = .{
187 .llvm_name = "mips32r2",
188 .description = "Mips32r2 ISA Support",
189 .dependencies = featureSet(&[_]Feature{
190 .mips32,
191 .mips3_32r2,
192 .mips4_32r2,
193 .mips5_32r2,
194 }),
195 };
196 result[@intFromEnum(Feature.mips32r3)] = .{
197 .llvm_name = "mips32r3",
198 .description = "Mips32r3 ISA Support",
199 .dependencies = featureSet(&[_]Feature{
200 .mips32r2,
201 }),
202 };
203 result[@intFromEnum(Feature.mips32r5)] = .{
204 .llvm_name = "mips32r5",
205 .description = "Mips32r5 ISA Support",
206 .dependencies = featureSet(&[_]Feature{
207 .mips32r3,
208 }),
209 };
210 result[@intFromEnum(Feature.mips32r6)] = .{
211 .llvm_name = "mips32r6",
212 .description = "Mips32r6 ISA Support [experimental]",
213 .dependencies = featureSet(&[_]Feature{
214 .abs2008,
215 .fp64,
216 .mips32r5,
217 .nan2008,
218 }),
219 };
220 result[@intFromEnum(Feature.mips3_32)] = .{
221 .llvm_name = "mips3_32",
222 .description = "Subset of MIPS-III that is also in MIPS32 [highly experimental]",
223 .dependencies = featureSet(&[_]Feature{}),
224 };
225 result[@intFromEnum(Feature.mips3_32r2)] = .{
226 .llvm_name = "mips3_32r2",
227 .description = "Subset of MIPS-III that is also in MIPS32r2 [highly experimental]",
228 .dependencies = featureSet(&[_]Feature{}),
229 };
230 result[@intFromEnum(Feature.mips3d)] = .{
231 .llvm_name = "mips3d",
232 .description = "Mips 3D ASE",
233 .dependencies = featureSet(&[_]Feature{}),
234 };
235 result[@intFromEnum(Feature.mips4)] = .{
236 .llvm_name = "mips4",
237 .description = "MIPS IV ISA Support",
238 .dependencies = featureSet(&[_]Feature{
239 .mips3,
240 .mips4_32,
241 .mips4_32r2,
242 }),
243 };
244 result[@intFromEnum(Feature.mips4_32)] = .{
245 .llvm_name = "mips4_32",
246 .description = "Subset of MIPS-IV that is also in MIPS32 [highly experimental]",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@intFromEnum(Feature.mips4_32r2)] = .{
250 .llvm_name = "mips4_32r2",
251 .description = "Subset of MIPS-IV that is also in MIPS32r2 [highly experimental]",
252 .dependencies = featureSet(&[_]Feature{}),
253 };
254 result[@intFromEnum(Feature.mips5)] = .{
255 .llvm_name = "mips5",
256 .description = "MIPS V ISA Support [highly experimental]",
257 .dependencies = featureSet(&[_]Feature{
258 .mips4,
259 .mips5_32r2,
260 }),
261 };
262 result[@intFromEnum(Feature.mips5_32r2)] = .{
263 .llvm_name = "mips5_32r2",
264 .description = "Subset of MIPS-V that is also in MIPS32r2 [highly experimental]",
265 .dependencies = featureSet(&[_]Feature{}),
266 };
267 result[@intFromEnum(Feature.mips64)] = .{
268 .llvm_name = "mips64",
269 .description = "Mips64 ISA Support",
270 .dependencies = featureSet(&[_]Feature{
271 .mips32,
272 .mips5,
273 }),
274 };
275 result[@intFromEnum(Feature.mips64r2)] = .{
276 .llvm_name = "mips64r2",
277 .description = "Mips64r2 ISA Support",
278 .dependencies = featureSet(&[_]Feature{
279 .mips32r2,
280 .mips64,
281 }),
282 };
283 result[@intFromEnum(Feature.mips64r3)] = .{
284 .llvm_name = "mips64r3",
285 .description = "Mips64r3 ISA Support",
286 .dependencies = featureSet(&[_]Feature{
287 .mips32r3,
288 .mips64r2,
289 }),
290 };
291 result[@intFromEnum(Feature.mips64r5)] = .{
292 .llvm_name = "mips64r5",
293 .description = "Mips64r5 ISA Support",
294 .dependencies = featureSet(&[_]Feature{
295 .mips32r5,
296 .mips64r3,
297 }),
298 };
299 result[@intFromEnum(Feature.mips64r6)] = .{
300 .llvm_name = "mips64r6",
301 .description = "Mips64r6 ISA Support [experimental]",
302 .dependencies = featureSet(&[_]Feature{
303 .mips32r6,
304 .mips64r5,
305 }),
306 };
307 result[@intFromEnum(Feature.msa)] = .{
308 .llvm_name = "msa",
309 .description = "Mips MSA ASE",
310 .dependencies = featureSet(&[_]Feature{}),
311 };
312 result[@intFromEnum(Feature.mt)] = .{
313 .llvm_name = "mt",
314 .description = "Mips MT ASE",
315 .dependencies = featureSet(&[_]Feature{}),
316 };
317 result[@intFromEnum(Feature.nan2008)] = .{
318 .llvm_name = "nan2008",
319 .description = "IEEE 754-2008 NaN encoding",
320 .dependencies = featureSet(&[_]Feature{}),
321 };
322 result[@intFromEnum(Feature.noabicalls)] = .{
323 .llvm_name = "noabicalls",
324 .description = "Disable SVR4-style position-independent code",
325 .dependencies = featureSet(&[_]Feature{}),
326 };
327 result[@intFromEnum(Feature.nomadd4)] = .{
328 .llvm_name = "nomadd4",
329 .description = "Disable 4-operand madd.fmt and related instructions",
330 .dependencies = featureSet(&[_]Feature{}),
331 };
332 result[@intFromEnum(Feature.nooddspreg)] = .{
333 .llvm_name = "nooddspreg",
334 .description = "Disable odd numbered single-precision registers",
335 .dependencies = featureSet(&[_]Feature{}),
336 };
337 result[@intFromEnum(Feature.p5600)] = .{
338 .llvm_name = "p5600",
339 .description = "The P5600 Processor",
340 .dependencies = featureSet(&[_]Feature{
341 .mips32r5,
342 }),
343 };
344 result[@intFromEnum(Feature.ptr64)] = .{
345 .llvm_name = "ptr64",
346 .description = "Pointers are 64-bit wide",
347 .dependencies = featureSet(&[_]Feature{}),
348 };
349 result[@intFromEnum(Feature.single_float)] = .{
350 .llvm_name = "single-float",
351 .description = "Only supports single precision float",
352 .dependencies = featureSet(&[_]Feature{}),
353 };
354 result[@intFromEnum(Feature.soft_float)] = .{
355 .llvm_name = "soft-float",
356 .description = "Does not support floating point instructions",
357 .dependencies = featureSet(&[_]Feature{}),
358 };
359 result[@intFromEnum(Feature.sym32)] = .{
360 .llvm_name = "sym32",
361 .description = "Symbols are 32 bit on Mips64",
362 .dependencies = featureSet(&[_]Feature{}),
363 };
364 result[@intFromEnum(Feature.use_indirect_jump_hazard)] = .{
365 .llvm_name = "use-indirect-jump-hazard",
366 .description = "Use indirect jump guards to prevent certain speculation based attacks",
367 .dependencies = featureSet(&[_]Feature{}),
368 };
369 result[@intFromEnum(Feature.use_tcc_in_div)] = .{
370 .llvm_name = "use-tcc-in-div",
371 .description = "Force the assembler to use trapping",
372 .dependencies = featureSet(&[_]Feature{}),
373 };
374 result[@intFromEnum(Feature.vfpu)] = .{
375 .llvm_name = "vfpu",
376 .description = "Enable vector FPU instructions",
377 .dependencies = featureSet(&[_]Feature{}),
378 };
379 result[@intFromEnum(Feature.virt)] = .{
380 .llvm_name = "virt",
381 .description = "Mips Virtualization ASE",
382 .dependencies = featureSet(&[_]Feature{}),
383 };
384 result[@intFromEnum(Feature.xgot)] = .{
385 .llvm_name = "xgot",
386 .description = "Assume 32-bit GOT",
387 .dependencies = featureSet(&[_]Feature{}),
388 };
389 const ti = @typeInfo(Feature);
390 for (&result, 0..) |*elem, i| {
391 elem.index = i;
392 elem.name = ti.Enum.fields[i].name;
393 }
394 break :blk result;
395};
396
397pub const cpu = struct {
398 pub const generic = CpuModel{
399 .name = "generic",
400 .llvm_name = "generic",
401 .features = featureSet(&[_]Feature{
402 .mips32,
403 }),
404 };
405 pub const mips1 = CpuModel{
406 .name = "mips1",
407 .llvm_name = "mips1",
408 .features = featureSet(&[_]Feature{
409 .mips1,
410 }),
411 };
412 pub const mips2 = CpuModel{
413 .name = "mips2",
414 .llvm_name = "mips2",
415 .features = featureSet(&[_]Feature{
416 .mips2,
417 }),
418 };
419 pub const mips3 = CpuModel{
420 .name = "mips3",
421 .llvm_name = "mips3",
422 .features = featureSet(&[_]Feature{
423 .mips3,
424 }),
425 };
426 pub const mips32 = CpuModel{
427 .name = "mips32",
428 .llvm_name = "mips32",
429 .features = featureSet(&[_]Feature{
430 .mips32,
431 }),
432 };
433 pub const mips32r2 = CpuModel{
434 .name = "mips32r2",
435 .llvm_name = "mips32r2",
436 .features = featureSet(&[_]Feature{
437 .mips32r2,
438 }),
439 };
440 pub const mips32r3 = CpuModel{
441 .name = "mips32r3",
442 .llvm_name = "mips32r3",
443 .features = featureSet(&[_]Feature{
444 .mips32r3,
445 }),
446 };
447 pub const mips32r5 = CpuModel{
448 .name = "mips32r5",
449 .llvm_name = "mips32r5",
450 .features = featureSet(&[_]Feature{
451 .mips32r5,
452 }),
453 };
454 pub const mips32r6 = CpuModel{
455 .name = "mips32r6",
456 .llvm_name = "mips32r6",
457 .features = featureSet(&[_]Feature{
458 .mips32r6,
459 }),
460 };
461 pub const mips4 = CpuModel{
462 .name = "mips4",
463 .llvm_name = "mips4",
464 .features = featureSet(&[_]Feature{
465 .mips4,
466 }),
467 };
468 pub const mips5 = CpuModel{
469 .name = "mips5",
470 .llvm_name = "mips5",
471 .features = featureSet(&[_]Feature{
472 .mips5,
473 }),
474 };
475 pub const mips64 = CpuModel{
476 .name = "mips64",
477 .llvm_name = "mips64",
478 .features = featureSet(&[_]Feature{
479 .mips64,
480 }),
481 };
482 pub const mips64r2 = CpuModel{
483 .name = "mips64r2",
484 .llvm_name = "mips64r2",
485 .features = featureSet(&[_]Feature{
486 .mips64r2,
487 }),
488 };
489 pub const mips64r3 = CpuModel{
490 .name = "mips64r3",
491 .llvm_name = "mips64r3",
492 .features = featureSet(&[_]Feature{
493 .mips64r3,
494 }),
495 };
496 pub const mips64r5 = CpuModel{
497 .name = "mips64r5",
498 .llvm_name = "mips64r5",
499 .features = featureSet(&[_]Feature{
500 .mips64r5,
501 }),
502 };
503 pub const mips64r6 = CpuModel{
504 .name = "mips64r6",
505 .llvm_name = "mips64r6",
506 .features = featureSet(&[_]Feature{
507 .mips64r6,
508 }),
509 };
510 pub const octeon = CpuModel{
511 .name = "octeon",
512 .llvm_name = "octeon",
513 .features = featureSet(&[_]Feature{
514 .cnmips,
515 }),
516 };
517 pub const @"octeon+" = CpuModel{
518 .name = "octeon+",
519 .llvm_name = "octeon+",
520 .features = featureSet(&[_]Feature{
521 .cnmipsp,
522 }),
523 };
524 pub const p5600 = CpuModel{
525 .name = "p5600",
526 .llvm_name = "p5600",
527 .features = featureSet(&[_]Feature{
528 .p5600,
529 }),
530 };
531};
lib/std/target/msp430.zig deleted-69
......@@ -1,69 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 ext,
9 hwmult16,
10 hwmult32,
11 hwmultf5,
12};
13
14pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
15pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
16pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
17pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
18
19pub const all_features = blk: {
20 const len = @typeInfo(Feature).Enum.fields.len;
21 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
22 var result: [len]CpuFeature = undefined;
23 result[@intFromEnum(Feature.ext)] = .{
24 .llvm_name = "ext",
25 .description = "Enable MSP430-X extensions",
26 .dependencies = featureSet(&[_]Feature{}),
27 };
28 result[@intFromEnum(Feature.hwmult16)] = .{
29 .llvm_name = "hwmult16",
30 .description = "Enable 16-bit hardware multiplier",
31 .dependencies = featureSet(&[_]Feature{}),
32 };
33 result[@intFromEnum(Feature.hwmult32)] = .{
34 .llvm_name = "hwmult32",
35 .description = "Enable 32-bit hardware multiplier",
36 .dependencies = featureSet(&[_]Feature{}),
37 };
38 result[@intFromEnum(Feature.hwmultf5)] = .{
39 .llvm_name = "hwmultf5",
40 .description = "Enable F5 series hardware multiplier",
41 .dependencies = featureSet(&[_]Feature{}),
42 };
43 const ti = @typeInfo(Feature);
44 for (&result, 0..) |*elem, i| {
45 elem.index = i;
46 elem.name = ti.Enum.fields[i].name;
47 }
48 break :blk result;
49};
50
51pub const cpu = struct {
52 pub const generic = CpuModel{
53 .name = "generic",
54 .llvm_name = "generic",
55 .features = featureSet(&[_]Feature{}),
56 };
57 pub const msp430 = CpuModel{
58 .name = "msp430",
59 .llvm_name = "msp430",
60 .features = featureSet(&[_]Feature{}),
61 };
62 pub const msp430x = CpuModel{
63 .name = "msp430x",
64 .llvm_name = "msp430x",
65 .features = featureSet(&[_]Feature{
66 .ext,
67 }),
68 };
69};
lib/std/target/nvptx.zig deleted-439
......@@ -1,439 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 ptx32,
9 ptx40,
10 ptx41,
11 ptx42,
12 ptx43,
13 ptx50,
14 ptx60,
15 ptx61,
16 ptx63,
17 ptx64,
18 ptx65,
19 ptx70,
20 ptx71,
21 ptx72,
22 ptx73,
23 ptx74,
24 ptx75,
25 ptx76,
26 ptx77,
27 ptx78,
28 ptx80,
29 ptx81,
30 sm_20,
31 sm_21,
32 sm_30,
33 sm_32,
34 sm_35,
35 sm_37,
36 sm_50,
37 sm_52,
38 sm_53,
39 sm_60,
40 sm_61,
41 sm_62,
42 sm_70,
43 sm_72,
44 sm_75,
45 sm_80,
46 sm_86,
47 sm_87,
48 sm_89,
49 sm_90,
50};
51
52pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
53pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
54pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
55pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
56
57pub const all_features = blk: {
58 const len = @typeInfo(Feature).Enum.fields.len;
59 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
60 var result: [len]CpuFeature = undefined;
61 result[@intFromEnum(Feature.ptx32)] = .{
62 .llvm_name = "ptx32",
63 .description = "Use PTX version 32",
64 .dependencies = featureSet(&[_]Feature{}),
65 };
66 result[@intFromEnum(Feature.ptx40)] = .{
67 .llvm_name = "ptx40",
68 .description = "Use PTX version 40",
69 .dependencies = featureSet(&[_]Feature{}),
70 };
71 result[@intFromEnum(Feature.ptx41)] = .{
72 .llvm_name = "ptx41",
73 .description = "Use PTX version 41",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.ptx42)] = .{
77 .llvm_name = "ptx42",
78 .description = "Use PTX version 42",
79 .dependencies = featureSet(&[_]Feature{}),
80 };
81 result[@intFromEnum(Feature.ptx43)] = .{
82 .llvm_name = "ptx43",
83 .description = "Use PTX version 43",
84 .dependencies = featureSet(&[_]Feature{}),
85 };
86 result[@intFromEnum(Feature.ptx50)] = .{
87 .llvm_name = "ptx50",
88 .description = "Use PTX version 50",
89 .dependencies = featureSet(&[_]Feature{}),
90 };
91 result[@intFromEnum(Feature.ptx60)] = .{
92 .llvm_name = "ptx60",
93 .description = "Use PTX version 60",
94 .dependencies = featureSet(&[_]Feature{}),
95 };
96 result[@intFromEnum(Feature.ptx61)] = .{
97 .llvm_name = "ptx61",
98 .description = "Use PTX version 61",
99 .dependencies = featureSet(&[_]Feature{}),
100 };
101 result[@intFromEnum(Feature.ptx63)] = .{
102 .llvm_name = "ptx63",
103 .description = "Use PTX version 63",
104 .dependencies = featureSet(&[_]Feature{}),
105 };
106 result[@intFromEnum(Feature.ptx64)] = .{
107 .llvm_name = "ptx64",
108 .description = "Use PTX version 64",
109 .dependencies = featureSet(&[_]Feature{}),
110 };
111 result[@intFromEnum(Feature.ptx65)] = .{
112 .llvm_name = "ptx65",
113 .description = "Use PTX version 65",
114 .dependencies = featureSet(&[_]Feature{}),
115 };
116 result[@intFromEnum(Feature.ptx70)] = .{
117 .llvm_name = "ptx70",
118 .description = "Use PTX version 70",
119 .dependencies = featureSet(&[_]Feature{}),
120 };
121 result[@intFromEnum(Feature.ptx71)] = .{
122 .llvm_name = "ptx71",
123 .description = "Use PTX version 71",
124 .dependencies = featureSet(&[_]Feature{}),
125 };
126 result[@intFromEnum(Feature.ptx72)] = .{
127 .llvm_name = "ptx72",
128 .description = "Use PTX version 72",
129 .dependencies = featureSet(&[_]Feature{}),
130 };
131 result[@intFromEnum(Feature.ptx73)] = .{
132 .llvm_name = "ptx73",
133 .description = "Use PTX version 73",
134 .dependencies = featureSet(&[_]Feature{}),
135 };
136 result[@intFromEnum(Feature.ptx74)] = .{
137 .llvm_name = "ptx74",
138 .description = "Use PTX version 74",
139 .dependencies = featureSet(&[_]Feature{}),
140 };
141 result[@intFromEnum(Feature.ptx75)] = .{
142 .llvm_name = "ptx75",
143 .description = "Use PTX version 75",
144 .dependencies = featureSet(&[_]Feature{}),
145 };
146 result[@intFromEnum(Feature.ptx76)] = .{
147 .llvm_name = "ptx76",
148 .description = "Use PTX version 76",
149 .dependencies = featureSet(&[_]Feature{}),
150 };
151 result[@intFromEnum(Feature.ptx77)] = .{
152 .llvm_name = "ptx77",
153 .description = "Use PTX version 77",
154 .dependencies = featureSet(&[_]Feature{}),
155 };
156 result[@intFromEnum(Feature.ptx78)] = .{
157 .llvm_name = "ptx78",
158 .description = "Use PTX version 78",
159 .dependencies = featureSet(&[_]Feature{}),
160 };
161 result[@intFromEnum(Feature.ptx80)] = .{
162 .llvm_name = "ptx80",
163 .description = "Use PTX version 80",
164 .dependencies = featureSet(&[_]Feature{}),
165 };
166 result[@intFromEnum(Feature.ptx81)] = .{
167 .llvm_name = "ptx81",
168 .description = "Use PTX version 81",
169 .dependencies = featureSet(&[_]Feature{}),
170 };
171 result[@intFromEnum(Feature.sm_20)] = .{
172 .llvm_name = "sm_20",
173 .description = "Target SM 20",
174 .dependencies = featureSet(&[_]Feature{}),
175 };
176 result[@intFromEnum(Feature.sm_21)] = .{
177 .llvm_name = "sm_21",
178 .description = "Target SM 21",
179 .dependencies = featureSet(&[_]Feature{}),
180 };
181 result[@intFromEnum(Feature.sm_30)] = .{
182 .llvm_name = "sm_30",
183 .description = "Target SM 30",
184 .dependencies = featureSet(&[_]Feature{}),
185 };
186 result[@intFromEnum(Feature.sm_32)] = .{
187 .llvm_name = "sm_32",
188 .description = "Target SM 32",
189 .dependencies = featureSet(&[_]Feature{}),
190 };
191 result[@intFromEnum(Feature.sm_35)] = .{
192 .llvm_name = "sm_35",
193 .description = "Target SM 35",
194 .dependencies = featureSet(&[_]Feature{}),
195 };
196 result[@intFromEnum(Feature.sm_37)] = .{
197 .llvm_name = "sm_37",
198 .description = "Target SM 37",
199 .dependencies = featureSet(&[_]Feature{}),
200 };
201 result[@intFromEnum(Feature.sm_50)] = .{
202 .llvm_name = "sm_50",
203 .description = "Target SM 50",
204 .dependencies = featureSet(&[_]Feature{}),
205 };
206 result[@intFromEnum(Feature.sm_52)] = .{
207 .llvm_name = "sm_52",
208 .description = "Target SM 52",
209 .dependencies = featureSet(&[_]Feature{}),
210 };
211 result[@intFromEnum(Feature.sm_53)] = .{
212 .llvm_name = "sm_53",
213 .description = "Target SM 53",
214 .dependencies = featureSet(&[_]Feature{}),
215 };
216 result[@intFromEnum(Feature.sm_60)] = .{
217 .llvm_name = "sm_60",
218 .description = "Target SM 60",
219 .dependencies = featureSet(&[_]Feature{}),
220 };
221 result[@intFromEnum(Feature.sm_61)] = .{
222 .llvm_name = "sm_61",
223 .description = "Target SM 61",
224 .dependencies = featureSet(&[_]Feature{}),
225 };
226 result[@intFromEnum(Feature.sm_62)] = .{
227 .llvm_name = "sm_62",
228 .description = "Target SM 62",
229 .dependencies = featureSet(&[_]Feature{}),
230 };
231 result[@intFromEnum(Feature.sm_70)] = .{
232 .llvm_name = "sm_70",
233 .description = "Target SM 70",
234 .dependencies = featureSet(&[_]Feature{}),
235 };
236 result[@intFromEnum(Feature.sm_72)] = .{
237 .llvm_name = "sm_72",
238 .description = "Target SM 72",
239 .dependencies = featureSet(&[_]Feature{}),
240 };
241 result[@intFromEnum(Feature.sm_75)] = .{
242 .llvm_name = "sm_75",
243 .description = "Target SM 75",
244 .dependencies = featureSet(&[_]Feature{}),
245 };
246 result[@intFromEnum(Feature.sm_80)] = .{
247 .llvm_name = "sm_80",
248 .description = "Target SM 80",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.sm_86)] = .{
252 .llvm_name = "sm_86",
253 .description = "Target SM 86",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.sm_87)] = .{
257 .llvm_name = "sm_87",
258 .description = "Target SM 87",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.sm_89)] = .{
262 .llvm_name = "sm_89",
263 .description = "Target SM 89",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.sm_90)] = .{
267 .llvm_name = "sm_90",
268 .description = "Target SM 90",
269 .dependencies = featureSet(&[_]Feature{}),
270 };
271 const ti = @typeInfo(Feature);
272 for (&result, 0..) |*elem, i| {
273 elem.index = i;
274 elem.name = ti.Enum.fields[i].name;
275 }
276 break :blk result;
277};
278
279pub const cpu = struct {
280 pub const sm_20 = CpuModel{
281 .name = "sm_20",
282 .llvm_name = "sm_20",
283 .features = featureSet(&[_]Feature{
284 .ptx32,
285 .sm_20,
286 }),
287 };
288 pub const sm_21 = CpuModel{
289 .name = "sm_21",
290 .llvm_name = "sm_21",
291 .features = featureSet(&[_]Feature{
292 .ptx32,
293 .sm_21,
294 }),
295 };
296 pub const sm_30 = CpuModel{
297 .name = "sm_30",
298 .llvm_name = "sm_30",
299 .features = featureSet(&[_]Feature{
300 .sm_30,
301 }),
302 };
303 pub const sm_32 = CpuModel{
304 .name = "sm_32",
305 .llvm_name = "sm_32",
306 .features = featureSet(&[_]Feature{
307 .ptx40,
308 .sm_32,
309 }),
310 };
311 pub const sm_35 = CpuModel{
312 .name = "sm_35",
313 .llvm_name = "sm_35",
314 .features = featureSet(&[_]Feature{
315 .ptx32,
316 .sm_35,
317 }),
318 };
319 pub const sm_37 = CpuModel{
320 .name = "sm_37",
321 .llvm_name = "sm_37",
322 .features = featureSet(&[_]Feature{
323 .ptx41,
324 .sm_37,
325 }),
326 };
327 pub const sm_50 = CpuModel{
328 .name = "sm_50",
329 .llvm_name = "sm_50",
330 .features = featureSet(&[_]Feature{
331 .ptx40,
332 .sm_50,
333 }),
334 };
335 pub const sm_52 = CpuModel{
336 .name = "sm_52",
337 .llvm_name = "sm_52",
338 .features = featureSet(&[_]Feature{
339 .ptx41,
340 .sm_52,
341 }),
342 };
343 pub const sm_53 = CpuModel{
344 .name = "sm_53",
345 .llvm_name = "sm_53",
346 .features = featureSet(&[_]Feature{
347 .ptx42,
348 .sm_53,
349 }),
350 };
351 pub const sm_60 = CpuModel{
352 .name = "sm_60",
353 .llvm_name = "sm_60",
354 .features = featureSet(&[_]Feature{
355 .ptx50,
356 .sm_60,
357 }),
358 };
359 pub const sm_61 = CpuModel{
360 .name = "sm_61",
361 .llvm_name = "sm_61",
362 .features = featureSet(&[_]Feature{
363 .ptx50,
364 .sm_61,
365 }),
366 };
367 pub const sm_62 = CpuModel{
368 .name = "sm_62",
369 .llvm_name = "sm_62",
370 .features = featureSet(&[_]Feature{
371 .ptx50,
372 .sm_62,
373 }),
374 };
375 pub const sm_70 = CpuModel{
376 .name = "sm_70",
377 .llvm_name = "sm_70",
378 .features = featureSet(&[_]Feature{
379 .ptx60,
380 .sm_70,
381 }),
382 };
383 pub const sm_72 = CpuModel{
384 .name = "sm_72",
385 .llvm_name = "sm_72",
386 .features = featureSet(&[_]Feature{
387 .ptx61,
388 .sm_72,
389 }),
390 };
391 pub const sm_75 = CpuModel{
392 .name = "sm_75",
393 .llvm_name = "sm_75",
394 .features = featureSet(&[_]Feature{
395 .ptx63,
396 .sm_75,
397 }),
398 };
399 pub const sm_80 = CpuModel{
400 .name = "sm_80",
401 .llvm_name = "sm_80",
402 .features = featureSet(&[_]Feature{
403 .ptx70,
404 .sm_80,
405 }),
406 };
407 pub const sm_86 = CpuModel{
408 .name = "sm_86",
409 .llvm_name = "sm_86",
410 .features = featureSet(&[_]Feature{
411 .ptx71,
412 .sm_86,
413 }),
414 };
415 pub const sm_87 = CpuModel{
416 .name = "sm_87",
417 .llvm_name = "sm_87",
418 .features = featureSet(&[_]Feature{
419 .ptx74,
420 .sm_87,
421 }),
422 };
423 pub const sm_89 = CpuModel{
424 .name = "sm_89",
425 .llvm_name = "sm_89",
426 .features = featureSet(&[_]Feature{
427 .ptx78,
428 .sm_89,
429 }),
430 };
431 pub const sm_90 = CpuModel{
432 .name = "sm_90",
433 .llvm_name = "sm_90",
434 .features = featureSet(&[_]Feature{
435 .ptx78,
436 .sm_90,
437 }),
438 };
439};
lib/std/target/powerpc.zig deleted-1192
......@@ -1,1192 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"64bit",
9 @"64bitregs",
10 aix,
11 allow_unaligned_fp_access,
12 altivec,
13 booke,
14 bpermd,
15 cmpb,
16 crbits,
17 crypto,
18 direct_move,
19 e500,
20 efpu2,
21 extdiv,
22 fast_MFLR,
23 fcpsgn,
24 float128,
25 fpcvt,
26 fprnd,
27 fpu,
28 fre,
29 fres,
30 frsqrte,
31 frsqrtes,
32 fsqrt,
33 fuse_add_logical,
34 fuse_addi_load,
35 fuse_addis_load,
36 fuse_arith_add,
37 fuse_back2back,
38 fuse_cmp,
39 fuse_logical,
40 fuse_logical_add,
41 fuse_sha3,
42 fuse_store,
43 fuse_wideimm,
44 fuse_zeromove,
45 fusion,
46 hard_float,
47 htm,
48 icbt,
49 invariant_function_descriptors,
50 isa_future_instructions,
51 isa_v206_instructions,
52 isa_v207_instructions,
53 isa_v30_instructions,
54 isa_v31_instructions,
55 isel,
56 ldbrx,
57 lfiwax,
58 longcall,
59 mfocrf,
60 mma,
61 modern_aix_as,
62 msync,
63 paired_vector_memops,
64 partword_atomics,
65 pcrelative_memops,
66 popcntd,
67 power10_vector,
68 power8_altivec,
69 power8_vector,
70 power9_altivec,
71 power9_vector,
72 ppc4xx,
73 ppc6xx,
74 ppc_postra_sched,
75 ppc_prera_sched,
76 predictable_select_expensive,
77 prefix_instrs,
78 privileged,
79 quadword_atomics,
80 recipprec,
81 rop_protect,
82 secure_plt,
83 slow_popcntd,
84 spe,
85 stfiwx,
86 two_const_nr,
87 vectors_use_two_units,
88 vsx,
89};
90
91pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
92pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
93pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
94pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
95
96pub const all_features = blk: {
97 const len = @typeInfo(Feature).Enum.fields.len;
98 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
99 var result: [len]CpuFeature = undefined;
100 result[@intFromEnum(Feature.@"64bit")] = .{
101 .llvm_name = "64bit",
102 .description = "Enable 64-bit instructions",
103 .dependencies = featureSet(&[_]Feature{}),
104 };
105 result[@intFromEnum(Feature.@"64bitregs")] = .{
106 .llvm_name = "64bitregs",
107 .description = "Enable 64-bit registers usage for ppc32 [beta]",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.aix)] = .{
111 .llvm_name = "aix",
112 .description = "AIX OS",
113 .dependencies = featureSet(&[_]Feature{}),
114 };
115 result[@intFromEnum(Feature.allow_unaligned_fp_access)] = .{
116 .llvm_name = "allow-unaligned-fp-access",
117 .description = "CPU does not trap on unaligned FP access",
118 .dependencies = featureSet(&[_]Feature{}),
119 };
120 result[@intFromEnum(Feature.altivec)] = .{
121 .llvm_name = "altivec",
122 .description = "Enable Altivec instructions",
123 .dependencies = featureSet(&[_]Feature{
124 .fpu,
125 }),
126 };
127 result[@intFromEnum(Feature.booke)] = .{
128 .llvm_name = "booke",
129 .description = "Enable Book E instructions",
130 .dependencies = featureSet(&[_]Feature{
131 .icbt,
132 }),
133 };
134 result[@intFromEnum(Feature.bpermd)] = .{
135 .llvm_name = "bpermd",
136 .description = "Enable the bpermd instruction",
137 .dependencies = featureSet(&[_]Feature{}),
138 };
139 result[@intFromEnum(Feature.cmpb)] = .{
140 .llvm_name = "cmpb",
141 .description = "Enable the cmpb instruction",
142 .dependencies = featureSet(&[_]Feature{}),
143 };
144 result[@intFromEnum(Feature.crbits)] = .{
145 .llvm_name = "crbits",
146 .description = "Use condition-register bits individually",
147 .dependencies = featureSet(&[_]Feature{}),
148 };
149 result[@intFromEnum(Feature.crypto)] = .{
150 .llvm_name = "crypto",
151 .description = "Enable POWER8 Crypto instructions",
152 .dependencies = featureSet(&[_]Feature{
153 .power8_altivec,
154 }),
155 };
156 result[@intFromEnum(Feature.direct_move)] = .{
157 .llvm_name = "direct-move",
158 .description = "Enable Power8 direct move instructions",
159 .dependencies = featureSet(&[_]Feature{
160 .vsx,
161 }),
162 };
163 result[@intFromEnum(Feature.e500)] = .{
164 .llvm_name = "e500",
165 .description = "Enable E500/E500mc instructions",
166 .dependencies = featureSet(&[_]Feature{}),
167 };
168 result[@intFromEnum(Feature.efpu2)] = .{
169 .llvm_name = "efpu2",
170 .description = "Enable Embedded Floating-Point APU 2 instructions",
171 .dependencies = featureSet(&[_]Feature{
172 .spe,
173 }),
174 };
175 result[@intFromEnum(Feature.extdiv)] = .{
176 .llvm_name = "extdiv",
177 .description = "Enable extended divide instructions",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.fast_MFLR)] = .{
181 .llvm_name = "fast-MFLR",
182 .description = "MFLR is a fast instruction",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.fcpsgn)] = .{
186 .llvm_name = "fcpsgn",
187 .description = "Enable the fcpsgn instruction",
188 .dependencies = featureSet(&[_]Feature{
189 .fpu,
190 }),
191 };
192 result[@intFromEnum(Feature.float128)] = .{
193 .llvm_name = "float128",
194 .description = "Enable the __float128 data type for IEEE-754R Binary128.",
195 .dependencies = featureSet(&[_]Feature{
196 .vsx,
197 }),
198 };
199 result[@intFromEnum(Feature.fpcvt)] = .{
200 .llvm_name = "fpcvt",
201 .description = "Enable fc[ft]* (unsigned and single-precision) and lfiwzx instructions",
202 .dependencies = featureSet(&[_]Feature{
203 .fpu,
204 }),
205 };
206 result[@intFromEnum(Feature.fprnd)] = .{
207 .llvm_name = "fprnd",
208 .description = "Enable the fri[mnpz] instructions",
209 .dependencies = featureSet(&[_]Feature{
210 .fpu,
211 }),
212 };
213 result[@intFromEnum(Feature.fpu)] = .{
214 .llvm_name = "fpu",
215 .description = "Enable classic FPU instructions",
216 .dependencies = featureSet(&[_]Feature{
217 .hard_float,
218 }),
219 };
220 result[@intFromEnum(Feature.fre)] = .{
221 .llvm_name = "fre",
222 .description = "Enable the fre instruction",
223 .dependencies = featureSet(&[_]Feature{
224 .fpu,
225 }),
226 };
227 result[@intFromEnum(Feature.fres)] = .{
228 .llvm_name = "fres",
229 .description = "Enable the fres instruction",
230 .dependencies = featureSet(&[_]Feature{
231 .fpu,
232 }),
233 };
234 result[@intFromEnum(Feature.frsqrte)] = .{
235 .llvm_name = "frsqrte",
236 .description = "Enable the frsqrte instruction",
237 .dependencies = featureSet(&[_]Feature{
238 .fpu,
239 }),
240 };
241 result[@intFromEnum(Feature.frsqrtes)] = .{
242 .llvm_name = "frsqrtes",
243 .description = "Enable the frsqrtes instruction",
244 .dependencies = featureSet(&[_]Feature{
245 .fpu,
246 }),
247 };
248 result[@intFromEnum(Feature.fsqrt)] = .{
249 .llvm_name = "fsqrt",
250 .description = "Enable the fsqrt instruction",
251 .dependencies = featureSet(&[_]Feature{
252 .fpu,
253 }),
254 };
255 result[@intFromEnum(Feature.fuse_add_logical)] = .{
256 .llvm_name = "fuse-add-logical",
257 .description = "Target supports Add with Logical Operations fusion",
258 .dependencies = featureSet(&[_]Feature{
259 .fusion,
260 }),
261 };
262 result[@intFromEnum(Feature.fuse_addi_load)] = .{
263 .llvm_name = "fuse-addi-load",
264 .description = "Power8 Addi-Load fusion",
265 .dependencies = featureSet(&[_]Feature{
266 .fusion,
267 }),
268 };
269 result[@intFromEnum(Feature.fuse_addis_load)] = .{
270 .llvm_name = "fuse-addis-load",
271 .description = "Power8 Addis-Load fusion",
272 .dependencies = featureSet(&[_]Feature{
273 .fusion,
274 }),
275 };
276 result[@intFromEnum(Feature.fuse_arith_add)] = .{
277 .llvm_name = "fuse-arith-add",
278 .description = "Target supports Arithmetic Operations with Add fusion",
279 .dependencies = featureSet(&[_]Feature{
280 .fusion,
281 }),
282 };
283 result[@intFromEnum(Feature.fuse_back2back)] = .{
284 .llvm_name = "fuse-back2back",
285 .description = "Target supports general back to back fusion",
286 .dependencies = featureSet(&[_]Feature{
287 .fusion,
288 }),
289 };
290 result[@intFromEnum(Feature.fuse_cmp)] = .{
291 .llvm_name = "fuse-cmp",
292 .description = "Target supports Comparison Operations fusion",
293 .dependencies = featureSet(&[_]Feature{
294 .fusion,
295 }),
296 };
297 result[@intFromEnum(Feature.fuse_logical)] = .{
298 .llvm_name = "fuse-logical",
299 .description = "Target supports Logical Operations fusion",
300 .dependencies = featureSet(&[_]Feature{
301 .fusion,
302 }),
303 };
304 result[@intFromEnum(Feature.fuse_logical_add)] = .{
305 .llvm_name = "fuse-logical-add",
306 .description = "Target supports Logical with Add Operations fusion",
307 .dependencies = featureSet(&[_]Feature{
308 .fusion,
309 }),
310 };
311 result[@intFromEnum(Feature.fuse_sha3)] = .{
312 .llvm_name = "fuse-sha3",
313 .description = "Target supports SHA3 assist fusion",
314 .dependencies = featureSet(&[_]Feature{
315 .fusion,
316 }),
317 };
318 result[@intFromEnum(Feature.fuse_store)] = .{
319 .llvm_name = "fuse-store",
320 .description = "Target supports store clustering",
321 .dependencies = featureSet(&[_]Feature{
322 .fusion,
323 }),
324 };
325 result[@intFromEnum(Feature.fuse_wideimm)] = .{
326 .llvm_name = "fuse-wideimm",
327 .description = "Target supports Wide-Immediate fusion",
328 .dependencies = featureSet(&[_]Feature{
329 .fusion,
330 }),
331 };
332 result[@intFromEnum(Feature.fuse_zeromove)] = .{
333 .llvm_name = "fuse-zeromove",
334 .description = "Target supports move to SPR with branch fusion",
335 .dependencies = featureSet(&[_]Feature{
336 .fusion,
337 }),
338 };
339 result[@intFromEnum(Feature.fusion)] = .{
340 .llvm_name = "fusion",
341 .description = "Target supports instruction fusion",
342 .dependencies = featureSet(&[_]Feature{}),
343 };
344 result[@intFromEnum(Feature.hard_float)] = .{
345 .llvm_name = "hard-float",
346 .description = "Enable floating-point instructions",
347 .dependencies = featureSet(&[_]Feature{}),
348 };
349 result[@intFromEnum(Feature.htm)] = .{
350 .llvm_name = "htm",
351 .description = "Enable Hardware Transactional Memory instructions",
352 .dependencies = featureSet(&[_]Feature{}),
353 };
354 result[@intFromEnum(Feature.icbt)] = .{
355 .llvm_name = "icbt",
356 .description = "Enable icbt instruction",
357 .dependencies = featureSet(&[_]Feature{}),
358 };
359 result[@intFromEnum(Feature.invariant_function_descriptors)] = .{
360 .llvm_name = "invariant-function-descriptors",
361 .description = "Assume function descriptors are invariant",
362 .dependencies = featureSet(&[_]Feature{}),
363 };
364 result[@intFromEnum(Feature.isa_future_instructions)] = .{
365 .llvm_name = "isa-future-instructions",
366 .description = "Enable instructions for Future ISA.",
367 .dependencies = featureSet(&[_]Feature{
368 .isa_v31_instructions,
369 }),
370 };
371 result[@intFromEnum(Feature.isa_v206_instructions)] = .{
372 .llvm_name = "isa-v206-instructions",
373 .description = "Enable instructions in ISA 2.06.",
374 .dependencies = featureSet(&[_]Feature{}),
375 };
376 result[@intFromEnum(Feature.isa_v207_instructions)] = .{
377 .llvm_name = "isa-v207-instructions",
378 .description = "Enable instructions in ISA 2.07.",
379 .dependencies = featureSet(&[_]Feature{}),
380 };
381 result[@intFromEnum(Feature.isa_v30_instructions)] = .{
382 .llvm_name = "isa-v30-instructions",
383 .description = "Enable instructions in ISA 3.0.",
384 .dependencies = featureSet(&[_]Feature{
385 .isa_v207_instructions,
386 }),
387 };
388 result[@intFromEnum(Feature.isa_v31_instructions)] = .{
389 .llvm_name = "isa-v31-instructions",
390 .description = "Enable instructions in ISA 3.1.",
391 .dependencies = featureSet(&[_]Feature{
392 .isa_v30_instructions,
393 }),
394 };
395 result[@intFromEnum(Feature.isel)] = .{
396 .llvm_name = "isel",
397 .description = "Enable the isel instruction",
398 .dependencies = featureSet(&[_]Feature{}),
399 };
400 result[@intFromEnum(Feature.ldbrx)] = .{
401 .llvm_name = "ldbrx",
402 .description = "Enable the ldbrx instruction",
403 .dependencies = featureSet(&[_]Feature{}),
404 };
405 result[@intFromEnum(Feature.lfiwax)] = .{
406 .llvm_name = "lfiwax",
407 .description = "Enable the lfiwax instruction",
408 .dependencies = featureSet(&[_]Feature{
409 .fpu,
410 }),
411 };
412 result[@intFromEnum(Feature.longcall)] = .{
413 .llvm_name = "longcall",
414 .description = "Always use indirect calls",
415 .dependencies = featureSet(&[_]Feature{}),
416 };
417 result[@intFromEnum(Feature.mfocrf)] = .{
418 .llvm_name = "mfocrf",
419 .description = "Enable the MFOCRF instruction",
420 .dependencies = featureSet(&[_]Feature{}),
421 };
422 result[@intFromEnum(Feature.mma)] = .{
423 .llvm_name = "mma",
424 .description = "Enable MMA instructions",
425 .dependencies = featureSet(&[_]Feature{
426 .paired_vector_memops,
427 .power8_vector,
428 .power9_altivec,
429 }),
430 };
431 result[@intFromEnum(Feature.modern_aix_as)] = .{
432 .llvm_name = "modern-aix-as",
433 .description = "AIX system assembler is modern enough to support new mnes",
434 .dependencies = featureSet(&[_]Feature{}),
435 };
436 result[@intFromEnum(Feature.msync)] = .{
437 .llvm_name = "msync",
438 .description = "Has only the msync instruction instead of sync",
439 .dependencies = featureSet(&[_]Feature{
440 .booke,
441 }),
442 };
443 result[@intFromEnum(Feature.paired_vector_memops)] = .{
444 .llvm_name = "paired-vector-memops",
445 .description = "32Byte load and store instructions",
446 .dependencies = featureSet(&[_]Feature{
447 .isa_v30_instructions,
448 }),
449 };
450 result[@intFromEnum(Feature.partword_atomics)] = .{
451 .llvm_name = "partword-atomics",
452 .description = "Enable l[bh]arx and st[bh]cx.",
453 .dependencies = featureSet(&[_]Feature{}),
454 };
455 result[@intFromEnum(Feature.pcrelative_memops)] = .{
456 .llvm_name = "pcrelative-memops",
457 .description = "Enable PC relative Memory Ops",
458 .dependencies = featureSet(&[_]Feature{
459 .prefix_instrs,
460 }),
461 };
462 result[@intFromEnum(Feature.popcntd)] = .{
463 .llvm_name = "popcntd",
464 .description = "Enable the popcnt[dw] instructions",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@intFromEnum(Feature.power10_vector)] = .{
468 .llvm_name = "power10-vector",
469 .description = "Enable POWER10 vector instructions",
470 .dependencies = featureSet(&[_]Feature{
471 .isa_v31_instructions,
472 .power9_vector,
473 }),
474 };
475 result[@intFromEnum(Feature.power8_altivec)] = .{
476 .llvm_name = "power8-altivec",
477 .description = "Enable POWER8 Altivec instructions",
478 .dependencies = featureSet(&[_]Feature{
479 .altivec,
480 }),
481 };
482 result[@intFromEnum(Feature.power8_vector)] = .{
483 .llvm_name = "power8-vector",
484 .description = "Enable POWER8 vector instructions",
485 .dependencies = featureSet(&[_]Feature{
486 .power8_altivec,
487 .vsx,
488 }),
489 };
490 result[@intFromEnum(Feature.power9_altivec)] = .{
491 .llvm_name = "power9-altivec",
492 .description = "Enable POWER9 Altivec instructions",
493 .dependencies = featureSet(&[_]Feature{
494 .isa_v30_instructions,
495 .power8_altivec,
496 }),
497 };
498 result[@intFromEnum(Feature.power9_vector)] = .{
499 .llvm_name = "power9-vector",
500 .description = "Enable POWER9 vector instructions",
501 .dependencies = featureSet(&[_]Feature{
502 .power8_vector,
503 .power9_altivec,
504 }),
505 };
506 result[@intFromEnum(Feature.ppc4xx)] = .{
507 .llvm_name = "ppc4xx",
508 .description = "Enable PPC 4xx instructions",
509 .dependencies = featureSet(&[_]Feature{}),
510 };
511 result[@intFromEnum(Feature.ppc6xx)] = .{
512 .llvm_name = "ppc6xx",
513 .description = "Enable PPC 6xx instructions",
514 .dependencies = featureSet(&[_]Feature{}),
515 };
516 result[@intFromEnum(Feature.ppc_postra_sched)] = .{
517 .llvm_name = "ppc-postra-sched",
518 .description = "Use PowerPC post-RA scheduling strategy",
519 .dependencies = featureSet(&[_]Feature{}),
520 };
521 result[@intFromEnum(Feature.ppc_prera_sched)] = .{
522 .llvm_name = "ppc-prera-sched",
523 .description = "Use PowerPC pre-RA scheduling strategy",
524 .dependencies = featureSet(&[_]Feature{}),
525 };
526 result[@intFromEnum(Feature.predictable_select_expensive)] = .{
527 .llvm_name = "predictable-select-expensive",
528 .description = "Prefer likely predicted branches over selects",
529 .dependencies = featureSet(&[_]Feature{}),
530 };
531 result[@intFromEnum(Feature.prefix_instrs)] = .{
532 .llvm_name = "prefix-instrs",
533 .description = "Enable prefixed instructions",
534 .dependencies = featureSet(&[_]Feature{
535 .power8_vector,
536 .power9_altivec,
537 }),
538 };
539 result[@intFromEnum(Feature.privileged)] = .{
540 .llvm_name = "privileged",
541 .description = "Add privileged instructions",
542 .dependencies = featureSet(&[_]Feature{}),
543 };
544 result[@intFromEnum(Feature.quadword_atomics)] = .{
545 .llvm_name = "quadword-atomics",
546 .description = "Enable lqarx and stqcx.",
547 .dependencies = featureSet(&[_]Feature{}),
548 };
549 result[@intFromEnum(Feature.recipprec)] = .{
550 .llvm_name = "recipprec",
551 .description = "Assume higher precision reciprocal estimates",
552 .dependencies = featureSet(&[_]Feature{}),
553 };
554 result[@intFromEnum(Feature.rop_protect)] = .{
555 .llvm_name = "rop-protect",
556 .description = "Add ROP protect",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
559 result[@intFromEnum(Feature.secure_plt)] = .{
560 .llvm_name = "secure-plt",
561 .description = "Enable secure plt mode",
562 .dependencies = featureSet(&[_]Feature{}),
563 };
564 result[@intFromEnum(Feature.slow_popcntd)] = .{
565 .llvm_name = "slow-popcntd",
566 .description = "Has slow popcnt[dw] instructions",
567 .dependencies = featureSet(&[_]Feature{}),
568 };
569 result[@intFromEnum(Feature.spe)] = .{
570 .llvm_name = "spe",
571 .description = "Enable SPE instructions",
572 .dependencies = featureSet(&[_]Feature{
573 .hard_float,
574 }),
575 };
576 result[@intFromEnum(Feature.stfiwx)] = .{
577 .llvm_name = "stfiwx",
578 .description = "Enable the stfiwx instruction",
579 .dependencies = featureSet(&[_]Feature{
580 .fpu,
581 }),
582 };
583 result[@intFromEnum(Feature.two_const_nr)] = .{
584 .llvm_name = "two-const-nr",
585 .description = "Requires two constant Newton-Raphson computation",
586 .dependencies = featureSet(&[_]Feature{}),
587 };
588 result[@intFromEnum(Feature.vectors_use_two_units)] = .{
589 .llvm_name = "vectors-use-two-units",
590 .description = "Vectors use two units",
591 .dependencies = featureSet(&[_]Feature{}),
592 };
593 result[@intFromEnum(Feature.vsx)] = .{
594 .llvm_name = "vsx",
595 .description = "Enable VSX instructions",
596 .dependencies = featureSet(&[_]Feature{
597 .altivec,
598 }),
599 };
600 const ti = @typeInfo(Feature);
601 for (&result, 0..) |*elem, i| {
602 elem.index = i;
603 elem.name = ti.Enum.fields[i].name;
604 }
605 break :blk result;
606};
607
608pub const cpu = struct {
609 pub const @"440" = CpuModel{
610 .name = "440",
611 .llvm_name = "440",
612 .features = featureSet(&[_]Feature{
613 .fres,
614 .frsqrte,
615 .isel,
616 .msync,
617 }),
618 };
619 pub const @"450" = CpuModel{
620 .name = "450",
621 .llvm_name = "450",
622 .features = featureSet(&[_]Feature{
623 .fres,
624 .frsqrte,
625 .isel,
626 .msync,
627 }),
628 };
629 pub const @"601" = CpuModel{
630 .name = "601",
631 .llvm_name = "601",
632 .features = featureSet(&[_]Feature{
633 .fpu,
634 }),
635 };
636 pub const @"602" = CpuModel{
637 .name = "602",
638 .llvm_name = "602",
639 .features = featureSet(&[_]Feature{
640 .fpu,
641 }),
642 };
643 pub const @"603" = CpuModel{
644 .name = "603",
645 .llvm_name = "603",
646 .features = featureSet(&[_]Feature{
647 .fres,
648 .frsqrte,
649 }),
650 };
651 pub const @"603e" = CpuModel{
652 .name = "603e",
653 .llvm_name = "603e",
654 .features = featureSet(&[_]Feature{
655 .fres,
656 .frsqrte,
657 }),
658 };
659 pub const @"603ev" = CpuModel{
660 .name = "603ev",
661 .llvm_name = "603ev",
662 .features = featureSet(&[_]Feature{
663 .fres,
664 .frsqrte,
665 }),
666 };
667 pub const @"604" = CpuModel{
668 .name = "604",
669 .llvm_name = "604",
670 .features = featureSet(&[_]Feature{
671 .fres,
672 .frsqrte,
673 }),
674 };
675 pub const @"604e" = CpuModel{
676 .name = "604e",
677 .llvm_name = "604e",
678 .features = featureSet(&[_]Feature{
679 .fres,
680 .frsqrte,
681 }),
682 };
683 pub const @"620" = CpuModel{
684 .name = "620",
685 .llvm_name = "620",
686 .features = featureSet(&[_]Feature{
687 .fres,
688 .frsqrte,
689 }),
690 };
691 pub const @"7400" = CpuModel{
692 .name = "7400",
693 .llvm_name = "7400",
694 .features = featureSet(&[_]Feature{
695 .altivec,
696 .fres,
697 .frsqrte,
698 }),
699 };
700 pub const @"7450" = CpuModel{
701 .name = "7450",
702 .llvm_name = "7450",
703 .features = featureSet(&[_]Feature{
704 .altivec,
705 .fres,
706 .frsqrte,
707 }),
708 };
709 pub const @"750" = CpuModel{
710 .name = "750",
711 .llvm_name = "750",
712 .features = featureSet(&[_]Feature{
713 .fres,
714 .frsqrte,
715 }),
716 };
717 pub const @"970" = CpuModel{
718 .name = "970",
719 .llvm_name = "970",
720 .features = featureSet(&[_]Feature{
721 .@"64bit",
722 .altivec,
723 .fres,
724 .frsqrte,
725 .fsqrt,
726 .mfocrf,
727 .stfiwx,
728 }),
729 };
730 pub const a2 = CpuModel{
731 .name = "a2",
732 .llvm_name = "a2",
733 .features = featureSet(&[_]Feature{
734 .@"64bit",
735 .booke,
736 .cmpb,
737 .fcpsgn,
738 .fpcvt,
739 .fprnd,
740 .fre,
741 .fres,
742 .frsqrte,
743 .frsqrtes,
744 .fsqrt,
745 .isa_v206_instructions,
746 .isel,
747 .ldbrx,
748 .lfiwax,
749 .mfocrf,
750 .recipprec,
751 .slow_popcntd,
752 .stfiwx,
753 }),
754 };
755 pub const e500 = CpuModel{
756 .name = "e500",
757 .llvm_name = "e500",
758 .features = featureSet(&[_]Feature{
759 .isel,
760 .msync,
761 .spe,
762 }),
763 };
764 pub const e500mc = CpuModel{
765 .name = "e500mc",
766 .llvm_name = "e500mc",
767 .features = featureSet(&[_]Feature{
768 .booke,
769 .isel,
770 .stfiwx,
771 }),
772 };
773 pub const e5500 = CpuModel{
774 .name = "e5500",
775 .llvm_name = "e5500",
776 .features = featureSet(&[_]Feature{
777 .@"64bit",
778 .booke,
779 .isel,
780 .mfocrf,
781 .stfiwx,
782 }),
783 };
784 pub const future = CpuModel{
785 .name = "future",
786 .llvm_name = "future",
787 .features = featureSet(&[_]Feature{
788 .@"64bit",
789 .allow_unaligned_fp_access,
790 .bpermd,
791 .cmpb,
792 .crbits,
793 .crypto,
794 .direct_move,
795 .extdiv,
796 .fast_MFLR,
797 .fcpsgn,
798 .fpcvt,
799 .fprnd,
800 .fre,
801 .fres,
802 .frsqrte,
803 .frsqrtes,
804 .fsqrt,
805 .fuse_add_logical,
806 .fuse_arith_add,
807 .fuse_logical,
808 .fuse_logical_add,
809 .fuse_sha3,
810 .fuse_store,
811 .htm,
812 .icbt,
813 .isa_future_instructions,
814 .isa_v206_instructions,
815 .isel,
816 .ldbrx,
817 .lfiwax,
818 .mfocrf,
819 .mma,
820 .partword_atomics,
821 .pcrelative_memops,
822 .popcntd,
823 .power10_vector,
824 .ppc_postra_sched,
825 .ppc_prera_sched,
826 .predictable_select_expensive,
827 .quadword_atomics,
828 .recipprec,
829 .stfiwx,
830 .two_const_nr,
831 }),
832 };
833 pub const g3 = CpuModel{
834 .name = "g3",
835 .llvm_name = "g3",
836 .features = featureSet(&[_]Feature{
837 .fres,
838 .frsqrte,
839 }),
840 };
841 pub const g4 = CpuModel{
842 .name = "g4",
843 .llvm_name = "g4",
844 .features = featureSet(&[_]Feature{
845 .altivec,
846 .fres,
847 .frsqrte,
848 }),
849 };
850 pub const @"g4+" = CpuModel{
851 .name = "g4+",
852 .llvm_name = "g4+",
853 .features = featureSet(&[_]Feature{
854 .altivec,
855 .fres,
856 .frsqrte,
857 }),
858 };
859 pub const g5 = CpuModel{
860 .name = "g5",
861 .llvm_name = "g5",
862 .features = featureSet(&[_]Feature{
863 .@"64bit",
864 .altivec,
865 .fres,
866 .frsqrte,
867 .fsqrt,
868 .mfocrf,
869 .stfiwx,
870 }),
871 };
872 pub const generic = CpuModel{
873 .name = "generic",
874 .llvm_name = "generic",
875 .features = featureSet(&[_]Feature{
876 .hard_float,
877 }),
878 };
879 pub const ppc = CpuModel{
880 .name = "ppc",
881 .llvm_name = "ppc",
882 .features = featureSet(&[_]Feature{
883 .hard_float,
884 }),
885 };
886 pub const ppc64 = CpuModel{
887 .name = "ppc64",
888 .llvm_name = "ppc64",
889 .features = featureSet(&[_]Feature{
890 .@"64bit",
891 .altivec,
892 .fres,
893 .frsqrte,
894 .fsqrt,
895 .mfocrf,
896 .stfiwx,
897 }),
898 };
899 pub const ppc64le = CpuModel{
900 .name = "ppc64le",
901 .llvm_name = "ppc64le",
902 .features = featureSet(&[_]Feature{
903 .@"64bit",
904 .allow_unaligned_fp_access,
905 .bpermd,
906 .cmpb,
907 .crbits,
908 .crypto,
909 .direct_move,
910 .extdiv,
911 .fcpsgn,
912 .fpcvt,
913 .fprnd,
914 .fre,
915 .fres,
916 .frsqrte,
917 .frsqrtes,
918 .fsqrt,
919 .fuse_addi_load,
920 .fuse_addis_load,
921 .htm,
922 .icbt,
923 .isa_v206_instructions,
924 .isa_v207_instructions,
925 .isel,
926 .ldbrx,
927 .lfiwax,
928 .mfocrf,
929 .partword_atomics,
930 .popcntd,
931 .power8_vector,
932 .predictable_select_expensive,
933 .quadword_atomics,
934 .recipprec,
935 .stfiwx,
936 .two_const_nr,
937 }),
938 };
939 pub const pwr10 = CpuModel{
940 .name = "pwr10",
941 .llvm_name = "pwr10",
942 .features = featureSet(&[_]Feature{
943 .@"64bit",
944 .allow_unaligned_fp_access,
945 .bpermd,
946 .cmpb,
947 .crbits,
948 .crypto,
949 .direct_move,
950 .extdiv,
951 .fast_MFLR,
952 .fcpsgn,
953 .fpcvt,
954 .fprnd,
955 .fre,
956 .fres,
957 .frsqrte,
958 .frsqrtes,
959 .fsqrt,
960 .fuse_add_logical,
961 .fuse_arith_add,
962 .fuse_logical,
963 .fuse_logical_add,
964 .fuse_sha3,
965 .fuse_store,
966 .htm,
967 .icbt,
968 .isa_v206_instructions,
969 .isel,
970 .ldbrx,
971 .lfiwax,
972 .mfocrf,
973 .mma,
974 .partword_atomics,
975 .pcrelative_memops,
976 .popcntd,
977 .power10_vector,
978 .ppc_postra_sched,
979 .ppc_prera_sched,
980 .predictable_select_expensive,
981 .quadword_atomics,
982 .recipprec,
983 .stfiwx,
984 .two_const_nr,
985 }),
986 };
987 pub const pwr3 = CpuModel{
988 .name = "pwr3",
989 .llvm_name = "pwr3",
990 .features = featureSet(&[_]Feature{
991 .@"64bit",
992 .altivec,
993 .fres,
994 .frsqrte,
995 .mfocrf,
996 .stfiwx,
997 }),
998 };
999 pub const pwr4 = CpuModel{
1000 .name = "pwr4",
1001 .llvm_name = "pwr4",
1002 .features = featureSet(&[_]Feature{
1003 .@"64bit",
1004 .altivec,
1005 .fres,
1006 .frsqrte,
1007 .fsqrt,
1008 .mfocrf,
1009 .stfiwx,
1010 }),
1011 };
1012 pub const pwr5 = CpuModel{
1013 .name = "pwr5",
1014 .llvm_name = "pwr5",
1015 .features = featureSet(&[_]Feature{
1016 .@"64bit",
1017 .altivec,
1018 .fre,
1019 .fres,
1020 .frsqrte,
1021 .frsqrtes,
1022 .fsqrt,
1023 .mfocrf,
1024 .stfiwx,
1025 }),
1026 };
1027 pub const pwr5x = CpuModel{
1028 .name = "pwr5x",
1029 .llvm_name = "pwr5x",
1030 .features = featureSet(&[_]Feature{
1031 .@"64bit",
1032 .altivec,
1033 .fprnd,
1034 .fre,
1035 .fres,
1036 .frsqrte,
1037 .frsqrtes,
1038 .fsqrt,
1039 .mfocrf,
1040 .stfiwx,
1041 }),
1042 };
1043 pub const pwr6 = CpuModel{
1044 .name = "pwr6",
1045 .llvm_name = "pwr6",
1046 .features = featureSet(&[_]Feature{
1047 .@"64bit",
1048 .altivec,
1049 .cmpb,
1050 .fcpsgn,
1051 .fprnd,
1052 .fre,
1053 .fres,
1054 .frsqrte,
1055 .frsqrtes,
1056 .fsqrt,
1057 .lfiwax,
1058 .mfocrf,
1059 .recipprec,
1060 .stfiwx,
1061 }),
1062 };
1063 pub const pwr6x = CpuModel{
1064 .name = "pwr6x",
1065 .llvm_name = "pwr6x",
1066 .features = featureSet(&[_]Feature{
1067 .@"64bit",
1068 .altivec,
1069 .cmpb,
1070 .fcpsgn,
1071 .fprnd,
1072 .fre,
1073 .fres,
1074 .frsqrte,
1075 .frsqrtes,
1076 .fsqrt,
1077 .lfiwax,
1078 .mfocrf,
1079 .recipprec,
1080 .stfiwx,
1081 }),
1082 };
1083 pub const pwr7 = CpuModel{
1084 .name = "pwr7",
1085 .llvm_name = "pwr7",
1086 .features = featureSet(&[_]Feature{
1087 .@"64bit",
1088 .allow_unaligned_fp_access,
1089 .bpermd,
1090 .cmpb,
1091 .extdiv,
1092 .fcpsgn,
1093 .fpcvt,
1094 .fprnd,
1095 .fre,
1096 .fres,
1097 .frsqrte,
1098 .frsqrtes,
1099 .fsqrt,
1100 .isa_v206_instructions,
1101 .isel,
1102 .ldbrx,
1103 .lfiwax,
1104 .mfocrf,
1105 .popcntd,
1106 .recipprec,
1107 .stfiwx,
1108 .two_const_nr,
1109 .vsx,
1110 }),
1111 };
1112 pub const pwr8 = CpuModel{
1113 .name = "pwr8",
1114 .llvm_name = "pwr8",
1115 .features = featureSet(&[_]Feature{
1116 .@"64bit",
1117 .allow_unaligned_fp_access,
1118 .bpermd,
1119 .cmpb,
1120 .crbits,
1121 .crypto,
1122 .direct_move,
1123 .extdiv,
1124 .fcpsgn,
1125 .fpcvt,
1126 .fprnd,
1127 .fre,
1128 .fres,
1129 .frsqrte,
1130 .frsqrtes,
1131 .fsqrt,
1132 .fuse_addi_load,
1133 .fuse_addis_load,
1134 .htm,
1135 .icbt,
1136 .isa_v206_instructions,
1137 .isa_v207_instructions,
1138 .isel,
1139 .ldbrx,
1140 .lfiwax,
1141 .mfocrf,
1142 .partword_atomics,
1143 .popcntd,
1144 .power8_vector,
1145 .predictable_select_expensive,
1146 .quadword_atomics,
1147 .recipprec,
1148 .stfiwx,
1149 .two_const_nr,
1150 }),
1151 };
1152 pub const pwr9 = CpuModel{
1153 .name = "pwr9",
1154 .llvm_name = "pwr9",
1155 .features = featureSet(&[_]Feature{
1156 .@"64bit",
1157 .allow_unaligned_fp_access,
1158 .bpermd,
1159 .cmpb,
1160 .crbits,
1161 .crypto,
1162 .direct_move,
1163 .extdiv,
1164 .fcpsgn,
1165 .fpcvt,
1166 .fprnd,
1167 .fre,
1168 .fres,
1169 .frsqrte,
1170 .frsqrtes,
1171 .fsqrt,
1172 .htm,
1173 .icbt,
1174 .isa_v206_instructions,
1175 .isel,
1176 .ldbrx,
1177 .lfiwax,
1178 .mfocrf,
1179 .partword_atomics,
1180 .popcntd,
1181 .power9_vector,
1182 .ppc_postra_sched,
1183 .ppc_prera_sched,
1184 .predictable_select_expensive,
1185 .quadword_atomics,
1186 .recipprec,
1187 .stfiwx,
1188 .two_const_nr,
1189 .vectors_use_two_units,
1190 }),
1191 };
1192};
lib/std/target/riscv.zig deleted-1341
......@@ -1,1341 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"32bit",
9 @"64bit",
10 a,
11 c,
12 d,
13 dlen_factor_2,
14 e,
15 experimental_smaia,
16 experimental_ssaia,
17 experimental_zacas,
18 experimental_zfa,
19 experimental_zfbfmin,
20 experimental_zicond,
21 experimental_zihintntl,
22 experimental_ztso,
23 experimental_zvbb,
24 experimental_zvbc,
25 experimental_zvfbfmin,
26 experimental_zvfbfwma,
27 experimental_zvkg,
28 experimental_zvkn,
29 experimental_zvknc,
30 experimental_zvkned,
31 experimental_zvkng,
32 experimental_zvknha,
33 experimental_zvknhb,
34 experimental_zvks,
35 experimental_zvksc,
36 experimental_zvksed,
37 experimental_zvksg,
38 experimental_zvksh,
39 experimental_zvkt,
40 f,
41 forced_atomics,
42 h,
43 lui_addi_fusion,
44 m,
45 no_default_unroll,
46 no_optimized_zero_stride_load,
47 no_rvc_hints,
48 relax,
49 reserve_x1,
50 reserve_x10,
51 reserve_x11,
52 reserve_x12,
53 reserve_x13,
54 reserve_x14,
55 reserve_x15,
56 reserve_x16,
57 reserve_x17,
58 reserve_x18,
59 reserve_x19,
60 reserve_x2,
61 reserve_x20,
62 reserve_x21,
63 reserve_x22,
64 reserve_x23,
65 reserve_x24,
66 reserve_x25,
67 reserve_x26,
68 reserve_x27,
69 reserve_x28,
70 reserve_x29,
71 reserve_x3,
72 reserve_x30,
73 reserve_x31,
74 reserve_x4,
75 reserve_x5,
76 reserve_x6,
77 reserve_x7,
78 reserve_x8,
79 reserve_x9,
80 save_restore,
81 seq_cst_trailing_fence,
82 short_forward_branch_opt,
83 svinval,
84 svnapot,
85 svpbmt,
86 tagged_globals,
87 unaligned_scalar_mem,
88 unaligned_vector_mem,
89 v,
90 xcvbitmanip,
91 xcvmac,
92 xsfcie,
93 xsfvcp,
94 xtheadba,
95 xtheadbb,
96 xtheadbs,
97 xtheadcmo,
98 xtheadcondmov,
99 xtheadfmemidx,
100 xtheadmac,
101 xtheadmemidx,
102 xtheadmempair,
103 xtheadsync,
104 xtheadvdot,
105 xventanacondops,
106 zawrs,
107 zba,
108 zbb,
109 zbc,
110 zbkb,
111 zbkc,
112 zbkx,
113 zbs,
114 zca,
115 zcb,
116 zcd,
117 zce,
118 zcf,
119 zcmp,
120 zcmt,
121 zdinx,
122 zfh,
123 zfhmin,
124 zfinx,
125 zhinx,
126 zhinxmin,
127 zicbom,
128 zicbop,
129 zicboz,
130 zicntr,
131 zicsr,
132 zifencei,
133 zihintpause,
134 zihpm,
135 zk,
136 zkn,
137 zknd,
138 zkne,
139 zknh,
140 zkr,
141 zks,
142 zksed,
143 zksh,
144 zkt,
145 zmmul,
146 zve32f,
147 zve32x,
148 zve64d,
149 zve64f,
150 zve64x,
151 zvfh,
152 zvl1024b,
153 zvl128b,
154 zvl16384b,
155 zvl2048b,
156 zvl256b,
157 zvl32768b,
158 zvl32b,
159 zvl4096b,
160 zvl512b,
161 zvl64b,
162 zvl65536b,
163 zvl8192b,
164};
165
166pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
167pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
168pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
169pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
170
171pub const all_features = blk: {
172 const len = @typeInfo(Feature).Enum.fields.len;
173 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
174 var result: [len]CpuFeature = undefined;
175 result[@intFromEnum(Feature.@"32bit")] = .{
176 .llvm_name = "32bit",
177 .description = "Implements RV32",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.@"64bit")] = .{
181 .llvm_name = "64bit",
182 .description = "Implements RV64",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.a)] = .{
186 .llvm_name = "a",
187 .description = "'A' (Atomic Instructions)",
188 .dependencies = featureSet(&[_]Feature{}),
189 };
190 result[@intFromEnum(Feature.c)] = .{
191 .llvm_name = "c",
192 .description = "'C' (Compressed Instructions)",
193 .dependencies = featureSet(&[_]Feature{}),
194 };
195 result[@intFromEnum(Feature.d)] = .{
196 .llvm_name = "d",
197 .description = "'D' (Double-Precision Floating-Point)",
198 .dependencies = featureSet(&[_]Feature{
199 .f,
200 }),
201 };
202 result[@intFromEnum(Feature.dlen_factor_2)] = .{
203 .llvm_name = "dlen-factor-2",
204 .description = "Vector unit DLEN(data path width) is half of VLEN",
205 .dependencies = featureSet(&[_]Feature{}),
206 };
207 result[@intFromEnum(Feature.e)] = .{
208 .llvm_name = "e",
209 .description = "Implements RV{32,64}E (provides 16 rather than 32 GPRs)",
210 .dependencies = featureSet(&[_]Feature{}),
211 };
212 result[@intFromEnum(Feature.experimental_smaia)] = .{
213 .llvm_name = "experimental-smaia",
214 .description = "'Smaia' (Smaia encompasses all added CSRs and all modifications to interrupt response behavior that the AIA specifies for a hart, over all privilege levels.)",
215 .dependencies = featureSet(&[_]Feature{}),
216 };
217 result[@intFromEnum(Feature.experimental_ssaia)] = .{
218 .llvm_name = "experimental-ssaia",
219 .description = "'Ssaia' (Ssaia is essentially the same as Smaia except excluding the machine-level CSRs and behavior not directly visible to supervisor level.)",
220 .dependencies = featureSet(&[_]Feature{}),
221 };
222 result[@intFromEnum(Feature.experimental_zacas)] = .{
223 .llvm_name = "experimental-zacas",
224 .description = "'Zacas' (Atomic Compare-And-Swap Instructions)",
225 .dependencies = featureSet(&[_]Feature{}),
226 };
227 result[@intFromEnum(Feature.experimental_zfa)] = .{
228 .llvm_name = "experimental-zfa",
229 .description = "'Zfa' (Additional Floating-Point)",
230 .dependencies = featureSet(&[_]Feature{
231 .f,
232 }),
233 };
234 result[@intFromEnum(Feature.experimental_zfbfmin)] = .{
235 .llvm_name = "experimental-zfbfmin",
236 .description = "'Zfbfmin' (Scalar BF16 Converts)",
237 .dependencies = featureSet(&[_]Feature{
238 .f,
239 }),
240 };
241 result[@intFromEnum(Feature.experimental_zicond)] = .{
242 .llvm_name = "experimental-zicond",
243 .description = "'Zicond' (Integer Conditional Operations)",
244 .dependencies = featureSet(&[_]Feature{}),
245 };
246 result[@intFromEnum(Feature.experimental_zihintntl)] = .{
247 .llvm_name = "experimental-zihintntl",
248 .description = "'Zihintntl' (Non-Temporal Locality Hints)",
249 .dependencies = featureSet(&[_]Feature{}),
250 };
251 result[@intFromEnum(Feature.experimental_ztso)] = .{
252 .llvm_name = "experimental-ztso",
253 .description = "'Ztso' (Memory Model - Total Store Order)",
254 .dependencies = featureSet(&[_]Feature{}),
255 };
256 result[@intFromEnum(Feature.experimental_zvbb)] = .{
257 .llvm_name = "experimental-zvbb",
258 .description = "'Zvbb' (Vector Bit-manipulation used in Cryptography)",
259 .dependencies = featureSet(&[_]Feature{}),
260 };
261 result[@intFromEnum(Feature.experimental_zvbc)] = .{
262 .llvm_name = "experimental-zvbc",
263 .description = "'Zvbc' (Vector Carryless Multiplication)",
264 .dependencies = featureSet(&[_]Feature{}),
265 };
266 result[@intFromEnum(Feature.experimental_zvfbfmin)] = .{
267 .llvm_name = "experimental-zvfbfmin",
268 .description = "'Zvbfmin' (Vector BF16 Converts)",
269 .dependencies = featureSet(&[_]Feature{
270 .zve32f,
271 }),
272 };
273 result[@intFromEnum(Feature.experimental_zvfbfwma)] = .{
274 .llvm_name = "experimental-zvfbfwma",
275 .description = "'Zvfbfwma' (Vector BF16 widening mul-add)",
276 .dependencies = featureSet(&[_]Feature{
277 .zve32f,
278 }),
279 };
280 result[@intFromEnum(Feature.experimental_zvkg)] = .{
281 .llvm_name = "experimental-zvkg",
282 .description = "'Zvkg' (Vector GCM instructions for Cryptography)",
283 .dependencies = featureSet(&[_]Feature{}),
284 };
285 result[@intFromEnum(Feature.experimental_zvkn)] = .{
286 .llvm_name = "experimental-zvkn",
287 .description = "This extension is shorthand for the following set of other extensions: Zvkned, Zvknhb, Zvbb, Zvbc, and Zvkt.",
288 .dependencies = featureSet(&[_]Feature{}),
289 };
290 result[@intFromEnum(Feature.experimental_zvknc)] = .{
291 .llvm_name = "experimental-zvknc",
292 .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvbc.",
293 .dependencies = featureSet(&[_]Feature{}),
294 };
295 result[@intFromEnum(Feature.experimental_zvkned)] = .{
296 .llvm_name = "experimental-zvkned",
297 .description = "'Zvkned' (Vector AES Encryption & Decryption (Single Round))",
298 .dependencies = featureSet(&[_]Feature{}),
299 };
300 result[@intFromEnum(Feature.experimental_zvkng)] = .{
301 .llvm_name = "experimental-zvkng",
302 .description = "This extension is shorthand for the following set of other extensions: Zvkn and Zvkg.",
303 .dependencies = featureSet(&[_]Feature{}),
304 };
305 result[@intFromEnum(Feature.experimental_zvknha)] = .{
306 .llvm_name = "experimental-zvknha",
307 .description = "'Zvknha' (Vector SHA-2 (SHA-256 only))",
308 .dependencies = featureSet(&[_]Feature{}),
309 };
310 result[@intFromEnum(Feature.experimental_zvknhb)] = .{
311 .llvm_name = "experimental-zvknhb",
312 .description = "'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512))",
313 .dependencies = featureSet(&[_]Feature{
314 .experimental_zvknha,
315 }),
316 };
317 result[@intFromEnum(Feature.experimental_zvks)] = .{
318 .llvm_name = "experimental-zvks",
319 .description = "This extension is shorthand for the following set of other extensions: Zvksed, Zvksh, Zvbb, Zvbc, and Zvkt.",
320 .dependencies = featureSet(&[_]Feature{}),
321 };
322 result[@intFromEnum(Feature.experimental_zvksc)] = .{
323 .llvm_name = "experimental-zvksc",
324 .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvbc.",
325 .dependencies = featureSet(&[_]Feature{}),
326 };
327 result[@intFromEnum(Feature.experimental_zvksed)] = .{
328 .llvm_name = "experimental-zvksed",
329 .description = "'Zvksed' (SM4 Block Cipher Instructions)",
330 .dependencies = featureSet(&[_]Feature{}),
331 };
332 result[@intFromEnum(Feature.experimental_zvksg)] = .{
333 .llvm_name = "experimental-zvksg",
334 .description = "This extension is shorthand for the following set of other extensions: Zvks and Zvkg.",
335 .dependencies = featureSet(&[_]Feature{}),
336 };
337 result[@intFromEnum(Feature.experimental_zvksh)] = .{
338 .llvm_name = "experimental-zvksh",
339 .description = "'Zvksh' (SM3 Hash Function Instructions)",
340 .dependencies = featureSet(&[_]Feature{}),
341 };
342 result[@intFromEnum(Feature.experimental_zvkt)] = .{
343 .llvm_name = "experimental-zvkt",
344 .description = "'Zvkt' (Vector Data-Independent Execution Latency)",
345 .dependencies = featureSet(&[_]Feature{}),
346 };
347 result[@intFromEnum(Feature.f)] = .{
348 .llvm_name = "f",
349 .description = "'F' (Single-Precision Floating-Point)",
350 .dependencies = featureSet(&[_]Feature{
351 .zicsr,
352 }),
353 };
354 result[@intFromEnum(Feature.forced_atomics)] = .{
355 .llvm_name = "forced-atomics",
356 .description = "Assume that lock-free native-width atomics are available",
357 .dependencies = featureSet(&[_]Feature{}),
358 };
359 result[@intFromEnum(Feature.h)] = .{
360 .llvm_name = "h",
361 .description = "'H' (Hypervisor)",
362 .dependencies = featureSet(&[_]Feature{}),
363 };
364 result[@intFromEnum(Feature.lui_addi_fusion)] = .{
365 .llvm_name = "lui-addi-fusion",
366 .description = "Enable LUI+ADDI macrofusion",
367 .dependencies = featureSet(&[_]Feature{}),
368 };
369 result[@intFromEnum(Feature.m)] = .{
370 .llvm_name = "m",
371 .description = "'M' (Integer Multiplication and Division)",
372 .dependencies = featureSet(&[_]Feature{}),
373 };
374 result[@intFromEnum(Feature.no_default_unroll)] = .{
375 .llvm_name = "no-default-unroll",
376 .description = "Disable default unroll preference.",
377 .dependencies = featureSet(&[_]Feature{}),
378 };
379 result[@intFromEnum(Feature.no_optimized_zero_stride_load)] = .{
380 .llvm_name = "no-optimized-zero-stride-load",
381 .description = "Hasn't optimized (perform fewer memory operations)zero-stride vector load",
382 .dependencies = featureSet(&[_]Feature{}),
383 };
384 result[@intFromEnum(Feature.no_rvc_hints)] = .{
385 .llvm_name = "no-rvc-hints",
386 .description = "Disable RVC Hint Instructions.",
387 .dependencies = featureSet(&[_]Feature{}),
388 };
389 result[@intFromEnum(Feature.relax)] = .{
390 .llvm_name = "relax",
391 .description = "Enable Linker relaxation.",
392 .dependencies = featureSet(&[_]Feature{}),
393 };
394 result[@intFromEnum(Feature.reserve_x1)] = .{
395 .llvm_name = "reserve-x1",
396 .description = "Reserve X1",
397 .dependencies = featureSet(&[_]Feature{}),
398 };
399 result[@intFromEnum(Feature.reserve_x10)] = .{
400 .llvm_name = "reserve-x10",
401 .description = "Reserve X10",
402 .dependencies = featureSet(&[_]Feature{}),
403 };
404 result[@intFromEnum(Feature.reserve_x11)] = .{
405 .llvm_name = "reserve-x11",
406 .description = "Reserve X11",
407 .dependencies = featureSet(&[_]Feature{}),
408 };
409 result[@intFromEnum(Feature.reserve_x12)] = .{
410 .llvm_name = "reserve-x12",
411 .description = "Reserve X12",
412 .dependencies = featureSet(&[_]Feature{}),
413 };
414 result[@intFromEnum(Feature.reserve_x13)] = .{
415 .llvm_name = "reserve-x13",
416 .description = "Reserve X13",
417 .dependencies = featureSet(&[_]Feature{}),
418 };
419 result[@intFromEnum(Feature.reserve_x14)] = .{
420 .llvm_name = "reserve-x14",
421 .description = "Reserve X14",
422 .dependencies = featureSet(&[_]Feature{}),
423 };
424 result[@intFromEnum(Feature.reserve_x15)] = .{
425 .llvm_name = "reserve-x15",
426 .description = "Reserve X15",
427 .dependencies = featureSet(&[_]Feature{}),
428 };
429 result[@intFromEnum(Feature.reserve_x16)] = .{
430 .llvm_name = "reserve-x16",
431 .description = "Reserve X16",
432 .dependencies = featureSet(&[_]Feature{}),
433 };
434 result[@intFromEnum(Feature.reserve_x17)] = .{
435 .llvm_name = "reserve-x17",
436 .description = "Reserve X17",
437 .dependencies = featureSet(&[_]Feature{}),
438 };
439 result[@intFromEnum(Feature.reserve_x18)] = .{
440 .llvm_name = "reserve-x18",
441 .description = "Reserve X18",
442 .dependencies = featureSet(&[_]Feature{}),
443 };
444 result[@intFromEnum(Feature.reserve_x19)] = .{
445 .llvm_name = "reserve-x19",
446 .description = "Reserve X19",
447 .dependencies = featureSet(&[_]Feature{}),
448 };
449 result[@intFromEnum(Feature.reserve_x2)] = .{
450 .llvm_name = "reserve-x2",
451 .description = "Reserve X2",
452 .dependencies = featureSet(&[_]Feature{}),
453 };
454 result[@intFromEnum(Feature.reserve_x20)] = .{
455 .llvm_name = "reserve-x20",
456 .description = "Reserve X20",
457 .dependencies = featureSet(&[_]Feature{}),
458 };
459 result[@intFromEnum(Feature.reserve_x21)] = .{
460 .llvm_name = "reserve-x21",
461 .description = "Reserve X21",
462 .dependencies = featureSet(&[_]Feature{}),
463 };
464 result[@intFromEnum(Feature.reserve_x22)] = .{
465 .llvm_name = "reserve-x22",
466 .description = "Reserve X22",
467 .dependencies = featureSet(&[_]Feature{}),
468 };
469 result[@intFromEnum(Feature.reserve_x23)] = .{
470 .llvm_name = "reserve-x23",
471 .description = "Reserve X23",
472 .dependencies = featureSet(&[_]Feature{}),
473 };
474 result[@intFromEnum(Feature.reserve_x24)] = .{
475 .llvm_name = "reserve-x24",
476 .description = "Reserve X24",
477 .dependencies = featureSet(&[_]Feature{}),
478 };
479 result[@intFromEnum(Feature.reserve_x25)] = .{
480 .llvm_name = "reserve-x25",
481 .description = "Reserve X25",
482 .dependencies = featureSet(&[_]Feature{}),
483 };
484 result[@intFromEnum(Feature.reserve_x26)] = .{
485 .llvm_name = "reserve-x26",
486 .description = "Reserve X26",
487 .dependencies = featureSet(&[_]Feature{}),
488 };
489 result[@intFromEnum(Feature.reserve_x27)] = .{
490 .llvm_name = "reserve-x27",
491 .description = "Reserve X27",
492 .dependencies = featureSet(&[_]Feature{}),
493 };
494 result[@intFromEnum(Feature.reserve_x28)] = .{
495 .llvm_name = "reserve-x28",
496 .description = "Reserve X28",
497 .dependencies = featureSet(&[_]Feature{}),
498 };
499 result[@intFromEnum(Feature.reserve_x29)] = .{
500 .llvm_name = "reserve-x29",
501 .description = "Reserve X29",
502 .dependencies = featureSet(&[_]Feature{}),
503 };
504 result[@intFromEnum(Feature.reserve_x3)] = .{
505 .llvm_name = "reserve-x3",
506 .description = "Reserve X3",
507 .dependencies = featureSet(&[_]Feature{}),
508 };
509 result[@intFromEnum(Feature.reserve_x30)] = .{
510 .llvm_name = "reserve-x30",
511 .description = "Reserve X30",
512 .dependencies = featureSet(&[_]Feature{}),
513 };
514 result[@intFromEnum(Feature.reserve_x31)] = .{
515 .llvm_name = "reserve-x31",
516 .description = "Reserve X31",
517 .dependencies = featureSet(&[_]Feature{}),
518 };
519 result[@intFromEnum(Feature.reserve_x4)] = .{
520 .llvm_name = "reserve-x4",
521 .description = "Reserve X4",
522 .dependencies = featureSet(&[_]Feature{}),
523 };
524 result[@intFromEnum(Feature.reserve_x5)] = .{
525 .llvm_name = "reserve-x5",
526 .description = "Reserve X5",
527 .dependencies = featureSet(&[_]Feature{}),
528 };
529 result[@intFromEnum(Feature.reserve_x6)] = .{
530 .llvm_name = "reserve-x6",
531 .description = "Reserve X6",
532 .dependencies = featureSet(&[_]Feature{}),
533 };
534 result[@intFromEnum(Feature.reserve_x7)] = .{
535 .llvm_name = "reserve-x7",
536 .description = "Reserve X7",
537 .dependencies = featureSet(&[_]Feature{}),
538 };
539 result[@intFromEnum(Feature.reserve_x8)] = .{
540 .llvm_name = "reserve-x8",
541 .description = "Reserve X8",
542 .dependencies = featureSet(&[_]Feature{}),
543 };
544 result[@intFromEnum(Feature.reserve_x9)] = .{
545 .llvm_name = "reserve-x9",
546 .description = "Reserve X9",
547 .dependencies = featureSet(&[_]Feature{}),
548 };
549 result[@intFromEnum(Feature.save_restore)] = .{
550 .llvm_name = "save-restore",
551 .description = "Enable save/restore.",
552 .dependencies = featureSet(&[_]Feature{}),
553 };
554 result[@intFromEnum(Feature.seq_cst_trailing_fence)] = .{
555 .llvm_name = "seq-cst-trailing-fence",
556 .description = "Enable trailing fence for seq-cst store.",
557 .dependencies = featureSet(&[_]Feature{}),
558 };
559 result[@intFromEnum(Feature.short_forward_branch_opt)] = .{
560 .llvm_name = "short-forward-branch-opt",
561 .description = "Enable short forward branch optimization",
562 .dependencies = featureSet(&[_]Feature{}),
563 };
564 result[@intFromEnum(Feature.svinval)] = .{
565 .llvm_name = "svinval",
566 .description = "'Svinval' (Fine-Grained Address-Translation Cache Invalidation)",
567 .dependencies = featureSet(&[_]Feature{}),
568 };
569 result[@intFromEnum(Feature.svnapot)] = .{
570 .llvm_name = "svnapot",
571 .description = "'Svnapot' (NAPOT Translation Contiguity)",
572 .dependencies = featureSet(&[_]Feature{}),
573 };
574 result[@intFromEnum(Feature.svpbmt)] = .{
575 .llvm_name = "svpbmt",
576 .description = "'Svpbmt' (Page-Based Memory Types)",
577 .dependencies = featureSet(&[_]Feature{}),
578 };
579 result[@intFromEnum(Feature.tagged_globals)] = .{
580 .llvm_name = "tagged-globals",
581 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",
582 .dependencies = featureSet(&[_]Feature{}),
583 };
584 result[@intFromEnum(Feature.unaligned_scalar_mem)] = .{
585 .llvm_name = "unaligned-scalar-mem",
586 .description = "Has reasonably performant unaligned scalar loads and stores",
587 .dependencies = featureSet(&[_]Feature{}),
588 };
589 result[@intFromEnum(Feature.unaligned_vector_mem)] = .{
590 .llvm_name = "unaligned-vector-mem",
591 .description = "Has reasonably performant unaligned vector loads and stores",
592 .dependencies = featureSet(&[_]Feature{}),
593 };
594 result[@intFromEnum(Feature.v)] = .{
595 .llvm_name = "v",
596 .description = "'V' (Vector Extension for Application Processors)",
597 .dependencies = featureSet(&[_]Feature{
598 .zve64d,
599 .zvl128b,
600 }),
601 };
602 result[@intFromEnum(Feature.xcvbitmanip)] = .{
603 .llvm_name = "xcvbitmanip",
604 .description = "'XCVbitmanip' (CORE-V Bit Manipulation)",
605 .dependencies = featureSet(&[_]Feature{}),
606 };
607 result[@intFromEnum(Feature.xcvmac)] = .{
608 .llvm_name = "xcvmac",
609 .description = "'XCVmac' (CORE-V Multiply-Accumulate)",
610 .dependencies = featureSet(&[_]Feature{}),
611 };
612 result[@intFromEnum(Feature.xsfcie)] = .{
613 .llvm_name = "xsfcie",
614 .description = "'XSfcie' (SiFive Custom Instruction Extension SCIE.)",
615 .dependencies = featureSet(&[_]Feature{}),
616 };
617 result[@intFromEnum(Feature.xsfvcp)] = .{
618 .llvm_name = "xsfvcp",
619 .description = "'XSfvcp' (SiFive Custom Vector Coprocessor Interface Instructions)",
620 .dependencies = featureSet(&[_]Feature{
621 .zve32x,
622 }),
623 };
624 result[@intFromEnum(Feature.xtheadba)] = .{
625 .llvm_name = "xtheadba",
626 .description = "'xtheadba' (T-Head address calculation instructions)",
627 .dependencies = featureSet(&[_]Feature{}),
628 };
629 result[@intFromEnum(Feature.xtheadbb)] = .{
630 .llvm_name = "xtheadbb",
631 .description = "'xtheadbb' (T-Head basic bit-manipulation instructions)",
632 .dependencies = featureSet(&[_]Feature{}),
633 };
634 result[@intFromEnum(Feature.xtheadbs)] = .{
635 .llvm_name = "xtheadbs",
636 .description = "'xtheadbs' (T-Head single-bit instructions)",
637 .dependencies = featureSet(&[_]Feature{}),
638 };
639 result[@intFromEnum(Feature.xtheadcmo)] = .{
640 .llvm_name = "xtheadcmo",
641 .description = "'xtheadcmo' (T-Head cache management instructions)",
642 .dependencies = featureSet(&[_]Feature{}),
643 };
644 result[@intFromEnum(Feature.xtheadcondmov)] = .{
645 .llvm_name = "xtheadcondmov",
646 .description = "'xtheadcondmov' (T-Head conditional move instructions)",
647 .dependencies = featureSet(&[_]Feature{}),
648 };
649 result[@intFromEnum(Feature.xtheadfmemidx)] = .{
650 .llvm_name = "xtheadfmemidx",
651 .description = "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)",
652 .dependencies = featureSet(&[_]Feature{
653 .f,
654 }),
655 };
656 result[@intFromEnum(Feature.xtheadmac)] = .{
657 .llvm_name = "xtheadmac",
658 .description = "'xtheadmac' (T-Head Multiply-Accumulate Instructions)",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.xtheadmemidx)] = .{
662 .llvm_name = "xtheadmemidx",
663 .description = "'xtheadmemidx' (T-Head Indexed Memory Operations)",
664 .dependencies = featureSet(&[_]Feature{}),
665 };
666 result[@intFromEnum(Feature.xtheadmempair)] = .{
667 .llvm_name = "xtheadmempair",
668 .description = "'xtheadmempair' (T-Head two-GPR Memory Operations)",
669 .dependencies = featureSet(&[_]Feature{}),
670 };
671 result[@intFromEnum(Feature.xtheadsync)] = .{
672 .llvm_name = "xtheadsync",
673 .description = "'xtheadsync' (T-Head multicore synchronization instructions)",
674 .dependencies = featureSet(&[_]Feature{}),
675 };
676 result[@intFromEnum(Feature.xtheadvdot)] = .{
677 .llvm_name = "xtheadvdot",
678 .description = "'xtheadvdot' (T-Head Vector Extensions for Dot)",
679 .dependencies = featureSet(&[_]Feature{
680 .v,
681 }),
682 };
683 result[@intFromEnum(Feature.xventanacondops)] = .{
684 .llvm_name = "xventanacondops",
685 .description = "'XVentanaCondOps' (Ventana Conditional Ops)",
686 .dependencies = featureSet(&[_]Feature{}),
687 };
688 result[@intFromEnum(Feature.zawrs)] = .{
689 .llvm_name = "zawrs",
690 .description = "'Zawrs' (Wait on Reservation Set)",
691 .dependencies = featureSet(&[_]Feature{}),
692 };
693 result[@intFromEnum(Feature.zba)] = .{
694 .llvm_name = "zba",
695 .description = "'Zba' (Address Generation Instructions)",
696 .dependencies = featureSet(&[_]Feature{}),
697 };
698 result[@intFromEnum(Feature.zbb)] = .{
699 .llvm_name = "zbb",
700 .description = "'Zbb' (Basic Bit-Manipulation)",
701 .dependencies = featureSet(&[_]Feature{}),
702 };
703 result[@intFromEnum(Feature.zbc)] = .{
704 .llvm_name = "zbc",
705 .description = "'Zbc' (Carry-Less Multiplication)",
706 .dependencies = featureSet(&[_]Feature{}),
707 };
708 result[@intFromEnum(Feature.zbkb)] = .{
709 .llvm_name = "zbkb",
710 .description = "'Zbkb' (Bitmanip instructions for Cryptography)",
711 .dependencies = featureSet(&[_]Feature{}),
712 };
713 result[@intFromEnum(Feature.zbkc)] = .{
714 .llvm_name = "zbkc",
715 .description = "'Zbkc' (Carry-less multiply instructions for Cryptography)",
716 .dependencies = featureSet(&[_]Feature{}),
717 };
718 result[@intFromEnum(Feature.zbkx)] = .{
719 .llvm_name = "zbkx",
720 .description = "'Zbkx' (Crossbar permutation instructions)",
721 .dependencies = featureSet(&[_]Feature{}),
722 };
723 result[@intFromEnum(Feature.zbs)] = .{
724 .llvm_name = "zbs",
725 .description = "'Zbs' (Single-Bit Instructions)",
726 .dependencies = featureSet(&[_]Feature{}),
727 };
728 result[@intFromEnum(Feature.zca)] = .{
729 .llvm_name = "zca",
730 .description = "'Zca' (part of the C extension, excluding compressed floating point loads/stores)",
731 .dependencies = featureSet(&[_]Feature{}),
732 };
733 result[@intFromEnum(Feature.zcb)] = .{
734 .llvm_name = "zcb",
735 .description = "'Zcb' (Compressed basic bit manipulation instructions)",
736 .dependencies = featureSet(&[_]Feature{
737 .zca,
738 }),
739 };
740 result[@intFromEnum(Feature.zcd)] = .{
741 .llvm_name = "zcd",
742 .description = "'Zcd' (Compressed Double-Precision Floating-Point Instructions)",
743 .dependencies = featureSet(&[_]Feature{
744 .zca,
745 }),
746 };
747 result[@intFromEnum(Feature.zce)] = .{
748 .llvm_name = "zce",
749 .description = "'Zce' (Compressed extensions for microcontrollers)",
750 .dependencies = featureSet(&[_]Feature{
751 .zcb,
752 .zcmp,
753 .zcmt,
754 }),
755 };
756 result[@intFromEnum(Feature.zcf)] = .{
757 .llvm_name = "zcf",
758 .description = "'Zcf' (Compressed Single-Precision Floating-Point Instructions)",
759 .dependencies = featureSet(&[_]Feature{
760 .zca,
761 }),
762 };
763 result[@intFromEnum(Feature.zcmp)] = .{
764 .llvm_name = "zcmp",
765 .description = "'Zcmp' (sequenced instuctions for code-size reduction)",
766 .dependencies = featureSet(&[_]Feature{
767 .zca,
768 }),
769 };
770 result[@intFromEnum(Feature.zcmt)] = .{
771 .llvm_name = "zcmt",
772 .description = "'Zcmt' (table jump instuctions for code-size reduction)",
773 .dependencies = featureSet(&[_]Feature{
774 .zca,
775 .zicsr,
776 }),
777 };
778 result[@intFromEnum(Feature.zdinx)] = .{
779 .llvm_name = "zdinx",
780 .description = "'Zdinx' (Double in Integer)",
781 .dependencies = featureSet(&[_]Feature{
782 .zfinx,
783 }),
784 };
785 result[@intFromEnum(Feature.zfh)] = .{
786 .llvm_name = "zfh",
787 .description = "'Zfh' (Half-Precision Floating-Point)",
788 .dependencies = featureSet(&[_]Feature{
789 .f,
790 }),
791 };
792 result[@intFromEnum(Feature.zfhmin)] = .{
793 .llvm_name = "zfhmin",
794 .description = "'Zfhmin' (Half-Precision Floating-Point Minimal)",
795 .dependencies = featureSet(&[_]Feature{
796 .f,
797 }),
798 };
799 result[@intFromEnum(Feature.zfinx)] = .{
800 .llvm_name = "zfinx",
801 .description = "'Zfinx' (Float in Integer)",
802 .dependencies = featureSet(&[_]Feature{
803 .zicsr,
804 }),
805 };
806 result[@intFromEnum(Feature.zhinx)] = .{
807 .llvm_name = "zhinx",
808 .description = "'Zhinx' (Half Float in Integer)",
809 .dependencies = featureSet(&[_]Feature{
810 .zfinx,
811 }),
812 };
813 result[@intFromEnum(Feature.zhinxmin)] = .{
814 .llvm_name = "zhinxmin",
815 .description = "'Zhinxmin' (Half Float in Integer Minimal)",
816 .dependencies = featureSet(&[_]Feature{
817 .zfinx,
818 }),
819 };
820 result[@intFromEnum(Feature.zicbom)] = .{
821 .llvm_name = "zicbom",
822 .description = "'Zicbom' (Cache-Block Management Instructions)",
823 .dependencies = featureSet(&[_]Feature{}),
824 };
825 result[@intFromEnum(Feature.zicbop)] = .{
826 .llvm_name = "zicbop",
827 .description = "'Zicbop' (Cache-Block Prefetch Instructions)",
828 .dependencies = featureSet(&[_]Feature{}),
829 };
830 result[@intFromEnum(Feature.zicboz)] = .{
831 .llvm_name = "zicboz",
832 .description = "'Zicboz' (Cache-Block Zero Instructions)",
833 .dependencies = featureSet(&[_]Feature{}),
834 };
835 result[@intFromEnum(Feature.zicntr)] = .{
836 .llvm_name = "zicntr",
837 .description = "'Zicntr' (Base Counters and Timers)",
838 .dependencies = featureSet(&[_]Feature{
839 .zicsr,
840 }),
841 };
842 result[@intFromEnum(Feature.zicsr)] = .{
843 .llvm_name = "zicsr",
844 .description = "'zicsr' (CSRs)",
845 .dependencies = featureSet(&[_]Feature{}),
846 };
847 result[@intFromEnum(Feature.zifencei)] = .{
848 .llvm_name = "zifencei",
849 .description = "'Zifencei' (fence.i)",
850 .dependencies = featureSet(&[_]Feature{}),
851 };
852 result[@intFromEnum(Feature.zihintpause)] = .{
853 .llvm_name = "zihintpause",
854 .description = "'Zihintpause' (Pause Hint)",
855 .dependencies = featureSet(&[_]Feature{}),
856 };
857 result[@intFromEnum(Feature.zihpm)] = .{
858 .llvm_name = "zihpm",
859 .description = "'Zihpm' (Hardware Performance Counters)",
860 .dependencies = featureSet(&[_]Feature{
861 .zicsr,
862 }),
863 };
864 result[@intFromEnum(Feature.zk)] = .{
865 .llvm_name = "zk",
866 .description = "'Zk' (Standard scalar cryptography extension)",
867 .dependencies = featureSet(&[_]Feature{
868 .zkn,
869 .zkr,
870 .zkt,
871 }),
872 };
873 result[@intFromEnum(Feature.zkn)] = .{
874 .llvm_name = "zkn",
875 .description = "'Zkn' (NIST Algorithm Suite)",
876 .dependencies = featureSet(&[_]Feature{
877 .zbkb,
878 .zbkc,
879 .zbkx,
880 .zknd,
881 .zkne,
882 .zknh,
883 }),
884 };
885 result[@intFromEnum(Feature.zknd)] = .{
886 .llvm_name = "zknd",
887 .description = "'Zknd' (NIST Suite: AES Decryption)",
888 .dependencies = featureSet(&[_]Feature{}),
889 };
890 result[@intFromEnum(Feature.zkne)] = .{
891 .llvm_name = "zkne",
892 .description = "'Zkne' (NIST Suite: AES Encryption)",
893 .dependencies = featureSet(&[_]Feature{}),
894 };
895 result[@intFromEnum(Feature.zknh)] = .{
896 .llvm_name = "zknh",
897 .description = "'Zknh' (NIST Suite: Hash Function Instructions)",
898 .dependencies = featureSet(&[_]Feature{}),
899 };
900 result[@intFromEnum(Feature.zkr)] = .{
901 .llvm_name = "zkr",
902 .description = "'Zkr' (Entropy Source Extension)",
903 .dependencies = featureSet(&[_]Feature{}),
904 };
905 result[@intFromEnum(Feature.zks)] = .{
906 .llvm_name = "zks",
907 .description = "'Zks' (ShangMi Algorithm Suite)",
908 .dependencies = featureSet(&[_]Feature{
909 .zbkb,
910 .zbkc,
911 .zbkx,
912 .zksed,
913 .zksh,
914 }),
915 };
916 result[@intFromEnum(Feature.zksed)] = .{
917 .llvm_name = "zksed",
918 .description = "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)",
919 .dependencies = featureSet(&[_]Feature{}),
920 };
921 result[@intFromEnum(Feature.zksh)] = .{
922 .llvm_name = "zksh",
923 .description = "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)",
924 .dependencies = featureSet(&[_]Feature{}),
925 };
926 result[@intFromEnum(Feature.zkt)] = .{
927 .llvm_name = "zkt",
928 .description = "'Zkt' (Data Independent Execution Latency)",
929 .dependencies = featureSet(&[_]Feature{}),
930 };
931 result[@intFromEnum(Feature.zmmul)] = .{
932 .llvm_name = "zmmul",
933 .description = "'Zmmul' (Integer Multiplication)",
934 .dependencies = featureSet(&[_]Feature{}),
935 };
936 result[@intFromEnum(Feature.zve32f)] = .{
937 .llvm_name = "zve32f",
938 .description = "'Zve32f' (Vector Extensions for Embedded Processors with maximal 32 EEW and F extension)",
939 .dependencies = featureSet(&[_]Feature{
940 .f,
941 .zve32x,
942 }),
943 };
944 result[@intFromEnum(Feature.zve32x)] = .{
945 .llvm_name = "zve32x",
946 .description = "'Zve32x' (Vector Extensions for Embedded Processors with maximal 32 EEW)",
947 .dependencies = featureSet(&[_]Feature{
948 .zicsr,
949 .zvl32b,
950 }),
951 };
952 result[@intFromEnum(Feature.zve64d)] = .{
953 .llvm_name = "zve64d",
954 .description = "'Zve64d' (Vector Extensions for Embedded Processors with maximal 64 EEW, F and D extension)",
955 .dependencies = featureSet(&[_]Feature{
956 .d,
957 .zve64f,
958 }),
959 };
960 result[@intFromEnum(Feature.zve64f)] = .{
961 .llvm_name = "zve64f",
962 .description = "'Zve64f' (Vector Extensions for Embedded Processors with maximal 64 EEW and F extension)",
963 .dependencies = featureSet(&[_]Feature{
964 .zve32f,
965 .zve64x,
966 }),
967 };
968 result[@intFromEnum(Feature.zve64x)] = .{
969 .llvm_name = "zve64x",
970 .description = "'Zve64x' (Vector Extensions for Embedded Processors with maximal 64 EEW)",
971 .dependencies = featureSet(&[_]Feature{
972 .zve32x,
973 .zvl64b,
974 }),
975 };
976 result[@intFromEnum(Feature.zvfh)] = .{
977 .llvm_name = "zvfh",
978 .description = "'Zvfh' (Vector Half-Precision Floating-Point)",
979 .dependencies = featureSet(&[_]Feature{
980 .zfhmin,
981 .zve32f,
982 }),
983 };
984 result[@intFromEnum(Feature.zvl1024b)] = .{
985 .llvm_name = "zvl1024b",
986 .description = "'Zvl' (Minimum Vector Length) 1024",
987 .dependencies = featureSet(&[_]Feature{
988 .zvl512b,
989 }),
990 };
991 result[@intFromEnum(Feature.zvl128b)] = .{
992 .llvm_name = "zvl128b",
993 .description = "'Zvl' (Minimum Vector Length) 128",
994 .dependencies = featureSet(&[_]Feature{
995 .zvl64b,
996 }),
997 };
998 result[@intFromEnum(Feature.zvl16384b)] = .{
999 .llvm_name = "zvl16384b",
1000 .description = "'Zvl' (Minimum Vector Length) 16384",
1001 .dependencies = featureSet(&[_]Feature{
1002 .zvl8192b,
1003 }),
1004 };
1005 result[@intFromEnum(Feature.zvl2048b)] = .{
1006 .llvm_name = "zvl2048b",
1007 .description = "'Zvl' (Minimum Vector Length) 2048",
1008 .dependencies = featureSet(&[_]Feature{
1009 .zvl1024b,
1010 }),
1011 };
1012 result[@intFromEnum(Feature.zvl256b)] = .{
1013 .llvm_name = "zvl256b",
1014 .description = "'Zvl' (Minimum Vector Length) 256",
1015 .dependencies = featureSet(&[_]Feature{
1016 .zvl128b,
1017 }),
1018 };
1019 result[@intFromEnum(Feature.zvl32768b)] = .{
1020 .llvm_name = "zvl32768b",
1021 .description = "'Zvl' (Minimum Vector Length) 32768",
1022 .dependencies = featureSet(&[_]Feature{
1023 .zvl16384b,
1024 }),
1025 };
1026 result[@intFromEnum(Feature.zvl32b)] = .{
1027 .llvm_name = "zvl32b",
1028 .description = "'Zvl' (Minimum Vector Length) 32",
1029 .dependencies = featureSet(&[_]Feature{}),
1030 };
1031 result[@intFromEnum(Feature.zvl4096b)] = .{
1032 .llvm_name = "zvl4096b",
1033 .description = "'Zvl' (Minimum Vector Length) 4096",
1034 .dependencies = featureSet(&[_]Feature{
1035 .zvl2048b,
1036 }),
1037 };
1038 result[@intFromEnum(Feature.zvl512b)] = .{
1039 .llvm_name = "zvl512b",
1040 .description = "'Zvl' (Minimum Vector Length) 512",
1041 .dependencies = featureSet(&[_]Feature{
1042 .zvl256b,
1043 }),
1044 };
1045 result[@intFromEnum(Feature.zvl64b)] = .{
1046 .llvm_name = "zvl64b",
1047 .description = "'Zvl' (Minimum Vector Length) 64",
1048 .dependencies = featureSet(&[_]Feature{
1049 .zvl32b,
1050 }),
1051 };
1052 result[@intFromEnum(Feature.zvl65536b)] = .{
1053 .llvm_name = "zvl65536b",
1054 .description = "'Zvl' (Minimum Vector Length) 65536",
1055 .dependencies = featureSet(&[_]Feature{
1056 .zvl32768b,
1057 }),
1058 };
1059 result[@intFromEnum(Feature.zvl8192b)] = .{
1060 .llvm_name = "zvl8192b",
1061 .description = "'Zvl' (Minimum Vector Length) 8192",
1062 .dependencies = featureSet(&[_]Feature{
1063 .zvl4096b,
1064 }),
1065 };
1066 const ti = @typeInfo(Feature);
1067 for (&result, 0..) |*elem, i| {
1068 elem.index = i;
1069 elem.name = ti.Enum.fields[i].name;
1070 }
1071 break :blk result;
1072};
1073
1074pub const cpu = struct {
1075 pub const baseline_rv32 = CpuModel{
1076 .name = "baseline_rv32",
1077 .llvm_name = null,
1078 .features = featureSet(&[_]Feature{
1079 .@"32bit",
1080 .a,
1081 .c,
1082 .d,
1083 .m,
1084 }),
1085 };
1086 pub const baseline_rv64 = CpuModel{
1087 .name = "baseline_rv64",
1088 .llvm_name = null,
1089 .features = featureSet(&[_]Feature{
1090 .@"64bit",
1091 .a,
1092 .c,
1093 .d,
1094 .m,
1095 }),
1096 };
1097 pub const generic = CpuModel{
1098 .name = "generic",
1099 .llvm_name = "generic",
1100 .features = featureSet(&[_]Feature{}),
1101 };
1102 pub const generic_rv32 = CpuModel{
1103 .name = "generic_rv32",
1104 .llvm_name = "generic-rv32",
1105 .features = featureSet(&[_]Feature{
1106 .@"32bit",
1107 }),
1108 };
1109 pub const generic_rv64 = CpuModel{
1110 .name = "generic_rv64",
1111 .llvm_name = "generic-rv64",
1112 .features = featureSet(&[_]Feature{
1113 .@"64bit",
1114 }),
1115 };
1116 pub const rocket = CpuModel{
1117 .name = "rocket",
1118 .llvm_name = "rocket",
1119 .features = featureSet(&[_]Feature{}),
1120 };
1121 pub const rocket_rv32 = CpuModel{
1122 .name = "rocket_rv32",
1123 .llvm_name = "rocket-rv32",
1124 .features = featureSet(&[_]Feature{
1125 .@"32bit",
1126 .zicsr,
1127 .zifencei,
1128 }),
1129 };
1130 pub const rocket_rv64 = CpuModel{
1131 .name = "rocket_rv64",
1132 .llvm_name = "rocket-rv64",
1133 .features = featureSet(&[_]Feature{
1134 .@"64bit",
1135 .zicsr,
1136 .zifencei,
1137 }),
1138 };
1139 pub const sifive_7_series = CpuModel{
1140 .name = "sifive_7_series",
1141 .llvm_name = "sifive-7-series",
1142 .features = featureSet(&[_]Feature{
1143 .no_default_unroll,
1144 .short_forward_branch_opt,
1145 }),
1146 };
1147 pub const sifive_e20 = CpuModel{
1148 .name = "sifive_e20",
1149 .llvm_name = "sifive-e20",
1150 .features = featureSet(&[_]Feature{
1151 .@"32bit",
1152 .c,
1153 .m,
1154 .zicsr,
1155 .zifencei,
1156 }),
1157 };
1158 pub const sifive_e21 = CpuModel{
1159 .name = "sifive_e21",
1160 .llvm_name = "sifive-e21",
1161 .features = featureSet(&[_]Feature{
1162 .@"32bit",
1163 .a,
1164 .c,
1165 .m,
1166 .zicsr,
1167 .zifencei,
1168 }),
1169 };
1170 pub const sifive_e24 = CpuModel{
1171 .name = "sifive_e24",
1172 .llvm_name = "sifive-e24",
1173 .features = featureSet(&[_]Feature{
1174 .@"32bit",
1175 .a,
1176 .c,
1177 .f,
1178 .m,
1179 .zifencei,
1180 }),
1181 };
1182 pub const sifive_e31 = CpuModel{
1183 .name = "sifive_e31",
1184 .llvm_name = "sifive-e31",
1185 .features = featureSet(&[_]Feature{
1186 .@"32bit",
1187 .a,
1188 .c,
1189 .m,
1190 .zicsr,
1191 .zifencei,
1192 }),
1193 };
1194 pub const sifive_e34 = CpuModel{
1195 .name = "sifive_e34",
1196 .llvm_name = "sifive-e34",
1197 .features = featureSet(&[_]Feature{
1198 .@"32bit",
1199 .a,
1200 .c,
1201 .f,
1202 .m,
1203 .zifencei,
1204 }),
1205 };
1206 pub const sifive_e76 = CpuModel{
1207 .name = "sifive_e76",
1208 .llvm_name = "sifive-e76",
1209 .features = featureSet(&[_]Feature{
1210 .@"32bit",
1211 .a,
1212 .c,
1213 .f,
1214 .m,
1215 .no_default_unroll,
1216 .short_forward_branch_opt,
1217 .zifencei,
1218 }),
1219 };
1220 pub const sifive_s21 = CpuModel{
1221 .name = "sifive_s21",
1222 .llvm_name = "sifive-s21",
1223 .features = featureSet(&[_]Feature{
1224 .@"64bit",
1225 .a,
1226 .c,
1227 .m,
1228 .zicsr,
1229 .zifencei,
1230 }),
1231 };
1232 pub const sifive_s51 = CpuModel{
1233 .name = "sifive_s51",
1234 .llvm_name = "sifive-s51",
1235 .features = featureSet(&[_]Feature{
1236 .@"64bit",
1237 .a,
1238 .c,
1239 .m,
1240 .zicsr,
1241 .zifencei,
1242 }),
1243 };
1244 pub const sifive_s54 = CpuModel{
1245 .name = "sifive_s54",
1246 .llvm_name = "sifive-s54",
1247 .features = featureSet(&[_]Feature{
1248 .@"64bit",
1249 .a,
1250 .c,
1251 .d,
1252 .m,
1253 .zifencei,
1254 }),
1255 };
1256 pub const sifive_s76 = CpuModel{
1257 .name = "sifive_s76",
1258 .llvm_name = "sifive-s76",
1259 .features = featureSet(&[_]Feature{
1260 .@"64bit",
1261 .a,
1262 .c,
1263 .d,
1264 .m,
1265 .no_default_unroll,
1266 .short_forward_branch_opt,
1267 .xsfcie,
1268 .zifencei,
1269 .zihintpause,
1270 }),
1271 };
1272 pub const sifive_u54 = CpuModel{
1273 .name = "sifive_u54",
1274 .llvm_name = "sifive-u54",
1275 .features = featureSet(&[_]Feature{
1276 .@"64bit",
1277 .a,
1278 .c,
1279 .d,
1280 .m,
1281 .zifencei,
1282 }),
1283 };
1284 pub const sifive_u74 = CpuModel{
1285 .name = "sifive_u74",
1286 .llvm_name = "sifive-u74",
1287 .features = featureSet(&[_]Feature{
1288 .@"64bit",
1289 .a,
1290 .c,
1291 .d,
1292 .m,
1293 .no_default_unroll,
1294 .short_forward_branch_opt,
1295 .zifencei,
1296 }),
1297 };
1298 pub const sifive_x280 = CpuModel{
1299 .name = "sifive_x280",
1300 .llvm_name = "sifive-x280",
1301 .features = featureSet(&[_]Feature{
1302 .@"64bit",
1303 .a,
1304 .c,
1305 .dlen_factor_2,
1306 .m,
1307 .no_default_unroll,
1308 .short_forward_branch_opt,
1309 .v,
1310 .zba,
1311 .zbb,
1312 .zfh,
1313 .zifencei,
1314 .zvfh,
1315 .zvl512b,
1316 }),
1317 };
1318 pub const syntacore_scr1_base = CpuModel{
1319 .name = "syntacore_scr1_base",
1320 .llvm_name = "syntacore-scr1-base",
1321 .features = featureSet(&[_]Feature{
1322 .@"32bit",
1323 .c,
1324 .no_default_unroll,
1325 .zicsr,
1326 .zifencei,
1327 }),
1328 };
1329 pub const syntacore_scr1_max = CpuModel{
1330 .name = "syntacore_scr1_max",
1331 .llvm_name = "syntacore-scr1-max",
1332 .features = featureSet(&[_]Feature{
1333 .@"32bit",
1334 .c,
1335 .m,
1336 .no_default_unroll,
1337 .zicsr,
1338 .zifencei,
1339 }),
1340 };
1341};
lib/std/target/s390x.zig deleted-667
......@@ -1,667 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 bear_enhancement,
9 deflate_conversion,
10 dfp_packed_conversion,
11 dfp_zoned_conversion,
12 distinct_ops,
13 enhanced_dat_2,
14 enhanced_sort,
15 execution_hint,
16 fast_serialization,
17 fp_extension,
18 guarded_storage,
19 high_word,
20 insert_reference_bits_multiple,
21 interlocked_access1,
22 load_and_trap,
23 load_and_zero_rightmost_byte,
24 load_store_on_cond,
25 load_store_on_cond_2,
26 message_security_assist_extension3,
27 message_security_assist_extension4,
28 message_security_assist_extension5,
29 message_security_assist_extension7,
30 message_security_assist_extension8,
31 message_security_assist_extension9,
32 miscellaneous_extensions,
33 miscellaneous_extensions_2,
34 miscellaneous_extensions_3,
35 nnp_assist,
36 population_count,
37 processor_activity_instrumentation,
38 processor_assist,
39 reset_dat_protection,
40 reset_reference_bits_multiple,
41 soft_float,
42 transactional_execution,
43 vector,
44 vector_enhancements_1,
45 vector_enhancements_2,
46 vector_packed_decimal,
47 vector_packed_decimal_enhancement,
48 vector_packed_decimal_enhancement_2,
49};
50
51pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
52pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
53pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
54pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
55
56pub const all_features = blk: {
57 const len = @typeInfo(Feature).Enum.fields.len;
58 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
59 var result: [len]CpuFeature = undefined;
60 result[@intFromEnum(Feature.bear_enhancement)] = .{
61 .llvm_name = "bear-enhancement",
62 .description = "Assume that the BEAR-enhancement facility is installed",
63 .dependencies = featureSet(&[_]Feature{}),
64 };
65 result[@intFromEnum(Feature.deflate_conversion)] = .{
66 .llvm_name = "deflate-conversion",
67 .description = "Assume that the deflate-conversion facility is installed",
68 .dependencies = featureSet(&[_]Feature{}),
69 };
70 result[@intFromEnum(Feature.dfp_packed_conversion)] = .{
71 .llvm_name = "dfp-packed-conversion",
72 .description = "Assume that the DFP packed-conversion facility is installed",
73 .dependencies = featureSet(&[_]Feature{}),
74 };
75 result[@intFromEnum(Feature.dfp_zoned_conversion)] = .{
76 .llvm_name = "dfp-zoned-conversion",
77 .description = "Assume that the DFP zoned-conversion facility is installed",
78 .dependencies = featureSet(&[_]Feature{}),
79 };
80 result[@intFromEnum(Feature.distinct_ops)] = .{
81 .llvm_name = "distinct-ops",
82 .description = "Assume that the distinct-operands facility is installed",
83 .dependencies = featureSet(&[_]Feature{}),
84 };
85 result[@intFromEnum(Feature.enhanced_dat_2)] = .{
86 .llvm_name = "enhanced-dat-2",
87 .description = "Assume that the enhanced-DAT facility 2 is installed",
88 .dependencies = featureSet(&[_]Feature{}),
89 };
90 result[@intFromEnum(Feature.enhanced_sort)] = .{
91 .llvm_name = "enhanced-sort",
92 .description = "Assume that the enhanced-sort facility is installed",
93 .dependencies = featureSet(&[_]Feature{}),
94 };
95 result[@intFromEnum(Feature.execution_hint)] = .{
96 .llvm_name = "execution-hint",
97 .description = "Assume that the execution-hint facility is installed",
98 .dependencies = featureSet(&[_]Feature{}),
99 };
100 result[@intFromEnum(Feature.fast_serialization)] = .{
101 .llvm_name = "fast-serialization",
102 .description = "Assume that the fast-serialization facility is installed",
103 .dependencies = featureSet(&[_]Feature{}),
104 };
105 result[@intFromEnum(Feature.fp_extension)] = .{
106 .llvm_name = "fp-extension",
107 .description = "Assume that the floating-point extension facility is installed",
108 .dependencies = featureSet(&[_]Feature{}),
109 };
110 result[@intFromEnum(Feature.guarded_storage)] = .{
111 .llvm_name = "guarded-storage",
112 .description = "Assume that the guarded-storage facility is installed",
113 .dependencies = featureSet(&[_]Feature{}),
114 };
115 result[@intFromEnum(Feature.high_word)] = .{
116 .llvm_name = "high-word",
117 .description = "Assume that the high-word facility is installed",
118 .dependencies = featureSet(&[_]Feature{}),
119 };
120 result[@intFromEnum(Feature.insert_reference_bits_multiple)] = .{
121 .llvm_name = "insert-reference-bits-multiple",
122 .description = "Assume that the insert-reference-bits-multiple facility is installed",
123 .dependencies = featureSet(&[_]Feature{}),
124 };
125 result[@intFromEnum(Feature.interlocked_access1)] = .{
126 .llvm_name = "interlocked-access1",
127 .description = "Assume that interlocked-access facility 1 is installed",
128 .dependencies = featureSet(&[_]Feature{}),
129 };
130 result[@intFromEnum(Feature.load_and_trap)] = .{
131 .llvm_name = "load-and-trap",
132 .description = "Assume that the load-and-trap facility is installed",
133 .dependencies = featureSet(&[_]Feature{}),
134 };
135 result[@intFromEnum(Feature.load_and_zero_rightmost_byte)] = .{
136 .llvm_name = "load-and-zero-rightmost-byte",
137 .description = "Assume that the load-and-zero-rightmost-byte facility is installed",
138 .dependencies = featureSet(&[_]Feature{}),
139 };
140 result[@intFromEnum(Feature.load_store_on_cond)] = .{
141 .llvm_name = "load-store-on-cond",
142 .description = "Assume that the load/store-on-condition facility is installed",
143 .dependencies = featureSet(&[_]Feature{}),
144 };
145 result[@intFromEnum(Feature.load_store_on_cond_2)] = .{
146 .llvm_name = "load-store-on-cond-2",
147 .description = "Assume that the load/store-on-condition facility 2 is installed",
148 .dependencies = featureSet(&[_]Feature{}),
149 };
150 result[@intFromEnum(Feature.message_security_assist_extension3)] = .{
151 .llvm_name = "message-security-assist-extension3",
152 .description = "Assume that the message-security-assist extension facility 3 is installed",
153 .dependencies = featureSet(&[_]Feature{}),
154 };
155 result[@intFromEnum(Feature.message_security_assist_extension4)] = .{
156 .llvm_name = "message-security-assist-extension4",
157 .description = "Assume that the message-security-assist extension facility 4 is installed",
158 .dependencies = featureSet(&[_]Feature{}),
159 };
160 result[@intFromEnum(Feature.message_security_assist_extension5)] = .{
161 .llvm_name = "message-security-assist-extension5",
162 .description = "Assume that the message-security-assist extension facility 5 is installed",
163 .dependencies = featureSet(&[_]Feature{}),
164 };
165 result[@intFromEnum(Feature.message_security_assist_extension7)] = .{
166 .llvm_name = "message-security-assist-extension7",
167 .description = "Assume that the message-security-assist extension facility 7 is installed",
168 .dependencies = featureSet(&[_]Feature{}),
169 };
170 result[@intFromEnum(Feature.message_security_assist_extension8)] = .{
171 .llvm_name = "message-security-assist-extension8",
172 .description = "Assume that the message-security-assist extension facility 8 is installed",
173 .dependencies = featureSet(&[_]Feature{}),
174 };
175 result[@intFromEnum(Feature.message_security_assist_extension9)] = .{
176 .llvm_name = "message-security-assist-extension9",
177 .description = "Assume that the message-security-assist extension facility 9 is installed",
178 .dependencies = featureSet(&[_]Feature{}),
179 };
180 result[@intFromEnum(Feature.miscellaneous_extensions)] = .{
181 .llvm_name = "miscellaneous-extensions",
182 .description = "Assume that the miscellaneous-extensions facility is installed",
183 .dependencies = featureSet(&[_]Feature{}),
184 };
185 result[@intFromEnum(Feature.miscellaneous_extensions_2)] = .{
186 .llvm_name = "miscellaneous-extensions-2",
187 .description = "Assume that the miscellaneous-extensions facility 2 is installed",
188 .dependencies = featureSet(&[_]Feature{}),
189 };
190 result[@intFromEnum(Feature.miscellaneous_extensions_3)] = .{
191 .llvm_name = "miscellaneous-extensions-3",
192 .description = "Assume that the miscellaneous-extensions facility 3 is installed",
193 .dependencies = featureSet(&[_]Feature{}),
194 };
195 result[@intFromEnum(Feature.nnp_assist)] = .{
196 .llvm_name = "nnp-assist",
197 .description = "Assume that the NNP-assist facility is installed",
198 .dependencies = featureSet(&[_]Feature{}),
199 };
200 result[@intFromEnum(Feature.population_count)] = .{
201 .llvm_name = "population-count",
202 .description = "Assume that the population-count facility is installed",
203 .dependencies = featureSet(&[_]Feature{}),
204 };
205 result[@intFromEnum(Feature.processor_activity_instrumentation)] = .{
206 .llvm_name = "processor-activity-instrumentation",
207 .description = "Assume that the processor-activity-instrumentation facility is installed",
208 .dependencies = featureSet(&[_]Feature{}),
209 };
210 result[@intFromEnum(Feature.processor_assist)] = .{
211 .llvm_name = "processor-assist",
212 .description = "Assume that the processor-assist facility is installed",
213 .dependencies = featureSet(&[_]Feature{}),
214 };
215 result[@intFromEnum(Feature.reset_dat_protection)] = .{
216 .llvm_name = "reset-dat-protection",
217 .description = "Assume that the reset-DAT-protection facility is installed",
218 .dependencies = featureSet(&[_]Feature{}),
219 };
220 result[@intFromEnum(Feature.reset_reference_bits_multiple)] = .{
221 .llvm_name = "reset-reference-bits-multiple",
222 .description = "Assume that the reset-reference-bits-multiple facility is installed",
223 .dependencies = featureSet(&[_]Feature{}),
224 };
225 result[@intFromEnum(Feature.soft_float)] = .{
226 .llvm_name = "soft-float",
227 .description = "Use software emulation for floating point",
228 .dependencies = featureSet(&[_]Feature{}),
229 };
230 result[@intFromEnum(Feature.transactional_execution)] = .{
231 .llvm_name = "transactional-execution",
232 .description = "Assume that the transactional-execution facility is installed",
233 .dependencies = featureSet(&[_]Feature{}),
234 };
235 result[@intFromEnum(Feature.vector)] = .{
236 .llvm_name = "vector",
237 .description = "Assume that the vectory facility is installed",
238 .dependencies = featureSet(&[_]Feature{}),
239 };
240 result[@intFromEnum(Feature.vector_enhancements_1)] = .{
241 .llvm_name = "vector-enhancements-1",
242 .description = "Assume that the vector enhancements facility 1 is installed",
243 .dependencies = featureSet(&[_]Feature{}),
244 };
245 result[@intFromEnum(Feature.vector_enhancements_2)] = .{
246 .llvm_name = "vector-enhancements-2",
247 .description = "Assume that the vector enhancements facility 2 is installed",
248 .dependencies = featureSet(&[_]Feature{}),
249 };
250 result[@intFromEnum(Feature.vector_packed_decimal)] = .{
251 .llvm_name = "vector-packed-decimal",
252 .description = "Assume that the vector packed decimal facility is installed",
253 .dependencies = featureSet(&[_]Feature{}),
254 };
255 result[@intFromEnum(Feature.vector_packed_decimal_enhancement)] = .{
256 .llvm_name = "vector-packed-decimal-enhancement",
257 .description = "Assume that the vector packed decimal enhancement facility is installed",
258 .dependencies = featureSet(&[_]Feature{}),
259 };
260 result[@intFromEnum(Feature.vector_packed_decimal_enhancement_2)] = .{
261 .llvm_name = "vector-packed-decimal-enhancement-2",
262 .description = "Assume that the vector packed decimal enhancement facility 2 is installed",
263 .dependencies = featureSet(&[_]Feature{}),
264 };
265 const ti = @typeInfo(Feature);
266 for (&result, 0..) |*elem, i| {
267 elem.index = i;
268 elem.name = ti.Enum.fields[i].name;
269 }
270 break :blk result;
271};
272
273pub const cpu = struct {
274 pub const arch10 = CpuModel{
275 .name = "arch10",
276 .llvm_name = "arch10",
277 .features = featureSet(&[_]Feature{
278 .dfp_zoned_conversion,
279 .distinct_ops,
280 .enhanced_dat_2,
281 .execution_hint,
282 .fast_serialization,
283 .fp_extension,
284 .high_word,
285 .interlocked_access1,
286 .load_and_trap,
287 .load_store_on_cond,
288 .message_security_assist_extension3,
289 .message_security_assist_extension4,
290 .miscellaneous_extensions,
291 .population_count,
292 .processor_assist,
293 .reset_reference_bits_multiple,
294 .transactional_execution,
295 }),
296 };
297 pub const arch11 = CpuModel{
298 .name = "arch11",
299 .llvm_name = "arch11",
300 .features = featureSet(&[_]Feature{
301 .dfp_packed_conversion,
302 .dfp_zoned_conversion,
303 .distinct_ops,
304 .enhanced_dat_2,
305 .execution_hint,
306 .fast_serialization,
307 .fp_extension,
308 .high_word,
309 .interlocked_access1,
310 .load_and_trap,
311 .load_and_zero_rightmost_byte,
312 .load_store_on_cond,
313 .load_store_on_cond_2,
314 .message_security_assist_extension3,
315 .message_security_assist_extension4,
316 .message_security_assist_extension5,
317 .miscellaneous_extensions,
318 .population_count,
319 .processor_assist,
320 .reset_reference_bits_multiple,
321 .transactional_execution,
322 .vector,
323 }),
324 };
325 pub const arch12 = CpuModel{
326 .name = "arch12",
327 .llvm_name = "arch12",
328 .features = featureSet(&[_]Feature{
329 .dfp_packed_conversion,
330 .dfp_zoned_conversion,
331 .distinct_ops,
332 .enhanced_dat_2,
333 .execution_hint,
334 .fast_serialization,
335 .fp_extension,
336 .guarded_storage,
337 .high_word,
338 .insert_reference_bits_multiple,
339 .interlocked_access1,
340 .load_and_trap,
341 .load_and_zero_rightmost_byte,
342 .load_store_on_cond,
343 .load_store_on_cond_2,
344 .message_security_assist_extension3,
345 .message_security_assist_extension4,
346 .message_security_assist_extension5,
347 .message_security_assist_extension7,
348 .message_security_assist_extension8,
349 .miscellaneous_extensions,
350 .miscellaneous_extensions_2,
351 .population_count,
352 .processor_assist,
353 .reset_reference_bits_multiple,
354 .transactional_execution,
355 .vector,
356 .vector_enhancements_1,
357 .vector_packed_decimal,
358 }),
359 };
360 pub const arch13 = CpuModel{
361 .name = "arch13",
362 .llvm_name = "arch13",
363 .features = featureSet(&[_]Feature{
364 .deflate_conversion,
365 .dfp_packed_conversion,
366 .dfp_zoned_conversion,
367 .distinct_ops,
368 .enhanced_dat_2,
369 .enhanced_sort,
370 .execution_hint,
371 .fast_serialization,
372 .fp_extension,
373 .guarded_storage,
374 .high_word,
375 .insert_reference_bits_multiple,
376 .interlocked_access1,
377 .load_and_trap,
378 .load_and_zero_rightmost_byte,
379 .load_store_on_cond,
380 .load_store_on_cond_2,
381 .message_security_assist_extension3,
382 .message_security_assist_extension4,
383 .message_security_assist_extension5,
384 .message_security_assist_extension7,
385 .message_security_assist_extension8,
386 .message_security_assist_extension9,
387 .miscellaneous_extensions,
388 .miscellaneous_extensions_2,
389 .miscellaneous_extensions_3,
390 .population_count,
391 .processor_assist,
392 .reset_reference_bits_multiple,
393 .transactional_execution,
394 .vector,
395 .vector_enhancements_1,
396 .vector_enhancements_2,
397 .vector_packed_decimal,
398 .vector_packed_decimal_enhancement,
399 }),
400 };
401 pub const arch14 = CpuModel{
402 .name = "arch14",
403 .llvm_name = "arch14",
404 .features = featureSet(&[_]Feature{
405 .bear_enhancement,
406 .deflate_conversion,
407 .dfp_packed_conversion,
408 .dfp_zoned_conversion,
409 .distinct_ops,
410 .enhanced_dat_2,
411 .enhanced_sort,
412 .execution_hint,
413 .fast_serialization,
414 .fp_extension,
415 .guarded_storage,
416 .high_word,
417 .insert_reference_bits_multiple,
418 .interlocked_access1,
419 .load_and_trap,
420 .load_and_zero_rightmost_byte,
421 .load_store_on_cond,
422 .load_store_on_cond_2,
423 .message_security_assist_extension3,
424 .message_security_assist_extension4,
425 .message_security_assist_extension5,
426 .message_security_assist_extension7,
427 .message_security_assist_extension8,
428 .message_security_assist_extension9,
429 .miscellaneous_extensions,
430 .miscellaneous_extensions_2,
431 .miscellaneous_extensions_3,
432 .nnp_assist,
433 .population_count,
434 .processor_activity_instrumentation,
435 .processor_assist,
436 .reset_dat_protection,
437 .reset_reference_bits_multiple,
438 .transactional_execution,
439 .vector,
440 .vector_enhancements_1,
441 .vector_enhancements_2,
442 .vector_packed_decimal,
443 .vector_packed_decimal_enhancement,
444 .vector_packed_decimal_enhancement_2,
445 }),
446 };
447 pub const arch8 = CpuModel{
448 .name = "arch8",
449 .llvm_name = "arch8",
450 .features = featureSet(&[_]Feature{}),
451 };
452 pub const arch9 = CpuModel{
453 .name = "arch9",
454 .llvm_name = "arch9",
455 .features = featureSet(&[_]Feature{
456 .distinct_ops,
457 .fast_serialization,
458 .fp_extension,
459 .high_word,
460 .interlocked_access1,
461 .load_store_on_cond,
462 .message_security_assist_extension3,
463 .message_security_assist_extension4,
464 .population_count,
465 .reset_reference_bits_multiple,
466 }),
467 };
468 pub const generic = CpuModel{
469 .name = "generic",
470 .llvm_name = "generic",
471 .features = featureSet(&[_]Feature{}),
472 };
473 pub const z10 = CpuModel{
474 .name = "z10",
475 .llvm_name = "z10",
476 .features = featureSet(&[_]Feature{}),
477 };
478 pub const z13 = CpuModel{
479 .name = "z13",
480 .llvm_name = "z13",
481 .features = featureSet(&[_]Feature{
482 .dfp_packed_conversion,
483 .dfp_zoned_conversion,
484 .distinct_ops,
485 .enhanced_dat_2,
486 .execution_hint,
487 .fast_serialization,
488 .fp_extension,
489 .high_word,
490 .interlocked_access1,
491 .load_and_trap,
492 .load_and_zero_rightmost_byte,
493 .load_store_on_cond,
494 .load_store_on_cond_2,
495 .message_security_assist_extension3,
496 .message_security_assist_extension4,
497 .message_security_assist_extension5,
498 .miscellaneous_extensions,
499 .population_count,
500 .processor_assist,
501 .reset_reference_bits_multiple,
502 .transactional_execution,
503 .vector,
504 }),
505 };
506 pub const z14 = CpuModel{
507 .name = "z14",
508 .llvm_name = "z14",
509 .features = featureSet(&[_]Feature{
510 .dfp_packed_conversion,
511 .dfp_zoned_conversion,
512 .distinct_ops,
513 .enhanced_dat_2,
514 .execution_hint,
515 .fast_serialization,
516 .fp_extension,
517 .guarded_storage,
518 .high_word,
519 .insert_reference_bits_multiple,
520 .interlocked_access1,
521 .load_and_trap,
522 .load_and_zero_rightmost_byte,
523 .load_store_on_cond,
524 .load_store_on_cond_2,
525 .message_security_assist_extension3,
526 .message_security_assist_extension4,
527 .message_security_assist_extension5,
528 .message_security_assist_extension7,
529 .message_security_assist_extension8,
530 .miscellaneous_extensions,
531 .miscellaneous_extensions_2,
532 .population_count,
533 .processor_assist,
534 .reset_reference_bits_multiple,
535 .transactional_execution,
536 .vector,
537 .vector_enhancements_1,
538 .vector_packed_decimal,
539 }),
540 };
541 pub const z15 = CpuModel{
542 .name = "z15",
543 .llvm_name = "z15",
544 .features = featureSet(&[_]Feature{
545 .deflate_conversion,
546 .dfp_packed_conversion,
547 .dfp_zoned_conversion,
548 .distinct_ops,
549 .enhanced_dat_2,
550 .enhanced_sort,
551 .execution_hint,
552 .fast_serialization,
553 .fp_extension,
554 .guarded_storage,
555 .high_word,
556 .insert_reference_bits_multiple,
557 .interlocked_access1,
558 .load_and_trap,
559 .load_and_zero_rightmost_byte,
560 .load_store_on_cond,
561 .load_store_on_cond_2,
562 .message_security_assist_extension3,
563 .message_security_assist_extension4,
564 .message_security_assist_extension5,
565 .message_security_assist_extension7,
566 .message_security_assist_extension8,
567 .message_security_assist_extension9,
568 .miscellaneous_extensions,
569 .miscellaneous_extensions_2,
570 .miscellaneous_extensions_3,
571 .population_count,
572 .processor_assist,
573 .reset_reference_bits_multiple,
574 .transactional_execution,
575 .vector,
576 .vector_enhancements_1,
577 .vector_enhancements_2,
578 .vector_packed_decimal,
579 .vector_packed_decimal_enhancement,
580 }),
581 };
582 pub const z16 = CpuModel{
583 .name = "z16",
584 .llvm_name = "z16",
585 .features = featureSet(&[_]Feature{
586 .bear_enhancement,
587 .deflate_conversion,
588 .dfp_packed_conversion,
589 .dfp_zoned_conversion,
590 .distinct_ops,
591 .enhanced_dat_2,
592 .enhanced_sort,
593 .execution_hint,
594 .fast_serialization,
595 .fp_extension,
596 .guarded_storage,
597 .high_word,
598 .insert_reference_bits_multiple,
599 .interlocked_access1,
600 .load_and_trap,
601 .load_and_zero_rightmost_byte,
602 .load_store_on_cond,
603 .load_store_on_cond_2,
604 .message_security_assist_extension3,
605 .message_security_assist_extension4,
606 .message_security_assist_extension5,
607 .message_security_assist_extension7,
608 .message_security_assist_extension8,
609 .message_security_assist_extension9,
610 .miscellaneous_extensions,
611 .miscellaneous_extensions_2,
612 .miscellaneous_extensions_3,
613 .nnp_assist,
614 .population_count,
615 .processor_activity_instrumentation,
616 .processor_assist,
617 .reset_dat_protection,
618 .reset_reference_bits_multiple,
619 .transactional_execution,
620 .vector,
621 .vector_enhancements_1,
622 .vector_enhancements_2,
623 .vector_packed_decimal,
624 .vector_packed_decimal_enhancement,
625 .vector_packed_decimal_enhancement_2,
626 }),
627 };
628 pub const z196 = CpuModel{
629 .name = "z196",
630 .llvm_name = "z196",
631 .features = featureSet(&[_]Feature{
632 .distinct_ops,
633 .fast_serialization,
634 .fp_extension,
635 .high_word,
636 .interlocked_access1,
637 .load_store_on_cond,
638 .message_security_assist_extension3,
639 .message_security_assist_extension4,
640 .population_count,
641 .reset_reference_bits_multiple,
642 }),
643 };
644 pub const zEC12 = CpuModel{
645 .name = "zEC12",
646 .llvm_name = "zEC12",
647 .features = featureSet(&[_]Feature{
648 .dfp_zoned_conversion,
649 .distinct_ops,
650 .enhanced_dat_2,
651 .execution_hint,
652 .fast_serialization,
653 .fp_extension,
654 .high_word,
655 .interlocked_access1,
656 .load_and_trap,
657 .load_store_on_cond,
658 .message_security_assist_extension3,
659 .message_security_assist_extension4,
660 .miscellaneous_extensions,
661 .population_count,
662 .processor_assist,
663 .reset_reference_bits_multiple,
664 .transactional_execution,
665 }),
666 };
667};
lib/std/target/sparc.zig deleted-455
......@@ -1,455 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 deprecated_v8,
9 detectroundchange,
10 fixallfdivsqrt,
11 hard_quad_float,
12 hasleoncasa,
13 hasumacsmac,
14 insertnopload,
15 leon,
16 leoncyclecounter,
17 leonpwrpsr,
18 no_fmuls,
19 no_fsmuld,
20 popc,
21 soft_float,
22 soft_mul_div,
23 v9,
24 vis,
25 vis2,
26 vis3,
27};
28
29pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
30pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
31pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
32pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
33
34pub const all_features = blk: {
35 const len = @typeInfo(Feature).Enum.fields.len;
36 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
37 var result: [len]CpuFeature = undefined;
38 result[@intFromEnum(Feature.deprecated_v8)] = .{
39 .llvm_name = "deprecated-v8",
40 .description = "Enable deprecated V8 instructions in V9 mode",
41 .dependencies = featureSet(&[_]Feature{}),
42 };
43 result[@intFromEnum(Feature.detectroundchange)] = .{
44 .llvm_name = "detectroundchange",
45 .description = "LEON3 erratum detection: Detects any rounding mode change request: use only the round-to-nearest rounding mode",
46 .dependencies = featureSet(&[_]Feature{}),
47 };
48 result[@intFromEnum(Feature.fixallfdivsqrt)] = .{
49 .llvm_name = "fixallfdivsqrt",
50 .description = "LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store",
51 .dependencies = featureSet(&[_]Feature{}),
52 };
53 result[@intFromEnum(Feature.hard_quad_float)] = .{
54 .llvm_name = "hard-quad-float",
55 .description = "Enable quad-word floating point instructions",
56 .dependencies = featureSet(&[_]Feature{}),
57 };
58 result[@intFromEnum(Feature.hasleoncasa)] = .{
59 .llvm_name = "hasleoncasa",
60 .description = "Enable CASA instruction for LEON3 and LEON4 processors",
61 .dependencies = featureSet(&[_]Feature{}),
62 };
63 result[@intFromEnum(Feature.hasumacsmac)] = .{
64 .llvm_name = "hasumacsmac",
65 .description = "Enable UMAC and SMAC for LEON3 and LEON4 processors",
66 .dependencies = featureSet(&[_]Feature{}),
67 };
68 result[@intFromEnum(Feature.insertnopload)] = .{
69 .llvm_name = "insertnopload",
70 .description = "LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction",
71 .dependencies = featureSet(&[_]Feature{}),
72 };
73 result[@intFromEnum(Feature.leon)] = .{
74 .llvm_name = "leon",
75 .description = "Enable LEON extensions",
76 .dependencies = featureSet(&[_]Feature{}),
77 };
78 result[@intFromEnum(Feature.leoncyclecounter)] = .{
79 .llvm_name = "leoncyclecounter",
80 .description = "Use the Leon cycle counter register",
81 .dependencies = featureSet(&[_]Feature{}),
82 };
83 result[@intFromEnum(Feature.leonpwrpsr)] = .{
84 .llvm_name = "leonpwrpsr",
85 .description = "Enable the PWRPSR instruction",
86 .dependencies = featureSet(&[_]Feature{}),
87 };
88 result[@intFromEnum(Feature.no_fmuls)] = .{
89 .llvm_name = "no-fmuls",
90 .description = "Disable the fmuls instruction.",
91 .dependencies = featureSet(&[_]Feature{}),
92 };
93 result[@intFromEnum(Feature.no_fsmuld)] = .{
94 .llvm_name = "no-fsmuld",
95 .description = "Disable the fsmuld instruction.",
96 .dependencies = featureSet(&[_]Feature{}),
97 };
98 result[@intFromEnum(Feature.popc)] = .{
99 .llvm_name = "popc",
100 .description = "Use the popc (population count) instruction",
101 .dependencies = featureSet(&[_]Feature{}),
102 };
103 result[@intFromEnum(Feature.soft_float)] = .{
104 .llvm_name = "soft-float",
105 .description = "Use software emulation for floating point",
106 .dependencies = featureSet(&[_]Feature{}),
107 };
108 result[@intFromEnum(Feature.soft_mul_div)] = .{
109 .llvm_name = "soft-mul-div",
110 .description = "Use software emulation for integer multiply and divide",
111 .dependencies = featureSet(&[_]Feature{}),
112 };
113 result[@intFromEnum(Feature.v9)] = .{
114 .llvm_name = "v9",
115 .description = "Enable SPARC-V9 instructions",
116 .dependencies = featureSet(&[_]Feature{}),
117 };
118 result[@intFromEnum(Feature.vis)] = .{
119 .llvm_name = "vis",
120 .description = "Enable UltraSPARC Visual Instruction Set extensions",
121 .dependencies = featureSet(&[_]Feature{}),
122 };
123 result[@intFromEnum(Feature.vis2)] = .{
124 .llvm_name = "vis2",
125 .description = "Enable Visual Instruction Set extensions II",
126 .dependencies = featureSet(&[_]Feature{}),
127 };
128 result[@intFromEnum(Feature.vis3)] = .{
129 .llvm_name = "vis3",
130 .description = "Enable Visual Instruction Set extensions III",
131 .dependencies = featureSet(&[_]Feature{}),
132 };
133 const ti = @typeInfo(Feature);
134 for (&result, 0..) |*elem, i| {
135 elem.index = i;
136 elem.name = ti.Enum.fields[i].name;
137 }
138 break :blk result;
139};
140
141pub const cpu = struct {
142 pub const at697e = CpuModel{
143 .name = "at697e",
144 .llvm_name = "at697e",
145 .features = featureSet(&[_]Feature{
146 .insertnopload,
147 .leon,
148 }),
149 };
150 pub const at697f = CpuModel{
151 .name = "at697f",
152 .llvm_name = "at697f",
153 .features = featureSet(&[_]Feature{
154 .insertnopload,
155 .leon,
156 }),
157 };
158 pub const f934 = CpuModel{
159 .name = "f934",
160 .llvm_name = "f934",
161 .features = featureSet(&[_]Feature{}),
162 };
163 pub const generic = CpuModel{
164 .name = "generic",
165 .llvm_name = "generic",
166 .features = featureSet(&[_]Feature{}),
167 };
168 pub const gr712rc = CpuModel{
169 .name = "gr712rc",
170 .llvm_name = "gr712rc",
171 .features = featureSet(&[_]Feature{
172 .hasleoncasa,
173 .leon,
174 }),
175 };
176 pub const gr740 = CpuModel{
177 .name = "gr740",
178 .llvm_name = "gr740",
179 .features = featureSet(&[_]Feature{
180 .hasleoncasa,
181 .hasumacsmac,
182 .leon,
183 .leoncyclecounter,
184 .leonpwrpsr,
185 }),
186 };
187 pub const hypersparc = CpuModel{
188 .name = "hypersparc",
189 .llvm_name = "hypersparc",
190 .features = featureSet(&[_]Feature{}),
191 };
192 pub const leon2 = CpuModel{
193 .name = "leon2",
194 .llvm_name = "leon2",
195 .features = featureSet(&[_]Feature{
196 .leon,
197 }),
198 };
199 pub const leon3 = CpuModel{
200 .name = "leon3",
201 .llvm_name = "leon3",
202 .features = featureSet(&[_]Feature{
203 .hasumacsmac,
204 .leon,
205 }),
206 };
207 pub const leon4 = CpuModel{
208 .name = "leon4",
209 .llvm_name = "leon4",
210 .features = featureSet(&[_]Feature{
211 .hasleoncasa,
212 .hasumacsmac,
213 .leon,
214 }),
215 };
216 pub const ma2080 = CpuModel{
217 .name = "ma2080",
218 .llvm_name = "ma2080",
219 .features = featureSet(&[_]Feature{
220 .hasleoncasa,
221 .leon,
222 }),
223 };
224 pub const ma2085 = CpuModel{
225 .name = "ma2085",
226 .llvm_name = "ma2085",
227 .features = featureSet(&[_]Feature{
228 .hasleoncasa,
229 .leon,
230 }),
231 };
232 pub const ma2100 = CpuModel{
233 .name = "ma2100",
234 .llvm_name = "ma2100",
235 .features = featureSet(&[_]Feature{
236 .hasleoncasa,
237 .leon,
238 }),
239 };
240 pub const ma2150 = CpuModel{
241 .name = "ma2150",
242 .llvm_name = "ma2150",
243 .features = featureSet(&[_]Feature{
244 .hasleoncasa,
245 .leon,
246 }),
247 };
248 pub const ma2155 = CpuModel{
249 .name = "ma2155",
250 .llvm_name = "ma2155",
251 .features = featureSet(&[_]Feature{
252 .hasleoncasa,
253 .leon,
254 }),
255 };
256 pub const ma2450 = CpuModel{
257 .name = "ma2450",
258 .llvm_name = "ma2450",
259 .features = featureSet(&[_]Feature{
260 .hasleoncasa,
261 .leon,
262 }),
263 };
264 pub const ma2455 = CpuModel{
265 .name = "ma2455",
266 .llvm_name = "ma2455",
267 .features = featureSet(&[_]Feature{
268 .hasleoncasa,
269 .leon,
270 }),
271 };
272 pub const ma2480 = CpuModel{
273 .name = "ma2480",
274 .llvm_name = "ma2480",
275 .features = featureSet(&[_]Feature{
276 .hasleoncasa,
277 .leon,
278 }),
279 };
280 pub const ma2485 = CpuModel{
281 .name = "ma2485",
282 .llvm_name = "ma2485",
283 .features = featureSet(&[_]Feature{
284 .hasleoncasa,
285 .leon,
286 }),
287 };
288 pub const ma2x5x = CpuModel{
289 .name = "ma2x5x",
290 .llvm_name = "ma2x5x",
291 .features = featureSet(&[_]Feature{
292 .hasleoncasa,
293 .leon,
294 }),
295 };
296 pub const ma2x8x = CpuModel{
297 .name = "ma2x8x",
298 .llvm_name = "ma2x8x",
299 .features = featureSet(&[_]Feature{
300 .hasleoncasa,
301 .leon,
302 }),
303 };
304 pub const myriad2 = CpuModel{
305 .name = "myriad2",
306 .llvm_name = "myriad2",
307 .features = featureSet(&[_]Feature{
308 .hasleoncasa,
309 .leon,
310 }),
311 };
312 pub const myriad2_1 = CpuModel{
313 .name = "myriad2_1",
314 .llvm_name = "myriad2.1",
315 .features = featureSet(&[_]Feature{
316 .hasleoncasa,
317 .leon,
318 }),
319 };
320 pub const myriad2_2 = CpuModel{
321 .name = "myriad2_2",
322 .llvm_name = "myriad2.2",
323 .features = featureSet(&[_]Feature{
324 .hasleoncasa,
325 .leon,
326 }),
327 };
328 pub const myriad2_3 = CpuModel{
329 .name = "myriad2_3",
330 .llvm_name = "myriad2.3",
331 .features = featureSet(&[_]Feature{
332 .hasleoncasa,
333 .leon,
334 }),
335 };
336 pub const niagara = CpuModel{
337 .name = "niagara",
338 .llvm_name = "niagara",
339 .features = featureSet(&[_]Feature{
340 .deprecated_v8,
341 .v9,
342 .vis,
343 .vis2,
344 }),
345 };
346 pub const niagara2 = CpuModel{
347 .name = "niagara2",
348 .llvm_name = "niagara2",
349 .features = featureSet(&[_]Feature{
350 .deprecated_v8,
351 .popc,
352 .v9,
353 .vis,
354 .vis2,
355 }),
356 };
357 pub const niagara3 = CpuModel{
358 .name = "niagara3",
359 .llvm_name = "niagara3",
360 .features = featureSet(&[_]Feature{
361 .deprecated_v8,
362 .popc,
363 .v9,
364 .vis,
365 .vis2,
366 }),
367 };
368 pub const niagara4 = CpuModel{
369 .name = "niagara4",
370 .llvm_name = "niagara4",
371 .features = featureSet(&[_]Feature{
372 .deprecated_v8,
373 .popc,
374 .v9,
375 .vis,
376 .vis2,
377 .vis3,
378 }),
379 };
380 pub const sparclet = CpuModel{
381 .name = "sparclet",
382 .llvm_name = "sparclet",
383 .features = featureSet(&[_]Feature{}),
384 };
385 pub const sparclite = CpuModel{
386 .name = "sparclite",
387 .llvm_name = "sparclite",
388 .features = featureSet(&[_]Feature{}),
389 };
390 pub const sparclite86x = CpuModel{
391 .name = "sparclite86x",
392 .llvm_name = "sparclite86x",
393 .features = featureSet(&[_]Feature{}),
394 };
395 pub const supersparc = CpuModel{
396 .name = "supersparc",
397 .llvm_name = "supersparc",
398 .features = featureSet(&[_]Feature{}),
399 };
400 pub const tsc701 = CpuModel{
401 .name = "tsc701",
402 .llvm_name = "tsc701",
403 .features = featureSet(&[_]Feature{}),
404 };
405 pub const ultrasparc = CpuModel{
406 .name = "ultrasparc",
407 .llvm_name = "ultrasparc",
408 .features = featureSet(&[_]Feature{
409 .deprecated_v8,
410 .v9,
411 .vis,
412 }),
413 };
414 pub const ultrasparc3 = CpuModel{
415 .name = "ultrasparc3",
416 .llvm_name = "ultrasparc3",
417 .features = featureSet(&[_]Feature{
418 .deprecated_v8,
419 .v9,
420 .vis,
421 .vis2,
422 }),
423 };
424 pub const ut699 = CpuModel{
425 .name = "ut699",
426 .llvm_name = "ut699",
427 .features = featureSet(&[_]Feature{
428 .fixallfdivsqrt,
429 .insertnopload,
430 .leon,
431 .no_fmuls,
432 .no_fsmuld,
433 }),
434 };
435 pub const v7 = CpuModel{
436 .name = "v7",
437 .llvm_name = "v7",
438 .features = featureSet(&[_]Feature{
439 .no_fsmuld,
440 .soft_mul_div,
441 }),
442 };
443 pub const v8 = CpuModel{
444 .name = "v8",
445 .llvm_name = "v8",
446 .features = featureSet(&[_]Feature{}),
447 };
448 pub const v9 = CpuModel{
449 .name = "v9",
450 .llvm_name = "v9",
451 .features = featureSet(&[_]Feature{
452 .v9,
453 }),
454 };
455};
lib/std/target/spirv.zig deleted-2091
......@@ -1,2091 +0,0 @@
1//! This file is auto-generated by tools/update_spirv_features.zig.
2//! TODO: Dependencies of capabilities on extensions.
3//! TODO: Dependencies of extensions on extensions.
4//! TODO: Dependencies of extensions on versions.
5
6const std = @import("../std.zig");
7const CpuFeature = std.Target.Cpu.Feature;
8const CpuModel = std.Target.Cpu.Model;
9
10pub const Feature = enum {
11 v1_1,
12 v1_2,
13 v1_3,
14 v1_4,
15 v1_5,
16 SPV_AMD_shader_fragment_mask,
17 SPV_AMD_gpu_shader_int16,
18 SPV_AMD_gpu_shader_half_float,
19 SPV_AMD_texture_gather_bias_lod,
20 SPV_AMD_shader_ballot,
21 SPV_AMD_gcn_shader,
22 SPV_AMD_shader_image_load_store_lod,
23 SPV_AMD_shader_explicit_vertex_parameter,
24 SPV_AMD_shader_trinary_minmax,
25 SPV_AMD_gpu_shader_half_float_fetch,
26 SPV_GOOGLE_hlsl_functionality1,
27 SPV_GOOGLE_user_type,
28 SPV_GOOGLE_decorate_string,
29 SPV_EXT_demote_to_helper_invocation,
30 SPV_EXT_descriptor_indexing,
31 SPV_EXT_fragment_fully_covered,
32 SPV_EXT_shader_stencil_export,
33 SPV_EXT_physical_storage_buffer,
34 SPV_EXT_shader_atomic_float_add,
35 SPV_EXT_shader_atomic_float_min_max,
36 SPV_EXT_shader_image_int64,
37 SPV_EXT_fragment_shader_interlock,
38 SPV_EXT_fragment_invocation_density,
39 SPV_EXT_shader_viewport_index_layer,
40 SPV_INTEL_loop_fuse,
41 SPV_INTEL_fpga_dsp_control,
42 SPV_INTEL_fpga_reg,
43 SPV_INTEL_fpga_memory_accesses,
44 SPV_INTEL_fpga_loop_controls,
45 SPV_INTEL_io_pipes,
46 SPV_INTEL_unstructured_loop_controls,
47 SPV_INTEL_blocking_pipes,
48 SPV_INTEL_device_side_avc_motion_estimation,
49 SPV_INTEL_fpga_memory_attributes,
50 SPV_INTEL_fp_fast_math_mode,
51 SPV_INTEL_media_block_io,
52 SPV_INTEL_shader_integer_functions2,
53 SPV_INTEL_subgroups,
54 SPV_INTEL_fpga_cluster_attributes,
55 SPV_INTEL_kernel_attributes,
56 SPV_INTEL_arbitrary_precision_integers,
57 SPV_KHR_8bit_storage,
58 SPV_KHR_shader_clock,
59 SPV_KHR_device_group,
60 SPV_KHR_16bit_storage,
61 SPV_KHR_variable_pointers,
62 SPV_KHR_no_integer_wrap_decoration,
63 SPV_KHR_subgroup_vote,
64 SPV_KHR_multiview,
65 SPV_KHR_shader_ballot,
66 SPV_KHR_vulkan_memory_model,
67 SPV_KHR_physical_storage_buffer,
68 SPV_KHR_workgroup_memory_explicit_layout,
69 SPV_KHR_fragment_shading_rate,
70 SPV_KHR_shader_atomic_counter_ops,
71 SPV_KHR_shader_draw_parameters,
72 SPV_KHR_storage_buffer_storage_class,
73 SPV_KHR_linkonce_odr,
74 SPV_KHR_terminate_invocation,
75 SPV_KHR_non_semantic_info,
76 SPV_KHR_post_depth_coverage,
77 SPV_KHR_expect_assume,
78 SPV_KHR_ray_tracing,
79 SPV_KHR_ray_query,
80 SPV_KHR_float_controls,
81 SPV_NV_viewport_array2,
82 SPV_NV_shader_subgroup_partitioned,
83 SPV_NVX_multiview_per_view_attributes,
84 SPV_NV_ray_tracing,
85 SPV_NV_shader_image_footprint,
86 SPV_NV_shading_rate,
87 SPV_NV_stereo_view_rendering,
88 SPV_NV_compute_shader_derivatives,
89 SPV_NV_shader_sm_builtins,
90 SPV_NV_mesh_shader,
91 SPV_NV_geometry_shader_passthrough,
92 SPV_NV_fragment_shader_barycentric,
93 SPV_NV_cooperative_matrix,
94 SPV_NV_sample_mask_override_coverage,
95 Matrix,
96 Shader,
97 Geometry,
98 Tessellation,
99 Addresses,
100 Linkage,
101 Kernel,
102 Vector16,
103 Float16Buffer,
104 Float16,
105 Float64,
106 Int64,
107 Int64Atomics,
108 ImageBasic,
109 ImageReadWrite,
110 ImageMipmap,
111 Pipes,
112 Groups,
113 DeviceEnqueue,
114 LiteralSampler,
115 AtomicStorage,
116 Int16,
117 TessellationPointSize,
118 GeometryPointSize,
119 ImageGatherExtended,
120 StorageImageMultisample,
121 UniformBufferArrayDynamicIndexing,
122 SampledImageArrayDynamicIndexing,
123 StorageBufferArrayDynamicIndexing,
124 StorageImageArrayDynamicIndexing,
125 ClipDistance,
126 CullDistance,
127 ImageCubeArray,
128 SampleRateShading,
129 ImageRect,
130 SampledRect,
131 GenericPointer,
132 Int8,
133 InputAttachment,
134 SparseResidency,
135 MinLod,
136 Sampled1D,
137 Image1D,
138 SampledCubeArray,
139 SampledBuffer,
140 ImageBuffer,
141 ImageMSArray,
142 StorageImageExtendedFormats,
143 ImageQuery,
144 DerivativeControl,
145 InterpolationFunction,
146 TransformFeedback,
147 GeometryStreams,
148 StorageImageReadWithoutFormat,
149 StorageImageWriteWithoutFormat,
150 MultiViewport,
151 SubgroupDispatch,
152 NamedBarrier,
153 PipeStorage,
154 GroupNonUniform,
155 GroupNonUniformVote,
156 GroupNonUniformArithmetic,
157 GroupNonUniformBallot,
158 GroupNonUniformShuffle,
159 GroupNonUniformShuffleRelative,
160 GroupNonUniformClustered,
161 GroupNonUniformQuad,
162 ShaderLayer,
163 ShaderViewportIndex,
164 FragmentShadingRateKHR,
165 SubgroupBallotKHR,
166 DrawParameters,
167 WorkgroupMemoryExplicitLayoutKHR,
168 WorkgroupMemoryExplicitLayout8BitAccessKHR,
169 WorkgroupMemoryExplicitLayout16BitAccessKHR,
170 SubgroupVoteKHR,
171 StorageBuffer16BitAccess,
172 StorageUniformBufferBlock16,
173 UniformAndStorageBuffer16BitAccess,
174 StorageUniform16,
175 StoragePushConstant16,
176 StorageInputOutput16,
177 DeviceGroup,
178 MultiView,
179 VariablePointersStorageBuffer,
180 VariablePointers,
181 AtomicStorageOps,
182 SampleMaskPostDepthCoverage,
183 StorageBuffer8BitAccess,
184 UniformAndStorageBuffer8BitAccess,
185 StoragePushConstant8,
186 DenormPreserve,
187 DenormFlushToZero,
188 SignedZeroInfNanPreserve,
189 RoundingModeRTE,
190 RoundingModeRTZ,
191 RayQueryProvisionalKHR,
192 RayQueryKHR,
193 RayTraversalPrimitiveCullingKHR,
194 RayTracingKHR,
195 Float16ImageAMD,
196 ImageGatherBiasLodAMD,
197 FragmentMaskAMD,
198 StencilExportEXT,
199 ImageReadWriteLodAMD,
200 Int64ImageEXT,
201 ShaderClockKHR,
202 SampleMaskOverrideCoverageNV,
203 GeometryShaderPassthroughNV,
204 ShaderViewportIndexLayerEXT,
205 ShaderViewportIndexLayerNV,
206 ShaderViewportMaskNV,
207 ShaderStereoViewNV,
208 PerViewAttributesNV,
209 FragmentFullyCoveredEXT,
210 MeshShadingNV,
211 ImageFootprintNV,
212 FragmentBarycentricNV,
213 ComputeDerivativeGroupQuadsNV,
214 FragmentDensityEXT,
215 ShadingRateNV,
216 GroupNonUniformPartitionedNV,
217 ShaderNonUniform,
218 ShaderNonUniformEXT,
219 RuntimeDescriptorArray,
220 RuntimeDescriptorArrayEXT,
221 InputAttachmentArrayDynamicIndexing,
222 InputAttachmentArrayDynamicIndexingEXT,
223 UniformTexelBufferArrayDynamicIndexing,
224 UniformTexelBufferArrayDynamicIndexingEXT,
225 StorageTexelBufferArrayDynamicIndexing,
226 StorageTexelBufferArrayDynamicIndexingEXT,
227 UniformBufferArrayNonUniformIndexing,
228 UniformBufferArrayNonUniformIndexingEXT,
229 SampledImageArrayNonUniformIndexing,
230 SampledImageArrayNonUniformIndexingEXT,
231 StorageBufferArrayNonUniformIndexing,
232 StorageBufferArrayNonUniformIndexingEXT,
233 StorageImageArrayNonUniformIndexing,
234 StorageImageArrayNonUniformIndexingEXT,
235 InputAttachmentArrayNonUniformIndexing,
236 InputAttachmentArrayNonUniformIndexingEXT,
237 UniformTexelBufferArrayNonUniformIndexing,
238 UniformTexelBufferArrayNonUniformIndexingEXT,
239 StorageTexelBufferArrayNonUniformIndexing,
240 StorageTexelBufferArrayNonUniformIndexingEXT,
241 RayTracingNV,
242 VulkanMemoryModel,
243 VulkanMemoryModelKHR,
244 VulkanMemoryModelDeviceScope,
245 VulkanMemoryModelDeviceScopeKHR,
246 PhysicalStorageBufferAddresses,
247 PhysicalStorageBufferAddressesEXT,
248 ComputeDerivativeGroupLinearNV,
249 RayTracingProvisionalKHR,
250 CooperativeMatrixNV,
251 FragmentShaderSampleInterlockEXT,
252 FragmentShaderShadingRateInterlockEXT,
253 ShaderSMBuiltinsNV,
254 FragmentShaderPixelInterlockEXT,
255 DemoteToHelperInvocationEXT,
256 SubgroupShuffleINTEL,
257 SubgroupBufferBlockIOINTEL,
258 SubgroupImageBlockIOINTEL,
259 SubgroupImageMediaBlockIOINTEL,
260 RoundToInfinityINTEL,
261 FloatingPointModeINTEL,
262 IntegerFunctions2INTEL,
263 FunctionPointersINTEL,
264 IndirectReferencesINTEL,
265 AsmINTEL,
266 AtomicFloat32MinMaxEXT,
267 AtomicFloat64MinMaxEXT,
268 AtomicFloat16MinMaxEXT,
269 VectorComputeINTEL,
270 VectorAnyINTEL,
271 ExpectAssumeKHR,
272 SubgroupAvcMotionEstimationINTEL,
273 SubgroupAvcMotionEstimationIntraINTEL,
274 SubgroupAvcMotionEstimationChromaINTEL,
275 VariableLengthArrayINTEL,
276 FunctionFloatControlINTEL,
277 FPGAMemoryAttributesINTEL,
278 FPFastMathModeINTEL,
279 ArbitraryPrecisionIntegersINTEL,
280 UnstructuredLoopControlsINTEL,
281 FPGALoopControlsINTEL,
282 KernelAttributesINTEL,
283 FPGAKernelAttributesINTEL,
284 FPGAMemoryAccessesINTEL,
285 FPGAClusterAttributesINTEL,
286 LoopFuseINTEL,
287 FPGABufferLocationINTEL,
288 USMStorageClassesINTEL,
289 IOPipesINTEL,
290 BlockingPipesINTEL,
291 FPGARegINTEL,
292 AtomicFloat32AddEXT,
293 AtomicFloat64AddEXT,
294 LongConstantCompositeINTEL,
295};
296
297pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
298pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
299pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
300pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
301
302pub const all_features = blk: {
303 @setEvalBranchQuota(2000);
304 const len = @typeInfo(Feature).Enum.fields.len;
305 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
306 var result: [len]CpuFeature = undefined;
307 result[@intFromEnum(Feature.v1_1)] = .{
308 .llvm_name = null,
309 .description = "SPIR-V version 1.1",
310 .dependencies = featureSet(&[_]Feature{}),
311 };
312 result[@intFromEnum(Feature.v1_2)] = .{
313 .llvm_name = null,
314 .description = "SPIR-V version 1.2",
315 .dependencies = featureSet(&[_]Feature{
316 .v1_1,
317 }),
318 };
319 result[@intFromEnum(Feature.v1_3)] = .{
320 .llvm_name = null,
321 .description = "SPIR-V version 1.3",
322 .dependencies = featureSet(&[_]Feature{
323 .v1_2,
324 }),
325 };
326 result[@intFromEnum(Feature.v1_4)] = .{
327 .llvm_name = null,
328 .description = "SPIR-V version 1.4",
329 .dependencies = featureSet(&[_]Feature{
330 .v1_3,
331 }),
332 };
333 result[@intFromEnum(Feature.v1_5)] = .{
334 .llvm_name = null,
335 .description = "SPIR-V version 1.5",
336 .dependencies = featureSet(&[_]Feature{
337 .v1_4,
338 }),
339 };
340 result[@intFromEnum(Feature.SPV_AMD_shader_fragment_mask)] = .{
341 .llvm_name = null,
342 .description = "SPIR-V extension SPV_AMD_shader_fragment_mask",
343 .dependencies = featureSet(&[_]Feature{}),
344 };
345 result[@intFromEnum(Feature.SPV_AMD_gpu_shader_int16)] = .{
346 .llvm_name = null,
347 .description = "SPIR-V extension SPV_AMD_gpu_shader_int16",
348 .dependencies = featureSet(&[_]Feature{}),
349 };
350 result[@intFromEnum(Feature.SPV_AMD_gpu_shader_half_float)] = .{
351 .llvm_name = null,
352 .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float",
353 .dependencies = featureSet(&[_]Feature{}),
354 };
355 result[@intFromEnum(Feature.SPV_AMD_texture_gather_bias_lod)] = .{
356 .llvm_name = null,
357 .description = "SPIR-V extension SPV_AMD_texture_gather_bias_lod",
358 .dependencies = featureSet(&[_]Feature{}),
359 };
360 result[@intFromEnum(Feature.SPV_AMD_shader_ballot)] = .{
361 .llvm_name = null,
362 .description = "SPIR-V extension SPV_AMD_shader_ballot",
363 .dependencies = featureSet(&[_]Feature{}),
364 };
365 result[@intFromEnum(Feature.SPV_AMD_gcn_shader)] = .{
366 .llvm_name = null,
367 .description = "SPIR-V extension SPV_AMD_gcn_shader",
368 .dependencies = featureSet(&[_]Feature{}),
369 };
370 result[@intFromEnum(Feature.SPV_AMD_shader_image_load_store_lod)] = .{
371 .llvm_name = null,
372 .description = "SPIR-V extension SPV_AMD_shader_image_load_store_lod",
373 .dependencies = featureSet(&[_]Feature{}),
374 };
375 result[@intFromEnum(Feature.SPV_AMD_shader_explicit_vertex_parameter)] = .{
376 .llvm_name = null,
377 .description = "SPIR-V extension SPV_AMD_shader_explicit_vertex_parameter",
378 .dependencies = featureSet(&[_]Feature{}),
379 };
380 result[@intFromEnum(Feature.SPV_AMD_shader_trinary_minmax)] = .{
381 .llvm_name = null,
382 .description = "SPIR-V extension SPV_AMD_shader_trinary_minmax",
383 .dependencies = featureSet(&[_]Feature{}),
384 };
385 result[@intFromEnum(Feature.SPV_AMD_gpu_shader_half_float_fetch)] = .{
386 .llvm_name = null,
387 .description = "SPIR-V extension SPV_AMD_gpu_shader_half_float_fetch",
388 .dependencies = featureSet(&[_]Feature{}),
389 };
390 result[@intFromEnum(Feature.SPV_GOOGLE_hlsl_functionality1)] = .{
391 .llvm_name = null,
392 .description = "SPIR-V extension SPV_GOOGLE_hlsl_functionality1",
393 .dependencies = featureSet(&[_]Feature{}),
394 };
395 result[@intFromEnum(Feature.SPV_GOOGLE_user_type)] = .{
396 .llvm_name = null,
397 .description = "SPIR-V extension SPV_GOOGLE_user_type",
398 .dependencies = featureSet(&[_]Feature{}),
399 };
400 result[@intFromEnum(Feature.SPV_GOOGLE_decorate_string)] = .{
401 .llvm_name = null,
402 .description = "SPIR-V extension SPV_GOOGLE_decorate_string",
403 .dependencies = featureSet(&[_]Feature{}),
404 };
405 result[@intFromEnum(Feature.SPV_EXT_demote_to_helper_invocation)] = .{
406 .llvm_name = null,
407 .description = "SPIR-V extension SPV_EXT_demote_to_helper_invocation",
408 .dependencies = featureSet(&[_]Feature{}),
409 };
410 result[@intFromEnum(Feature.SPV_EXT_descriptor_indexing)] = .{
411 .llvm_name = null,
412 .description = "SPIR-V extension SPV_EXT_descriptor_indexing",
413 .dependencies = featureSet(&[_]Feature{}),
414 };
415 result[@intFromEnum(Feature.SPV_EXT_fragment_fully_covered)] = .{
416 .llvm_name = null,
417 .description = "SPIR-V extension SPV_EXT_fragment_fully_covered",
418 .dependencies = featureSet(&[_]Feature{}),
419 };
420 result[@intFromEnum(Feature.SPV_EXT_shader_stencil_export)] = .{
421 .llvm_name = null,
422 .description = "SPIR-V extension SPV_EXT_shader_stencil_export",
423 .dependencies = featureSet(&[_]Feature{}),
424 };
425 result[@intFromEnum(Feature.SPV_EXT_physical_storage_buffer)] = .{
426 .llvm_name = null,
427 .description = "SPIR-V extension SPV_EXT_physical_storage_buffer",
428 .dependencies = featureSet(&[_]Feature{}),
429 };
430 result[@intFromEnum(Feature.SPV_EXT_shader_atomic_float_add)] = .{
431 .llvm_name = null,
432 .description = "SPIR-V extension SPV_EXT_shader_atomic_float_add",
433 .dependencies = featureSet(&[_]Feature{}),
434 };
435 result[@intFromEnum(Feature.SPV_EXT_shader_atomic_float_min_max)] = .{
436 .llvm_name = null,
437 .description = "SPIR-V extension SPV_EXT_shader_atomic_float_min_max",
438 .dependencies = featureSet(&[_]Feature{}),
439 };
440 result[@intFromEnum(Feature.SPV_EXT_shader_image_int64)] = .{
441 .llvm_name = null,
442 .description = "SPIR-V extension SPV_EXT_shader_image_int64",
443 .dependencies = featureSet(&[_]Feature{}),
444 };
445 result[@intFromEnum(Feature.SPV_EXT_fragment_shader_interlock)] = .{
446 .llvm_name = null,
447 .description = "SPIR-V extension SPV_EXT_fragment_shader_interlock",
448 .dependencies = featureSet(&[_]Feature{}),
449 };
450 result[@intFromEnum(Feature.SPV_EXT_fragment_invocation_density)] = .{
451 .llvm_name = null,
452 .description = "SPIR-V extension SPV_EXT_fragment_invocation_density",
453 .dependencies = featureSet(&[_]Feature{}),
454 };
455 result[@intFromEnum(Feature.SPV_EXT_shader_viewport_index_layer)] = .{
456 .llvm_name = null,
457 .description = "SPIR-V extension SPV_EXT_shader_viewport_index_layer",
458 .dependencies = featureSet(&[_]Feature{}),
459 };
460 result[@intFromEnum(Feature.SPV_INTEL_loop_fuse)] = .{
461 .llvm_name = null,
462 .description = "SPIR-V extension SPV_INTEL_loop_fuse",
463 .dependencies = featureSet(&[_]Feature{}),
464 };
465 result[@intFromEnum(Feature.SPV_INTEL_fpga_dsp_control)] = .{
466 .llvm_name = null,
467 .description = "SPIR-V extension SPV_INTEL_fpga_dsp_control",
468 .dependencies = featureSet(&[_]Feature{}),
469 };
470 result[@intFromEnum(Feature.SPV_INTEL_fpga_reg)] = .{
471 .llvm_name = null,
472 .description = "SPIR-V extension SPV_INTEL_fpga_reg",
473 .dependencies = featureSet(&[_]Feature{}),
474 };
475 result[@intFromEnum(Feature.SPV_INTEL_fpga_memory_accesses)] = .{
476 .llvm_name = null,
477 .description = "SPIR-V extension SPV_INTEL_fpga_memory_accesses",
478 .dependencies = featureSet(&[_]Feature{}),
479 };
480 result[@intFromEnum(Feature.SPV_INTEL_fpga_loop_controls)] = .{
481 .llvm_name = null,
482 .description = "SPIR-V extension SPV_INTEL_fpga_loop_controls",
483 .dependencies = featureSet(&[_]Feature{}),
484 };
485 result[@intFromEnum(Feature.SPV_INTEL_io_pipes)] = .{
486 .llvm_name = null,
487 .description = "SPIR-V extension SPV_INTEL_io_pipes",
488 .dependencies = featureSet(&[_]Feature{}),
489 };
490 result[@intFromEnum(Feature.SPV_INTEL_unstructured_loop_controls)] = .{
491 .llvm_name = null,
492 .description = "SPIR-V extension SPV_INTEL_unstructured_loop_controls",
493 .dependencies = featureSet(&[_]Feature{}),
494 };
495 result[@intFromEnum(Feature.SPV_INTEL_blocking_pipes)] = .{
496 .llvm_name = null,
497 .description = "SPIR-V extension SPV_INTEL_blocking_pipes",
498 .dependencies = featureSet(&[_]Feature{}),
499 };
500 result[@intFromEnum(Feature.SPV_INTEL_device_side_avc_motion_estimation)] = .{
501 .llvm_name = null,
502 .description = "SPIR-V extension SPV_INTEL_device_side_avc_motion_estimation",
503 .dependencies = featureSet(&[_]Feature{}),
504 };
505 result[@intFromEnum(Feature.SPV_INTEL_fpga_memory_attributes)] = .{
506 .llvm_name = null,
507 .description = "SPIR-V extension SPV_INTEL_fpga_memory_attributes",
508 .dependencies = featureSet(&[_]Feature{}),
509 };
510 result[@intFromEnum(Feature.SPV_INTEL_fp_fast_math_mode)] = .{
511 .llvm_name = null,
512 .description = "SPIR-V extension SPV_INTEL_fp_fast_math_mode",
513 .dependencies = featureSet(&[_]Feature{}),
514 };
515 result[@intFromEnum(Feature.SPV_INTEL_media_block_io)] = .{
516 .llvm_name = null,
517 .description = "SPIR-V extension SPV_INTEL_media_block_io",
518 .dependencies = featureSet(&[_]Feature{}),
519 };
520 result[@intFromEnum(Feature.SPV_INTEL_shader_integer_functions2)] = .{
521 .llvm_name = null,
522 .description = "SPIR-V extension SPV_INTEL_shader_integer_functions2",
523 .dependencies = featureSet(&[_]Feature{}),
524 };
525 result[@intFromEnum(Feature.SPV_INTEL_subgroups)] = .{
526 .llvm_name = null,
527 .description = "SPIR-V extension SPV_INTEL_subgroups",
528 .dependencies = featureSet(&[_]Feature{}),
529 };
530 result[@intFromEnum(Feature.SPV_INTEL_fpga_cluster_attributes)] = .{
531 .llvm_name = null,
532 .description = "SPIR-V extension SPV_INTEL_fpga_cluster_attributes",
533 .dependencies = featureSet(&[_]Feature{}),
534 };
535 result[@intFromEnum(Feature.SPV_INTEL_kernel_attributes)] = .{
536 .llvm_name = null,
537 .description = "SPIR-V extension SPV_INTEL_kernel_attributes",
538 .dependencies = featureSet(&[_]Feature{}),
539 };
540 result[@intFromEnum(Feature.SPV_INTEL_arbitrary_precision_integers)] = .{
541 .llvm_name = null,
542 .description = "SPIR-V extension SPV_INTEL_arbitrary_precision_integers",
543 .dependencies = featureSet(&[_]Feature{}),
544 };
545 result[@intFromEnum(Feature.SPV_KHR_8bit_storage)] = .{
546 .llvm_name = null,
547 .description = "SPIR-V extension SPV_KHR_8bit_storage",
548 .dependencies = featureSet(&[_]Feature{}),
549 };
550 result[@intFromEnum(Feature.SPV_KHR_shader_clock)] = .{
551 .llvm_name = null,
552 .description = "SPIR-V extension SPV_KHR_shader_clock",
553 .dependencies = featureSet(&[_]Feature{}),
554 };
555 result[@intFromEnum(Feature.SPV_KHR_device_group)] = .{
556 .llvm_name = null,
557 .description = "SPIR-V extension SPV_KHR_device_group",
558 .dependencies = featureSet(&[_]Feature{}),
559 };
560 result[@intFromEnum(Feature.SPV_KHR_16bit_storage)] = .{
561 .llvm_name = null,
562 .description = "SPIR-V extension SPV_KHR_16bit_storage",
563 .dependencies = featureSet(&[_]Feature{}),
564 };
565 result[@intFromEnum(Feature.SPV_KHR_variable_pointers)] = .{
566 .llvm_name = null,
567 .description = "SPIR-V extension SPV_KHR_variable_pointers",
568 .dependencies = featureSet(&[_]Feature{}),
569 };
570 result[@intFromEnum(Feature.SPV_KHR_no_integer_wrap_decoration)] = .{
571 .llvm_name = null,
572 .description = "SPIR-V extension SPV_KHR_no_integer_wrap_decoration",
573 .dependencies = featureSet(&[_]Feature{}),
574 };
575 result[@intFromEnum(Feature.SPV_KHR_subgroup_vote)] = .{
576 .llvm_name = null,
577 .description = "SPIR-V extension SPV_KHR_subgroup_vote",
578 .dependencies = featureSet(&[_]Feature{}),
579 };
580 result[@intFromEnum(Feature.SPV_KHR_multiview)] = .{
581 .llvm_name = null,
582 .description = "SPIR-V extension SPV_KHR_multiview",
583 .dependencies = featureSet(&[_]Feature{}),
584 };
585 result[@intFromEnum(Feature.SPV_KHR_shader_ballot)] = .{
586 .llvm_name = null,
587 .description = "SPIR-V extension SPV_KHR_shader_ballot",
588 .dependencies = featureSet(&[_]Feature{}),
589 };
590 result[@intFromEnum(Feature.SPV_KHR_vulkan_memory_model)] = .{
591 .llvm_name = null,
592 .description = "SPIR-V extension SPV_KHR_vulkan_memory_model",
593 .dependencies = featureSet(&[_]Feature{}),
594 };
595 result[@intFromEnum(Feature.SPV_KHR_physical_storage_buffer)] = .{
596 .llvm_name = null,
597 .description = "SPIR-V extension SPV_KHR_physical_storage_buffer",
598 .dependencies = featureSet(&[_]Feature{}),
599 };
600 result[@intFromEnum(Feature.SPV_KHR_workgroup_memory_explicit_layout)] = .{
601 .llvm_name = null,
602 .description = "SPIR-V extension SPV_KHR_workgroup_memory_explicit_layout",
603 .dependencies = featureSet(&[_]Feature{}),
604 };
605 result[@intFromEnum(Feature.SPV_KHR_fragment_shading_rate)] = .{
606 .llvm_name = null,
607 .description = "SPIR-V extension SPV_KHR_fragment_shading_rate",
608 .dependencies = featureSet(&[_]Feature{}),
609 };
610 result[@intFromEnum(Feature.SPV_KHR_shader_atomic_counter_ops)] = .{
611 .llvm_name = null,
612 .description = "SPIR-V extension SPV_KHR_shader_atomic_counter_ops",
613 .dependencies = featureSet(&[_]Feature{}),
614 };
615 result[@intFromEnum(Feature.SPV_KHR_shader_draw_parameters)] = .{
616 .llvm_name = null,
617 .description = "SPIR-V extension SPV_KHR_shader_draw_parameters",
618 .dependencies = featureSet(&[_]Feature{}),
619 };
620 result[@intFromEnum(Feature.SPV_KHR_storage_buffer_storage_class)] = .{
621 .llvm_name = null,
622 .description = "SPIR-V extension SPV_KHR_storage_buffer_storage_class",
623 .dependencies = featureSet(&[_]Feature{}),
624 };
625 result[@intFromEnum(Feature.SPV_KHR_linkonce_odr)] = .{
626 .llvm_name = null,
627 .description = "SPIR-V extension SPV_KHR_linkonce_odr",
628 .dependencies = featureSet(&[_]Feature{}),
629 };
630 result[@intFromEnum(Feature.SPV_KHR_terminate_invocation)] = .{
631 .llvm_name = null,
632 .description = "SPIR-V extension SPV_KHR_terminate_invocation",
633 .dependencies = featureSet(&[_]Feature{}),
634 };
635 result[@intFromEnum(Feature.SPV_KHR_non_semantic_info)] = .{
636 .llvm_name = null,
637 .description = "SPIR-V extension SPV_KHR_non_semantic_info",
638 .dependencies = featureSet(&[_]Feature{}),
639 };
640 result[@intFromEnum(Feature.SPV_KHR_post_depth_coverage)] = .{
641 .llvm_name = null,
642 .description = "SPIR-V extension SPV_KHR_post_depth_coverage",
643 .dependencies = featureSet(&[_]Feature{}),
644 };
645 result[@intFromEnum(Feature.SPV_KHR_expect_assume)] = .{
646 .llvm_name = null,
647 .description = "SPIR-V extension SPV_KHR_expect_assume",
648 .dependencies = featureSet(&[_]Feature{}),
649 };
650 result[@intFromEnum(Feature.SPV_KHR_ray_tracing)] = .{
651 .llvm_name = null,
652 .description = "SPIR-V extension SPV_KHR_ray_tracing",
653 .dependencies = featureSet(&[_]Feature{}),
654 };
655 result[@intFromEnum(Feature.SPV_KHR_ray_query)] = .{
656 .llvm_name = null,
657 .description = "SPIR-V extension SPV_KHR_ray_query",
658 .dependencies = featureSet(&[_]Feature{}),
659 };
660 result[@intFromEnum(Feature.SPV_KHR_float_controls)] = .{
661 .llvm_name = null,
662 .description = "SPIR-V extension SPV_KHR_float_controls",
663 .dependencies = featureSet(&[_]Feature{}),
664 };
665 result[@intFromEnum(Feature.SPV_NV_viewport_array2)] = .{
666 .llvm_name = null,
667 .description = "SPIR-V extension SPV_NV_viewport_array2",
668 .dependencies = featureSet(&[_]Feature{}),
669 };
670 result[@intFromEnum(Feature.SPV_NV_shader_subgroup_partitioned)] = .{
671 .llvm_name = null,
672 .description = "SPIR-V extension SPV_NV_shader_subgroup_partitioned",
673 .dependencies = featureSet(&[_]Feature{}),
674 };
675 result[@intFromEnum(Feature.SPV_NVX_multiview_per_view_attributes)] = .{
676 .llvm_name = null,
677 .description = "SPIR-V extension SPV_NVX_multiview_per_view_attributes",
678 .dependencies = featureSet(&[_]Feature{}),
679 };
680 result[@intFromEnum(Feature.SPV_NV_ray_tracing)] = .{
681 .llvm_name = null,
682 .description = "SPIR-V extension SPV_NV_ray_tracing",
683 .dependencies = featureSet(&[_]Feature{}),
684 };
685 result[@intFromEnum(Feature.SPV_NV_shader_image_footprint)] = .{
686 .llvm_name = null,
687 .description = "SPIR-V extension SPV_NV_shader_image_footprint",
688 .dependencies = featureSet(&[_]Feature{}),
689 };
690 result[@intFromEnum(Feature.SPV_NV_shading_rate)] = .{
691 .llvm_name = null,
692 .description = "SPIR-V extension SPV_NV_shading_rate",
693 .dependencies = featureSet(&[_]Feature{}),
694 };
695 result[@intFromEnum(Feature.SPV_NV_stereo_view_rendering)] = .{
696 .llvm_name = null,
697 .description = "SPIR-V extension SPV_NV_stereo_view_rendering",
698 .dependencies = featureSet(&[_]Feature{}),
699 };
700 result[@intFromEnum(Feature.SPV_NV_compute_shader_derivatives)] = .{
701 .llvm_name = null,
702 .description = "SPIR-V extension SPV_NV_compute_shader_derivatives",
703 .dependencies = featureSet(&[_]Feature{}),
704 };
705 result[@intFromEnum(Feature.SPV_NV_shader_sm_builtins)] = .{
706 .llvm_name = null,
707 .description = "SPIR-V extension SPV_NV_shader_sm_builtins",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.SPV_NV_mesh_shader)] = .{
711 .llvm_name = null,
712 .description = "SPIR-V extension SPV_NV_mesh_shader",
713 .dependencies = featureSet(&[_]Feature{}),
714 };
715 result[@intFromEnum(Feature.SPV_NV_geometry_shader_passthrough)] = .{
716 .llvm_name = null,
717 .description = "SPIR-V extension SPV_NV_geometry_shader_passthrough",
718 .dependencies = featureSet(&[_]Feature{}),
719 };
720 result[@intFromEnum(Feature.SPV_NV_fragment_shader_barycentric)] = .{
721 .llvm_name = null,
722 .description = "SPIR-V extension SPV_NV_fragment_shader_barycentric",
723 .dependencies = featureSet(&[_]Feature{}),
724 };
725 result[@intFromEnum(Feature.SPV_NV_cooperative_matrix)] = .{
726 .llvm_name = null,
727 .description = "SPIR-V extension SPV_NV_cooperative_matrix",
728 .dependencies = featureSet(&[_]Feature{}),
729 };
730 result[@intFromEnum(Feature.SPV_NV_sample_mask_override_coverage)] = .{
731 .llvm_name = null,
732 .description = "SPIR-V extension SPV_NV_sample_mask_override_coverage",
733 .dependencies = featureSet(&[_]Feature{}),
734 };
735 result[@intFromEnum(Feature.Matrix)] = .{
736 .llvm_name = null,
737 .description = "Enable SPIR-V capability Matrix",
738 .dependencies = featureSet(&[_]Feature{}),
739 };
740 result[@intFromEnum(Feature.Shader)] = .{
741 .llvm_name = null,
742 .description = "Enable SPIR-V capability Shader",
743 .dependencies = featureSet(&[_]Feature{
744 .Matrix,
745 }),
746 };
747 result[@intFromEnum(Feature.Geometry)] = .{
748 .llvm_name = null,
749 .description = "Enable SPIR-V capability Geometry",
750 .dependencies = featureSet(&[_]Feature{
751 .Shader,
752 }),
753 };
754 result[@intFromEnum(Feature.Tessellation)] = .{
755 .llvm_name = null,
756 .description = "Enable SPIR-V capability Tessellation",
757 .dependencies = featureSet(&[_]Feature{
758 .Shader,
759 }),
760 };
761 result[@intFromEnum(Feature.Addresses)] = .{
762 .llvm_name = null,
763 .description = "Enable SPIR-V capability Addresses",
764 .dependencies = featureSet(&[_]Feature{}),
765 };
766 result[@intFromEnum(Feature.Linkage)] = .{
767 .llvm_name = null,
768 .description = "Enable SPIR-V capability Linkage",
769 .dependencies = featureSet(&[_]Feature{}),
770 };
771 result[@intFromEnum(Feature.Kernel)] = .{
772 .llvm_name = null,
773 .description = "Enable SPIR-V capability Kernel",
774 .dependencies = featureSet(&[_]Feature{}),
775 };
776 result[@intFromEnum(Feature.Vector16)] = .{
777 .llvm_name = null,
778 .description = "Enable SPIR-V capability Vector16",
779 .dependencies = featureSet(&[_]Feature{
780 .Kernel,
781 }),
782 };
783 result[@intFromEnum(Feature.Float16Buffer)] = .{
784 .llvm_name = null,
785 .description = "Enable SPIR-V capability Float16Buffer",
786 .dependencies = featureSet(&[_]Feature{
787 .Kernel,
788 }),
789 };
790 result[@intFromEnum(Feature.Float16)] = .{
791 .llvm_name = null,
792 .description = "Enable SPIR-V capability Float16",
793 .dependencies = featureSet(&[_]Feature{}),
794 };
795 result[@intFromEnum(Feature.Float64)] = .{
796 .llvm_name = null,
797 .description = "Enable SPIR-V capability Float64",
798 .dependencies = featureSet(&[_]Feature{}),
799 };
800 result[@intFromEnum(Feature.Int64)] = .{
801 .llvm_name = null,
802 .description = "Enable SPIR-V capability Int64",
803 .dependencies = featureSet(&[_]Feature{}),
804 };
805 result[@intFromEnum(Feature.Int64Atomics)] = .{
806 .llvm_name = null,
807 .description = "Enable SPIR-V capability Int64Atomics",
808 .dependencies = featureSet(&[_]Feature{
809 .Int64,
810 }),
811 };
812 result[@intFromEnum(Feature.ImageBasic)] = .{
813 .llvm_name = null,
814 .description = "Enable SPIR-V capability ImageBasic",
815 .dependencies = featureSet(&[_]Feature{
816 .Kernel,
817 }),
818 };
819 result[@intFromEnum(Feature.ImageReadWrite)] = .{
820 .llvm_name = null,
821 .description = "Enable SPIR-V capability ImageReadWrite",
822 .dependencies = featureSet(&[_]Feature{
823 .ImageBasic,
824 }),
825 };
826 result[@intFromEnum(Feature.ImageMipmap)] = .{
827 .llvm_name = null,
828 .description = "Enable SPIR-V capability ImageMipmap",
829 .dependencies = featureSet(&[_]Feature{
830 .ImageBasic,
831 }),
832 };
833 result[@intFromEnum(Feature.Pipes)] = .{
834 .llvm_name = null,
835 .description = "Enable SPIR-V capability Pipes",
836 .dependencies = featureSet(&[_]Feature{
837 .Kernel,
838 }),
839 };
840 result[@intFromEnum(Feature.Groups)] = .{
841 .llvm_name = null,
842 .description = "Enable SPIR-V capability Groups",
843 .dependencies = featureSet(&[_]Feature{}),
844 };
845 result[@intFromEnum(Feature.DeviceEnqueue)] = .{
846 .llvm_name = null,
847 .description = "Enable SPIR-V capability DeviceEnqueue",
848 .dependencies = featureSet(&[_]Feature{
849 .Kernel,
850 }),
851 };
852 result[@intFromEnum(Feature.LiteralSampler)] = .{
853 .llvm_name = null,
854 .description = "Enable SPIR-V capability LiteralSampler",
855 .dependencies = featureSet(&[_]Feature{
856 .Kernel,
857 }),
858 };
859 result[@intFromEnum(Feature.AtomicStorage)] = .{
860 .llvm_name = null,
861 .description = "Enable SPIR-V capability AtomicStorage",
862 .dependencies = featureSet(&[_]Feature{
863 .Shader,
864 }),
865 };
866 result[@intFromEnum(Feature.Int16)] = .{
867 .llvm_name = null,
868 .description = "Enable SPIR-V capability Int16",
869 .dependencies = featureSet(&[_]Feature{}),
870 };
871 result[@intFromEnum(Feature.TessellationPointSize)] = .{
872 .llvm_name = null,
873 .description = "Enable SPIR-V capability TessellationPointSize",
874 .dependencies = featureSet(&[_]Feature{
875 .Tessellation,
876 }),
877 };
878 result[@intFromEnum(Feature.GeometryPointSize)] = .{
879 .llvm_name = null,
880 .description = "Enable SPIR-V capability GeometryPointSize",
881 .dependencies = featureSet(&[_]Feature{
882 .Geometry,
883 }),
884 };
885 result[@intFromEnum(Feature.ImageGatherExtended)] = .{
886 .llvm_name = null,
887 .description = "Enable SPIR-V capability ImageGatherExtended",
888 .dependencies = featureSet(&[_]Feature{
889 .Shader,
890 }),
891 };
892 result[@intFromEnum(Feature.StorageImageMultisample)] = .{
893 .llvm_name = null,
894 .description = "Enable SPIR-V capability StorageImageMultisample",
895 .dependencies = featureSet(&[_]Feature{
896 .Shader,
897 }),
898 };
899 result[@intFromEnum(Feature.UniformBufferArrayDynamicIndexing)] = .{
900 .llvm_name = null,
901 .description = "Enable SPIR-V capability UniformBufferArrayDynamicIndexing",
902 .dependencies = featureSet(&[_]Feature{
903 .Shader,
904 }),
905 };
906 result[@intFromEnum(Feature.SampledImageArrayDynamicIndexing)] = .{
907 .llvm_name = null,
908 .description = "Enable SPIR-V capability SampledImageArrayDynamicIndexing",
909 .dependencies = featureSet(&[_]Feature{
910 .Shader,
911 }),
912 };
913 result[@intFromEnum(Feature.StorageBufferArrayDynamicIndexing)] = .{
914 .llvm_name = null,
915 .description = "Enable SPIR-V capability StorageBufferArrayDynamicIndexing",
916 .dependencies = featureSet(&[_]Feature{
917 .Shader,
918 }),
919 };
920 result[@intFromEnum(Feature.StorageImageArrayDynamicIndexing)] = .{
921 .llvm_name = null,
922 .description = "Enable SPIR-V capability StorageImageArrayDynamicIndexing",
923 .dependencies = featureSet(&[_]Feature{
924 .Shader,
925 }),
926 };
927 result[@intFromEnum(Feature.ClipDistance)] = .{
928 .llvm_name = null,
929 .description = "Enable SPIR-V capability ClipDistance",
930 .dependencies = featureSet(&[_]Feature{
931 .Shader,
932 }),
933 };
934 result[@intFromEnum(Feature.CullDistance)] = .{
935 .llvm_name = null,
936 .description = "Enable SPIR-V capability CullDistance",
937 .dependencies = featureSet(&[_]Feature{
938 .Shader,
939 }),
940 };
941 result[@intFromEnum(Feature.ImageCubeArray)] = .{
942 .llvm_name = null,
943 .description = "Enable SPIR-V capability ImageCubeArray",
944 .dependencies = featureSet(&[_]Feature{
945 .SampledCubeArray,
946 }),
947 };
948 result[@intFromEnum(Feature.SampleRateShading)] = .{
949 .llvm_name = null,
950 .description = "Enable SPIR-V capability SampleRateShading",
951 .dependencies = featureSet(&[_]Feature{
952 .Shader,
953 }),
954 };
955 result[@intFromEnum(Feature.ImageRect)] = .{
956 .llvm_name = null,
957 .description = "Enable SPIR-V capability ImageRect",
958 .dependencies = featureSet(&[_]Feature{
959 .SampledRect,
960 }),
961 };
962 result[@intFromEnum(Feature.SampledRect)] = .{
963 .llvm_name = null,
964 .description = "Enable SPIR-V capability SampledRect",
965 .dependencies = featureSet(&[_]Feature{
966 .Shader,
967 }),
968 };
969 result[@intFromEnum(Feature.GenericPointer)] = .{
970 .llvm_name = null,
971 .description = "Enable SPIR-V capability GenericPointer",
972 .dependencies = featureSet(&[_]Feature{
973 .Addresses,
974 }),
975 };
976 result[@intFromEnum(Feature.Int8)] = .{
977 .llvm_name = null,
978 .description = "Enable SPIR-V capability Int8",
979 .dependencies = featureSet(&[_]Feature{}),
980 };
981 result[@intFromEnum(Feature.InputAttachment)] = .{
982 .llvm_name = null,
983 .description = "Enable SPIR-V capability InputAttachment",
984 .dependencies = featureSet(&[_]Feature{
985 .Shader,
986 }),
987 };
988 result[@intFromEnum(Feature.SparseResidency)] = .{
989 .llvm_name = null,
990 .description = "Enable SPIR-V capability SparseResidency",
991 .dependencies = featureSet(&[_]Feature{
992 .Shader,
993 }),
994 };
995 result[@intFromEnum(Feature.MinLod)] = .{
996 .llvm_name = null,
997 .description = "Enable SPIR-V capability MinLod",
998 .dependencies = featureSet(&[_]Feature{
999 .Shader,
1000 }),
1001 };
1002 result[@intFromEnum(Feature.Sampled1D)] = .{
1003 .llvm_name = null,
1004 .description = "Enable SPIR-V capability Sampled1D",
1005 .dependencies = featureSet(&[_]Feature{}),
1006 };
1007 result[@intFromEnum(Feature.Image1D)] = .{
1008 .llvm_name = null,
1009 .description = "Enable SPIR-V capability Image1D",
1010 .dependencies = featureSet(&[_]Feature{
1011 .Sampled1D,
1012 }),
1013 };
1014 result[@intFromEnum(Feature.SampledCubeArray)] = .{
1015 .llvm_name = null,
1016 .description = "Enable SPIR-V capability SampledCubeArray",
1017 .dependencies = featureSet(&[_]Feature{
1018 .Shader,
1019 }),
1020 };
1021 result[@intFromEnum(Feature.SampledBuffer)] = .{
1022 .llvm_name = null,
1023 .description = "Enable SPIR-V capability SampledBuffer",
1024 .dependencies = featureSet(&[_]Feature{}),
1025 };
1026 result[@intFromEnum(Feature.ImageBuffer)] = .{
1027 .llvm_name = null,
1028 .description = "Enable SPIR-V capability ImageBuffer",
1029 .dependencies = featureSet(&[_]Feature{
1030 .SampledBuffer,
1031 }),
1032 };
1033 result[@intFromEnum(Feature.ImageMSArray)] = .{
1034 .llvm_name = null,
1035 .description = "Enable SPIR-V capability ImageMSArray",
1036 .dependencies = featureSet(&[_]Feature{
1037 .Shader,
1038 }),
1039 };
1040 result[@intFromEnum(Feature.StorageImageExtendedFormats)] = .{
1041 .llvm_name = null,
1042 .description = "Enable SPIR-V capability StorageImageExtendedFormats",
1043 .dependencies = featureSet(&[_]Feature{
1044 .Shader,
1045 }),
1046 };
1047 result[@intFromEnum(Feature.ImageQuery)] = .{
1048 .llvm_name = null,
1049 .description = "Enable SPIR-V capability ImageQuery",
1050 .dependencies = featureSet(&[_]Feature{
1051 .Shader,
1052 }),
1053 };
1054 result[@intFromEnum(Feature.DerivativeControl)] = .{
1055 .llvm_name = null,
1056 .description = "Enable SPIR-V capability DerivativeControl",
1057 .dependencies = featureSet(&[_]Feature{
1058 .Shader,
1059 }),
1060 };
1061 result[@intFromEnum(Feature.InterpolationFunction)] = .{
1062 .llvm_name = null,
1063 .description = "Enable SPIR-V capability InterpolationFunction",
1064 .dependencies = featureSet(&[_]Feature{
1065 .Shader,
1066 }),
1067 };
1068 result[@intFromEnum(Feature.TransformFeedback)] = .{
1069 .llvm_name = null,
1070 .description = "Enable SPIR-V capability TransformFeedback",
1071 .dependencies = featureSet(&[_]Feature{
1072 .Shader,
1073 }),
1074 };
1075 result[@intFromEnum(Feature.GeometryStreams)] = .{
1076 .llvm_name = null,
1077 .description = "Enable SPIR-V capability GeometryStreams",
1078 .dependencies = featureSet(&[_]Feature{
1079 .Geometry,
1080 }),
1081 };
1082 result[@intFromEnum(Feature.StorageImageReadWithoutFormat)] = .{
1083 .llvm_name = null,
1084 .description = "Enable SPIR-V capability StorageImageReadWithoutFormat",
1085 .dependencies = featureSet(&[_]Feature{
1086 .Shader,
1087 }),
1088 };
1089 result[@intFromEnum(Feature.StorageImageWriteWithoutFormat)] = .{
1090 .llvm_name = null,
1091 .description = "Enable SPIR-V capability StorageImageWriteWithoutFormat",
1092 .dependencies = featureSet(&[_]Feature{
1093 .Shader,
1094 }),
1095 };
1096 result[@intFromEnum(Feature.MultiViewport)] = .{
1097 .llvm_name = null,
1098 .description = "Enable SPIR-V capability MultiViewport",
1099 .dependencies = featureSet(&[_]Feature{
1100 .Geometry,
1101 }),
1102 };
1103 result[@intFromEnum(Feature.SubgroupDispatch)] = .{
1104 .llvm_name = null,
1105 .description = "Enable SPIR-V capability SubgroupDispatch",
1106 .dependencies = featureSet(&[_]Feature{
1107 .v1_1,
1108 .DeviceEnqueue,
1109 }),
1110 };
1111 result[@intFromEnum(Feature.NamedBarrier)] = .{
1112 .llvm_name = null,
1113 .description = "Enable SPIR-V capability NamedBarrier",
1114 .dependencies = featureSet(&[_]Feature{
1115 .v1_1,
1116 .Kernel,
1117 }),
1118 };
1119 result[@intFromEnum(Feature.PipeStorage)] = .{
1120 .llvm_name = null,
1121 .description = "Enable SPIR-V capability PipeStorage",
1122 .dependencies = featureSet(&[_]Feature{
1123 .v1_1,
1124 .Pipes,
1125 }),
1126 };
1127 result[@intFromEnum(Feature.GroupNonUniform)] = .{
1128 .llvm_name = null,
1129 .description = "Enable SPIR-V capability GroupNonUniform",
1130 .dependencies = featureSet(&[_]Feature{
1131 .v1_3,
1132 }),
1133 };
1134 result[@intFromEnum(Feature.GroupNonUniformVote)] = .{
1135 .llvm_name = null,
1136 .description = "Enable SPIR-V capability GroupNonUniformVote",
1137 .dependencies = featureSet(&[_]Feature{
1138 .v1_3,
1139 .GroupNonUniform,
1140 }),
1141 };
1142 result[@intFromEnum(Feature.GroupNonUniformArithmetic)] = .{
1143 .llvm_name = null,
1144 .description = "Enable SPIR-V capability GroupNonUniformArithmetic",
1145 .dependencies = featureSet(&[_]Feature{
1146 .v1_3,
1147 .GroupNonUniform,
1148 }),
1149 };
1150 result[@intFromEnum(Feature.GroupNonUniformBallot)] = .{
1151 .llvm_name = null,
1152 .description = "Enable SPIR-V capability GroupNonUniformBallot",
1153 .dependencies = featureSet(&[_]Feature{
1154 .v1_3,
1155 .GroupNonUniform,
1156 }),
1157 };
1158 result[@intFromEnum(Feature.GroupNonUniformShuffle)] = .{
1159 .llvm_name = null,
1160 .description = "Enable SPIR-V capability GroupNonUniformShuffle",
1161 .dependencies = featureSet(&[_]Feature{
1162 .v1_3,
1163 .GroupNonUniform,
1164 }),
1165 };
1166 result[@intFromEnum(Feature.GroupNonUniformShuffleRelative)] = .{
1167 .llvm_name = null,
1168 .description = "Enable SPIR-V capability GroupNonUniformShuffleRelative",
1169 .dependencies = featureSet(&[_]Feature{
1170 .v1_3,
1171 .GroupNonUniform,
1172 }),
1173 };
1174 result[@intFromEnum(Feature.GroupNonUniformClustered)] = .{
1175 .llvm_name = null,
1176 .description = "Enable SPIR-V capability GroupNonUniformClustered",
1177 .dependencies = featureSet(&[_]Feature{
1178 .v1_3,
1179 .GroupNonUniform,
1180 }),
1181 };
1182 result[@intFromEnum(Feature.GroupNonUniformQuad)] = .{
1183 .llvm_name = null,
1184 .description = "Enable SPIR-V capability GroupNonUniformQuad",
1185 .dependencies = featureSet(&[_]Feature{
1186 .v1_3,
1187 .GroupNonUniform,
1188 }),
1189 };
1190 result[@intFromEnum(Feature.ShaderLayer)] = .{
1191 .llvm_name = null,
1192 .description = "Enable SPIR-V capability ShaderLayer",
1193 .dependencies = featureSet(&[_]Feature{
1194 .v1_5,
1195 }),
1196 };
1197 result[@intFromEnum(Feature.ShaderViewportIndex)] = .{
1198 .llvm_name = null,
1199 .description = "Enable SPIR-V capability ShaderViewportIndex",
1200 .dependencies = featureSet(&[_]Feature{
1201 .v1_5,
1202 }),
1203 };
1204 result[@intFromEnum(Feature.FragmentShadingRateKHR)] = .{
1205 .llvm_name = null,
1206 .description = "Enable SPIR-V capability FragmentShadingRateKHR",
1207 .dependencies = featureSet(&[_]Feature{
1208 .Shader,
1209 }),
1210 };
1211 result[@intFromEnum(Feature.SubgroupBallotKHR)] = .{
1212 .llvm_name = null,
1213 .description = "Enable SPIR-V capability SubgroupBallotKHR",
1214 .dependencies = featureSet(&[_]Feature{}),
1215 };
1216 result[@intFromEnum(Feature.DrawParameters)] = .{
1217 .llvm_name = null,
1218 .description = "Enable SPIR-V capability DrawParameters",
1219 .dependencies = featureSet(&[_]Feature{
1220 .v1_3,
1221 .Shader,
1222 }),
1223 };
1224 result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayoutKHR)] = .{
1225 .llvm_name = null,
1226 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayoutKHR",
1227 .dependencies = featureSet(&[_]Feature{
1228 .Shader,
1229 }),
1230 };
1231 result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayout8BitAccessKHR)] = .{
1232 .llvm_name = null,
1233 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout8BitAccessKHR",
1234 .dependencies = featureSet(&[_]Feature{
1235 .WorkgroupMemoryExplicitLayoutKHR,
1236 }),
1237 };
1238 result[@intFromEnum(Feature.WorkgroupMemoryExplicitLayout16BitAccessKHR)] = .{
1239 .llvm_name = null,
1240 .description = "Enable SPIR-V capability WorkgroupMemoryExplicitLayout16BitAccessKHR",
1241 .dependencies = featureSet(&[_]Feature{
1242 .Shader,
1243 }),
1244 };
1245 result[@intFromEnum(Feature.SubgroupVoteKHR)] = .{
1246 .llvm_name = null,
1247 .description = "Enable SPIR-V capability SubgroupVoteKHR",
1248 .dependencies = featureSet(&[_]Feature{}),
1249 };
1250 result[@intFromEnum(Feature.StorageBuffer16BitAccess)] = .{
1251 .llvm_name = null,
1252 .description = "Enable SPIR-V capability StorageBuffer16BitAccess",
1253 .dependencies = featureSet(&[_]Feature{
1254 .v1_3,
1255 }),
1256 };
1257 result[@intFromEnum(Feature.StorageUniformBufferBlock16)] = .{
1258 .llvm_name = null,
1259 .description = "Enable SPIR-V capability StorageUniformBufferBlock16",
1260 .dependencies = featureSet(&[_]Feature{
1261 .v1_3,
1262 }),
1263 };
1264 result[@intFromEnum(Feature.UniformAndStorageBuffer16BitAccess)] = .{
1265 .llvm_name = null,
1266 .description = "Enable SPIR-V capability UniformAndStorageBuffer16BitAccess",
1267 .dependencies = featureSet(&[_]Feature{
1268 .v1_3,
1269 .StorageBuffer16BitAccess,
1270 .StorageUniformBufferBlock16,
1271 }),
1272 };
1273 result[@intFromEnum(Feature.StorageUniform16)] = .{
1274 .llvm_name = null,
1275 .description = "Enable SPIR-V capability StorageUniform16",
1276 .dependencies = featureSet(&[_]Feature{
1277 .v1_3,
1278 .StorageBuffer16BitAccess,
1279 .StorageUniformBufferBlock16,
1280 }),
1281 };
1282 result[@intFromEnum(Feature.StoragePushConstant16)] = .{
1283 .llvm_name = null,
1284 .description = "Enable SPIR-V capability StoragePushConstant16",
1285 .dependencies = featureSet(&[_]Feature{
1286 .v1_3,
1287 }),
1288 };
1289 result[@intFromEnum(Feature.StorageInputOutput16)] = .{
1290 .llvm_name = null,
1291 .description = "Enable SPIR-V capability StorageInputOutput16",
1292 .dependencies = featureSet(&[_]Feature{
1293 .v1_3,
1294 }),
1295 };
1296 result[@intFromEnum(Feature.DeviceGroup)] = .{
1297 .llvm_name = null,
1298 .description = "Enable SPIR-V capability DeviceGroup",
1299 .dependencies = featureSet(&[_]Feature{
1300 .v1_3,
1301 }),
1302 };
1303 result[@intFromEnum(Feature.MultiView)] = .{
1304 .llvm_name = null,
1305 .description = "Enable SPIR-V capability MultiView",
1306 .dependencies = featureSet(&[_]Feature{
1307 .v1_3,
1308 .Shader,
1309 }),
1310 };
1311 result[@intFromEnum(Feature.VariablePointersStorageBuffer)] = .{
1312 .llvm_name = null,
1313 .description = "Enable SPIR-V capability VariablePointersStorageBuffer",
1314 .dependencies = featureSet(&[_]Feature{
1315 .v1_3,
1316 .Shader,
1317 }),
1318 };
1319 result[@intFromEnum(Feature.VariablePointers)] = .{
1320 .llvm_name = null,
1321 .description = "Enable SPIR-V capability VariablePointers",
1322 .dependencies = featureSet(&[_]Feature{
1323 .v1_3,
1324 .VariablePointersStorageBuffer,
1325 }),
1326 };
1327 result[@intFromEnum(Feature.AtomicStorageOps)] = .{
1328 .llvm_name = null,
1329 .description = "Enable SPIR-V capability AtomicStorageOps",
1330 .dependencies = featureSet(&[_]Feature{}),
1331 };
1332 result[@intFromEnum(Feature.SampleMaskPostDepthCoverage)] = .{
1333 .llvm_name = null,
1334 .description = "Enable SPIR-V capability SampleMaskPostDepthCoverage",
1335 .dependencies = featureSet(&[_]Feature{}),
1336 };
1337 result[@intFromEnum(Feature.StorageBuffer8BitAccess)] = .{
1338 .llvm_name = null,
1339 .description = "Enable SPIR-V capability StorageBuffer8BitAccess",
1340 .dependencies = featureSet(&[_]Feature{
1341 .v1_5,
1342 }),
1343 };
1344 result[@intFromEnum(Feature.UniformAndStorageBuffer8BitAccess)] = .{
1345 .llvm_name = null,
1346 .description = "Enable SPIR-V capability UniformAndStorageBuffer8BitAccess",
1347 .dependencies = featureSet(&[_]Feature{
1348 .v1_5,
1349 .StorageBuffer8BitAccess,
1350 }),
1351 };
1352 result[@intFromEnum(Feature.StoragePushConstant8)] = .{
1353 .llvm_name = null,
1354 .description = "Enable SPIR-V capability StoragePushConstant8",
1355 .dependencies = featureSet(&[_]Feature{
1356 .v1_5,
1357 }),
1358 };
1359 result[@intFromEnum(Feature.DenormPreserve)] = .{
1360 .llvm_name = null,
1361 .description = "Enable SPIR-V capability DenormPreserve",
1362 .dependencies = featureSet(&[_]Feature{
1363 .v1_4,
1364 }),
1365 };
1366 result[@intFromEnum(Feature.DenormFlushToZero)] = .{
1367 .llvm_name = null,
1368 .description = "Enable SPIR-V capability DenormFlushToZero",
1369 .dependencies = featureSet(&[_]Feature{
1370 .v1_4,
1371 }),
1372 };
1373 result[@intFromEnum(Feature.SignedZeroInfNanPreserve)] = .{
1374 .llvm_name = null,
1375 .description = "Enable SPIR-V capability SignedZeroInfNanPreserve",
1376 .dependencies = featureSet(&[_]Feature{
1377 .v1_4,
1378 }),
1379 };
1380 result[@intFromEnum(Feature.RoundingModeRTE)] = .{
1381 .llvm_name = null,
1382 .description = "Enable SPIR-V capability RoundingModeRTE",
1383 .dependencies = featureSet(&[_]Feature{
1384 .v1_4,
1385 }),
1386 };
1387 result[@intFromEnum(Feature.RoundingModeRTZ)] = .{
1388 .llvm_name = null,
1389 .description = "Enable SPIR-V capability RoundingModeRTZ",
1390 .dependencies = featureSet(&[_]Feature{
1391 .v1_4,
1392 }),
1393 };
1394 result[@intFromEnum(Feature.RayQueryProvisionalKHR)] = .{
1395 .llvm_name = null,
1396 .description = "Enable SPIR-V capability RayQueryProvisionalKHR",
1397 .dependencies = featureSet(&[_]Feature{
1398 .Shader,
1399 }),
1400 };
1401 result[@intFromEnum(Feature.RayQueryKHR)] = .{
1402 .llvm_name = null,
1403 .description = "Enable SPIR-V capability RayQueryKHR",
1404 .dependencies = featureSet(&[_]Feature{
1405 .Shader,
1406 }),
1407 };
1408 result[@intFromEnum(Feature.RayTraversalPrimitiveCullingKHR)] = .{
1409 .llvm_name = null,
1410 .description = "Enable SPIR-V capability RayTraversalPrimitiveCullingKHR",
1411 .dependencies = featureSet(&[_]Feature{
1412 .RayQueryKHR,
1413 .RayTracingKHR,
1414 }),
1415 };
1416 result[@intFromEnum(Feature.RayTracingKHR)] = .{
1417 .llvm_name = null,
1418 .description = "Enable SPIR-V capability RayTracingKHR",
1419 .dependencies = featureSet(&[_]Feature{
1420 .Shader,
1421 }),
1422 };
1423 result[@intFromEnum(Feature.Float16ImageAMD)] = .{
1424 .llvm_name = null,
1425 .description = "Enable SPIR-V capability Float16ImageAMD",
1426 .dependencies = featureSet(&[_]Feature{
1427 .Shader,
1428 }),
1429 };
1430 result[@intFromEnum(Feature.ImageGatherBiasLodAMD)] = .{
1431 .llvm_name = null,
1432 .description = "Enable SPIR-V capability ImageGatherBiasLodAMD",
1433 .dependencies = featureSet(&[_]Feature{
1434 .Shader,
1435 }),
1436 };
1437 result[@intFromEnum(Feature.FragmentMaskAMD)] = .{
1438 .llvm_name = null,
1439 .description = "Enable SPIR-V capability FragmentMaskAMD",
1440 .dependencies = featureSet(&[_]Feature{
1441 .Shader,
1442 }),
1443 };
1444 result[@intFromEnum(Feature.StencilExportEXT)] = .{
1445 .llvm_name = null,
1446 .description = "Enable SPIR-V capability StencilExportEXT",
1447 .dependencies = featureSet(&[_]Feature{
1448 .Shader,
1449 }),
1450 };
1451 result[@intFromEnum(Feature.ImageReadWriteLodAMD)] = .{
1452 .llvm_name = null,
1453 .description = "Enable SPIR-V capability ImageReadWriteLodAMD",
1454 .dependencies = featureSet(&[_]Feature{
1455 .Shader,
1456 }),
1457 };
1458 result[@intFromEnum(Feature.Int64ImageEXT)] = .{
1459 .llvm_name = null,
1460 .description = "Enable SPIR-V capability Int64ImageEXT",
1461 .dependencies = featureSet(&[_]Feature{
1462 .Shader,
1463 }),
1464 };
1465 result[@intFromEnum(Feature.ShaderClockKHR)] = .{
1466 .llvm_name = null,
1467 .description = "Enable SPIR-V capability ShaderClockKHR",
1468 .dependencies = featureSet(&[_]Feature{
1469 .Shader,
1470 }),
1471 };
1472 result[@intFromEnum(Feature.SampleMaskOverrideCoverageNV)] = .{
1473 .llvm_name = null,
1474 .description = "Enable SPIR-V capability SampleMaskOverrideCoverageNV",
1475 .dependencies = featureSet(&[_]Feature{
1476 .SampleRateShading,
1477 }),
1478 };
1479 result[@intFromEnum(Feature.GeometryShaderPassthroughNV)] = .{
1480 .llvm_name = null,
1481 .description = "Enable SPIR-V capability GeometryShaderPassthroughNV",
1482 .dependencies = featureSet(&[_]Feature{
1483 .Geometry,
1484 }),
1485 };
1486 result[@intFromEnum(Feature.ShaderViewportIndexLayerEXT)] = .{
1487 .llvm_name = null,
1488 .description = "Enable SPIR-V capability ShaderViewportIndexLayerEXT",
1489 .dependencies = featureSet(&[_]Feature{
1490 .MultiViewport,
1491 }),
1492 };
1493 result[@intFromEnum(Feature.ShaderViewportIndexLayerNV)] = .{
1494 .llvm_name = null,
1495 .description = "Enable SPIR-V capability ShaderViewportIndexLayerNV",
1496 .dependencies = featureSet(&[_]Feature{
1497 .MultiViewport,
1498 }),
1499 };
1500 result[@intFromEnum(Feature.ShaderViewportMaskNV)] = .{
1501 .llvm_name = null,
1502 .description = "Enable SPIR-V capability ShaderViewportMaskNV",
1503 .dependencies = featureSet(&[_]Feature{
1504 .ShaderViewportIndexLayerNV,
1505 }),
1506 };
1507 result[@intFromEnum(Feature.ShaderStereoViewNV)] = .{
1508 .llvm_name = null,
1509 .description = "Enable SPIR-V capability ShaderStereoViewNV",
1510 .dependencies = featureSet(&[_]Feature{
1511 .ShaderViewportMaskNV,
1512 }),
1513 };
1514 result[@intFromEnum(Feature.PerViewAttributesNV)] = .{
1515 .llvm_name = null,
1516 .description = "Enable SPIR-V capability PerViewAttributesNV",
1517 .dependencies = featureSet(&[_]Feature{
1518 .MultiView,
1519 }),
1520 };
1521 result[@intFromEnum(Feature.FragmentFullyCoveredEXT)] = .{
1522 .llvm_name = null,
1523 .description = "Enable SPIR-V capability FragmentFullyCoveredEXT",
1524 .dependencies = featureSet(&[_]Feature{
1525 .Shader,
1526 }),
1527 };
1528 result[@intFromEnum(Feature.MeshShadingNV)] = .{
1529 .llvm_name = null,
1530 .description = "Enable SPIR-V capability MeshShadingNV",
1531 .dependencies = featureSet(&[_]Feature{
1532 .Shader,
1533 }),
1534 };
1535 result[@intFromEnum(Feature.ImageFootprintNV)] = .{
1536 .llvm_name = null,
1537 .description = "Enable SPIR-V capability ImageFootprintNV",
1538 .dependencies = featureSet(&[_]Feature{}),
1539 };
1540 result[@intFromEnum(Feature.FragmentBarycentricNV)] = .{
1541 .llvm_name = null,
1542 .description = "Enable SPIR-V capability FragmentBarycentricNV",
1543 .dependencies = featureSet(&[_]Feature{}),
1544 };
1545 result[@intFromEnum(Feature.ComputeDerivativeGroupQuadsNV)] = .{
1546 .llvm_name = null,
1547 .description = "Enable SPIR-V capability ComputeDerivativeGroupQuadsNV",
1548 .dependencies = featureSet(&[_]Feature{}),
1549 };
1550 result[@intFromEnum(Feature.FragmentDensityEXT)] = .{
1551 .llvm_name = null,
1552 .description = "Enable SPIR-V capability FragmentDensityEXT",
1553 .dependencies = featureSet(&[_]Feature{
1554 .Shader,
1555 }),
1556 };
1557 result[@intFromEnum(Feature.ShadingRateNV)] = .{
1558 .llvm_name = null,
1559 .description = "Enable SPIR-V capability ShadingRateNV",
1560 .dependencies = featureSet(&[_]Feature{
1561 .Shader,
1562 }),
1563 };
1564 result[@intFromEnum(Feature.GroupNonUniformPartitionedNV)] = .{
1565 .llvm_name = null,
1566 .description = "Enable SPIR-V capability GroupNonUniformPartitionedNV",
1567 .dependencies = featureSet(&[_]Feature{}),
1568 };
1569 result[@intFromEnum(Feature.ShaderNonUniform)] = .{
1570 .llvm_name = null,
1571 .description = "Enable SPIR-V capability ShaderNonUniform",
1572 .dependencies = featureSet(&[_]Feature{
1573 .v1_5,
1574 .Shader,
1575 }),
1576 };
1577 result[@intFromEnum(Feature.ShaderNonUniformEXT)] = .{
1578 .llvm_name = null,
1579 .description = "Enable SPIR-V capability ShaderNonUniformEXT",
1580 .dependencies = featureSet(&[_]Feature{
1581 .v1_5,
1582 .Shader,
1583 }),
1584 };
1585 result[@intFromEnum(Feature.RuntimeDescriptorArray)] = .{
1586 .llvm_name = null,
1587 .description = "Enable SPIR-V capability RuntimeDescriptorArray",
1588 .dependencies = featureSet(&[_]Feature{
1589 .v1_5,
1590 .Shader,
1591 }),
1592 };
1593 result[@intFromEnum(Feature.RuntimeDescriptorArrayEXT)] = .{
1594 .llvm_name = null,
1595 .description = "Enable SPIR-V capability RuntimeDescriptorArrayEXT",
1596 .dependencies = featureSet(&[_]Feature{
1597 .v1_5,
1598 .Shader,
1599 }),
1600 };
1601 result[@intFromEnum(Feature.InputAttachmentArrayDynamicIndexing)] = .{
1602 .llvm_name = null,
1603 .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexing",
1604 .dependencies = featureSet(&[_]Feature{
1605 .v1_5,
1606 .InputAttachment,
1607 }),
1608 };
1609 result[@intFromEnum(Feature.InputAttachmentArrayDynamicIndexingEXT)] = .{
1610 .llvm_name = null,
1611 .description = "Enable SPIR-V capability InputAttachmentArrayDynamicIndexingEXT",
1612 .dependencies = featureSet(&[_]Feature{
1613 .v1_5,
1614 .InputAttachment,
1615 }),
1616 };
1617 result[@intFromEnum(Feature.UniformTexelBufferArrayDynamicIndexing)] = .{
1618 .llvm_name = null,
1619 .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexing",
1620 .dependencies = featureSet(&[_]Feature{
1621 .v1_5,
1622 .SampledBuffer,
1623 }),
1624 };
1625 result[@intFromEnum(Feature.UniformTexelBufferArrayDynamicIndexingEXT)] = .{
1626 .llvm_name = null,
1627 .description = "Enable SPIR-V capability UniformTexelBufferArrayDynamicIndexingEXT",
1628 .dependencies = featureSet(&[_]Feature{
1629 .v1_5,
1630 .SampledBuffer,
1631 }),
1632 };
1633 result[@intFromEnum(Feature.StorageTexelBufferArrayDynamicIndexing)] = .{
1634 .llvm_name = null,
1635 .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexing",
1636 .dependencies = featureSet(&[_]Feature{
1637 .v1_5,
1638 .ImageBuffer,
1639 }),
1640 };
1641 result[@intFromEnum(Feature.StorageTexelBufferArrayDynamicIndexingEXT)] = .{
1642 .llvm_name = null,
1643 .description = "Enable SPIR-V capability StorageTexelBufferArrayDynamicIndexingEXT",
1644 .dependencies = featureSet(&[_]Feature{
1645 .v1_5,
1646 .ImageBuffer,
1647 }),
1648 };
1649 result[@intFromEnum(Feature.UniformBufferArrayNonUniformIndexing)] = .{
1650 .llvm_name = null,
1651 .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexing",
1652 .dependencies = featureSet(&[_]Feature{
1653 .v1_5,
1654 .ShaderNonUniform,
1655 }),
1656 };
1657 result[@intFromEnum(Feature.UniformBufferArrayNonUniformIndexingEXT)] = .{
1658 .llvm_name = null,
1659 .description = "Enable SPIR-V capability UniformBufferArrayNonUniformIndexingEXT",
1660 .dependencies = featureSet(&[_]Feature{
1661 .v1_5,
1662 .ShaderNonUniform,
1663 }),
1664 };
1665 result[@intFromEnum(Feature.SampledImageArrayNonUniformIndexing)] = .{
1666 .llvm_name = null,
1667 .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexing",
1668 .dependencies = featureSet(&[_]Feature{
1669 .v1_5,
1670 .ShaderNonUniform,
1671 }),
1672 };
1673 result[@intFromEnum(Feature.SampledImageArrayNonUniformIndexingEXT)] = .{
1674 .llvm_name = null,
1675 .description = "Enable SPIR-V capability SampledImageArrayNonUniformIndexingEXT",
1676 .dependencies = featureSet(&[_]Feature{
1677 .v1_5,
1678 .ShaderNonUniform,
1679 }),
1680 };
1681 result[@intFromEnum(Feature.StorageBufferArrayNonUniformIndexing)] = .{
1682 .llvm_name = null,
1683 .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexing",
1684 .dependencies = featureSet(&[_]Feature{
1685 .v1_5,
1686 .ShaderNonUniform,
1687 }),
1688 };
1689 result[@intFromEnum(Feature.StorageBufferArrayNonUniformIndexingEXT)] = .{
1690 .llvm_name = null,
1691 .description = "Enable SPIR-V capability StorageBufferArrayNonUniformIndexingEXT",
1692 .dependencies = featureSet(&[_]Feature{
1693 .v1_5,
1694 .ShaderNonUniform,
1695 }),
1696 };
1697 result[@intFromEnum(Feature.StorageImageArrayNonUniformIndexing)] = .{
1698 .llvm_name = null,
1699 .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexing",
1700 .dependencies = featureSet(&[_]Feature{
1701 .v1_5,
1702 .ShaderNonUniform,
1703 }),
1704 };
1705 result[@intFromEnum(Feature.StorageImageArrayNonUniformIndexingEXT)] = .{
1706 .llvm_name = null,
1707 .description = "Enable SPIR-V capability StorageImageArrayNonUniformIndexingEXT",
1708 .dependencies = featureSet(&[_]Feature{
1709 .v1_5,
1710 .ShaderNonUniform,
1711 }),
1712 };
1713 result[@intFromEnum(Feature.InputAttachmentArrayNonUniformIndexing)] = .{
1714 .llvm_name = null,
1715 .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexing",
1716 .dependencies = featureSet(&[_]Feature{
1717 .v1_5,
1718 .InputAttachment,
1719 .ShaderNonUniform,
1720 }),
1721 };
1722 result[@intFromEnum(Feature.InputAttachmentArrayNonUniformIndexingEXT)] = .{
1723 .llvm_name = null,
1724 .description = "Enable SPIR-V capability InputAttachmentArrayNonUniformIndexingEXT",
1725 .dependencies = featureSet(&[_]Feature{
1726 .v1_5,
1727 .InputAttachment,
1728 .ShaderNonUniform,
1729 }),
1730 };
1731 result[@intFromEnum(Feature.UniformTexelBufferArrayNonUniformIndexing)] = .{
1732 .llvm_name = null,
1733 .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexing",
1734 .dependencies = featureSet(&[_]Feature{
1735 .v1_5,
1736 .SampledBuffer,
1737 .ShaderNonUniform,
1738 }),
1739 };
1740 result[@intFromEnum(Feature.UniformTexelBufferArrayNonUniformIndexingEXT)] = .{
1741 .llvm_name = null,
1742 .description = "Enable SPIR-V capability UniformTexelBufferArrayNonUniformIndexingEXT",
1743 .dependencies = featureSet(&[_]Feature{
1744 .v1_5,
1745 .SampledBuffer,
1746 .ShaderNonUniform,
1747 }),
1748 };
1749 result[@intFromEnum(Feature.StorageTexelBufferArrayNonUniformIndexing)] = .{
1750 .llvm_name = null,
1751 .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexing",
1752 .dependencies = featureSet(&[_]Feature{
1753 .v1_5,
1754 .ImageBuffer,
1755 .ShaderNonUniform,
1756 }),
1757 };
1758 result[@intFromEnum(Feature.StorageTexelBufferArrayNonUniformIndexingEXT)] = .{
1759 .llvm_name = null,
1760 .description = "Enable SPIR-V capability StorageTexelBufferArrayNonUniformIndexingEXT",
1761 .dependencies = featureSet(&[_]Feature{
1762 .v1_5,
1763 .ImageBuffer,
1764 .ShaderNonUniform,
1765 }),
1766 };
1767 result[@intFromEnum(Feature.RayTracingNV)] = .{
1768 .llvm_name = null,
1769 .description = "Enable SPIR-V capability RayTracingNV",
1770 .dependencies = featureSet(&[_]Feature{
1771 .Shader,
1772 }),
1773 };
1774 result[@intFromEnum(Feature.VulkanMemoryModel)] = .{
1775 .llvm_name = null,
1776 .description = "Enable SPIR-V capability VulkanMemoryModel",
1777 .dependencies = featureSet(&[_]Feature{
1778 .v1_5,
1779 }),
1780 };
1781 result[@intFromEnum(Feature.VulkanMemoryModelKHR)] = .{
1782 .llvm_name = null,
1783 .description = "Enable SPIR-V capability VulkanMemoryModelKHR",
1784 .dependencies = featureSet(&[_]Feature{
1785 .v1_5,
1786 }),
1787 };
1788 result[@intFromEnum(Feature.VulkanMemoryModelDeviceScope)] = .{
1789 .llvm_name = null,
1790 .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScope",
1791 .dependencies = featureSet(&[_]Feature{
1792 .v1_5,
1793 }),
1794 };
1795 result[@intFromEnum(Feature.VulkanMemoryModelDeviceScopeKHR)] = .{
1796 .llvm_name = null,
1797 .description = "Enable SPIR-V capability VulkanMemoryModelDeviceScopeKHR",
1798 .dependencies = featureSet(&[_]Feature{
1799 .v1_5,
1800 }),
1801 };
1802 result[@intFromEnum(Feature.PhysicalStorageBufferAddresses)] = .{
1803 .llvm_name = null,
1804 .description = "Enable SPIR-V capability PhysicalStorageBufferAddresses",
1805 .dependencies = featureSet(&[_]Feature{
1806 .v1_5,
1807 .Shader,
1808 }),
1809 };
1810 result[@intFromEnum(Feature.PhysicalStorageBufferAddressesEXT)] = .{
1811 .llvm_name = null,
1812 .description = "Enable SPIR-V capability PhysicalStorageBufferAddressesEXT",
1813 .dependencies = featureSet(&[_]Feature{
1814 .v1_5,
1815 .Shader,
1816 }),
1817 };
1818 result[@intFromEnum(Feature.ComputeDerivativeGroupLinearNV)] = .{
1819 .llvm_name = null,
1820 .description = "Enable SPIR-V capability ComputeDerivativeGroupLinearNV",
1821 .dependencies = featureSet(&[_]Feature{}),
1822 };
1823 result[@intFromEnum(Feature.RayTracingProvisionalKHR)] = .{
1824 .llvm_name = null,
1825 .description = "Enable SPIR-V capability RayTracingProvisionalKHR",
1826 .dependencies = featureSet(&[_]Feature{
1827 .Shader,
1828 }),
1829 };
1830 result[@intFromEnum(Feature.CooperativeMatrixNV)] = .{
1831 .llvm_name = null,
1832 .description = "Enable SPIR-V capability CooperativeMatrixNV",
1833 .dependencies = featureSet(&[_]Feature{
1834 .Shader,
1835 }),
1836 };
1837 result[@intFromEnum(Feature.FragmentShaderSampleInterlockEXT)] = .{
1838 .llvm_name = null,
1839 .description = "Enable SPIR-V capability FragmentShaderSampleInterlockEXT",
1840 .dependencies = featureSet(&[_]Feature{
1841 .Shader,
1842 }),
1843 };
1844 result[@intFromEnum(Feature.FragmentShaderShadingRateInterlockEXT)] = .{
1845 .llvm_name = null,
1846 .description = "Enable SPIR-V capability FragmentShaderShadingRateInterlockEXT",
1847 .dependencies = featureSet(&[_]Feature{
1848 .Shader,
1849 }),
1850 };
1851 result[@intFromEnum(Feature.ShaderSMBuiltinsNV)] = .{
1852 .llvm_name = null,
1853 .description = "Enable SPIR-V capability ShaderSMBuiltinsNV",
1854 .dependencies = featureSet(&[_]Feature{
1855 .Shader,
1856 }),
1857 };
1858 result[@intFromEnum(Feature.FragmentShaderPixelInterlockEXT)] = .{
1859 .llvm_name = null,
1860 .description = "Enable SPIR-V capability FragmentShaderPixelInterlockEXT",
1861 .dependencies = featureSet(&[_]Feature{
1862 .Shader,
1863 }),
1864 };
1865 result[@intFromEnum(Feature.DemoteToHelperInvocationEXT)] = .{
1866 .llvm_name = null,
1867 .description = "Enable SPIR-V capability DemoteToHelperInvocationEXT",
1868 .dependencies = featureSet(&[_]Feature{
1869 .Shader,
1870 }),
1871 };
1872 result[@intFromEnum(Feature.SubgroupShuffleINTEL)] = .{
1873 .llvm_name = null,
1874 .description = "Enable SPIR-V capability SubgroupShuffleINTEL",
1875 .dependencies = featureSet(&[_]Feature{}),
1876 };
1877 result[@intFromEnum(Feature.SubgroupBufferBlockIOINTEL)] = .{
1878 .llvm_name = null,
1879 .description = "Enable SPIR-V capability SubgroupBufferBlockIOINTEL",
1880 .dependencies = featureSet(&[_]Feature{}),
1881 };
1882 result[@intFromEnum(Feature.SubgroupImageBlockIOINTEL)] = .{
1883 .llvm_name = null,
1884 .description = "Enable SPIR-V capability SubgroupImageBlockIOINTEL",
1885 .dependencies = featureSet(&[_]Feature{}),
1886 };
1887 result[@intFromEnum(Feature.SubgroupImageMediaBlockIOINTEL)] = .{
1888 .llvm_name = null,
1889 .description = "Enable SPIR-V capability SubgroupImageMediaBlockIOINTEL",
1890 .dependencies = featureSet(&[_]Feature{}),
1891 };
1892 result[@intFromEnum(Feature.RoundToInfinityINTEL)] = .{
1893 .llvm_name = null,
1894 .description = "Enable SPIR-V capability RoundToInfinityINTEL",
1895 .dependencies = featureSet(&[_]Feature{}),
1896 };
1897 result[@intFromEnum(Feature.FloatingPointModeINTEL)] = .{
1898 .llvm_name = null,
1899 .description = "Enable SPIR-V capability FloatingPointModeINTEL",
1900 .dependencies = featureSet(&[_]Feature{}),
1901 };
1902 result[@intFromEnum(Feature.IntegerFunctions2INTEL)] = .{
1903 .llvm_name = null,
1904 .description = "Enable SPIR-V capability IntegerFunctions2INTEL",
1905 .dependencies = featureSet(&[_]Feature{
1906 .Shader,
1907 }),
1908 };
1909 result[@intFromEnum(Feature.FunctionPointersINTEL)] = .{
1910 .llvm_name = null,
1911 .description = "Enable SPIR-V capability FunctionPointersINTEL",
1912 .dependencies = featureSet(&[_]Feature{}),
1913 };
1914 result[@intFromEnum(Feature.IndirectReferencesINTEL)] = .{
1915 .llvm_name = null,
1916 .description = "Enable SPIR-V capability IndirectReferencesINTEL",
1917 .dependencies = featureSet(&[_]Feature{}),
1918 };
1919 result[@intFromEnum(Feature.AsmINTEL)] = .{
1920 .llvm_name = null,
1921 .description = "Enable SPIR-V capability AsmINTEL",
1922 .dependencies = featureSet(&[_]Feature{}),
1923 };
1924 result[@intFromEnum(Feature.AtomicFloat32MinMaxEXT)] = .{
1925 .llvm_name = null,
1926 .description = "Enable SPIR-V capability AtomicFloat32MinMaxEXT",
1927 .dependencies = featureSet(&[_]Feature{}),
1928 };
1929 result[@intFromEnum(Feature.AtomicFloat64MinMaxEXT)] = .{
1930 .llvm_name = null,
1931 .description = "Enable SPIR-V capability AtomicFloat64MinMaxEXT",
1932 .dependencies = featureSet(&[_]Feature{}),
1933 };
1934 result[@intFromEnum(Feature.AtomicFloat16MinMaxEXT)] = .{
1935 .llvm_name = null,
1936 .description = "Enable SPIR-V capability AtomicFloat16MinMaxEXT",
1937 .dependencies = featureSet(&[_]Feature{}),
1938 };
1939 result[@intFromEnum(Feature.VectorComputeINTEL)] = .{
1940 .llvm_name = null,
1941 .description = "Enable SPIR-V capability VectorComputeINTEL",
1942 .dependencies = featureSet(&[_]Feature{
1943 .VectorAnyINTEL,
1944 }),
1945 };
1946 result[@intFromEnum(Feature.VectorAnyINTEL)] = .{
1947 .llvm_name = null,
1948 .description = "Enable SPIR-V capability VectorAnyINTEL",
1949 .dependencies = featureSet(&[_]Feature{}),
1950 };
1951 result[@intFromEnum(Feature.ExpectAssumeKHR)] = .{
1952 .llvm_name = null,
1953 .description = "Enable SPIR-V capability ExpectAssumeKHR",
1954 .dependencies = featureSet(&[_]Feature{}),
1955 };
1956 result[@intFromEnum(Feature.SubgroupAvcMotionEstimationINTEL)] = .{
1957 .llvm_name = null,
1958 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationINTEL",
1959 .dependencies = featureSet(&[_]Feature{}),
1960 };
1961 result[@intFromEnum(Feature.SubgroupAvcMotionEstimationIntraINTEL)] = .{
1962 .llvm_name = null,
1963 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationIntraINTEL",
1964 .dependencies = featureSet(&[_]Feature{}),
1965 };
1966 result[@intFromEnum(Feature.SubgroupAvcMotionEstimationChromaINTEL)] = .{
1967 .llvm_name = null,
1968 .description = "Enable SPIR-V capability SubgroupAvcMotionEstimationChromaINTEL",
1969 .dependencies = featureSet(&[_]Feature{}),
1970 };
1971 result[@intFromEnum(Feature.VariableLengthArrayINTEL)] = .{
1972 .llvm_name = null,
1973 .description = "Enable SPIR-V capability VariableLengthArrayINTEL",
1974 .dependencies = featureSet(&[_]Feature{}),
1975 };
1976 result[@intFromEnum(Feature.FunctionFloatControlINTEL)] = .{
1977 .llvm_name = null,
1978 .description = "Enable SPIR-V capability FunctionFloatControlINTEL",
1979 .dependencies = featureSet(&[_]Feature{}),
1980 };
1981 result[@intFromEnum(Feature.FPGAMemoryAttributesINTEL)] = .{
1982 .llvm_name = null,
1983 .description = "Enable SPIR-V capability FPGAMemoryAttributesINTEL",
1984 .dependencies = featureSet(&[_]Feature{}),
1985 };
1986 result[@intFromEnum(Feature.FPFastMathModeINTEL)] = .{
1987 .llvm_name = null,
1988 .description = "Enable SPIR-V capability FPFastMathModeINTEL",
1989 .dependencies = featureSet(&[_]Feature{
1990 .Kernel,
1991 }),
1992 };
1993 result[@intFromEnum(Feature.ArbitraryPrecisionIntegersINTEL)] = .{
1994 .llvm_name = null,
1995 .description = "Enable SPIR-V capability ArbitraryPrecisionIntegersINTEL",
1996 .dependencies = featureSet(&[_]Feature{}),
1997 };
1998 result[@intFromEnum(Feature.UnstructuredLoopControlsINTEL)] = .{
1999 .llvm_name = null,
2000 .description = "Enable SPIR-V capability UnstructuredLoopControlsINTEL",
2001 .dependencies = featureSet(&[_]Feature{}),
2002 };
2003 result[@intFromEnum(Feature.FPGALoopControlsINTEL)] = .{
2004 .llvm_name = null,
2005 .description = "Enable SPIR-V capability FPGALoopControlsINTEL",
2006 .dependencies = featureSet(&[_]Feature{}),
2007 };
2008 result[@intFromEnum(Feature.KernelAttributesINTEL)] = .{
2009 .llvm_name = null,
2010 .description = "Enable SPIR-V capability KernelAttributesINTEL",
2011 .dependencies = featureSet(&[_]Feature{}),
2012 };
2013 result[@intFromEnum(Feature.FPGAKernelAttributesINTEL)] = .{
2014 .llvm_name = null,
2015 .description = "Enable SPIR-V capability FPGAKernelAttributesINTEL",
2016 .dependencies = featureSet(&[_]Feature{}),
2017 };
2018 result[@intFromEnum(Feature.FPGAMemoryAccessesINTEL)] = .{
2019 .llvm_name = null,
2020 .description = "Enable SPIR-V capability FPGAMemoryAccessesINTEL",
2021 .dependencies = featureSet(&[_]Feature{}),
2022 };
2023 result[@intFromEnum(Feature.FPGAClusterAttributesINTEL)] = .{
2024 .llvm_name = null,
2025 .description = "Enable SPIR-V capability FPGAClusterAttributesINTEL",
2026 .dependencies = featureSet(&[_]Feature{}),
2027 };
2028 result[@intFromEnum(Feature.LoopFuseINTEL)] = .{
2029 .llvm_name = null,
2030 .description = "Enable SPIR-V capability LoopFuseINTEL",
2031 .dependencies = featureSet(&[_]Feature{}),
2032 };
2033 result[@intFromEnum(Feature.FPGABufferLocationINTEL)] = .{
2034 .llvm_name = null,
2035 .description = "Enable SPIR-V capability FPGABufferLocationINTEL",
2036 .dependencies = featureSet(&[_]Feature{}),
2037 };
2038 result[@intFromEnum(Feature.USMStorageClassesINTEL)] = .{
2039 .llvm_name = null,
2040 .description = "Enable SPIR-V capability USMStorageClassesINTEL",
2041 .dependencies = featureSet(&[_]Feature{}),
2042 };
2043 result[@intFromEnum(Feature.IOPipesINTEL)] = .{
2044 .llvm_name = null,
2045 .description = "Enable SPIR-V capability IOPipesINTEL",
2046 .dependencies = featureSet(&[_]Feature{}),
2047 };
2048 result[@intFromEnum(Feature.BlockingPipesINTEL)] = .{
2049 .llvm_name = null,
2050 .description = "Enable SPIR-V capability BlockingPipesINTEL",
2051 .dependencies = featureSet(&[_]Feature{}),
2052 };
2053 result[@intFromEnum(Feature.FPGARegINTEL)] = .{
2054 .llvm_name = null,
2055 .description = "Enable SPIR-V capability FPGARegINTEL",
2056 .dependencies = featureSet(&[_]Feature{}),
2057 };
2058 result[@intFromEnum(Feature.AtomicFloat32AddEXT)] = .{
2059 .llvm_name = null,
2060 .description = "Enable SPIR-V capability AtomicFloat32AddEXT",
2061 .dependencies = featureSet(&[_]Feature{
2062 .Shader,
2063 }),
2064 };
2065 result[@intFromEnum(Feature.AtomicFloat64AddEXT)] = .{
2066 .llvm_name = null,
2067 .description = "Enable SPIR-V capability AtomicFloat64AddEXT",
2068 .dependencies = featureSet(&[_]Feature{
2069 .Shader,
2070 }),
2071 };
2072 result[@intFromEnum(Feature.LongConstantCompositeINTEL)] = .{
2073 .llvm_name = null,
2074 .description = "Enable SPIR-V capability LongConstantCompositeINTEL",
2075 .dependencies = featureSet(&[_]Feature{}),
2076 };
2077 const ti = @typeInfo(Feature);
2078 for (&result, 0..) |*elem, i| {
2079 elem.index = i;
2080 elem.name = ti.Enum.fields[i].name;
2081 }
2082 break :blk result;
2083};
2084
2085pub const cpu = struct {
2086 pub const generic = CpuModel{
2087 .name = "generic",
2088 .llvm_name = "generic",
2089 .features = featureSet(&[_]Feature{}),
2090 };
2091};
lib/std/target/ve.zig deleted-39
......@@ -1,39 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 vpu,
9};
10
11pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
12pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
13pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
14pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
15
16pub const all_features = blk: {
17 const len = @typeInfo(Feature).Enum.fields.len;
18 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
19 var result: [len]CpuFeature = undefined;
20 result[@intFromEnum(Feature.vpu)] = .{
21 .llvm_name = "vpu",
22 .description = "Enable the VPU",
23 .dependencies = featureSet(&[_]Feature{}),
24 };
25 const ti = @typeInfo(Feature);
26 for (&result, 0..) |*elem, i| {
27 elem.index = i;
28 elem.name = ti.Enum.fields[i].name;
29 }
30 break :blk result;
31};
32
33pub const cpu = struct {
34 pub const generic = CpuModel{
35 .name = "generic",
36 .llvm_name = "generic",
37 .features = featureSet(&[_]Feature{}),
38 };
39};
lib/std/target/wasm.zig deleted-126
......@@ -1,126 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 atomics,
9 bulk_memory,
10 exception_handling,
11 extended_const,
12 multivalue,
13 mutable_globals,
14 nontrapping_fptoint,
15 reference_types,
16 relaxed_simd,
17 sign_ext,
18 simd128,
19 tail_call,
20};
21
22pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
23pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
24pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
25pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
26
27pub const all_features = blk: {
28 const len = @typeInfo(Feature).Enum.fields.len;
29 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
30 var result: [len]CpuFeature = undefined;
31 result[@intFromEnum(Feature.atomics)] = .{
32 .llvm_name = "atomics",
33 .description = "Enable Atomics",
34 .dependencies = featureSet(&[_]Feature{}),
35 };
36 result[@intFromEnum(Feature.bulk_memory)] = .{
37 .llvm_name = "bulk-memory",
38 .description = "Enable bulk memory operations",
39 .dependencies = featureSet(&[_]Feature{}),
40 };
41 result[@intFromEnum(Feature.exception_handling)] = .{
42 .llvm_name = "exception-handling",
43 .description = "Enable Wasm exception handling",
44 .dependencies = featureSet(&[_]Feature{}),
45 };
46 result[@intFromEnum(Feature.extended_const)] = .{
47 .llvm_name = "extended-const",
48 .description = "Enable extended const expressions",
49 .dependencies = featureSet(&[_]Feature{}),
50 };
51 result[@intFromEnum(Feature.multivalue)] = .{
52 .llvm_name = "multivalue",
53 .description = "Enable multivalue blocks, instructions, and functions",
54 .dependencies = featureSet(&[_]Feature{}),
55 };
56 result[@intFromEnum(Feature.mutable_globals)] = .{
57 .llvm_name = "mutable-globals",
58 .description = "Enable mutable globals",
59 .dependencies = featureSet(&[_]Feature{}),
60 };
61 result[@intFromEnum(Feature.nontrapping_fptoint)] = .{
62 .llvm_name = "nontrapping-fptoint",
63 .description = "Enable non-trapping float-to-int conversion operators",
64 .dependencies = featureSet(&[_]Feature{}),
65 };
66 result[@intFromEnum(Feature.reference_types)] = .{
67 .llvm_name = "reference-types",
68 .description = "Enable reference types",
69 .dependencies = featureSet(&[_]Feature{}),
70 };
71 result[@intFromEnum(Feature.relaxed_simd)] = .{
72 .llvm_name = "relaxed-simd",
73 .description = "Enable relaxed-simd instructions",
74 .dependencies = featureSet(&[_]Feature{}),
75 };
76 result[@intFromEnum(Feature.sign_ext)] = .{
77 .llvm_name = "sign-ext",
78 .description = "Enable sign extension operators",
79 .dependencies = featureSet(&[_]Feature{}),
80 };
81 result[@intFromEnum(Feature.simd128)] = .{
82 .llvm_name = "simd128",
83 .description = "Enable 128-bit SIMD",
84 .dependencies = featureSet(&[_]Feature{}),
85 };
86 result[@intFromEnum(Feature.tail_call)] = .{
87 .llvm_name = "tail-call",
88 .description = "Enable tail call instructions",
89 .dependencies = featureSet(&[_]Feature{}),
90 };
91 const ti = @typeInfo(Feature);
92 for (&result, 0..) |*elem, i| {
93 elem.index = i;
94 elem.name = ti.Enum.fields[i].name;
95 }
96 break :blk result;
97};
98
99pub const cpu = struct {
100 pub const bleeding_edge = CpuModel{
101 .name = "bleeding_edge",
102 .llvm_name = "bleeding-edge",
103 .features = featureSet(&[_]Feature{
104 .atomics,
105 .bulk_memory,
106 .mutable_globals,
107 .nontrapping_fptoint,
108 .sign_ext,
109 .simd128,
110 .tail_call,
111 }),
112 };
113 pub const generic = CpuModel{
114 .name = "generic",
115 .llvm_name = "generic",
116 .features = featureSet(&[_]Feature{
117 .mutable_globals,
118 .sign_ext,
119 }),
120 };
121 pub const mvp = CpuModel{
122 .name = "mvp",
123 .llvm_name = "mvp",
124 .features = featureSet(&[_]Feature{}),
125 };
126};
lib/std/target/x86.zig deleted-4179
......@@ -1,4179 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 @"16bit_mode",
9 @"32bit_mode",
10 @"3dnow",
11 @"3dnowa",
12 @"64bit",
13 adx,
14 aes,
15 allow_light_256_bit,
16 amx_bf16,
17 amx_complex,
18 amx_fp16,
19 amx_int8,
20 amx_tile,
21 avx,
22 avx2,
23 avx512bf16,
24 avx512bitalg,
25 avx512bw,
26 avx512cd,
27 avx512dq,
28 avx512er,
29 avx512f,
30 avx512fp16,
31 avx512ifma,
32 avx512pf,
33 avx512vbmi,
34 avx512vbmi2,
35 avx512vl,
36 avx512vnni,
37 avx512vp2intersect,
38 avx512vpopcntdq,
39 avxifma,
40 avxneconvert,
41 avxvnni,
42 avxvnniint16,
43 avxvnniint8,
44 bmi,
45 bmi2,
46 branchfusion,
47 cldemote,
48 clflushopt,
49 clwb,
50 clzero,
51 cmov,
52 cmpccxadd,
53 crc32,
54 cx16,
55 cx8,
56 enqcmd,
57 ermsb,
58 f16c,
59 false_deps_getmant,
60 false_deps_lzcnt_tzcnt,
61 false_deps_mulc,
62 false_deps_mullq,
63 false_deps_perm,
64 false_deps_popcnt,
65 false_deps_range,
66 fast_11bytenop,
67 fast_15bytenop,
68 fast_7bytenop,
69 fast_bextr,
70 fast_gather,
71 fast_hops,
72 fast_lzcnt,
73 fast_movbe,
74 fast_scalar_fsqrt,
75 fast_scalar_shift_masks,
76 fast_shld_rotate,
77 fast_variable_crosslane_shuffle,
78 fast_variable_perlane_shuffle,
79 fast_vector_fsqrt,
80 fast_vector_shift_masks,
81 faster_shift_than_shuffle,
82 fma,
83 fma4,
84 fsgsbase,
85 fsrm,
86 fxsr,
87 gfni,
88 harden_sls_ijmp,
89 harden_sls_ret,
90 hreset,
91 idivl_to_divb,
92 idivq_to_divl,
93 invpcid,
94 kl,
95 lea_sp,
96 lea_uses_ag,
97 lvi_cfi,
98 lvi_load_hardening,
99 lwp,
100 lzcnt,
101 macrofusion,
102 mmx,
103 movbe,
104 movdir64b,
105 movdiri,
106 mwaitx,
107 no_bypass_delay,
108 no_bypass_delay_blend,
109 no_bypass_delay_mov,
110 no_bypass_delay_shuffle,
111 nopl,
112 pad_short_functions,
113 pclmul,
114 pconfig,
115 pku,
116 popcnt,
117 prefer_128_bit,
118 prefer_256_bit,
119 prefer_mask_registers,
120 prefer_movmsk_over_vtest,
121 prefetchi,
122 prefetchwt1,
123 prfchw,
124 ptwrite,
125 raoint,
126 rdpid,
127 rdpru,
128 rdrnd,
129 rdseed,
130 retpoline,
131 retpoline_external_thunk,
132 retpoline_indirect_branches,
133 retpoline_indirect_calls,
134 rtm,
135 sahf,
136 sbb_dep_breaking,
137 serialize,
138 seses,
139 sgx,
140 sha,
141 sha512,
142 shstk,
143 slow_3ops_lea,
144 slow_incdec,
145 slow_lea,
146 slow_pmaddwd,
147 slow_pmulld,
148 slow_shld,
149 slow_two_mem_ops,
150 slow_unaligned_mem_16,
151 slow_unaligned_mem_32,
152 sm3,
153 sm4,
154 soft_float,
155 sse,
156 sse2,
157 sse3,
158 sse4_1,
159 sse4_2,
160 sse4a,
161 sse_unaligned_mem,
162 ssse3,
163 tagged_globals,
164 tbm,
165 tsxldtrk,
166 tuning_fast_imm_vector_shift,
167 uintr,
168 use_glm_div_sqrt_costs,
169 use_slm_arith_costs,
170 vaes,
171 vpclmulqdq,
172 vzeroupper,
173 waitpkg,
174 wbnoinvd,
175 widekl,
176 x87,
177 xop,
178 xsave,
179 xsavec,
180 xsaveopt,
181 xsaves,
182};
183
184pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
185pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
186pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
187pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
188
189pub const all_features = blk: {
190 const len = @typeInfo(Feature).Enum.fields.len;
191 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
192 var result: [len]CpuFeature = undefined;
193 result[@intFromEnum(Feature.@"16bit_mode")] = .{
194 .llvm_name = "16bit-mode",
195 .description = "16-bit mode (i8086)",
196 .dependencies = featureSet(&[_]Feature{}),
197 };
198 result[@intFromEnum(Feature.@"32bit_mode")] = .{
199 .llvm_name = "32bit-mode",
200 .description = "32-bit mode (80386)",
201 .dependencies = featureSet(&[_]Feature{}),
202 };
203 result[@intFromEnum(Feature.@"3dnow")] = .{
204 .llvm_name = "3dnow",
205 .description = "Enable 3DNow! instructions",
206 .dependencies = featureSet(&[_]Feature{
207 .mmx,
208 }),
209 };
210 result[@intFromEnum(Feature.@"3dnowa")] = .{
211 .llvm_name = "3dnowa",
212 .description = "Enable 3DNow! Athlon instructions",
213 .dependencies = featureSet(&[_]Feature{
214 .@"3dnow",
215 }),
216 };
217 result[@intFromEnum(Feature.@"64bit")] = .{
218 .llvm_name = "64bit",
219 .description = "Support 64-bit instructions",
220 .dependencies = featureSet(&[_]Feature{}),
221 };
222 result[@intFromEnum(Feature.adx)] = .{
223 .llvm_name = "adx",
224 .description = "Support ADX instructions",
225 .dependencies = featureSet(&[_]Feature{}),
226 };
227 result[@intFromEnum(Feature.aes)] = .{
228 .llvm_name = "aes",
229 .description = "Enable AES instructions",
230 .dependencies = featureSet(&[_]Feature{
231 .sse2,
232 }),
233 };
234 result[@intFromEnum(Feature.allow_light_256_bit)] = .{
235 .llvm_name = "allow-light-256-bit",
236 .description = "Enable generation of 256-bit load/stores even if we prefer 128-bit",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@intFromEnum(Feature.amx_bf16)] = .{
240 .llvm_name = "amx-bf16",
241 .description = "Support AMX-BF16 instructions",
242 .dependencies = featureSet(&[_]Feature{
243 .amx_tile,
244 }),
245 };
246 result[@intFromEnum(Feature.amx_complex)] = .{
247 .llvm_name = "amx-complex",
248 .description = "Support AMX-COMPLEX instructions",
249 .dependencies = featureSet(&[_]Feature{
250 .amx_tile,
251 }),
252 };
253 result[@intFromEnum(Feature.amx_fp16)] = .{
254 .llvm_name = "amx-fp16",
255 .description = "Support AMX amx-fp16 instructions",
256 .dependencies = featureSet(&[_]Feature{
257 .amx_tile,
258 }),
259 };
260 result[@intFromEnum(Feature.amx_int8)] = .{
261 .llvm_name = "amx-int8",
262 .description = "Support AMX-INT8 instructions",
263 .dependencies = featureSet(&[_]Feature{
264 .amx_tile,
265 }),
266 };
267 result[@intFromEnum(Feature.amx_tile)] = .{
268 .llvm_name = "amx-tile",
269 .description = "Support AMX-TILE instructions",
270 .dependencies = featureSet(&[_]Feature{}),
271 };
272 result[@intFromEnum(Feature.avx)] = .{
273 .llvm_name = "avx",
274 .description = "Enable AVX instructions",
275 .dependencies = featureSet(&[_]Feature{
276 .sse4_2,
277 }),
278 };
279 result[@intFromEnum(Feature.avx2)] = .{
280 .llvm_name = "avx2",
281 .description = "Enable AVX2 instructions",
282 .dependencies = featureSet(&[_]Feature{
283 .avx,
284 }),
285 };
286 result[@intFromEnum(Feature.avx512bf16)] = .{
287 .llvm_name = "avx512bf16",
288 .description = "Support bfloat16 floating point",
289 .dependencies = featureSet(&[_]Feature{
290 .avx512bw,
291 }),
292 };
293 result[@intFromEnum(Feature.avx512bitalg)] = .{
294 .llvm_name = "avx512bitalg",
295 .description = "Enable AVX-512 Bit Algorithms",
296 .dependencies = featureSet(&[_]Feature{
297 .avx512bw,
298 }),
299 };
300 result[@intFromEnum(Feature.avx512bw)] = .{
301 .llvm_name = "avx512bw",
302 .description = "Enable AVX-512 Byte and Word Instructions",
303 .dependencies = featureSet(&[_]Feature{
304 .avx512f,
305 }),
306 };
307 result[@intFromEnum(Feature.avx512cd)] = .{
308 .llvm_name = "avx512cd",
309 .description = "Enable AVX-512 Conflict Detection Instructions",
310 .dependencies = featureSet(&[_]Feature{
311 .avx512f,
312 }),
313 };
314 result[@intFromEnum(Feature.avx512dq)] = .{
315 .llvm_name = "avx512dq",
316 .description = "Enable AVX-512 Doubleword and Quadword Instructions",
317 .dependencies = featureSet(&[_]Feature{
318 .avx512f,
319 }),
320 };
321 result[@intFromEnum(Feature.avx512er)] = .{
322 .llvm_name = "avx512er",
323 .description = "Enable AVX-512 Exponential and Reciprocal Instructions",
324 .dependencies = featureSet(&[_]Feature{
325 .avx512f,
326 }),
327 };
328 result[@intFromEnum(Feature.avx512f)] = .{
329 .llvm_name = "avx512f",
330 .description = "Enable AVX-512 instructions",
331 .dependencies = featureSet(&[_]Feature{
332 .avx2,
333 .f16c,
334 .fma,
335 }),
336 };
337 result[@intFromEnum(Feature.avx512fp16)] = .{
338 .llvm_name = "avx512fp16",
339 .description = "Support 16-bit floating point",
340 .dependencies = featureSet(&[_]Feature{
341 .avx512bw,
342 .avx512dq,
343 .avx512vl,
344 }),
345 };
346 result[@intFromEnum(Feature.avx512ifma)] = .{
347 .llvm_name = "avx512ifma",
348 .description = "Enable AVX-512 Integer Fused Multiple-Add",
349 .dependencies = featureSet(&[_]Feature{
350 .avx512f,
351 }),
352 };
353 result[@intFromEnum(Feature.avx512pf)] = .{
354 .llvm_name = "avx512pf",
355 .description = "Enable AVX-512 PreFetch Instructions",
356 .dependencies = featureSet(&[_]Feature{
357 .avx512f,
358 }),
359 };
360 result[@intFromEnum(Feature.avx512vbmi)] = .{
361 .llvm_name = "avx512vbmi",
362 .description = "Enable AVX-512 Vector Byte Manipulation Instructions",
363 .dependencies = featureSet(&[_]Feature{
364 .avx512bw,
365 }),
366 };
367 result[@intFromEnum(Feature.avx512vbmi2)] = .{
368 .llvm_name = "avx512vbmi2",
369 .description = "Enable AVX-512 further Vector Byte Manipulation Instructions",
370 .dependencies = featureSet(&[_]Feature{
371 .avx512bw,
372 }),
373 };
374 result[@intFromEnum(Feature.avx512vl)] = .{
375 .llvm_name = "avx512vl",
376 .description = "Enable AVX-512 Vector Length eXtensions",
377 .dependencies = featureSet(&[_]Feature{
378 .avx512f,
379 }),
380 };
381 result[@intFromEnum(Feature.avx512vnni)] = .{
382 .llvm_name = "avx512vnni",
383 .description = "Enable AVX-512 Vector Neural Network Instructions",
384 .dependencies = featureSet(&[_]Feature{
385 .avx512f,
386 }),
387 };
388 result[@intFromEnum(Feature.avx512vp2intersect)] = .{
389 .llvm_name = "avx512vp2intersect",
390 .description = "Enable AVX-512 vp2intersect",
391 .dependencies = featureSet(&[_]Feature{
392 .avx512f,
393 }),
394 };
395 result[@intFromEnum(Feature.avx512vpopcntdq)] = .{
396 .llvm_name = "avx512vpopcntdq",
397 .description = "Enable AVX-512 Population Count Instructions",
398 .dependencies = featureSet(&[_]Feature{
399 .avx512f,
400 }),
401 };
402 result[@intFromEnum(Feature.avxifma)] = .{
403 .llvm_name = "avxifma",
404 .description = "Enable AVX-IFMA",
405 .dependencies = featureSet(&[_]Feature{
406 .avx2,
407 }),
408 };
409 result[@intFromEnum(Feature.avxneconvert)] = .{
410 .llvm_name = "avxneconvert",
411 .description = "Support AVX-NE-CONVERT instructions",
412 .dependencies = featureSet(&[_]Feature{
413 .avx2,
414 }),
415 };
416 result[@intFromEnum(Feature.avxvnni)] = .{
417 .llvm_name = "avxvnni",
418 .description = "Support AVX_VNNI encoding",
419 .dependencies = featureSet(&[_]Feature{
420 .avx2,
421 }),
422 };
423 result[@intFromEnum(Feature.avxvnniint16)] = .{
424 .llvm_name = "avxvnniint16",
425 .description = "Enable AVX-VNNI-INT16",
426 .dependencies = featureSet(&[_]Feature{
427 .avx2,
428 }),
429 };
430 result[@intFromEnum(Feature.avxvnniint8)] = .{
431 .llvm_name = "avxvnniint8",
432 .description = "Enable AVX-VNNI-INT8",
433 .dependencies = featureSet(&[_]Feature{
434 .avx2,
435 }),
436 };
437 result[@intFromEnum(Feature.bmi)] = .{
438 .llvm_name = "bmi",
439 .description = "Support BMI instructions",
440 .dependencies = featureSet(&[_]Feature{}),
441 };
442 result[@intFromEnum(Feature.bmi2)] = .{
443 .llvm_name = "bmi2",
444 .description = "Support BMI2 instructions",
445 .dependencies = featureSet(&[_]Feature{}),
446 };
447 result[@intFromEnum(Feature.branchfusion)] = .{
448 .llvm_name = "branchfusion",
449 .description = "CMP/TEST can be fused with conditional branches",
450 .dependencies = featureSet(&[_]Feature{}),
451 };
452 result[@intFromEnum(Feature.cldemote)] = .{
453 .llvm_name = "cldemote",
454 .description = "Enable Cache Line Demote",
455 .dependencies = featureSet(&[_]Feature{}),
456 };
457 result[@intFromEnum(Feature.clflushopt)] = .{
458 .llvm_name = "clflushopt",
459 .description = "Flush A Cache Line Optimized",
460 .dependencies = featureSet(&[_]Feature{}),
461 };
462 result[@intFromEnum(Feature.clwb)] = .{
463 .llvm_name = "clwb",
464 .description = "Cache Line Write Back",
465 .dependencies = featureSet(&[_]Feature{}),
466 };
467 result[@intFromEnum(Feature.clzero)] = .{
468 .llvm_name = "clzero",
469 .description = "Enable Cache Line Zero",
470 .dependencies = featureSet(&[_]Feature{}),
471 };
472 result[@intFromEnum(Feature.cmov)] = .{
473 .llvm_name = "cmov",
474 .description = "Enable conditional move instructions",
475 .dependencies = featureSet(&[_]Feature{}),
476 };
477 result[@intFromEnum(Feature.cmpccxadd)] = .{
478 .llvm_name = "cmpccxadd",
479 .description = "Support CMPCCXADD instructions",
480 .dependencies = featureSet(&[_]Feature{}),
481 };
482 result[@intFromEnum(Feature.crc32)] = .{
483 .llvm_name = "crc32",
484 .description = "Enable SSE 4.2 CRC32 instruction (used when SSE4.2 is supported but function is GPR only)",
485 .dependencies = featureSet(&[_]Feature{}),
486 };
487 result[@intFromEnum(Feature.cx16)] = .{
488 .llvm_name = "cx16",
489 .description = "64-bit with cmpxchg16b (this is true for most x86-64 chips, but not the first AMD chips)",
490 .dependencies = featureSet(&[_]Feature{
491 .cx8,
492 }),
493 };
494 result[@intFromEnum(Feature.cx8)] = .{
495 .llvm_name = "cx8",
496 .description = "Support CMPXCHG8B instructions",
497 .dependencies = featureSet(&[_]Feature{}),
498 };
499 result[@intFromEnum(Feature.enqcmd)] = .{
500 .llvm_name = "enqcmd",
501 .description = "Has ENQCMD instructions",
502 .dependencies = featureSet(&[_]Feature{}),
503 };
504 result[@intFromEnum(Feature.ermsb)] = .{
505 .llvm_name = "ermsb",
506 .description = "REP MOVS/STOS are fast",
507 .dependencies = featureSet(&[_]Feature{}),
508 };
509 result[@intFromEnum(Feature.f16c)] = .{
510 .llvm_name = "f16c",
511 .description = "Support 16-bit floating point conversion instructions",
512 .dependencies = featureSet(&[_]Feature{
513 .avx,
514 }),
515 };
516 result[@intFromEnum(Feature.false_deps_getmant)] = .{
517 .llvm_name = "false-deps-getmant",
518 .description = "VGETMANTSS/SD/SH and VGETMANDPS/PD(memory version) has a false dependency on dest register",
519 .dependencies = featureSet(&[_]Feature{}),
520 };
521 result[@intFromEnum(Feature.false_deps_lzcnt_tzcnt)] = .{
522 .llvm_name = "false-deps-lzcnt-tzcnt",
523 .description = "LZCNT/TZCNT have a false dependency on dest register",
524 .dependencies = featureSet(&[_]Feature{}),
525 };
526 result[@intFromEnum(Feature.false_deps_mulc)] = .{
527 .llvm_name = "false-deps-mulc",
528 .description = "VF[C]MULCPH/SH has a false dependency on dest register",
529 .dependencies = featureSet(&[_]Feature{}),
530 };
531 result[@intFromEnum(Feature.false_deps_mullq)] = .{
532 .llvm_name = "false-deps-mullq",
533 .description = "VPMULLQ has a false dependency on dest register",
534 .dependencies = featureSet(&[_]Feature{}),
535 };
536 result[@intFromEnum(Feature.false_deps_perm)] = .{
537 .llvm_name = "false-deps-perm",
538 .description = "VPERMD/Q/PS/PD has a false dependency on dest register",
539 .dependencies = featureSet(&[_]Feature{}),
540 };
541 result[@intFromEnum(Feature.false_deps_popcnt)] = .{
542 .llvm_name = "false-deps-popcnt",
543 .description = "POPCNT has a false dependency on dest register",
544 .dependencies = featureSet(&[_]Feature{}),
545 };
546 result[@intFromEnum(Feature.false_deps_range)] = .{
547 .llvm_name = "false-deps-range",
548 .description = "VRANGEPD/PS/SD/SS has a false dependency on dest register",
549 .dependencies = featureSet(&[_]Feature{}),
550 };
551 result[@intFromEnum(Feature.fast_11bytenop)] = .{
552 .llvm_name = "fast-11bytenop",
553 .description = "Target can quickly decode up to 11 byte NOPs",
554 .dependencies = featureSet(&[_]Feature{}),
555 };
556 result[@intFromEnum(Feature.fast_15bytenop)] = .{
557 .llvm_name = "fast-15bytenop",
558 .description = "Target can quickly decode up to 15 byte NOPs",
559 .dependencies = featureSet(&[_]Feature{}),
560 };
561 result[@intFromEnum(Feature.fast_7bytenop)] = .{
562 .llvm_name = "fast-7bytenop",
563 .description = "Target can quickly decode up to 7 byte NOPs",
564 .dependencies = featureSet(&[_]Feature{}),
565 };
566 result[@intFromEnum(Feature.fast_bextr)] = .{
567 .llvm_name = "fast-bextr",
568 .description = "Indicates that the BEXTR instruction is implemented as a single uop with good throughput",
569 .dependencies = featureSet(&[_]Feature{}),
570 };
571 result[@intFromEnum(Feature.fast_gather)] = .{
572 .llvm_name = "fast-gather",
573 .description = "Indicates if gather is reasonably fast (this is true for Skylake client and all AVX-512 CPUs)",
574 .dependencies = featureSet(&[_]Feature{}),
575 };
576 result[@intFromEnum(Feature.fast_hops)] = .{
577 .llvm_name = "fast-hops",
578 .description = "Prefer horizontal vector math instructions (haddp, phsub, etc.) over normal vector instructions with shuffles",
579 .dependencies = featureSet(&[_]Feature{}),
580 };
581 result[@intFromEnum(Feature.fast_lzcnt)] = .{
582 .llvm_name = "fast-lzcnt",
583 .description = "LZCNT instructions are as fast as most simple integer ops",
584 .dependencies = featureSet(&[_]Feature{}),
585 };
586 result[@intFromEnum(Feature.fast_movbe)] = .{
587 .llvm_name = "fast-movbe",
588 .description = "Prefer a movbe over a single-use load + bswap / single-use bswap + store",
589 .dependencies = featureSet(&[_]Feature{}),
590 };
591 result[@intFromEnum(Feature.fast_scalar_fsqrt)] = .{
592 .llvm_name = "fast-scalar-fsqrt",
593 .description = "Scalar SQRT is fast (disable Newton-Raphson)",
594 .dependencies = featureSet(&[_]Feature{}),
595 };
596 result[@intFromEnum(Feature.fast_scalar_shift_masks)] = .{
597 .llvm_name = "fast-scalar-shift-masks",
598 .description = "Prefer a left/right scalar logical shift pair over a shift+and pair",
599 .dependencies = featureSet(&[_]Feature{}),
600 };
601 result[@intFromEnum(Feature.fast_shld_rotate)] = .{
602 .llvm_name = "fast-shld-rotate",
603 .description = "SHLD can be used as a faster rotate",
604 .dependencies = featureSet(&[_]Feature{}),
605 };
606 result[@intFromEnum(Feature.fast_variable_crosslane_shuffle)] = .{
607 .llvm_name = "fast-variable-crosslane-shuffle",
608 .description = "Cross-lane shuffles with variable masks are fast",
609 .dependencies = featureSet(&[_]Feature{}),
610 };
611 result[@intFromEnum(Feature.fast_variable_perlane_shuffle)] = .{
612 .llvm_name = "fast-variable-perlane-shuffle",
613 .description = "Per-lane shuffles with variable masks are fast",
614 .dependencies = featureSet(&[_]Feature{}),
615 };
616 result[@intFromEnum(Feature.fast_vector_fsqrt)] = .{
617 .llvm_name = "fast-vector-fsqrt",
618 .description = "Vector SQRT is fast (disable Newton-Raphson)",
619 .dependencies = featureSet(&[_]Feature{}),
620 };
621 result[@intFromEnum(Feature.fast_vector_shift_masks)] = .{
622 .llvm_name = "fast-vector-shift-masks",
623 .description = "Prefer a left/right vector logical shift pair over a shift+and pair",
624 .dependencies = featureSet(&[_]Feature{}),
625 };
626 result[@intFromEnum(Feature.faster_shift_than_shuffle)] = .{
627 .llvm_name = "faster-shift-than-shuffle",
628 .description = "Shifts are faster (or as fast) as shuffle",
629 .dependencies = featureSet(&[_]Feature{}),
630 };
631 result[@intFromEnum(Feature.fma)] = .{
632 .llvm_name = "fma",
633 .description = "Enable three-operand fused multiple-add",
634 .dependencies = featureSet(&[_]Feature{
635 .avx,
636 }),
637 };
638 result[@intFromEnum(Feature.fma4)] = .{
639 .llvm_name = "fma4",
640 .description = "Enable four-operand fused multiple-add",
641 .dependencies = featureSet(&[_]Feature{
642 .avx,
643 .sse4a,
644 }),
645 };
646 result[@intFromEnum(Feature.fsgsbase)] = .{
647 .llvm_name = "fsgsbase",
648 .description = "Support FS/GS Base instructions",
649 .dependencies = featureSet(&[_]Feature{}),
650 };
651 result[@intFromEnum(Feature.fsrm)] = .{
652 .llvm_name = "fsrm",
653 .description = "REP MOVSB of short lengths is faster",
654 .dependencies = featureSet(&[_]Feature{}),
655 };
656 result[@intFromEnum(Feature.fxsr)] = .{
657 .llvm_name = "fxsr",
658 .description = "Support fxsave/fxrestore instructions",
659 .dependencies = featureSet(&[_]Feature{}),
660 };
661 result[@intFromEnum(Feature.gfni)] = .{
662 .llvm_name = "gfni",
663 .description = "Enable Galois Field Arithmetic Instructions",
664 .dependencies = featureSet(&[_]Feature{
665 .sse2,
666 }),
667 };
668 result[@intFromEnum(Feature.harden_sls_ijmp)] = .{
669 .llvm_name = "harden-sls-ijmp",
670 .description = "Harden against straight line speculation across indirect JMP instructions.",
671 .dependencies = featureSet(&[_]Feature{}),
672 };
673 result[@intFromEnum(Feature.harden_sls_ret)] = .{
674 .llvm_name = "harden-sls-ret",
675 .description = "Harden against straight line speculation across RET instructions.",
676 .dependencies = featureSet(&[_]Feature{}),
677 };
678 result[@intFromEnum(Feature.hreset)] = .{
679 .llvm_name = "hreset",
680 .description = "Has hreset instruction",
681 .dependencies = featureSet(&[_]Feature{}),
682 };
683 result[@intFromEnum(Feature.idivl_to_divb)] = .{
684 .llvm_name = "idivl-to-divb",
685 .description = "Use 8-bit divide for positive values less than 256",
686 .dependencies = featureSet(&[_]Feature{}),
687 };
688 result[@intFromEnum(Feature.idivq_to_divl)] = .{
689 .llvm_name = "idivq-to-divl",
690 .description = "Use 32-bit divide for positive values less than 2^32",
691 .dependencies = featureSet(&[_]Feature{}),
692 };
693 result[@intFromEnum(Feature.invpcid)] = .{
694 .llvm_name = "invpcid",
695 .description = "Invalidate Process-Context Identifier",
696 .dependencies = featureSet(&[_]Feature{}),
697 };
698 result[@intFromEnum(Feature.kl)] = .{
699 .llvm_name = "kl",
700 .description = "Support Key Locker kl Instructions",
701 .dependencies = featureSet(&[_]Feature{
702 .sse2,
703 }),
704 };
705 result[@intFromEnum(Feature.lea_sp)] = .{
706 .llvm_name = "lea-sp",
707 .description = "Use LEA for adjusting the stack pointer (this is an optimization for Intel Atom processors)",
708 .dependencies = featureSet(&[_]Feature{}),
709 };
710 result[@intFromEnum(Feature.lea_uses_ag)] = .{
711 .llvm_name = "lea-uses-ag",
712 .description = "LEA instruction needs inputs at AG stage",
713 .dependencies = featureSet(&[_]Feature{}),
714 };
715 result[@intFromEnum(Feature.lvi_cfi)] = .{
716 .llvm_name = "lvi-cfi",
717 .description = "Prevent indirect calls/branches from using a memory operand, and precede all indirect calls/branches from a register with an LFENCE instruction to serialize control flow. Also decompose RET instructions into a POP+LFENCE+JMP sequence.",
718 .dependencies = featureSet(&[_]Feature{}),
719 };
720 result[@intFromEnum(Feature.lvi_load_hardening)] = .{
721 .llvm_name = "lvi-load-hardening",
722 .description = "Insert LFENCE instructions to prevent data speculatively injected into loads from being used maliciously.",
723 .dependencies = featureSet(&[_]Feature{}),
724 };
725 result[@intFromEnum(Feature.lwp)] = .{
726 .llvm_name = "lwp",
727 .description = "Enable LWP instructions",
728 .dependencies = featureSet(&[_]Feature{}),
729 };
730 result[@intFromEnum(Feature.lzcnt)] = .{
731 .llvm_name = "lzcnt",
732 .description = "Support LZCNT instruction",
733 .dependencies = featureSet(&[_]Feature{}),
734 };
735 result[@intFromEnum(Feature.macrofusion)] = .{
736 .llvm_name = "macrofusion",
737 .description = "Various instructions can be fused with conditional branches",
738 .dependencies = featureSet(&[_]Feature{}),
739 };
740 result[@intFromEnum(Feature.mmx)] = .{
741 .llvm_name = "mmx",
742 .description = "Enable MMX instructions",
743 .dependencies = featureSet(&[_]Feature{}),
744 };
745 result[@intFromEnum(Feature.movbe)] = .{
746 .llvm_name = "movbe",
747 .description = "Support MOVBE instruction",
748 .dependencies = featureSet(&[_]Feature{}),
749 };
750 result[@intFromEnum(Feature.movdir64b)] = .{
751 .llvm_name = "movdir64b",
752 .description = "Support movdir64b instruction (direct store 64 bytes)",
753 .dependencies = featureSet(&[_]Feature{}),
754 };
755 result[@intFromEnum(Feature.movdiri)] = .{
756 .llvm_name = "movdiri",
757 .description = "Support movdiri instruction (direct store integer)",
758 .dependencies = featureSet(&[_]Feature{}),
759 };
760 result[@intFromEnum(Feature.mwaitx)] = .{
761 .llvm_name = "mwaitx",
762 .description = "Enable MONITORX/MWAITX timer functionality",
763 .dependencies = featureSet(&[_]Feature{}),
764 };
765 result[@intFromEnum(Feature.no_bypass_delay)] = .{
766 .llvm_name = "no-bypass-delay",
767 .description = "Has no bypass delay when using the 'wrong' domain",
768 .dependencies = featureSet(&[_]Feature{}),
769 };
770 result[@intFromEnum(Feature.no_bypass_delay_blend)] = .{
771 .llvm_name = "no-bypass-delay-blend",
772 .description = "Has no bypass delay when using the 'wrong' blend type",
773 .dependencies = featureSet(&[_]Feature{}),
774 };
775 result[@intFromEnum(Feature.no_bypass_delay_mov)] = .{
776 .llvm_name = "no-bypass-delay-mov",
777 .description = "Has no bypass delay when using the 'wrong' mov type",
778 .dependencies = featureSet(&[_]Feature{}),
779 };
780 result[@intFromEnum(Feature.no_bypass_delay_shuffle)] = .{
781 .llvm_name = "no-bypass-delay-shuffle",
782 .description = "Has no bypass delay when using the 'wrong' shuffle type",
783 .dependencies = featureSet(&[_]Feature{}),
784 };
785 result[@intFromEnum(Feature.nopl)] = .{
786 .llvm_name = "nopl",
787 .description = "Enable NOPL instruction (generally pentium pro+)",
788 .dependencies = featureSet(&[_]Feature{}),
789 };
790 result[@intFromEnum(Feature.pad_short_functions)] = .{
791 .llvm_name = "pad-short-functions",
792 .description = "Pad short functions (to prevent a stall when returning too early)",
793 .dependencies = featureSet(&[_]Feature{}),
794 };
795 result[@intFromEnum(Feature.pclmul)] = .{
796 .llvm_name = "pclmul",
797 .description = "Enable packed carry-less multiplication instructions",
798 .dependencies = featureSet(&[_]Feature{
799 .sse2,
800 }),
801 };
802 result[@intFromEnum(Feature.pconfig)] = .{
803 .llvm_name = "pconfig",
804 .description = "platform configuration instruction",
805 .dependencies = featureSet(&[_]Feature{}),
806 };
807 result[@intFromEnum(Feature.pku)] = .{
808 .llvm_name = "pku",
809 .description = "Enable protection keys",
810 .dependencies = featureSet(&[_]Feature{}),
811 };
812 result[@intFromEnum(Feature.popcnt)] = .{
813 .llvm_name = "popcnt",
814 .description = "Support POPCNT instruction",
815 .dependencies = featureSet(&[_]Feature{}),
816 };
817 result[@intFromEnum(Feature.prefer_128_bit)] = .{
818 .llvm_name = "prefer-128-bit",
819 .description = "Prefer 128-bit AVX instructions",
820 .dependencies = featureSet(&[_]Feature{}),
821 };
822 result[@intFromEnum(Feature.prefer_256_bit)] = .{
823 .llvm_name = "prefer-256-bit",
824 .description = "Prefer 256-bit AVX instructions",
825 .dependencies = featureSet(&[_]Feature{}),
826 };
827 result[@intFromEnum(Feature.prefer_mask_registers)] = .{
828 .llvm_name = "prefer-mask-registers",
829 .description = "Prefer AVX512 mask registers over PTEST/MOVMSK",
830 .dependencies = featureSet(&[_]Feature{}),
831 };
832 result[@intFromEnum(Feature.prefer_movmsk_over_vtest)] = .{
833 .llvm_name = "prefer-movmsk-over-vtest",
834 .description = "Prefer movmsk over vtest instruction",
835 .dependencies = featureSet(&[_]Feature{}),
836 };
837 result[@intFromEnum(Feature.prefetchi)] = .{
838 .llvm_name = "prefetchi",
839 .description = "Prefetch instruction with T0 or T1 Hint",
840 .dependencies = featureSet(&[_]Feature{}),
841 };
842 result[@intFromEnum(Feature.prefetchwt1)] = .{
843 .llvm_name = "prefetchwt1",
844 .description = "Prefetch with Intent to Write and T1 Hint",
845 .dependencies = featureSet(&[_]Feature{}),
846 };
847 result[@intFromEnum(Feature.prfchw)] = .{
848 .llvm_name = "prfchw",
849 .description = "Support PRFCHW instructions",
850 .dependencies = featureSet(&[_]Feature{}),
851 };
852 result[@intFromEnum(Feature.ptwrite)] = .{
853 .llvm_name = "ptwrite",
854 .description = "Support ptwrite instruction",
855 .dependencies = featureSet(&[_]Feature{}),
856 };
857 result[@intFromEnum(Feature.raoint)] = .{
858 .llvm_name = "raoint",
859 .description = "Support RAO-INT instructions",
860 .dependencies = featureSet(&[_]Feature{}),
861 };
862 result[@intFromEnum(Feature.rdpid)] = .{
863 .llvm_name = "rdpid",
864 .description = "Support RDPID instructions",
865 .dependencies = featureSet(&[_]Feature{}),
866 };
867 result[@intFromEnum(Feature.rdpru)] = .{
868 .llvm_name = "rdpru",
869 .description = "Support RDPRU instructions",
870 .dependencies = featureSet(&[_]Feature{}),
871 };
872 result[@intFromEnum(Feature.rdrnd)] = .{
873 .llvm_name = "rdrnd",
874 .description = "Support RDRAND instruction",
875 .dependencies = featureSet(&[_]Feature{}),
876 };
877 result[@intFromEnum(Feature.rdseed)] = .{
878 .llvm_name = "rdseed",
879 .description = "Support RDSEED instruction",
880 .dependencies = featureSet(&[_]Feature{}),
881 };
882 result[@intFromEnum(Feature.retpoline)] = .{
883 .llvm_name = "retpoline",
884 .description = "Remove speculation of indirect branches from the generated code, either by avoiding them entirely or lowering them with a speculation blocking construct",
885 .dependencies = featureSet(&[_]Feature{
886 .retpoline_indirect_branches,
887 .retpoline_indirect_calls,
888 }),
889 };
890 result[@intFromEnum(Feature.retpoline_external_thunk)] = .{
891 .llvm_name = "retpoline-external-thunk",
892 .description = "When lowering an indirect call or branch using a `retpoline`, rely on the specified user provided thunk rather than emitting one ourselves. Only has effect when combined with some other retpoline feature",
893 .dependencies = featureSet(&[_]Feature{
894 .retpoline_indirect_calls,
895 }),
896 };
897 result[@intFromEnum(Feature.retpoline_indirect_branches)] = .{
898 .llvm_name = "retpoline-indirect-branches",
899 .description = "Remove speculation of indirect branches from the generated code",
900 .dependencies = featureSet(&[_]Feature{}),
901 };
902 result[@intFromEnum(Feature.retpoline_indirect_calls)] = .{
903 .llvm_name = "retpoline-indirect-calls",
904 .description = "Remove speculation of indirect calls from the generated code",
905 .dependencies = featureSet(&[_]Feature{}),
906 };
907 result[@intFromEnum(Feature.rtm)] = .{
908 .llvm_name = "rtm",
909 .description = "Support RTM instructions",
910 .dependencies = featureSet(&[_]Feature{}),
911 };
912 result[@intFromEnum(Feature.sahf)] = .{
913 .llvm_name = "sahf",
914 .description = "Support LAHF and SAHF instructions in 64-bit mode",
915 .dependencies = featureSet(&[_]Feature{}),
916 };
917 result[@intFromEnum(Feature.sbb_dep_breaking)] = .{
918 .llvm_name = "sbb-dep-breaking",
919 .description = "SBB with same register has no source dependency",
920 .dependencies = featureSet(&[_]Feature{}),
921 };
922 result[@intFromEnum(Feature.serialize)] = .{
923 .llvm_name = "serialize",
924 .description = "Has serialize instruction",
925 .dependencies = featureSet(&[_]Feature{}),
926 };
927 result[@intFromEnum(Feature.seses)] = .{
928 .llvm_name = "seses",
929 .description = "Prevent speculative execution side channel timing attacks by inserting a speculation barrier before memory reads, memory writes, and conditional branches. Implies LVI Control Flow integrity.",
930 .dependencies = featureSet(&[_]Feature{
931 .lvi_cfi,
932 }),
933 };
934 result[@intFromEnum(Feature.sgx)] = .{
935 .llvm_name = "sgx",
936 .description = "Enable Software Guard Extensions",
937 .dependencies = featureSet(&[_]Feature{}),
938 };
939 result[@intFromEnum(Feature.sha)] = .{
940 .llvm_name = "sha",
941 .description = "Enable SHA instructions",
942 .dependencies = featureSet(&[_]Feature{
943 .sse2,
944 }),
945 };
946 result[@intFromEnum(Feature.sha512)] = .{
947 .llvm_name = "sha512",
948 .description = "Support SHA512 instructions",
949 .dependencies = featureSet(&[_]Feature{
950 .avx,
951 }),
952 };
953 result[@intFromEnum(Feature.shstk)] = .{
954 .llvm_name = "shstk",
955 .description = "Support CET Shadow-Stack instructions",
956 .dependencies = featureSet(&[_]Feature{}),
957 };
958 result[@intFromEnum(Feature.slow_3ops_lea)] = .{
959 .llvm_name = "slow-3ops-lea",
960 .description = "LEA instruction with 3 ops or certain registers is slow",
961 .dependencies = featureSet(&[_]Feature{}),
962 };
963 result[@intFromEnum(Feature.slow_incdec)] = .{
964 .llvm_name = "slow-incdec",
965 .description = "INC and DEC instructions are slower than ADD and SUB",
966 .dependencies = featureSet(&[_]Feature{}),
967 };
968 result[@intFromEnum(Feature.slow_lea)] = .{
969 .llvm_name = "slow-lea",
970 .description = "LEA instruction with certain arguments is slow",
971 .dependencies = featureSet(&[_]Feature{}),
972 };
973 result[@intFromEnum(Feature.slow_pmaddwd)] = .{
974 .llvm_name = "slow-pmaddwd",
975 .description = "PMADDWD is slower than PMULLD",
976 .dependencies = featureSet(&[_]Feature{}),
977 };
978 result[@intFromEnum(Feature.slow_pmulld)] = .{
979 .llvm_name = "slow-pmulld",
980 .description = "PMULLD instruction is slow (compared to PMULLW/PMULHW and PMULUDQ)",
981 .dependencies = featureSet(&[_]Feature{}),
982 };
983 result[@intFromEnum(Feature.slow_shld)] = .{
984 .llvm_name = "slow-shld",
985 .description = "SHLD instruction is slow",
986 .dependencies = featureSet(&[_]Feature{}),
987 };
988 result[@intFromEnum(Feature.slow_two_mem_ops)] = .{
989 .llvm_name = "slow-two-mem-ops",
990 .description = "Two memory operand instructions are slow",
991 .dependencies = featureSet(&[_]Feature{}),
992 };
993 result[@intFromEnum(Feature.slow_unaligned_mem_16)] = .{
994 .llvm_name = "slow-unaligned-mem-16",
995 .description = "Slow unaligned 16-byte memory access",
996 .dependencies = featureSet(&[_]Feature{}),
997 };
998 result[@intFromEnum(Feature.slow_unaligned_mem_32)] = .{
999 .llvm_name = "slow-unaligned-mem-32",
1000 .description = "Slow unaligned 32-byte memory access",
1001 .dependencies = featureSet(&[_]Feature{}),
1002 };
1003 result[@intFromEnum(Feature.sm3)] = .{
1004 .llvm_name = "sm3",
1005 .description = "Support SM3 instructions",
1006 .dependencies = featureSet(&[_]Feature{
1007 .avx,
1008 }),
1009 };
1010 result[@intFromEnum(Feature.sm4)] = .{
1011 .llvm_name = "sm4",
1012 .description = "Support SM4 instructions",
1013 .dependencies = featureSet(&[_]Feature{
1014 .avx,
1015 }),
1016 };
1017 result[@intFromEnum(Feature.soft_float)] = .{
1018 .llvm_name = "soft-float",
1019 .description = "Use software floating point features",
1020 .dependencies = featureSet(&[_]Feature{}),
1021 };
1022 result[@intFromEnum(Feature.sse)] = .{
1023 .llvm_name = "sse",
1024 .description = "Enable SSE instructions",
1025 .dependencies = featureSet(&[_]Feature{}),
1026 };
1027 result[@intFromEnum(Feature.sse2)] = .{
1028 .llvm_name = "sse2",
1029 .description = "Enable SSE2 instructions",
1030 .dependencies = featureSet(&[_]Feature{
1031 .sse,
1032 }),
1033 };
1034 result[@intFromEnum(Feature.sse3)] = .{
1035 .llvm_name = "sse3",
1036 .description = "Enable SSE3 instructions",
1037 .dependencies = featureSet(&[_]Feature{
1038 .sse2,
1039 }),
1040 };
1041 result[@intFromEnum(Feature.sse4_1)] = .{
1042 .llvm_name = "sse4.1",
1043 .description = "Enable SSE 4.1 instructions",
1044 .dependencies = featureSet(&[_]Feature{
1045 .ssse3,
1046 }),
1047 };
1048 result[@intFromEnum(Feature.sse4_2)] = .{
1049 .llvm_name = "sse4.2",
1050 .description = "Enable SSE 4.2 instructions",
1051 .dependencies = featureSet(&[_]Feature{
1052 .sse4_1,
1053 }),
1054 };
1055 result[@intFromEnum(Feature.sse4a)] = .{
1056 .llvm_name = "sse4a",
1057 .description = "Support SSE 4a instructions",
1058 .dependencies = featureSet(&[_]Feature{
1059 .sse3,
1060 }),
1061 };
1062 result[@intFromEnum(Feature.sse_unaligned_mem)] = .{
1063 .llvm_name = "sse-unaligned-mem",
1064 .description = "Allow unaligned memory operands with SSE instructions (this may require setting a configuration bit in the processor)",
1065 .dependencies = featureSet(&[_]Feature{}),
1066 };
1067 result[@intFromEnum(Feature.ssse3)] = .{
1068 .llvm_name = "ssse3",
1069 .description = "Enable SSSE3 instructions",
1070 .dependencies = featureSet(&[_]Feature{
1071 .sse3,
1072 }),
1073 };
1074 result[@intFromEnum(Feature.tagged_globals)] = .{
1075 .llvm_name = "tagged-globals",
1076 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits.",
1077 .dependencies = featureSet(&[_]Feature{}),
1078 };
1079 result[@intFromEnum(Feature.tbm)] = .{
1080 .llvm_name = "tbm",
1081 .description = "Enable TBM instructions",
1082 .dependencies = featureSet(&[_]Feature{}),
1083 };
1084 result[@intFromEnum(Feature.tsxldtrk)] = .{
1085 .llvm_name = "tsxldtrk",
1086 .description = "Support TSXLDTRK instructions",
1087 .dependencies = featureSet(&[_]Feature{}),
1088 };
1089 result[@intFromEnum(Feature.tuning_fast_imm_vector_shift)] = .{
1090 .llvm_name = "tuning-fast-imm-vector-shift",
1091 .description = "Vector shifts are fast (2/cycle) as opposed to slow (1/cycle)",
1092 .dependencies = featureSet(&[_]Feature{}),
1093 };
1094 result[@intFromEnum(Feature.uintr)] = .{
1095 .llvm_name = "uintr",
1096 .description = "Has UINTR Instructions",
1097 .dependencies = featureSet(&[_]Feature{}),
1098 };
1099 result[@intFromEnum(Feature.use_glm_div_sqrt_costs)] = .{
1100 .llvm_name = "use-glm-div-sqrt-costs",
1101 .description = "Use Goldmont specific floating point div/sqrt costs",
1102 .dependencies = featureSet(&[_]Feature{}),
1103 };
1104 result[@intFromEnum(Feature.use_slm_arith_costs)] = .{
1105 .llvm_name = "use-slm-arith-costs",
1106 .description = "Use Silvermont specific arithmetic costs",
1107 .dependencies = featureSet(&[_]Feature{}),
1108 };
1109 result[@intFromEnum(Feature.vaes)] = .{
1110 .llvm_name = "vaes",
1111 .description = "Promote selected AES instructions to AVX512/AVX registers",
1112 .dependencies = featureSet(&[_]Feature{
1113 .aes,
1114 .avx,
1115 }),
1116 };
1117 result[@intFromEnum(Feature.vpclmulqdq)] = .{
1118 .llvm_name = "vpclmulqdq",
1119 .description = "Enable vpclmulqdq instructions",
1120 .dependencies = featureSet(&[_]Feature{
1121 .avx,
1122 .pclmul,
1123 }),
1124 };
1125 result[@intFromEnum(Feature.vzeroupper)] = .{
1126 .llvm_name = "vzeroupper",
1127 .description = "Should insert vzeroupper instructions",
1128 .dependencies = featureSet(&[_]Feature{}),
1129 };
1130 result[@intFromEnum(Feature.waitpkg)] = .{
1131 .llvm_name = "waitpkg",
1132 .description = "Wait and pause enhancements",
1133 .dependencies = featureSet(&[_]Feature{}),
1134 };
1135 result[@intFromEnum(Feature.wbnoinvd)] = .{
1136 .llvm_name = "wbnoinvd",
1137 .description = "Write Back No Invalidate",
1138 .dependencies = featureSet(&[_]Feature{}),
1139 };
1140 result[@intFromEnum(Feature.widekl)] = .{
1141 .llvm_name = "widekl",
1142 .description = "Support Key Locker wide Instructions",
1143 .dependencies = featureSet(&[_]Feature{
1144 .kl,
1145 }),
1146 };
1147 result[@intFromEnum(Feature.x87)] = .{
1148 .llvm_name = "x87",
1149 .description = "Enable X87 float instructions",
1150 .dependencies = featureSet(&[_]Feature{}),
1151 };
1152 result[@intFromEnum(Feature.xop)] = .{
1153 .llvm_name = "xop",
1154 .description = "Enable XOP instructions",
1155 .dependencies = featureSet(&[_]Feature{
1156 .fma4,
1157 }),
1158 };
1159 result[@intFromEnum(Feature.xsave)] = .{
1160 .llvm_name = "xsave",
1161 .description = "Support xsave instructions",
1162 .dependencies = featureSet(&[_]Feature{}),
1163 };
1164 result[@intFromEnum(Feature.xsavec)] = .{
1165 .llvm_name = "xsavec",
1166 .description = "Support xsavec instructions",
1167 .dependencies = featureSet(&[_]Feature{
1168 .xsave,
1169 }),
1170 };
1171 result[@intFromEnum(Feature.xsaveopt)] = .{
1172 .llvm_name = "xsaveopt",
1173 .description = "Support xsaveopt instructions",
1174 .dependencies = featureSet(&[_]Feature{
1175 .xsave,
1176 }),
1177 };
1178 result[@intFromEnum(Feature.xsaves)] = .{
1179 .llvm_name = "xsaves",
1180 .description = "Support xsaves instructions",
1181 .dependencies = featureSet(&[_]Feature{
1182 .xsave,
1183 }),
1184 };
1185 const ti = @typeInfo(Feature);
1186 for (&result, 0..) |*elem, i| {
1187 elem.index = i;
1188 elem.name = ti.Enum.fields[i].name;
1189 }
1190 break :blk result;
1191};
1192
1193pub const cpu = struct {
1194 pub const alderlake = CpuModel{
1195 .name = "alderlake",
1196 .llvm_name = "alderlake",
1197 .features = featureSet(&[_]Feature{
1198 .@"64bit",
1199 .adx,
1200 .allow_light_256_bit,
1201 .avxvnni,
1202 .bmi,
1203 .bmi2,
1204 .cldemote,
1205 .clflushopt,
1206 .clwb,
1207 .cmov,
1208 .crc32,
1209 .cx16,
1210 .f16c,
1211 .false_deps_perm,
1212 .false_deps_popcnt,
1213 .fast_15bytenop,
1214 .fast_gather,
1215 .fast_scalar_fsqrt,
1216 .fast_shld_rotate,
1217 .fast_variable_crosslane_shuffle,
1218 .fast_variable_perlane_shuffle,
1219 .fast_vector_fsqrt,
1220 .fma,
1221 .fsgsbase,
1222 .fxsr,
1223 .gfni,
1224 .hreset,
1225 .idivq_to_divl,
1226 .invpcid,
1227 .lzcnt,
1228 .macrofusion,
1229 .mmx,
1230 .movbe,
1231 .movdir64b,
1232 .movdiri,
1233 .no_bypass_delay_blend,
1234 .no_bypass_delay_mov,
1235 .no_bypass_delay_shuffle,
1236 .nopl,
1237 .pconfig,
1238 .pku,
1239 .popcnt,
1240 .prefer_movmsk_over_vtest,
1241 .prfchw,
1242 .ptwrite,
1243 .rdpid,
1244 .rdrnd,
1245 .rdseed,
1246 .sahf,
1247 .serialize,
1248 .sha,
1249 .shstk,
1250 .slow_3ops_lea,
1251 .tuning_fast_imm_vector_shift,
1252 .vaes,
1253 .vpclmulqdq,
1254 .vzeroupper,
1255 .waitpkg,
1256 .widekl,
1257 .x87,
1258 .xsavec,
1259 .xsaveopt,
1260 .xsaves,
1261 }),
1262 };
1263 pub const amdfam10 = CpuModel{
1264 .name = "amdfam10",
1265 .llvm_name = "amdfam10",
1266 .features = featureSet(&[_]Feature{
1267 .@"3dnowa",
1268 .@"64bit",
1269 .cmov,
1270 .cx16,
1271 .fast_scalar_shift_masks,
1272 .fxsr,
1273 .lzcnt,
1274 .nopl,
1275 .popcnt,
1276 .prfchw,
1277 .sahf,
1278 .sbb_dep_breaking,
1279 .slow_shld,
1280 .sse4a,
1281 .vzeroupper,
1282 .x87,
1283 }),
1284 };
1285 pub const athlon = CpuModel{
1286 .name = "athlon",
1287 .llvm_name = "athlon",
1288 .features = featureSet(&[_]Feature{
1289 .@"3dnowa",
1290 .cmov,
1291 .cx8,
1292 .nopl,
1293 .slow_shld,
1294 .slow_unaligned_mem_16,
1295 .vzeroupper,
1296 .x87,
1297 }),
1298 };
1299 pub const athlon64 = CpuModel{
1300 .name = "athlon64",
1301 .llvm_name = "athlon64",
1302 .features = featureSet(&[_]Feature{
1303 .@"3dnowa",
1304 .@"64bit",
1305 .cmov,
1306 .cx8,
1307 .fast_scalar_shift_masks,
1308 .fxsr,
1309 .nopl,
1310 .sbb_dep_breaking,
1311 .slow_shld,
1312 .slow_unaligned_mem_16,
1313 .sse2,
1314 .vzeroupper,
1315 .x87,
1316 }),
1317 };
1318 pub const athlon64_sse3 = CpuModel{
1319 .name = "athlon64_sse3",
1320 .llvm_name = "athlon64-sse3",
1321 .features = featureSet(&[_]Feature{
1322 .@"3dnowa",
1323 .@"64bit",
1324 .cmov,
1325 .cx16,
1326 .fast_scalar_shift_masks,
1327 .fxsr,
1328 .nopl,
1329 .sbb_dep_breaking,
1330 .slow_shld,
1331 .slow_unaligned_mem_16,
1332 .sse3,
1333 .vzeroupper,
1334 .x87,
1335 }),
1336 };
1337 pub const athlon_4 = CpuModel{
1338 .name = "athlon_4",
1339 .llvm_name = "athlon-4",
1340 .features = featureSet(&[_]Feature{
1341 .@"3dnowa",
1342 .cmov,
1343 .cx8,
1344 .fxsr,
1345 .nopl,
1346 .slow_shld,
1347 .slow_unaligned_mem_16,
1348 .sse,
1349 .vzeroupper,
1350 .x87,
1351 }),
1352 };
1353 pub const athlon_fx = CpuModel{
1354 .name = "athlon_fx",
1355 .llvm_name = "athlon-fx",
1356 .features = featureSet(&[_]Feature{
1357 .@"3dnowa",
1358 .@"64bit",
1359 .cmov,
1360 .cx8,
1361 .fast_scalar_shift_masks,
1362 .fxsr,
1363 .nopl,
1364 .sbb_dep_breaking,
1365 .slow_shld,
1366 .slow_unaligned_mem_16,
1367 .sse2,
1368 .vzeroupper,
1369 .x87,
1370 }),
1371 };
1372 pub const athlon_mp = CpuModel{
1373 .name = "athlon_mp",
1374 .llvm_name = "athlon-mp",
1375 .features = featureSet(&[_]Feature{
1376 .@"3dnowa",
1377 .cmov,
1378 .cx8,
1379 .fxsr,
1380 .nopl,
1381 .slow_shld,
1382 .slow_unaligned_mem_16,
1383 .sse,
1384 .vzeroupper,
1385 .x87,
1386 }),
1387 };
1388 pub const athlon_tbird = CpuModel{
1389 .name = "athlon_tbird",
1390 .llvm_name = "athlon-tbird",
1391 .features = featureSet(&[_]Feature{
1392 .@"3dnowa",
1393 .cmov,
1394 .cx8,
1395 .nopl,
1396 .slow_shld,
1397 .slow_unaligned_mem_16,
1398 .vzeroupper,
1399 .x87,
1400 }),
1401 };
1402 pub const athlon_xp = CpuModel{
1403 .name = "athlon_xp",
1404 .llvm_name = "athlon-xp",
1405 .features = featureSet(&[_]Feature{
1406 .@"3dnowa",
1407 .cmov,
1408 .cx8,
1409 .fxsr,
1410 .nopl,
1411 .slow_shld,
1412 .slow_unaligned_mem_16,
1413 .sse,
1414 .vzeroupper,
1415 .x87,
1416 }),
1417 };
1418 pub const atom = CpuModel{
1419 .name = "atom",
1420 .llvm_name = "atom",
1421 .features = featureSet(&[_]Feature{
1422 .@"64bit",
1423 .cmov,
1424 .cx16,
1425 .fxsr,
1426 .idivl_to_divb,
1427 .idivq_to_divl,
1428 .lea_sp,
1429 .lea_uses_ag,
1430 .mmx,
1431 .movbe,
1432 .no_bypass_delay,
1433 .nopl,
1434 .pad_short_functions,
1435 .sahf,
1436 .slow_two_mem_ops,
1437 .slow_unaligned_mem_16,
1438 .ssse3,
1439 .vzeroupper,
1440 .x87,
1441 }),
1442 };
1443 pub const atom_sse4_2_movbe = CpuModel{
1444 .name = "atom_sse4_2_movbe",
1445 .llvm_name = "atom_sse4_2_movbe",
1446 .features = featureSet(&[_]Feature{
1447 .@"64bit",
1448 .aes,
1449 .clflushopt,
1450 .cmov,
1451 .crc32,
1452 .cx16,
1453 .false_deps_popcnt,
1454 .fast_7bytenop,
1455 .fast_movbe,
1456 .fsgsbase,
1457 .fxsr,
1458 .idivq_to_divl,
1459 .mmx,
1460 .movbe,
1461 .no_bypass_delay,
1462 .nopl,
1463 .pclmul,
1464 .popcnt,
1465 .prfchw,
1466 .rdrnd,
1467 .rdseed,
1468 .sahf,
1469 .sha,
1470 .slow_incdec,
1471 .slow_lea,
1472 .slow_pmulld,
1473 .slow_two_mem_ops,
1474 .sse4_2,
1475 .use_slm_arith_costs,
1476 .vzeroupper,
1477 .x87,
1478 .xsavec,
1479 .xsaveopt,
1480 .xsaves,
1481 }),
1482 };
1483 pub const barcelona = CpuModel{
1484 .name = "barcelona",
1485 .llvm_name = "barcelona",
1486 .features = featureSet(&[_]Feature{
1487 .@"3dnowa",
1488 .@"64bit",
1489 .cmov,
1490 .cx16,
1491 .fast_scalar_shift_masks,
1492 .fxsr,
1493 .lzcnt,
1494 .nopl,
1495 .popcnt,
1496 .prfchw,
1497 .sahf,
1498 .sbb_dep_breaking,
1499 .slow_shld,
1500 .sse4a,
1501 .vzeroupper,
1502 .x87,
1503 }),
1504 };
1505 pub const bdver1 = CpuModel{
1506 .name = "bdver1",
1507 .llvm_name = "bdver1",
1508 .features = featureSet(&[_]Feature{
1509 .@"64bit",
1510 .aes,
1511 .branchfusion,
1512 .cmov,
1513 .crc32,
1514 .cx16,
1515 .fast_11bytenop,
1516 .fast_scalar_shift_masks,
1517 .fxsr,
1518 .lwp,
1519 .lzcnt,
1520 .mmx,
1521 .nopl,
1522 .pclmul,
1523 .popcnt,
1524 .prfchw,
1525 .sahf,
1526 .sbb_dep_breaking,
1527 .slow_shld,
1528 .vzeroupper,
1529 .x87,
1530 .xop,
1531 .xsave,
1532 }),
1533 };
1534 pub const bdver2 = CpuModel{
1535 .name = "bdver2",
1536 .llvm_name = "bdver2",
1537 .features = featureSet(&[_]Feature{
1538 .@"64bit",
1539 .aes,
1540 .bmi,
1541 .branchfusion,
1542 .cmov,
1543 .crc32,
1544 .cx16,
1545 .f16c,
1546 .fast_11bytenop,
1547 .fast_bextr,
1548 .fast_movbe,
1549 .fast_scalar_shift_masks,
1550 .fma,
1551 .fxsr,
1552 .lwp,
1553 .lzcnt,
1554 .mmx,
1555 .nopl,
1556 .pclmul,
1557 .popcnt,
1558 .prfchw,
1559 .sahf,
1560 .sbb_dep_breaking,
1561 .slow_shld,
1562 .tbm,
1563 .vzeroupper,
1564 .x87,
1565 .xop,
1566 .xsave,
1567 }),
1568 };
1569 pub const bdver3 = CpuModel{
1570 .name = "bdver3",
1571 .llvm_name = "bdver3",
1572 .features = featureSet(&[_]Feature{
1573 .@"64bit",
1574 .aes,
1575 .bmi,
1576 .branchfusion,
1577 .cmov,
1578 .crc32,
1579 .cx16,
1580 .f16c,
1581 .fast_11bytenop,
1582 .fast_bextr,
1583 .fast_movbe,
1584 .fast_scalar_shift_masks,
1585 .fma,
1586 .fsgsbase,
1587 .fxsr,
1588 .lwp,
1589 .lzcnt,
1590 .mmx,
1591 .nopl,
1592 .pclmul,
1593 .popcnt,
1594 .prfchw,
1595 .sahf,
1596 .sbb_dep_breaking,
1597 .slow_shld,
1598 .tbm,
1599 .vzeroupper,
1600 .x87,
1601 .xop,
1602 .xsaveopt,
1603 }),
1604 };
1605 pub const bdver4 = CpuModel{
1606 .name = "bdver4",
1607 .llvm_name = "bdver4",
1608 .features = featureSet(&[_]Feature{
1609 .@"64bit",
1610 .aes,
1611 .avx2,
1612 .bmi,
1613 .bmi2,
1614 .branchfusion,
1615 .cmov,
1616 .crc32,
1617 .cx16,
1618 .f16c,
1619 .fast_11bytenop,
1620 .fast_bextr,
1621 .fast_movbe,
1622 .fast_scalar_shift_masks,
1623 .fma,
1624 .fsgsbase,
1625 .fxsr,
1626 .lwp,
1627 .lzcnt,
1628 .mmx,
1629 .movbe,
1630 .mwaitx,
1631 .nopl,
1632 .pclmul,
1633 .popcnt,
1634 .prfchw,
1635 .rdrnd,
1636 .sahf,
1637 .sbb_dep_breaking,
1638 .slow_shld,
1639 .tbm,
1640 .vzeroupper,
1641 .x87,
1642 .xop,
1643 .xsaveopt,
1644 }),
1645 };
1646 pub const bonnell = CpuModel{
1647 .name = "bonnell",
1648 .llvm_name = "bonnell",
1649 .features = featureSet(&[_]Feature{
1650 .@"64bit",
1651 .cmov,
1652 .cx16,
1653 .fxsr,
1654 .idivl_to_divb,
1655 .idivq_to_divl,
1656 .lea_sp,
1657 .lea_uses_ag,
1658 .mmx,
1659 .movbe,
1660 .no_bypass_delay,
1661 .nopl,
1662 .pad_short_functions,
1663 .sahf,
1664 .slow_two_mem_ops,
1665 .slow_unaligned_mem_16,
1666 .ssse3,
1667 .vzeroupper,
1668 .x87,
1669 }),
1670 };
1671 pub const broadwell = CpuModel{
1672 .name = "broadwell",
1673 .llvm_name = "broadwell",
1674 .features = featureSet(&[_]Feature{
1675 .@"64bit",
1676 .adx,
1677 .allow_light_256_bit,
1678 .avx2,
1679 .bmi,
1680 .bmi2,
1681 .cmov,
1682 .crc32,
1683 .cx16,
1684 .ermsb,
1685 .f16c,
1686 .false_deps_lzcnt_tzcnt,
1687 .false_deps_popcnt,
1688 .fast_15bytenop,
1689 .fast_scalar_fsqrt,
1690 .fast_shld_rotate,
1691 .fast_variable_crosslane_shuffle,
1692 .fast_variable_perlane_shuffle,
1693 .fma,
1694 .fsgsbase,
1695 .fxsr,
1696 .idivq_to_divl,
1697 .invpcid,
1698 .lzcnt,
1699 .macrofusion,
1700 .mmx,
1701 .movbe,
1702 .no_bypass_delay_mov,
1703 .no_bypass_delay_shuffle,
1704 .nopl,
1705 .pclmul,
1706 .popcnt,
1707 .prfchw,
1708 .rdrnd,
1709 .rdseed,
1710 .sahf,
1711 .slow_3ops_lea,
1712 .vzeroupper,
1713 .x87,
1714 .xsaveopt,
1715 }),
1716 };
1717 pub const btver1 = CpuModel{
1718 .name = "btver1",
1719 .llvm_name = "btver1",
1720 .features = featureSet(&[_]Feature{
1721 .@"64bit",
1722 .cmov,
1723 .cx16,
1724 .fast_15bytenop,
1725 .fast_scalar_shift_masks,
1726 .fast_vector_shift_masks,
1727 .fxsr,
1728 .lzcnt,
1729 .mmx,
1730 .nopl,
1731 .popcnt,
1732 .prfchw,
1733 .sahf,
1734 .sbb_dep_breaking,
1735 .slow_shld,
1736 .sse4a,
1737 .ssse3,
1738 .vzeroupper,
1739 .x87,
1740 }),
1741 };
1742 pub const btver2 = CpuModel{
1743 .name = "btver2",
1744 .llvm_name = "btver2",
1745 .features = featureSet(&[_]Feature{
1746 .@"64bit",
1747 .aes,
1748 .bmi,
1749 .cmov,
1750 .crc32,
1751 .cx16,
1752 .f16c,
1753 .fast_15bytenop,
1754 .fast_bextr,
1755 .fast_hops,
1756 .fast_lzcnt,
1757 .fast_movbe,
1758 .fast_scalar_shift_masks,
1759 .fast_vector_shift_masks,
1760 .fxsr,
1761 .lzcnt,
1762 .mmx,
1763 .movbe,
1764 .nopl,
1765 .pclmul,
1766 .popcnt,
1767 .prfchw,
1768 .sahf,
1769 .sbb_dep_breaking,
1770 .slow_shld,
1771 .sse4a,
1772 .x87,
1773 .xsaveopt,
1774 }),
1775 };
1776 pub const c3 = CpuModel{
1777 .name = "c3",
1778 .llvm_name = "c3",
1779 .features = featureSet(&[_]Feature{
1780 .@"3dnow",
1781 .slow_unaligned_mem_16,
1782 .vzeroupper,
1783 .x87,
1784 }),
1785 };
1786 pub const c3_2 = CpuModel{
1787 .name = "c3_2",
1788 .llvm_name = "c3-2",
1789 .features = featureSet(&[_]Feature{
1790 .cmov,
1791 .cx8,
1792 .fxsr,
1793 .mmx,
1794 .slow_unaligned_mem_16,
1795 .sse,
1796 .vzeroupper,
1797 .x87,
1798 }),
1799 };
1800 pub const cannonlake = CpuModel{
1801 .name = "cannonlake",
1802 .llvm_name = "cannonlake",
1803 .features = featureSet(&[_]Feature{
1804 .@"64bit",
1805 .adx,
1806 .aes,
1807 .allow_light_256_bit,
1808 .avx512cd,
1809 .avx512dq,
1810 .avx512ifma,
1811 .avx512vbmi,
1812 .avx512vl,
1813 .bmi,
1814 .bmi2,
1815 .clflushopt,
1816 .cmov,
1817 .crc32,
1818 .cx16,
1819 .ermsb,
1820 .fast_15bytenop,
1821 .fast_gather,
1822 .fast_scalar_fsqrt,
1823 .fast_shld_rotate,
1824 .fast_variable_crosslane_shuffle,
1825 .fast_variable_perlane_shuffle,
1826 .fast_vector_fsqrt,
1827 .fsgsbase,
1828 .fxsr,
1829 .idivq_to_divl,
1830 .invpcid,
1831 .lzcnt,
1832 .macrofusion,
1833 .mmx,
1834 .movbe,
1835 .no_bypass_delay_blend,
1836 .no_bypass_delay_mov,
1837 .no_bypass_delay_shuffle,
1838 .nopl,
1839 .pclmul,
1840 .pku,
1841 .popcnt,
1842 .prefer_256_bit,
1843 .prfchw,
1844 .rdrnd,
1845 .rdseed,
1846 .sahf,
1847 .sha,
1848 .slow_3ops_lea,
1849 .tuning_fast_imm_vector_shift,
1850 .vzeroupper,
1851 .x87,
1852 .xsavec,
1853 .xsaveopt,
1854 .xsaves,
1855 }),
1856 };
1857 pub const cascadelake = CpuModel{
1858 .name = "cascadelake",
1859 .llvm_name = "cascadelake",
1860 .features = featureSet(&[_]Feature{
1861 .@"64bit",
1862 .adx,
1863 .aes,
1864 .allow_light_256_bit,
1865 .avx512bw,
1866 .avx512cd,
1867 .avx512dq,
1868 .avx512vl,
1869 .avx512vnni,
1870 .bmi,
1871 .bmi2,
1872 .clflushopt,
1873 .clwb,
1874 .cmov,
1875 .crc32,
1876 .cx16,
1877 .ermsb,
1878 .false_deps_popcnt,
1879 .fast_15bytenop,
1880 .fast_gather,
1881 .fast_scalar_fsqrt,
1882 .fast_shld_rotate,
1883 .fast_variable_crosslane_shuffle,
1884 .fast_variable_perlane_shuffle,
1885 .fast_vector_fsqrt,
1886 .faster_shift_than_shuffle,
1887 .fsgsbase,
1888 .fxsr,
1889 .idivq_to_divl,
1890 .invpcid,
1891 .lzcnt,
1892 .macrofusion,
1893 .mmx,
1894 .movbe,
1895 .no_bypass_delay_blend,
1896 .no_bypass_delay_mov,
1897 .no_bypass_delay_shuffle,
1898 .nopl,
1899 .pclmul,
1900 .pku,
1901 .popcnt,
1902 .prefer_256_bit,
1903 .prfchw,
1904 .rdrnd,
1905 .rdseed,
1906 .sahf,
1907 .slow_3ops_lea,
1908 .tuning_fast_imm_vector_shift,
1909 .vzeroupper,
1910 .x87,
1911 .xsavec,
1912 .xsaveopt,
1913 .xsaves,
1914 }),
1915 };
1916 pub const cooperlake = CpuModel{
1917 .name = "cooperlake",
1918 .llvm_name = "cooperlake",
1919 .features = featureSet(&[_]Feature{
1920 .@"64bit",
1921 .adx,
1922 .aes,
1923 .allow_light_256_bit,
1924 .avx512bf16,
1925 .avx512cd,
1926 .avx512dq,
1927 .avx512vl,
1928 .avx512vnni,
1929 .bmi,
1930 .bmi2,
1931 .clflushopt,
1932 .clwb,
1933 .cmov,
1934 .crc32,
1935 .cx16,
1936 .ermsb,
1937 .false_deps_popcnt,
1938 .fast_15bytenop,
1939 .fast_gather,
1940 .fast_scalar_fsqrt,
1941 .fast_shld_rotate,
1942 .fast_variable_crosslane_shuffle,
1943 .fast_variable_perlane_shuffle,
1944 .fast_vector_fsqrt,
1945 .faster_shift_than_shuffle,
1946 .fsgsbase,
1947 .fxsr,
1948 .idivq_to_divl,
1949 .invpcid,
1950 .lzcnt,
1951 .macrofusion,
1952 .mmx,
1953 .movbe,
1954 .no_bypass_delay_blend,
1955 .no_bypass_delay_mov,
1956 .no_bypass_delay_shuffle,
1957 .nopl,
1958 .pclmul,
1959 .pku,
1960 .popcnt,
1961 .prefer_256_bit,
1962 .prfchw,
1963 .rdrnd,
1964 .rdseed,
1965 .sahf,
1966 .slow_3ops_lea,
1967 .tuning_fast_imm_vector_shift,
1968 .vzeroupper,
1969 .x87,
1970 .xsavec,
1971 .xsaveopt,
1972 .xsaves,
1973 }),
1974 };
1975 pub const core2 = CpuModel{
1976 .name = "core2",
1977 .llvm_name = "core2",
1978 .features = featureSet(&[_]Feature{
1979 .@"64bit",
1980 .cmov,
1981 .cx16,
1982 .fxsr,
1983 .macrofusion,
1984 .mmx,
1985 .nopl,
1986 .sahf,
1987 .slow_unaligned_mem_16,
1988 .ssse3,
1989 .vzeroupper,
1990 .x87,
1991 }),
1992 };
1993 pub const corei7 = CpuModel{
1994 .name = "corei7",
1995 .llvm_name = "corei7",
1996 .features = featureSet(&[_]Feature{
1997 .@"64bit",
1998 .cmov,
1999 .crc32,
2000 .cx16,
2001 .fxsr,
2002 .macrofusion,
2003 .mmx,
2004 .no_bypass_delay_mov,
2005 .nopl,
2006 .popcnt,
2007 .sahf,
2008 .sse4_2,
2009 .vzeroupper,
2010 .x87,
2011 }),
2012 };
2013 pub const emeraldrapids = CpuModel{
2014 .name = "emeraldrapids",
2015 .llvm_name = "emeraldrapids",
2016 .features = featureSet(&[_]Feature{
2017 .@"64bit",
2018 .adx,
2019 .allow_light_256_bit,
2020 .amx_bf16,
2021 .amx_int8,
2022 .avx512bf16,
2023 .avx512bitalg,
2024 .avx512cd,
2025 .avx512fp16,
2026 .avx512ifma,
2027 .avx512vbmi,
2028 .avx512vbmi2,
2029 .avx512vnni,
2030 .avx512vpopcntdq,
2031 .avxvnni,
2032 .bmi,
2033 .bmi2,
2034 .cldemote,
2035 .clflushopt,
2036 .clwb,
2037 .cmov,
2038 .crc32,
2039 .cx16,
2040 .enqcmd,
2041 .ermsb,
2042 .false_deps_getmant,
2043 .false_deps_mulc,
2044 .false_deps_mullq,
2045 .false_deps_perm,
2046 .false_deps_range,
2047 .fast_15bytenop,
2048 .fast_gather,
2049 .fast_scalar_fsqrt,
2050 .fast_shld_rotate,
2051 .fast_variable_crosslane_shuffle,
2052 .fast_variable_perlane_shuffle,
2053 .fast_vector_fsqrt,
2054 .fsgsbase,
2055 .fsrm,
2056 .fxsr,
2057 .gfni,
2058 .idivq_to_divl,
2059 .invpcid,
2060 .lzcnt,
2061 .macrofusion,
2062 .mmx,
2063 .movbe,
2064 .movdir64b,
2065 .movdiri,
2066 .no_bypass_delay_blend,
2067 .no_bypass_delay_mov,
2068 .no_bypass_delay_shuffle,
2069 .nopl,
2070 .pconfig,
2071 .pku,
2072 .popcnt,
2073 .prefer_256_bit,
2074 .prfchw,
2075 .ptwrite,
2076 .rdpid,
2077 .rdrnd,
2078 .rdseed,
2079 .sahf,
2080 .serialize,
2081 .sha,
2082 .shstk,
2083 .tsxldtrk,
2084 .tuning_fast_imm_vector_shift,
2085 .uintr,
2086 .vaes,
2087 .vpclmulqdq,
2088 .vzeroupper,
2089 .waitpkg,
2090 .wbnoinvd,
2091 .x87,
2092 .xsavec,
2093 .xsaveopt,
2094 .xsaves,
2095 }),
2096 };
2097 pub const generic = CpuModel{
2098 .name = "generic",
2099 .llvm_name = "generic",
2100 .features = featureSet(&[_]Feature{
2101 .@"64bit",
2102 .cx8,
2103 .fast_15bytenop,
2104 .fast_scalar_fsqrt,
2105 .idivq_to_divl,
2106 .macrofusion,
2107 .slow_3ops_lea,
2108 .vzeroupper,
2109 .x87,
2110 }),
2111 };
2112 pub const geode = CpuModel{
2113 .name = "geode",
2114 .llvm_name = "geode",
2115 .features = featureSet(&[_]Feature{
2116 .@"3dnowa",
2117 .cx8,
2118 .slow_unaligned_mem_16,
2119 .vzeroupper,
2120 .x87,
2121 }),
2122 };
2123 pub const goldmont = CpuModel{
2124 .name = "goldmont",
2125 .llvm_name = "goldmont",
2126 .features = featureSet(&[_]Feature{
2127 .@"64bit",
2128 .aes,
2129 .clflushopt,
2130 .cmov,
2131 .crc32,
2132 .cx16,
2133 .false_deps_popcnt,
2134 .fast_movbe,
2135 .fsgsbase,
2136 .fxsr,
2137 .mmx,
2138 .movbe,
2139 .no_bypass_delay,
2140 .nopl,
2141 .pclmul,
2142 .popcnt,
2143 .prfchw,
2144 .rdrnd,
2145 .rdseed,
2146 .sahf,
2147 .sha,
2148 .slow_incdec,
2149 .slow_lea,
2150 .slow_two_mem_ops,
2151 .sse4_2,
2152 .use_glm_div_sqrt_costs,
2153 .vzeroupper,
2154 .x87,
2155 .xsavec,
2156 .xsaveopt,
2157 .xsaves,
2158 }),
2159 };
2160 pub const goldmont_plus = CpuModel{
2161 .name = "goldmont_plus",
2162 .llvm_name = "goldmont-plus",
2163 .features = featureSet(&[_]Feature{
2164 .@"64bit",
2165 .aes,
2166 .clflushopt,
2167 .cmov,
2168 .crc32,
2169 .cx16,
2170 .fast_movbe,
2171 .fsgsbase,
2172 .fxsr,
2173 .mmx,
2174 .movbe,
2175 .no_bypass_delay,
2176 .nopl,
2177 .pclmul,
2178 .popcnt,
2179 .prfchw,
2180 .ptwrite,
2181 .rdpid,
2182 .rdrnd,
2183 .rdseed,
2184 .sahf,
2185 .sha,
2186 .slow_incdec,
2187 .slow_lea,
2188 .slow_two_mem_ops,
2189 .sse4_2,
2190 .use_glm_div_sqrt_costs,
2191 .vzeroupper,
2192 .x87,
2193 .xsavec,
2194 .xsaveopt,
2195 .xsaves,
2196 }),
2197 };
2198 pub const grandridge = CpuModel{
2199 .name = "grandridge",
2200 .llvm_name = "grandridge",
2201 .features = featureSet(&[_]Feature{
2202 .@"64bit",
2203 .adx,
2204 .avxifma,
2205 .avxneconvert,
2206 .avxvnni,
2207 .avxvnniint8,
2208 .bmi,
2209 .bmi2,
2210 .cldemote,
2211 .clflushopt,
2212 .clwb,
2213 .cmov,
2214 .cmpccxadd,
2215 .crc32,
2216 .cx16,
2217 .enqcmd,
2218 .f16c,
2219 .fast_movbe,
2220 .fma,
2221 .fsgsbase,
2222 .fxsr,
2223 .gfni,
2224 .hreset,
2225 .invpcid,
2226 .lzcnt,
2227 .mmx,
2228 .movbe,
2229 .movdir64b,
2230 .movdiri,
2231 .no_bypass_delay,
2232 .nopl,
2233 .pconfig,
2234 .pku,
2235 .popcnt,
2236 .prfchw,
2237 .ptwrite,
2238 .raoint,
2239 .rdpid,
2240 .rdrnd,
2241 .rdseed,
2242 .sahf,
2243 .serialize,
2244 .sha,
2245 .shstk,
2246 .slow_incdec,
2247 .slow_lea,
2248 .slow_two_mem_ops,
2249 .uintr,
2250 .use_glm_div_sqrt_costs,
2251 .vaes,
2252 .vpclmulqdq,
2253 .vzeroupper,
2254 .waitpkg,
2255 .widekl,
2256 .x87,
2257 .xsavec,
2258 .xsaveopt,
2259 .xsaves,
2260 }),
2261 };
2262 pub const graniterapids = CpuModel{
2263 .name = "graniterapids",
2264 .llvm_name = "graniterapids",
2265 .features = featureSet(&[_]Feature{
2266 .@"64bit",
2267 .adx,
2268 .allow_light_256_bit,
2269 .amx_bf16,
2270 .amx_fp16,
2271 .amx_int8,
2272 .avx512bf16,
2273 .avx512bitalg,
2274 .avx512cd,
2275 .avx512fp16,
2276 .avx512ifma,
2277 .avx512vbmi,
2278 .avx512vbmi2,
2279 .avx512vnni,
2280 .avx512vpopcntdq,
2281 .avxvnni,
2282 .bmi,
2283 .bmi2,
2284 .cldemote,
2285 .clflushopt,
2286 .clwb,
2287 .cmov,
2288 .crc32,
2289 .cx16,
2290 .enqcmd,
2291 .ermsb,
2292 .false_deps_getmant,
2293 .false_deps_mulc,
2294 .false_deps_mullq,
2295 .false_deps_perm,
2296 .false_deps_range,
2297 .fast_15bytenop,
2298 .fast_gather,
2299 .fast_scalar_fsqrt,
2300 .fast_shld_rotate,
2301 .fast_variable_crosslane_shuffle,
2302 .fast_variable_perlane_shuffle,
2303 .fast_vector_fsqrt,
2304 .fsgsbase,
2305 .fsrm,
2306 .fxsr,
2307 .gfni,
2308 .idivq_to_divl,
2309 .invpcid,
2310 .lzcnt,
2311 .macrofusion,
2312 .mmx,
2313 .movbe,
2314 .movdir64b,
2315 .movdiri,
2316 .no_bypass_delay_blend,
2317 .no_bypass_delay_mov,
2318 .no_bypass_delay_shuffle,
2319 .nopl,
2320 .pconfig,
2321 .pku,
2322 .popcnt,
2323 .prefer_256_bit,
2324 .prefetchi,
2325 .prfchw,
2326 .ptwrite,
2327 .rdpid,
2328 .rdrnd,
2329 .rdseed,
2330 .sahf,
2331 .serialize,
2332 .sha,
2333 .shstk,
2334 .tsxldtrk,
2335 .tuning_fast_imm_vector_shift,
2336 .uintr,
2337 .vaes,
2338 .vpclmulqdq,
2339 .vzeroupper,
2340 .waitpkg,
2341 .wbnoinvd,
2342 .x87,
2343 .xsavec,
2344 .xsaveopt,
2345 .xsaves,
2346 }),
2347 };
2348 pub const graniterapids_d = CpuModel{
2349 .name = "graniterapids_d",
2350 .llvm_name = "graniterapids-d",
2351 .features = featureSet(&[_]Feature{
2352 .@"64bit",
2353 .adx,
2354 .allow_light_256_bit,
2355 .amx_bf16,
2356 .amx_complex,
2357 .amx_fp16,
2358 .amx_int8,
2359 .avx512bf16,
2360 .avx512bitalg,
2361 .avx512cd,
2362 .avx512fp16,
2363 .avx512ifma,
2364 .avx512vbmi,
2365 .avx512vbmi2,
2366 .avx512vnni,
2367 .avx512vpopcntdq,
2368 .avxvnni,
2369 .bmi,
2370 .bmi2,
2371 .cldemote,
2372 .clflushopt,
2373 .clwb,
2374 .cmov,
2375 .crc32,
2376 .cx16,
2377 .enqcmd,
2378 .ermsb,
2379 .false_deps_getmant,
2380 .false_deps_mulc,
2381 .false_deps_mullq,
2382 .false_deps_perm,
2383 .false_deps_range,
2384 .fast_15bytenop,
2385 .fast_gather,
2386 .fast_scalar_fsqrt,
2387 .fast_shld_rotate,
2388 .fast_variable_crosslane_shuffle,
2389 .fast_variable_perlane_shuffle,
2390 .fast_vector_fsqrt,
2391 .fsgsbase,
2392 .fsrm,
2393 .fxsr,
2394 .gfni,
2395 .idivq_to_divl,
2396 .invpcid,
2397 .lzcnt,
2398 .macrofusion,
2399 .mmx,
2400 .movbe,
2401 .movdir64b,
2402 .movdiri,
2403 .no_bypass_delay_blend,
2404 .no_bypass_delay_mov,
2405 .no_bypass_delay_shuffle,
2406 .nopl,
2407 .pconfig,
2408 .pku,
2409 .popcnt,
2410 .prefer_256_bit,
2411 .prefetchi,
2412 .prfchw,
2413 .ptwrite,
2414 .rdpid,
2415 .rdrnd,
2416 .rdseed,
2417 .sahf,
2418 .serialize,
2419 .sha,
2420 .shstk,
2421 .tsxldtrk,
2422 .tuning_fast_imm_vector_shift,
2423 .uintr,
2424 .vaes,
2425 .vpclmulqdq,
2426 .vzeroupper,
2427 .waitpkg,
2428 .wbnoinvd,
2429 .x87,
2430 .xsavec,
2431 .xsaveopt,
2432 .xsaves,
2433 }),
2434 };
2435 pub const haswell = CpuModel{
2436 .name = "haswell",
2437 .llvm_name = "haswell",
2438 .features = featureSet(&[_]Feature{
2439 .@"64bit",
2440 .allow_light_256_bit,
2441 .avx2,
2442 .bmi,
2443 .bmi2,
2444 .cmov,
2445 .crc32,
2446 .cx16,
2447 .ermsb,
2448 .f16c,
2449 .false_deps_lzcnt_tzcnt,
2450 .false_deps_popcnt,
2451 .fast_15bytenop,
2452 .fast_scalar_fsqrt,
2453 .fast_shld_rotate,
2454 .fast_variable_crosslane_shuffle,
2455 .fast_variable_perlane_shuffle,
2456 .fma,
2457 .fsgsbase,
2458 .fxsr,
2459 .idivq_to_divl,
2460 .invpcid,
2461 .lzcnt,
2462 .macrofusion,
2463 .mmx,
2464 .movbe,
2465 .no_bypass_delay_mov,
2466 .no_bypass_delay_shuffle,
2467 .nopl,
2468 .pclmul,
2469 .popcnt,
2470 .rdrnd,
2471 .sahf,
2472 .slow_3ops_lea,
2473 .vzeroupper,
2474 .x87,
2475 .xsaveopt,
2476 }),
2477 };
2478 pub const @"i386" = CpuModel{
2479 .name = "i386",
2480 .llvm_name = "i386",
2481 .features = featureSet(&[_]Feature{
2482 .slow_unaligned_mem_16,
2483 .vzeroupper,
2484 .x87,
2485 }),
2486 };
2487 pub const @"i486" = CpuModel{
2488 .name = "i486",
2489 .llvm_name = "i486",
2490 .features = featureSet(&[_]Feature{
2491 .slow_unaligned_mem_16,
2492 .vzeroupper,
2493 .x87,
2494 }),
2495 };
2496 pub const @"i586" = CpuModel{
2497 .name = "i586",
2498 .llvm_name = "i586",
2499 .features = featureSet(&[_]Feature{
2500 .cx8,
2501 .slow_unaligned_mem_16,
2502 .vzeroupper,
2503 .x87,
2504 }),
2505 };
2506 pub const @"i686" = CpuModel{
2507 .name = "i686",
2508 .llvm_name = "i686",
2509 .features = featureSet(&[_]Feature{
2510 .cmov,
2511 .cx8,
2512 .slow_unaligned_mem_16,
2513 .vzeroupper,
2514 .x87,
2515 }),
2516 };
2517 pub const icelake_client = CpuModel{
2518 .name = "icelake_client",
2519 .llvm_name = "icelake-client",
2520 .features = featureSet(&[_]Feature{
2521 .@"64bit",
2522 .adx,
2523 .allow_light_256_bit,
2524 .avx512bitalg,
2525 .avx512cd,
2526 .avx512dq,
2527 .avx512ifma,
2528 .avx512vbmi,
2529 .avx512vbmi2,
2530 .avx512vl,
2531 .avx512vnni,
2532 .avx512vpopcntdq,
2533 .bmi,
2534 .bmi2,
2535 .clflushopt,
2536 .cmov,
2537 .crc32,
2538 .cx16,
2539 .ermsb,
2540 .fast_15bytenop,
2541 .fast_gather,
2542 .fast_scalar_fsqrt,
2543 .fast_shld_rotate,
2544 .fast_variable_crosslane_shuffle,
2545 .fast_variable_perlane_shuffle,
2546 .fast_vector_fsqrt,
2547 .fsgsbase,
2548 .fsrm,
2549 .fxsr,
2550 .gfni,
2551 .idivq_to_divl,
2552 .invpcid,
2553 .lzcnt,
2554 .macrofusion,
2555 .mmx,
2556 .movbe,
2557 .no_bypass_delay_blend,
2558 .no_bypass_delay_mov,
2559 .no_bypass_delay_shuffle,
2560 .nopl,
2561 .pku,
2562 .popcnt,
2563 .prefer_256_bit,
2564 .prfchw,
2565 .rdpid,
2566 .rdrnd,
2567 .rdseed,
2568 .sahf,
2569 .sha,
2570 .tuning_fast_imm_vector_shift,
2571 .vaes,
2572 .vpclmulqdq,
2573 .vzeroupper,
2574 .x87,
2575 .xsavec,
2576 .xsaveopt,
2577 .xsaves,
2578 }),
2579 };
2580 pub const icelake_server = CpuModel{
2581 .name = "icelake_server",
2582 .llvm_name = "icelake-server",
2583 .features = featureSet(&[_]Feature{
2584 .@"64bit",
2585 .adx,
2586 .allow_light_256_bit,
2587 .avx512bitalg,
2588 .avx512cd,
2589 .avx512dq,
2590 .avx512ifma,
2591 .avx512vbmi,
2592 .avx512vbmi2,
2593 .avx512vl,
2594 .avx512vnni,
2595 .avx512vpopcntdq,
2596 .bmi,
2597 .bmi2,
2598 .clflushopt,
2599 .clwb,
2600 .cmov,
2601 .crc32,
2602 .cx16,
2603 .ermsb,
2604 .fast_15bytenop,
2605 .fast_gather,
2606 .fast_scalar_fsqrt,
2607 .fast_shld_rotate,
2608 .fast_variable_crosslane_shuffle,
2609 .fast_variable_perlane_shuffle,
2610 .fast_vector_fsqrt,
2611 .fsgsbase,
2612 .fsrm,
2613 .fxsr,
2614 .gfni,
2615 .idivq_to_divl,
2616 .invpcid,
2617 .lzcnt,
2618 .macrofusion,
2619 .mmx,
2620 .movbe,
2621 .no_bypass_delay_blend,
2622 .no_bypass_delay_mov,
2623 .no_bypass_delay_shuffle,
2624 .nopl,
2625 .pconfig,
2626 .pku,
2627 .popcnt,
2628 .prefer_256_bit,
2629 .prfchw,
2630 .rdpid,
2631 .rdrnd,
2632 .rdseed,
2633 .sahf,
2634 .sha,
2635 .tuning_fast_imm_vector_shift,
2636 .vaes,
2637 .vpclmulqdq,
2638 .vzeroupper,
2639 .wbnoinvd,
2640 .x87,
2641 .xsavec,
2642 .xsaveopt,
2643 .xsaves,
2644 }),
2645 };
2646 pub const ivybridge = CpuModel{
2647 .name = "ivybridge",
2648 .llvm_name = "ivybridge",
2649 .features = featureSet(&[_]Feature{
2650 .@"64bit",
2651 .cmov,
2652 .crc32,
2653 .cx16,
2654 .f16c,
2655 .false_deps_popcnt,
2656 .fast_15bytenop,
2657 .fast_scalar_fsqrt,
2658 .fast_shld_rotate,
2659 .fsgsbase,
2660 .fxsr,
2661 .idivq_to_divl,
2662 .macrofusion,
2663 .mmx,
2664 .no_bypass_delay_mov,
2665 .nopl,
2666 .pclmul,
2667 .popcnt,
2668 .rdrnd,
2669 .sahf,
2670 .slow_3ops_lea,
2671 .slow_unaligned_mem_32,
2672 .vzeroupper,
2673 .x87,
2674 .xsaveopt,
2675 }),
2676 };
2677 pub const k6 = CpuModel{
2678 .name = "k6",
2679 .llvm_name = "k6",
2680 .features = featureSet(&[_]Feature{
2681 .cx8,
2682 .mmx,
2683 .slow_unaligned_mem_16,
2684 .vzeroupper,
2685 .x87,
2686 }),
2687 };
2688 pub const k6_2 = CpuModel{
2689 .name = "k6_2",
2690 .llvm_name = "k6-2",
2691 .features = featureSet(&[_]Feature{
2692 .@"3dnow",
2693 .cx8,
2694 .slow_unaligned_mem_16,
2695 .vzeroupper,
2696 .x87,
2697 }),
2698 };
2699 pub const k6_3 = CpuModel{
2700 .name = "k6_3",
2701 .llvm_name = "k6-3",
2702 .features = featureSet(&[_]Feature{
2703 .@"3dnow",
2704 .cx8,
2705 .slow_unaligned_mem_16,
2706 .vzeroupper,
2707 .x87,
2708 }),
2709 };
2710 pub const k8 = CpuModel{
2711 .name = "k8",
2712 .llvm_name = "k8",
2713 .features = featureSet(&[_]Feature{
2714 .@"3dnowa",
2715 .@"64bit",
2716 .cmov,
2717 .cx8,
2718 .fast_scalar_shift_masks,
2719 .fxsr,
2720 .nopl,
2721 .sbb_dep_breaking,
2722 .slow_shld,
2723 .slow_unaligned_mem_16,
2724 .sse2,
2725 .vzeroupper,
2726 .x87,
2727 }),
2728 };
2729 pub const k8_sse3 = CpuModel{
2730 .name = "k8_sse3",
2731 .llvm_name = "k8-sse3",
2732 .features = featureSet(&[_]Feature{
2733 .@"3dnowa",
2734 .@"64bit",
2735 .cmov,
2736 .cx16,
2737 .fast_scalar_shift_masks,
2738 .fxsr,
2739 .nopl,
2740 .sbb_dep_breaking,
2741 .slow_shld,
2742 .slow_unaligned_mem_16,
2743 .sse3,
2744 .vzeroupper,
2745 .x87,
2746 }),
2747 };
2748 pub const knl = CpuModel{
2749 .name = "knl",
2750 .llvm_name = "knl",
2751 .features = featureSet(&[_]Feature{
2752 .@"64bit",
2753 .adx,
2754 .aes,
2755 .avx512cd,
2756 .avx512er,
2757 .avx512pf,
2758 .bmi,
2759 .bmi2,
2760 .cmov,
2761 .crc32,
2762 .cx16,
2763 .fast_gather,
2764 .fast_movbe,
2765 .fsgsbase,
2766 .fxsr,
2767 .idivq_to_divl,
2768 .lzcnt,
2769 .mmx,
2770 .movbe,
2771 .nopl,
2772 .pclmul,
2773 .popcnt,
2774 .prefer_mask_registers,
2775 .prefetchwt1,
2776 .prfchw,
2777 .rdrnd,
2778 .rdseed,
2779 .sahf,
2780 .slow_3ops_lea,
2781 .slow_incdec,
2782 .slow_pmaddwd,
2783 .slow_two_mem_ops,
2784 .x87,
2785 .xsaveopt,
2786 }),
2787 };
2788 pub const knm = CpuModel{
2789 .name = "knm",
2790 .llvm_name = "knm",
2791 .features = featureSet(&[_]Feature{
2792 .@"64bit",
2793 .adx,
2794 .aes,
2795 .avx512cd,
2796 .avx512er,
2797 .avx512pf,
2798 .avx512vpopcntdq,
2799 .bmi,
2800 .bmi2,
2801 .cmov,
2802 .crc32,
2803 .cx16,
2804 .fast_gather,
2805 .fast_movbe,
2806 .fsgsbase,
2807 .fxsr,
2808 .idivq_to_divl,
2809 .lzcnt,
2810 .mmx,
2811 .movbe,
2812 .nopl,
2813 .pclmul,
2814 .popcnt,
2815 .prefer_mask_registers,
2816 .prefetchwt1,
2817 .prfchw,
2818 .rdrnd,
2819 .rdseed,
2820 .sahf,
2821 .slow_3ops_lea,
2822 .slow_incdec,
2823 .slow_pmaddwd,
2824 .slow_two_mem_ops,
2825 .x87,
2826 .xsaveopt,
2827 }),
2828 };
2829 pub const lakemont = CpuModel{
2830 .name = "lakemont",
2831 .llvm_name = "lakemont",
2832 .features = featureSet(&[_]Feature{
2833 .cx8,
2834 .slow_unaligned_mem_16,
2835 .soft_float,
2836 .vzeroupper,
2837 }),
2838 };
2839 pub const meteorlake = CpuModel{
2840 .name = "meteorlake",
2841 .llvm_name = "meteorlake",
2842 .features = featureSet(&[_]Feature{
2843 .@"64bit",
2844 .adx,
2845 .allow_light_256_bit,
2846 .avxvnni,
2847 .bmi,
2848 .bmi2,
2849 .cldemote,
2850 .clflushopt,
2851 .clwb,
2852 .cmov,
2853 .crc32,
2854 .cx16,
2855 .f16c,
2856 .false_deps_perm,
2857 .false_deps_popcnt,
2858 .fast_15bytenop,
2859 .fast_gather,
2860 .fast_scalar_fsqrt,
2861 .fast_shld_rotate,
2862 .fast_variable_crosslane_shuffle,
2863 .fast_variable_perlane_shuffle,
2864 .fast_vector_fsqrt,
2865 .fma,
2866 .fsgsbase,
2867 .fxsr,
2868 .gfni,
2869 .hreset,
2870 .idivq_to_divl,
2871 .invpcid,
2872 .lzcnt,
2873 .macrofusion,
2874 .mmx,
2875 .movbe,
2876 .movdir64b,
2877 .movdiri,
2878 .no_bypass_delay_blend,
2879 .no_bypass_delay_mov,
2880 .no_bypass_delay_shuffle,
2881 .nopl,
2882 .pconfig,
2883 .pku,
2884 .popcnt,
2885 .prefer_movmsk_over_vtest,
2886 .prfchw,
2887 .ptwrite,
2888 .rdpid,
2889 .rdrnd,
2890 .rdseed,
2891 .sahf,
2892 .serialize,
2893 .sha,
2894 .shstk,
2895 .slow_3ops_lea,
2896 .tuning_fast_imm_vector_shift,
2897 .vaes,
2898 .vpclmulqdq,
2899 .vzeroupper,
2900 .waitpkg,
2901 .widekl,
2902 .x87,
2903 .xsavec,
2904 .xsaveopt,
2905 .xsaves,
2906 }),
2907 };
2908 pub const nehalem = CpuModel{
2909 .name = "nehalem",
2910 .llvm_name = "nehalem",
2911 .features = featureSet(&[_]Feature{
2912 .@"64bit",
2913 .cmov,
2914 .crc32,
2915 .cx16,
2916 .fxsr,
2917 .macrofusion,
2918 .mmx,
2919 .no_bypass_delay_mov,
2920 .nopl,
2921 .popcnt,
2922 .sahf,
2923 .sse4_2,
2924 .vzeroupper,
2925 .x87,
2926 }),
2927 };
2928 pub const nocona = CpuModel{
2929 .name = "nocona",
2930 .llvm_name = "nocona",
2931 .features = featureSet(&[_]Feature{
2932 .@"64bit",
2933 .cmov,
2934 .cx16,
2935 .fxsr,
2936 .mmx,
2937 .nopl,
2938 .slow_unaligned_mem_16,
2939 .sse3,
2940 .vzeroupper,
2941 .x87,
2942 }),
2943 };
2944 pub const opteron = CpuModel{
2945 .name = "opteron",
2946 .llvm_name = "opteron",
2947 .features = featureSet(&[_]Feature{
2948 .@"3dnowa",
2949 .@"64bit",
2950 .cmov,
2951 .cx8,
2952 .fast_scalar_shift_masks,
2953 .fxsr,
2954 .nopl,
2955 .sbb_dep_breaking,
2956 .slow_shld,
2957 .slow_unaligned_mem_16,
2958 .sse2,
2959 .vzeroupper,
2960 .x87,
2961 }),
2962 };
2963 pub const opteron_sse3 = CpuModel{
2964 .name = "opteron_sse3",
2965 .llvm_name = "opteron-sse3",
2966 .features = featureSet(&[_]Feature{
2967 .@"3dnowa",
2968 .@"64bit",
2969 .cmov,
2970 .cx16,
2971 .fast_scalar_shift_masks,
2972 .fxsr,
2973 .nopl,
2974 .sbb_dep_breaking,
2975 .slow_shld,
2976 .slow_unaligned_mem_16,
2977 .sse3,
2978 .vzeroupper,
2979 .x87,
2980 }),
2981 };
2982 pub const penryn = CpuModel{
2983 .name = "penryn",
2984 .llvm_name = "penryn",
2985 .features = featureSet(&[_]Feature{
2986 .@"64bit",
2987 .cmov,
2988 .cx16,
2989 .fxsr,
2990 .macrofusion,
2991 .mmx,
2992 .nopl,
2993 .sahf,
2994 .slow_unaligned_mem_16,
2995 .sse4_1,
2996 .vzeroupper,
2997 .x87,
2998 }),
2999 };
3000 pub const pentium = CpuModel{
3001 .name = "pentium",
3002 .llvm_name = "pentium",
3003 .features = featureSet(&[_]Feature{
3004 .cx8,
3005 .slow_unaligned_mem_16,
3006 .vzeroupper,
3007 .x87,
3008 }),
3009 };
3010 pub const pentium2 = CpuModel{
3011 .name = "pentium2",
3012 .llvm_name = "pentium2",
3013 .features = featureSet(&[_]Feature{
3014 .cmov,
3015 .cx8,
3016 .fxsr,
3017 .mmx,
3018 .nopl,
3019 .slow_unaligned_mem_16,
3020 .vzeroupper,
3021 .x87,
3022 }),
3023 };
3024 pub const pentium3 = CpuModel{
3025 .name = "pentium3",
3026 .llvm_name = "pentium3",
3027 .features = featureSet(&[_]Feature{
3028 .cmov,
3029 .cx8,
3030 .fxsr,
3031 .mmx,
3032 .nopl,
3033 .slow_unaligned_mem_16,
3034 .sse,
3035 .vzeroupper,
3036 .x87,
3037 }),
3038 };
3039 pub const pentium3m = CpuModel{
3040 .name = "pentium3m",
3041 .llvm_name = "pentium3m",
3042 .features = featureSet(&[_]Feature{
3043 .cmov,
3044 .cx8,
3045 .fxsr,
3046 .mmx,
3047 .nopl,
3048 .slow_unaligned_mem_16,
3049 .sse,
3050 .vzeroupper,
3051 .x87,
3052 }),
3053 };
3054 pub const pentium4 = CpuModel{
3055 .name = "pentium4",
3056 .llvm_name = "pentium4",
3057 .features = featureSet(&[_]Feature{
3058 .cmov,
3059 .cx8,
3060 .fxsr,
3061 .mmx,
3062 .nopl,
3063 .slow_unaligned_mem_16,
3064 .sse2,
3065 .vzeroupper,
3066 .x87,
3067 }),
3068 };
3069 pub const pentium_m = CpuModel{
3070 .name = "pentium_m",
3071 .llvm_name = "pentium-m",
3072 .features = featureSet(&[_]Feature{
3073 .cmov,
3074 .cx8,
3075 .fxsr,
3076 .mmx,
3077 .nopl,
3078 .slow_unaligned_mem_16,
3079 .sse2,
3080 .vzeroupper,
3081 .x87,
3082 }),
3083 };
3084 pub const pentium_mmx = CpuModel{
3085 .name = "pentium_mmx",
3086 .llvm_name = "pentium-mmx",
3087 .features = featureSet(&[_]Feature{
3088 .cx8,
3089 .mmx,
3090 .slow_unaligned_mem_16,
3091 .vzeroupper,
3092 .x87,
3093 }),
3094 };
3095 pub const pentiumpro = CpuModel{
3096 .name = "pentiumpro",
3097 .llvm_name = "pentiumpro",
3098 .features = featureSet(&[_]Feature{
3099 .cmov,
3100 .cx8,
3101 .nopl,
3102 .slow_unaligned_mem_16,
3103 .vzeroupper,
3104 .x87,
3105 }),
3106 };
3107 pub const prescott = CpuModel{
3108 .name = "prescott",
3109 .llvm_name = "prescott",
3110 .features = featureSet(&[_]Feature{
3111 .cmov,
3112 .cx8,
3113 .fxsr,
3114 .mmx,
3115 .nopl,
3116 .slow_unaligned_mem_16,
3117 .sse3,
3118 .vzeroupper,
3119 .x87,
3120 }),
3121 };
3122 pub const raptorlake = CpuModel{
3123 .name = "raptorlake",
3124 .llvm_name = "raptorlake",
3125 .features = featureSet(&[_]Feature{
3126 .@"64bit",
3127 .adx,
3128 .allow_light_256_bit,
3129 .avxvnni,
3130 .bmi,
3131 .bmi2,
3132 .cldemote,
3133 .clflushopt,
3134 .clwb,
3135 .cmov,
3136 .crc32,
3137 .cx16,
3138 .f16c,
3139 .false_deps_perm,
3140 .false_deps_popcnt,
3141 .fast_15bytenop,
3142 .fast_gather,
3143 .fast_scalar_fsqrt,
3144 .fast_shld_rotate,
3145 .fast_variable_crosslane_shuffle,
3146 .fast_variable_perlane_shuffle,
3147 .fast_vector_fsqrt,
3148 .fma,
3149 .fsgsbase,
3150 .fxsr,
3151 .gfni,
3152 .hreset,
3153 .idivq_to_divl,
3154 .invpcid,
3155 .lzcnt,
3156 .macrofusion,
3157 .mmx,
3158 .movbe,
3159 .movdir64b,
3160 .movdiri,
3161 .no_bypass_delay_blend,
3162 .no_bypass_delay_mov,
3163 .no_bypass_delay_shuffle,
3164 .nopl,
3165 .pconfig,
3166 .pku,
3167 .popcnt,
3168 .prefer_movmsk_over_vtest,
3169 .prfchw,
3170 .ptwrite,
3171 .rdpid,
3172 .rdrnd,
3173 .rdseed,
3174 .sahf,
3175 .serialize,
3176 .sha,
3177 .shstk,
3178 .slow_3ops_lea,
3179 .tuning_fast_imm_vector_shift,
3180 .vaes,
3181 .vpclmulqdq,
3182 .vzeroupper,
3183 .waitpkg,
3184 .widekl,
3185 .x87,
3186 .xsavec,
3187 .xsaveopt,
3188 .xsaves,
3189 }),
3190 };
3191 pub const rocketlake = CpuModel{
3192 .name = "rocketlake",
3193 .llvm_name = "rocketlake",
3194 .features = featureSet(&[_]Feature{
3195 .@"64bit",
3196 .adx,
3197 .allow_light_256_bit,
3198 .avx512bitalg,
3199 .avx512cd,
3200 .avx512dq,
3201 .avx512ifma,
3202 .avx512vbmi,
3203 .avx512vbmi2,
3204 .avx512vl,
3205 .avx512vnni,
3206 .avx512vpopcntdq,
3207 .bmi,
3208 .bmi2,
3209 .clflushopt,
3210 .cmov,
3211 .crc32,
3212 .cx16,
3213 .ermsb,
3214 .fast_15bytenop,
3215 .fast_gather,
3216 .fast_scalar_fsqrt,
3217 .fast_shld_rotate,
3218 .fast_variable_crosslane_shuffle,
3219 .fast_variable_perlane_shuffle,
3220 .fast_vector_fsqrt,
3221 .fsgsbase,
3222 .fsrm,
3223 .fxsr,
3224 .gfni,
3225 .idivq_to_divl,
3226 .invpcid,
3227 .lzcnt,
3228 .macrofusion,
3229 .mmx,
3230 .movbe,
3231 .no_bypass_delay_blend,
3232 .no_bypass_delay_mov,
3233 .no_bypass_delay_shuffle,
3234 .nopl,
3235 .pku,
3236 .popcnt,
3237 .prefer_256_bit,
3238 .prfchw,
3239 .rdpid,
3240 .rdrnd,
3241 .rdseed,
3242 .sahf,
3243 .sha,
3244 .tuning_fast_imm_vector_shift,
3245 .vaes,
3246 .vpclmulqdq,
3247 .vzeroupper,
3248 .x87,
3249 .xsavec,
3250 .xsaveopt,
3251 .xsaves,
3252 }),
3253 };
3254 pub const sandybridge = CpuModel{
3255 .name = "sandybridge",
3256 .llvm_name = "sandybridge",
3257 .features = featureSet(&[_]Feature{
3258 .@"64bit",
3259 .avx,
3260 .cmov,
3261 .crc32,
3262 .cx16,
3263 .false_deps_popcnt,
3264 .fast_15bytenop,
3265 .fast_scalar_fsqrt,
3266 .fast_shld_rotate,
3267 .fxsr,
3268 .idivq_to_divl,
3269 .macrofusion,
3270 .mmx,
3271 .no_bypass_delay_mov,
3272 .nopl,
3273 .pclmul,
3274 .popcnt,
3275 .sahf,
3276 .slow_3ops_lea,
3277 .slow_unaligned_mem_32,
3278 .vzeroupper,
3279 .x87,
3280 .xsaveopt,
3281 }),
3282 };
3283 pub const sapphirerapids = CpuModel{
3284 .name = "sapphirerapids",
3285 .llvm_name = "sapphirerapids",
3286 .features = featureSet(&[_]Feature{
3287 .@"64bit",
3288 .adx,
3289 .allow_light_256_bit,
3290 .amx_bf16,
3291 .amx_int8,
3292 .avx512bf16,
3293 .avx512bitalg,
3294 .avx512cd,
3295 .avx512fp16,
3296 .avx512ifma,
3297 .avx512vbmi,
3298 .avx512vbmi2,
3299 .avx512vnni,
3300 .avx512vpopcntdq,
3301 .avxvnni,
3302 .bmi,
3303 .bmi2,
3304 .cldemote,
3305 .clflushopt,
3306 .clwb,
3307 .cmov,
3308 .crc32,
3309 .cx16,
3310 .enqcmd,
3311 .ermsb,
3312 .false_deps_getmant,
3313 .false_deps_mulc,
3314 .false_deps_mullq,
3315 .false_deps_perm,
3316 .false_deps_range,
3317 .fast_15bytenop,
3318 .fast_gather,
3319 .fast_scalar_fsqrt,
3320 .fast_shld_rotate,
3321 .fast_variable_crosslane_shuffle,
3322 .fast_variable_perlane_shuffle,
3323 .fast_vector_fsqrt,
3324 .fsgsbase,
3325 .fsrm,
3326 .fxsr,
3327 .gfni,
3328 .idivq_to_divl,
3329 .invpcid,
3330 .lzcnt,
3331 .macrofusion,
3332 .mmx,
3333 .movbe,
3334 .movdir64b,
3335 .movdiri,
3336 .no_bypass_delay_blend,
3337 .no_bypass_delay_mov,
3338 .no_bypass_delay_shuffle,
3339 .nopl,
3340 .pconfig,
3341 .pku,
3342 .popcnt,
3343 .prefer_256_bit,
3344 .prfchw,
3345 .ptwrite,
3346 .rdpid,
3347 .rdrnd,
3348 .rdseed,
3349 .sahf,
3350 .serialize,
3351 .sha,
3352 .shstk,
3353 .tsxldtrk,
3354 .tuning_fast_imm_vector_shift,
3355 .uintr,
3356 .vaes,
3357 .vpclmulqdq,
3358 .vzeroupper,
3359 .waitpkg,
3360 .wbnoinvd,
3361 .x87,
3362 .xsavec,
3363 .xsaveopt,
3364 .xsaves,
3365 }),
3366 };
3367 pub const sierraforest = CpuModel{
3368 .name = "sierraforest",
3369 .llvm_name = "sierraforest",
3370 .features = featureSet(&[_]Feature{
3371 .@"64bit",
3372 .adx,
3373 .avxifma,
3374 .avxneconvert,
3375 .avxvnni,
3376 .avxvnniint8,
3377 .bmi,
3378 .bmi2,
3379 .cldemote,
3380 .clflushopt,
3381 .clwb,
3382 .cmov,
3383 .cmpccxadd,
3384 .crc32,
3385 .cx16,
3386 .enqcmd,
3387 .f16c,
3388 .fast_movbe,
3389 .fma,
3390 .fsgsbase,
3391 .fxsr,
3392 .gfni,
3393 .hreset,
3394 .invpcid,
3395 .lzcnt,
3396 .mmx,
3397 .movbe,
3398 .movdir64b,
3399 .movdiri,
3400 .no_bypass_delay,
3401 .nopl,
3402 .pconfig,
3403 .pku,
3404 .popcnt,
3405 .prfchw,
3406 .ptwrite,
3407 .rdpid,
3408 .rdrnd,
3409 .rdseed,
3410 .sahf,
3411 .serialize,
3412 .sha,
3413 .shstk,
3414 .slow_incdec,
3415 .slow_lea,
3416 .slow_two_mem_ops,
3417 .uintr,
3418 .use_glm_div_sqrt_costs,
3419 .vaes,
3420 .vpclmulqdq,
3421 .vzeroupper,
3422 .waitpkg,
3423 .widekl,
3424 .x87,
3425 .xsavec,
3426 .xsaveopt,
3427 .xsaves,
3428 }),
3429 };
3430 pub const silvermont = CpuModel{
3431 .name = "silvermont",
3432 .llvm_name = "silvermont",
3433 .features = featureSet(&[_]Feature{
3434 .@"64bit",
3435 .cmov,
3436 .crc32,
3437 .cx16,
3438 .false_deps_popcnt,
3439 .fast_7bytenop,
3440 .fast_movbe,
3441 .fxsr,
3442 .idivq_to_divl,
3443 .mmx,
3444 .movbe,
3445 .no_bypass_delay,
3446 .nopl,
3447 .pclmul,
3448 .popcnt,
3449 .prfchw,
3450 .rdrnd,
3451 .sahf,
3452 .slow_incdec,
3453 .slow_lea,
3454 .slow_pmulld,
3455 .slow_two_mem_ops,
3456 .sse4_2,
3457 .use_slm_arith_costs,
3458 .vzeroupper,
3459 .x87,
3460 }),
3461 };
3462 pub const skx = CpuModel{
3463 .name = "skx",
3464 .llvm_name = "skx",
3465 .features = featureSet(&[_]Feature{
3466 .@"64bit",
3467 .adx,
3468 .aes,
3469 .allow_light_256_bit,
3470 .avx512bw,
3471 .avx512cd,
3472 .avx512dq,
3473 .avx512vl,
3474 .bmi,
3475 .bmi2,
3476 .clflushopt,
3477 .clwb,
3478 .cmov,
3479 .crc32,
3480 .cx16,
3481 .ermsb,
3482 .false_deps_popcnt,
3483 .fast_15bytenop,
3484 .fast_gather,
3485 .fast_scalar_fsqrt,
3486 .fast_shld_rotate,
3487 .fast_variable_crosslane_shuffle,
3488 .fast_variable_perlane_shuffle,
3489 .fast_vector_fsqrt,
3490 .faster_shift_than_shuffle,
3491 .fsgsbase,
3492 .fxsr,
3493 .idivq_to_divl,
3494 .invpcid,
3495 .lzcnt,
3496 .macrofusion,
3497 .mmx,
3498 .movbe,
3499 .no_bypass_delay_blend,
3500 .no_bypass_delay_mov,
3501 .no_bypass_delay_shuffle,
3502 .nopl,
3503 .pclmul,
3504 .pku,
3505 .popcnt,
3506 .prefer_256_bit,
3507 .prfchw,
3508 .rdrnd,
3509 .rdseed,
3510 .sahf,
3511 .slow_3ops_lea,
3512 .tuning_fast_imm_vector_shift,
3513 .vzeroupper,
3514 .x87,
3515 .xsavec,
3516 .xsaveopt,
3517 .xsaves,
3518 }),
3519 };
3520 pub const skylake = CpuModel{
3521 .name = "skylake",
3522 .llvm_name = "skylake",
3523 .features = featureSet(&[_]Feature{
3524 .@"64bit",
3525 .adx,
3526 .aes,
3527 .allow_light_256_bit,
3528 .avx2,
3529 .bmi,
3530 .bmi2,
3531 .clflushopt,
3532 .cmov,
3533 .crc32,
3534 .cx16,
3535 .ermsb,
3536 .f16c,
3537 .false_deps_popcnt,
3538 .fast_15bytenop,
3539 .fast_gather,
3540 .fast_scalar_fsqrt,
3541 .fast_shld_rotate,
3542 .fast_variable_crosslane_shuffle,
3543 .fast_variable_perlane_shuffle,
3544 .fast_vector_fsqrt,
3545 .fma,
3546 .fsgsbase,
3547 .fxsr,
3548 .idivq_to_divl,
3549 .invpcid,
3550 .lzcnt,
3551 .macrofusion,
3552 .mmx,
3553 .movbe,
3554 .no_bypass_delay_blend,
3555 .no_bypass_delay_mov,
3556 .no_bypass_delay_shuffle,
3557 .nopl,
3558 .pclmul,
3559 .popcnt,
3560 .prfchw,
3561 .rdrnd,
3562 .rdseed,
3563 .sahf,
3564 .slow_3ops_lea,
3565 .vzeroupper,
3566 .x87,
3567 .xsavec,
3568 .xsaveopt,
3569 .xsaves,
3570 }),
3571 };
3572 pub const skylake_avx512 = CpuModel{
3573 .name = "skylake_avx512",
3574 .llvm_name = "skylake-avx512",
3575 .features = featureSet(&[_]Feature{
3576 .@"64bit",
3577 .adx,
3578 .aes,
3579 .allow_light_256_bit,
3580 .avx512bw,
3581 .avx512cd,
3582 .avx512dq,
3583 .avx512vl,
3584 .bmi,
3585 .bmi2,
3586 .clflushopt,
3587 .clwb,
3588 .cmov,
3589 .crc32,
3590 .cx16,
3591 .ermsb,
3592 .false_deps_popcnt,
3593 .fast_15bytenop,
3594 .fast_gather,
3595 .fast_scalar_fsqrt,
3596 .fast_shld_rotate,
3597 .fast_variable_crosslane_shuffle,
3598 .fast_variable_perlane_shuffle,
3599 .fast_vector_fsqrt,
3600 .faster_shift_than_shuffle,
3601 .fsgsbase,
3602 .fxsr,
3603 .idivq_to_divl,
3604 .invpcid,
3605 .lzcnt,
3606 .macrofusion,
3607 .mmx,
3608 .movbe,
3609 .no_bypass_delay_blend,
3610 .no_bypass_delay_mov,
3611 .no_bypass_delay_shuffle,
3612 .nopl,
3613 .pclmul,
3614 .pku,
3615 .popcnt,
3616 .prefer_256_bit,
3617 .prfchw,
3618 .rdrnd,
3619 .rdseed,
3620 .sahf,
3621 .slow_3ops_lea,
3622 .tuning_fast_imm_vector_shift,
3623 .vzeroupper,
3624 .x87,
3625 .xsavec,
3626 .xsaveopt,
3627 .xsaves,
3628 }),
3629 };
3630 pub const slm = CpuModel{
3631 .name = "slm",
3632 .llvm_name = "slm",
3633 .features = featureSet(&[_]Feature{
3634 .@"64bit",
3635 .cmov,
3636 .crc32,
3637 .cx16,
3638 .false_deps_popcnt,
3639 .fast_7bytenop,
3640 .fast_movbe,
3641 .fxsr,
3642 .idivq_to_divl,
3643 .mmx,
3644 .movbe,
3645 .no_bypass_delay,
3646 .nopl,
3647 .pclmul,
3648 .popcnt,
3649 .prfchw,
3650 .rdrnd,
3651 .sahf,
3652 .slow_incdec,
3653 .slow_lea,
3654 .slow_pmulld,
3655 .slow_two_mem_ops,
3656 .sse4_2,
3657 .use_slm_arith_costs,
3658 .vzeroupper,
3659 .x87,
3660 }),
3661 };
3662 pub const tigerlake = CpuModel{
3663 .name = "tigerlake",
3664 .llvm_name = "tigerlake",
3665 .features = featureSet(&[_]Feature{
3666 .@"64bit",
3667 .adx,
3668 .allow_light_256_bit,
3669 .avx512bitalg,
3670 .avx512cd,
3671 .avx512dq,
3672 .avx512ifma,
3673 .avx512vbmi,
3674 .avx512vbmi2,
3675 .avx512vl,
3676 .avx512vnni,
3677 .avx512vp2intersect,
3678 .avx512vpopcntdq,
3679 .bmi,
3680 .bmi2,
3681 .clflushopt,
3682 .clwb,
3683 .cmov,
3684 .crc32,
3685 .cx16,
3686 .ermsb,
3687 .fast_15bytenop,
3688 .fast_gather,
3689 .fast_scalar_fsqrt,
3690 .fast_shld_rotate,
3691 .fast_variable_crosslane_shuffle,
3692 .fast_variable_perlane_shuffle,
3693 .fast_vector_fsqrt,
3694 .fsgsbase,
3695 .fsrm,
3696 .fxsr,
3697 .gfni,
3698 .idivq_to_divl,
3699 .invpcid,
3700 .lzcnt,
3701 .macrofusion,
3702 .mmx,
3703 .movbe,
3704 .movdir64b,
3705 .movdiri,
3706 .no_bypass_delay_blend,
3707 .no_bypass_delay_mov,
3708 .no_bypass_delay_shuffle,
3709 .nopl,
3710 .pku,
3711 .popcnt,
3712 .prefer_256_bit,
3713 .prfchw,
3714 .rdpid,
3715 .rdrnd,
3716 .rdseed,
3717 .sahf,
3718 .sha,
3719 .shstk,
3720 .tuning_fast_imm_vector_shift,
3721 .vaes,
3722 .vpclmulqdq,
3723 .vzeroupper,
3724 .x87,
3725 .xsavec,
3726 .xsaveopt,
3727 .xsaves,
3728 }),
3729 };
3730 pub const tremont = CpuModel{
3731 .name = "tremont",
3732 .llvm_name = "tremont",
3733 .features = featureSet(&[_]Feature{
3734 .@"64bit",
3735 .aes,
3736 .clflushopt,
3737 .clwb,
3738 .cmov,
3739 .crc32,
3740 .cx16,
3741 .fast_movbe,
3742 .fsgsbase,
3743 .fxsr,
3744 .gfni,
3745 .mmx,
3746 .movbe,
3747 .no_bypass_delay,
3748 .nopl,
3749 .pclmul,
3750 .popcnt,
3751 .prfchw,
3752 .ptwrite,
3753 .rdpid,
3754 .rdrnd,
3755 .rdseed,
3756 .sahf,
3757 .sha,
3758 .slow_incdec,
3759 .slow_lea,
3760 .slow_two_mem_ops,
3761 .sse4_2,
3762 .use_glm_div_sqrt_costs,
3763 .vzeroupper,
3764 .x87,
3765 .xsavec,
3766 .xsaveopt,
3767 .xsaves,
3768 }),
3769 };
3770 pub const westmere = CpuModel{
3771 .name = "westmere",
3772 .llvm_name = "westmere",
3773 .features = featureSet(&[_]Feature{
3774 .@"64bit",
3775 .cmov,
3776 .crc32,
3777 .cx16,
3778 .fxsr,
3779 .macrofusion,
3780 .mmx,
3781 .no_bypass_delay_mov,
3782 .nopl,
3783 .pclmul,
3784 .popcnt,
3785 .sahf,
3786 .sse4_2,
3787 .vzeroupper,
3788 .x87,
3789 }),
3790 };
3791 pub const winchip2 = CpuModel{
3792 .name = "winchip2",
3793 .llvm_name = "winchip2",
3794 .features = featureSet(&[_]Feature{
3795 .@"3dnow",
3796 .slow_unaligned_mem_16,
3797 .vzeroupper,
3798 .x87,
3799 }),
3800 };
3801 pub const winchip_c6 = CpuModel{
3802 .name = "winchip_c6",
3803 .llvm_name = "winchip-c6",
3804 .features = featureSet(&[_]Feature{
3805 .mmx,
3806 .slow_unaligned_mem_16,
3807 .vzeroupper,
3808 .x87,
3809 }),
3810 };
3811 pub const x86_64 = CpuModel{
3812 .name = "x86_64",
3813 .llvm_name = "x86-64",
3814 .features = featureSet(&[_]Feature{
3815 .@"64bit",
3816 .cmov,
3817 .cx8,
3818 .fxsr,
3819 .idivq_to_divl,
3820 .macrofusion,
3821 .mmx,
3822 .nopl,
3823 .slow_3ops_lea,
3824 .slow_incdec,
3825 .sse2,
3826 .vzeroupper,
3827 .x87,
3828 }),
3829 };
3830 pub const x86_64_v2 = CpuModel{
3831 .name = "x86_64_v2",
3832 .llvm_name = "x86-64-v2",
3833 .features = featureSet(&[_]Feature{
3834 .@"64bit",
3835 .cmov,
3836 .crc32,
3837 .cx16,
3838 .false_deps_popcnt,
3839 .fast_15bytenop,
3840 .fast_scalar_fsqrt,
3841 .fast_shld_rotate,
3842 .fxsr,
3843 .idivq_to_divl,
3844 .macrofusion,
3845 .mmx,
3846 .nopl,
3847 .popcnt,
3848 .sahf,
3849 .slow_3ops_lea,
3850 .slow_unaligned_mem_32,
3851 .sse4_2,
3852 .vzeroupper,
3853 .x87,
3854 }),
3855 };
3856 pub const x86_64_v3 = CpuModel{
3857 .name = "x86_64_v3",
3858 .llvm_name = "x86-64-v3",
3859 .features = featureSet(&[_]Feature{
3860 .@"64bit",
3861 .allow_light_256_bit,
3862 .avx2,
3863 .bmi,
3864 .bmi2,
3865 .cmov,
3866 .crc32,
3867 .cx16,
3868 .f16c,
3869 .false_deps_lzcnt_tzcnt,
3870 .false_deps_popcnt,
3871 .fast_15bytenop,
3872 .fast_scalar_fsqrt,
3873 .fast_shld_rotate,
3874 .fast_variable_crosslane_shuffle,
3875 .fast_variable_perlane_shuffle,
3876 .fma,
3877 .fxsr,
3878 .idivq_to_divl,
3879 .lzcnt,
3880 .macrofusion,
3881 .mmx,
3882 .movbe,
3883 .nopl,
3884 .popcnt,
3885 .sahf,
3886 .slow_3ops_lea,
3887 .vzeroupper,
3888 .x87,
3889 .xsave,
3890 }),
3891 };
3892 pub const x86_64_v4 = CpuModel{
3893 .name = "x86_64_v4",
3894 .llvm_name = "x86-64-v4",
3895 .features = featureSet(&[_]Feature{
3896 .@"64bit",
3897 .allow_light_256_bit,
3898 .avx512bw,
3899 .avx512cd,
3900 .avx512dq,
3901 .avx512vl,
3902 .bmi,
3903 .bmi2,
3904 .cmov,
3905 .crc32,
3906 .cx16,
3907 .false_deps_popcnt,
3908 .fast_15bytenop,
3909 .fast_gather,
3910 .fast_scalar_fsqrt,
3911 .fast_shld_rotate,
3912 .fast_variable_crosslane_shuffle,
3913 .fast_variable_perlane_shuffle,
3914 .fast_vector_fsqrt,
3915 .fxsr,
3916 .idivq_to_divl,
3917 .lzcnt,
3918 .macrofusion,
3919 .mmx,
3920 .movbe,
3921 .nopl,
3922 .popcnt,
3923 .prefer_256_bit,
3924 .sahf,
3925 .slow_3ops_lea,
3926 .vzeroupper,
3927 .x87,
3928 .xsave,
3929 }),
3930 };
3931 pub const yonah = CpuModel{
3932 .name = "yonah",
3933 .llvm_name = "yonah",
3934 .features = featureSet(&[_]Feature{
3935 .cmov,
3936 .cx8,
3937 .fxsr,
3938 .mmx,
3939 .nopl,
3940 .slow_unaligned_mem_16,
3941 .sse3,
3942 .vzeroupper,
3943 .x87,
3944 }),
3945 };
3946 pub const znver1 = CpuModel{
3947 .name = "znver1",
3948 .llvm_name = "znver1",
3949 .features = featureSet(&[_]Feature{
3950 .@"64bit",
3951 .adx,
3952 .aes,
3953 .allow_light_256_bit,
3954 .avx2,
3955 .bmi,
3956 .bmi2,
3957 .branchfusion,
3958 .clflushopt,
3959 .clzero,
3960 .cmov,
3961 .crc32,
3962 .cx16,
3963 .f16c,
3964 .fast_15bytenop,
3965 .fast_bextr,
3966 .fast_lzcnt,
3967 .fast_movbe,
3968 .fast_scalar_fsqrt,
3969 .fast_scalar_shift_masks,
3970 .fast_variable_perlane_shuffle,
3971 .fast_vector_fsqrt,
3972 .fma,
3973 .fsgsbase,
3974 .fxsr,
3975 .lzcnt,
3976 .mmx,
3977 .movbe,
3978 .mwaitx,
3979 .nopl,
3980 .pclmul,
3981 .popcnt,
3982 .prfchw,
3983 .rdrnd,
3984 .rdseed,
3985 .sahf,
3986 .sbb_dep_breaking,
3987 .sha,
3988 .slow_shld,
3989 .sse4a,
3990 .vzeroupper,
3991 .x87,
3992 .xsavec,
3993 .xsaveopt,
3994 .xsaves,
3995 }),
3996 };
3997 pub const znver2 = CpuModel{
3998 .name = "znver2",
3999 .llvm_name = "znver2",
4000 .features = featureSet(&[_]Feature{
4001 .@"64bit",
4002 .adx,
4003 .aes,
4004 .allow_light_256_bit,
4005 .avx2,
4006 .bmi,
4007 .bmi2,
4008 .branchfusion,
4009 .clflushopt,
4010 .clwb,
4011 .clzero,
4012 .cmov,
4013 .crc32,
4014 .cx16,
4015 .f16c,
4016 .fast_15bytenop,
4017 .fast_bextr,
4018 .fast_lzcnt,
4019 .fast_movbe,
4020 .fast_scalar_fsqrt,
4021 .fast_scalar_shift_masks,
4022 .fast_variable_perlane_shuffle,
4023 .fast_vector_fsqrt,
4024 .fma,
4025 .fsgsbase,
4026 .fxsr,
4027 .lzcnt,
4028 .mmx,
4029 .movbe,
4030 .mwaitx,
4031 .nopl,
4032 .pclmul,
4033 .popcnt,
4034 .prfchw,
4035 .rdpid,
4036 .rdpru,
4037 .rdrnd,
4038 .rdseed,
4039 .sahf,
4040 .sbb_dep_breaking,
4041 .sha,
4042 .slow_shld,
4043 .sse4a,
4044 .vzeroupper,
4045 .wbnoinvd,
4046 .x87,
4047 .xsavec,
4048 .xsaveopt,
4049 .xsaves,
4050 }),
4051 };
4052 pub const znver3 = CpuModel{
4053 .name = "znver3",
4054 .llvm_name = "znver3",
4055 .features = featureSet(&[_]Feature{
4056 .@"64bit",
4057 .adx,
4058 .allow_light_256_bit,
4059 .avx2,
4060 .bmi,
4061 .bmi2,
4062 .branchfusion,
4063 .clflushopt,
4064 .clwb,
4065 .clzero,
4066 .cmov,
4067 .crc32,
4068 .cx16,
4069 .f16c,
4070 .fast_15bytenop,
4071 .fast_bextr,
4072 .fast_lzcnt,
4073 .fast_movbe,
4074 .fast_scalar_fsqrt,
4075 .fast_scalar_shift_masks,
4076 .fast_variable_perlane_shuffle,
4077 .fast_vector_fsqrt,
4078 .fma,
4079 .fsgsbase,
4080 .fsrm,
4081 .fxsr,
4082 .invpcid,
4083 .lzcnt,
4084 .macrofusion,
4085 .mmx,
4086 .movbe,
4087 .mwaitx,
4088 .nopl,
4089 .pku,
4090 .popcnt,
4091 .prfchw,
4092 .rdpid,
4093 .rdpru,
4094 .rdrnd,
4095 .rdseed,
4096 .sahf,
4097 .sbb_dep_breaking,
4098 .sha,
4099 .slow_shld,
4100 .sse4a,
4101 .vaes,
4102 .vpclmulqdq,
4103 .vzeroupper,
4104 .wbnoinvd,
4105 .x87,
4106 .xsavec,
4107 .xsaveopt,
4108 .xsaves,
4109 }),
4110 };
4111 pub const znver4 = CpuModel{
4112 .name = "znver4",
4113 .llvm_name = "znver4",
4114 .features = featureSet(&[_]Feature{
4115 .@"64bit",
4116 .adx,
4117 .allow_light_256_bit,
4118 .avx512bf16,
4119 .avx512bitalg,
4120 .avx512cd,
4121 .avx512dq,
4122 .avx512ifma,
4123 .avx512vbmi,
4124 .avx512vbmi2,
4125 .avx512vl,
4126 .avx512vnni,
4127 .avx512vpopcntdq,
4128 .bmi,
4129 .bmi2,
4130 .branchfusion,
4131 .clflushopt,
4132 .clwb,
4133 .clzero,
4134 .cmov,
4135 .crc32,
4136 .cx16,
4137 .fast_15bytenop,
4138 .fast_bextr,
4139 .fast_lzcnt,
4140 .fast_movbe,
4141 .fast_scalar_fsqrt,
4142 .fast_scalar_shift_masks,
4143 .fast_variable_perlane_shuffle,
4144 .fast_vector_fsqrt,
4145 .fsgsbase,
4146 .fsrm,
4147 .fxsr,
4148 .gfni,
4149 .invpcid,
4150 .lzcnt,
4151 .macrofusion,
4152 .mmx,
4153 .movbe,
4154 .mwaitx,
4155 .nopl,
4156 .pku,
4157 .popcnt,
4158 .prfchw,
4159 .rdpid,
4160 .rdpru,
4161 .rdrnd,
4162 .rdseed,
4163 .sahf,
4164 .sbb_dep_breaking,
4165 .sha,
4166 .shstk,
4167 .slow_shld,
4168 .sse4a,
4169 .vaes,
4170 .vpclmulqdq,
4171 .vzeroupper,
4172 .wbnoinvd,
4173 .x87,
4174 .xsavec,
4175 .xsaveopt,
4176 .xsaves,
4177 }),
4178 };
4179};
lib/std/target/xtensa.zig deleted-39
......@@ -1,39 +0,0 @@
1//! This file is auto-generated by tools/update_cpu_features.zig.
2
3const std = @import("../std.zig");
4const CpuFeature = std.Target.Cpu.Feature;
5const CpuModel = std.Target.Cpu.Model;
6
7pub const Feature = enum {
8 density,
9};
10
11pub const featureSet = CpuFeature.feature_set_fns(Feature).featureSet;
12pub const featureSetHas = CpuFeature.feature_set_fns(Feature).featureSetHas;
13pub const featureSetHasAny = CpuFeature.feature_set_fns(Feature).featureSetHasAny;
14pub const featureSetHasAll = CpuFeature.feature_set_fns(Feature).featureSetHasAll;
15
16pub const all_features = blk: {
17 const len = @typeInfo(Feature).Enum.fields.len;
18 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
19 var result: [len]CpuFeature = undefined;
20 result[@intFromEnum(Feature.density)] = .{
21 .llvm_name = "density",
22 .description = "Enable Density instructions",
23 .dependencies = featureSet(&[_]Feature{}),
24 };
25 const ti = @typeInfo(Feature);
26 for (&result, 0..) |*elem, i| {
27 elem.index = i;
28 elem.name = ti.Enum.fields[i].name;
29 }
30 break :blk result;
31};
32
33pub const cpu = struct {
34 pub const generic = CpuModel{
35 .name = "generic",
36 .llvm_name = "generic",
37 .features = featureSet(&[_]Feature{}),
38 };
39};
lib/std/zig.zig+121-5
......@@ -1,7 +1,4 @@
1const std = @import("std.zig");
2const tokenizer = @import("zig/tokenizer.zig");
31pub const fmt = @import("zig/fmt.zig");
4const assert = std.debug.assert;
52
63pub const ErrorBundle = @import("zig/ErrorBundle.zig");
74pub const Server = @import("zig/Server.zig");
......@@ -16,7 +13,8 @@ pub const number_literal = @import("zig/number_literal.zig");
1613pub const primitives = @import("zig/primitives.zig");
1714pub const Ast = @import("zig/Ast.zig");
1815pub const system = @import("zig/system.zig");
19pub const CrossTarget = @import("zig/CrossTarget.zig");
16/// Deprecated: use `std.Target.Query`.
17pub const CrossTarget = std.Target.Query;
2018pub const BuiltinFn = @import("zig/BuiltinFn.zig");
2119pub const AstRlAnnotate = @import("zig/AstRlAnnotate.zig");
2220
......@@ -114,7 +112,7 @@ pub const BinNameOptions = struct {
114112};
115113
116114/// Returns the standard file system basename of a binary generated by the Zig compiler.
117pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {
115pub fn binNameAlloc(allocator: Allocator, options: BinNameOptions) error{OutOfMemory}![]u8 {
118116 const root_name = options.root_name;
119117 const target = options.target;
120118 switch (target.ofmt) {
......@@ -203,6 +201,124 @@ pub fn binNameAlloc(allocator: std.mem.Allocator, options: BinNameOptions) error
203201 }
204202}
205203
204pub const BuildId = union(enum) {
205 none,
206 fast,
207 uuid,
208 sha1,
209 md5,
210 hexstring: HexString,
211
212 pub fn eql(a: BuildId, b: BuildId) bool {
213 const Tag = @typeInfo(BuildId).Union.tag_type.?;
214 const a_tag: Tag = a;
215 const b_tag: Tag = b;
216 if (a_tag != b_tag) return false;
217 return switch (a) {
218 .none, .fast, .uuid, .sha1, .md5 => true,
219 .hexstring => |a_hexstring| std.mem.eql(u8, a_hexstring.toSlice(), b.hexstring.toSlice()),
220 };
221 }
222
223 pub const HexString = struct {
224 bytes: [32]u8,
225 len: u8,
226
227 /// Result is byte values, *not* hex-encoded.
228 pub fn toSlice(hs: *const HexString) []const u8 {
229 return hs.bytes[0..hs.len];
230 }
231 };
232
233 /// Input is byte values, *not* hex-encoded.
234 /// Asserts `bytes` fits inside `HexString`
235 pub fn initHexString(bytes: []const u8) BuildId {
236 var result: BuildId = .{ .hexstring = .{
237 .bytes = undefined,
238 .len = @intCast(bytes.len),
239 } };
240 @memcpy(result.hexstring.bytes[0..bytes.len], bytes);
241 return result;
242 }
243
244 /// Converts UTF-8 text to a `BuildId`.
245 pub fn parse(text: []const u8) !BuildId {
246 if (std.mem.eql(u8, text, "none")) {
247 return .none;
248 } else if (std.mem.eql(u8, text, "fast")) {
249 return .fast;
250 } else if (std.mem.eql(u8, text, "uuid")) {
251 return .uuid;
252 } else if (std.mem.eql(u8, text, "sha1") or std.mem.eql(u8, text, "tree")) {
253 return .sha1;
254 } else if (std.mem.eql(u8, text, "md5")) {
255 return .md5;
256 } else if (std.mem.startsWith(u8, text, "0x")) {
257 var result: BuildId = .{ .hexstring = undefined };
258 const slice = try std.fmt.hexToBytes(&result.hexstring.bytes, text[2..]);
259 result.hexstring.len = @as(u8, @intCast(slice.len));
260 return result;
261 }
262 return error.InvalidBuildIdStyle;
263 }
264
265 test parse {
266 try std.testing.expectEqual(BuildId.md5, try parse("md5"));
267 try std.testing.expectEqual(BuildId.none, try parse("none"));
268 try std.testing.expectEqual(BuildId.fast, try parse("fast"));
269 try std.testing.expectEqual(BuildId.uuid, try parse("uuid"));
270 try std.testing.expectEqual(BuildId.sha1, try parse("sha1"));
271 try std.testing.expectEqual(BuildId.sha1, try parse("tree"));
272
273 try std.testing.expect(BuildId.initHexString("").eql(try parse("0x")));
274 try std.testing.expect(BuildId.initHexString("\x12\x34\x56").eql(try parse("0x123456")));
275 try std.testing.expectError(error.InvalidLength, parse("0x12-34"));
276 try std.testing.expectError(error.InvalidCharacter, parse("0xfoobbb"));
277 try std.testing.expectError(error.InvalidBuildIdStyle, parse("yaddaxxx"));
278 }
279};
280
281/// Renders a `std.Target.Cpu` value into a textual representation that can be parsed
282/// via the `-mcpu` flag passed to the Zig compiler.
283/// Appends the result to `buffer`.
284pub fn serializeCpu(buffer: *std.ArrayList(u8), cpu: std.Target.Cpu) Allocator.Error!void {
285 const all_features = cpu.arch.allFeaturesList();
286 var populated_cpu_features = cpu.model.features;
287 populated_cpu_features.populateDependencies(all_features);
288
289 try buffer.appendSlice(cpu.model.name);
290
291 if (populated_cpu_features.eql(cpu.features)) {
292 // The CPU name alone is sufficient.
293 return;
294 }
295
296 for (all_features, 0..) |feature, i_usize| {
297 const i: std.Target.Cpu.Feature.Set.Index = @intCast(i_usize);
298 const in_cpu_set = populated_cpu_features.isEnabled(i);
299 const in_actual_set = cpu.features.isEnabled(i);
300 try buffer.ensureUnusedCapacity(feature.name.len + 1);
301 if (in_cpu_set and !in_actual_set) {
302 buffer.appendAssumeCapacity('-');
303 buffer.appendSliceAssumeCapacity(feature.name);
304 } else if (!in_cpu_set and in_actual_set) {
305 buffer.appendAssumeCapacity('+');
306 buffer.appendSliceAssumeCapacity(feature.name);
307 }
308 }
309}
310
311pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![]u8 {
312 var buffer = std.ArrayList(u8).init(ally);
313 try serializeCpu(&buffer, cpu);
314 return buffer.toOwnedSlice();
315}
316
317const std = @import("std.zig");
318const tokenizer = @import("zig/tokenizer.zig");
319const assert = std.debug.assert;
320const Allocator = std.mem.Allocator;
321
206322test {
207323 @import("std").testing.refAllDecls(@This());
208324}
lib/std/zig/CrossTarget.zig deleted-895
......@@ -1,895 +0,0 @@
1//! Contains all the same data as `Target`, additionally introducing the concept of "the native target".
2//! The purpose of this abstraction is to provide meaningful and unsurprising defaults.
3//! This struct does reference any resources and it is copyable.
4
5const CrossTarget = @This();
6const std = @import("../std.zig");
7const builtin = @import("builtin");
8const assert = std.debug.assert;
9const Target = std.Target;
10const mem = std.mem;
11
12/// `null` means native.
13cpu_arch: ?Target.Cpu.Arch = null,
14
15cpu_model: CpuModel = CpuModel.determined_by_cpu_arch,
16
17/// Sparse set of CPU features to add to the set from `cpu_model`.
18cpu_features_add: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
19
20/// Sparse set of CPU features to remove from the set from `cpu_model`.
21cpu_features_sub: Target.Cpu.Feature.Set = Target.Cpu.Feature.Set.empty,
22
23/// `null` means native.
24os_tag: ?Target.Os.Tag = null,
25
26/// `null` means the default version range for `os_tag`. If `os_tag` is `null` (native)
27/// then `null` for this field means native.
28os_version_min: ?OsVersion = null,
29
30/// When cross compiling, `null` means default (latest known OS version).
31/// When `os_tag` is native, `null` means equal to the native OS version.
32os_version_max: ?OsVersion = null,
33
34/// `null` means default when cross compiling, or native when os_tag is native.
35/// If `isGnuLibC()` is `false`, this must be `null` and is ignored.
36glibc_version: ?SemanticVersion = null,
37
38/// `null` means the native C ABI, if `os_tag` is native, otherwise it means the default C ABI.
39abi: ?Target.Abi = null,
40
41/// When `os_tag` is `null`, then `null` means native. Otherwise it means the standard path
42/// based on the `os_tag`.
43dynamic_linker: DynamicLinker = DynamicLinker{},
44
45/// `null` means default for the cpu/arch/os combo.
46ofmt: ?Target.ObjectFormat = null,
47
48pub const CpuModel = union(enum) {
49 /// Always native
50 native,
51
52 /// Always baseline
53 baseline,
54
55 /// If CPU Architecture is native, then the CPU model will be native. Otherwise,
56 /// it will be baseline.
57 determined_by_cpu_arch,
58
59 explicit: *const Target.Cpu.Model,
60};
61
62pub const OsVersion = union(enum) {
63 none: void,
64 semver: SemanticVersion,
65 windows: Target.Os.WindowsVersion,
66};
67
68pub const SemanticVersion = std.SemanticVersion;
69
70pub const DynamicLinker = Target.DynamicLinker;
71
72pub fn fromTarget(target: Target) CrossTarget {
73 var result: CrossTarget = .{
74 .cpu_arch = target.cpu.arch,
75 .cpu_model = .{ .explicit = target.cpu.model },
76 .os_tag = target.os.tag,
77 .os_version_min = undefined,
78 .os_version_max = undefined,
79 .abi = target.abi,
80 .glibc_version = if (target.isGnuLibC())
81 target.os.version_range.linux.glibc
82 else
83 null,
84 };
85 result.updateOsVersionRange(target.os);
86
87 const all_features = target.cpu.arch.allFeaturesList();
88 var cpu_model_set = target.cpu.model.features;
89 cpu_model_set.populateDependencies(all_features);
90 {
91 // The "add" set is the full set with the CPU Model set removed.
92 const add_set = &result.cpu_features_add;
93 add_set.* = target.cpu.features;
94 add_set.removeFeatureSet(cpu_model_set);
95 }
96 {
97 // The "sub" set is the features that are on in CPU Model set and off in the full set.
98 const sub_set = &result.cpu_features_sub;
99 sub_set.* = cpu_model_set;
100 sub_set.removeFeatureSet(target.cpu.features);
101 }
102 return result;
103}
104
105fn updateOsVersionRange(self: *CrossTarget, os: Target.Os) void {
106 switch (os.tag) {
107 .freestanding,
108 .ananas,
109 .cloudabi,
110 .fuchsia,
111 .kfreebsd,
112 .lv2,
113 .solaris,
114 .illumos,
115 .zos,
116 .haiku,
117 .minix,
118 .rtems,
119 .nacl,
120 .aix,
121 .cuda,
122 .nvcl,
123 .amdhsa,
124 .ps4,
125 .ps5,
126 .elfiamcu,
127 .mesa3d,
128 .contiki,
129 .amdpal,
130 .hermit,
131 .hurd,
132 .wasi,
133 .emscripten,
134 .driverkit,
135 .shadermodel,
136 .liteos,
137 .uefi,
138 .opencl,
139 .glsl450,
140 .vulkan,
141 .plan9,
142 .other,
143 => {
144 self.os_version_min = .{ .none = {} };
145 self.os_version_max = .{ .none = {} };
146 },
147
148 .freebsd,
149 .macos,
150 .ios,
151 .tvos,
152 .watchos,
153 .netbsd,
154 .openbsd,
155 .dragonfly,
156 => {
157 self.os_version_min = .{ .semver = os.version_range.semver.min };
158 self.os_version_max = .{ .semver = os.version_range.semver.max };
159 },
160
161 .linux => {
162 self.os_version_min = .{ .semver = os.version_range.linux.range.min };
163 self.os_version_max = .{ .semver = os.version_range.linux.range.max };
164 },
165
166 .windows => {
167 self.os_version_min = .{ .windows = os.version_range.windows.min };
168 self.os_version_max = .{ .windows = os.version_range.windows.max };
169 },
170 }
171}
172
173/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
174pub fn toTarget(self: CrossTarget) Target {
175 return .{
176 .cpu = self.getCpu(),
177 .os = self.getOs(),
178 .abi = self.getAbi(),
179 .ofmt = self.getObjectFormat(),
180 };
181}
182
183pub const ParseOptions = struct {
184 /// This is sometimes called a "triple". It looks roughly like this:
185 /// riscv64-linux-musl
186 /// The fields are, respectively:
187 /// * CPU Architecture
188 /// * Operating System (and optional version range)
189 /// * C ABI (optional, with optional glibc version)
190 /// The string "native" can be used for CPU architecture as well as Operating System.
191 /// If the CPU Architecture is specified as "native", then the Operating System and C ABI may be omitted.
192 arch_os_abi: []const u8 = "native",
193
194 /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
195 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
196 /// to remove from the set.
197 /// The following special strings are recognized for CPU Model name:
198 /// * "baseline" - The "default" set of CPU features for cross-compiling. A conservative set
199 /// of features that is expected to be supported on most available hardware.
200 /// * "native" - The native CPU model is to be detected when compiling.
201 /// If this field is not provided (`null`), then the value will depend on the
202 /// parsed CPU Architecture. If native, then this will be "native". Otherwise, it will be "baseline".
203 cpu_features: ?[]const u8 = null,
204
205 /// Absolute path to dynamic linker, to override the default, which is either a natively
206 /// detected path, or a standard path.
207 dynamic_linker: ?[]const u8 = null,
208
209 object_format: ?[]const u8 = null,
210
211 /// If this is provided, the function will populate some information about parsing failures,
212 /// so that user-friendly error messages can be delivered.
213 diagnostics: ?*Diagnostics = null,
214
215 pub const Diagnostics = struct {
216 /// If the architecture was determined, this will be populated.
217 arch: ?Target.Cpu.Arch = null,
218
219 /// If the OS name was determined, this will be populated.
220 os_name: ?[]const u8 = null,
221
222 /// If the OS tag was determined, this will be populated.
223 os_tag: ?Target.Os.Tag = null,
224
225 /// If the ABI was determined, this will be populated.
226 abi: ?Target.Abi = null,
227
228 /// If the CPU name was determined, this will be populated.
229 cpu_name: ?[]const u8 = null,
230
231 /// If error.UnknownCpuFeature is returned, this will be populated.
232 unknown_feature_name: ?[]const u8 = null,
233 };
234};
235
236pub fn parse(args: ParseOptions) !CrossTarget {
237 var dummy_diags: ParseOptions.Diagnostics = undefined;
238 const diags = args.diagnostics orelse &dummy_diags;
239
240 var result: CrossTarget = .{
241 .dynamic_linker = DynamicLinker.init(args.dynamic_linker),
242 };
243
244 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
245 const arch_name = it.first();
246 const arch_is_native = mem.eql(u8, arch_name, "native");
247 if (!arch_is_native) {
248 result.cpu_arch = std.meta.stringToEnum(Target.Cpu.Arch, arch_name) orelse
249 return error.UnknownArchitecture;
250 }
251 const arch = result.getCpuArch();
252 diags.arch = arch;
253
254 if (it.next()) |os_text| {
255 try parseOs(&result, diags, os_text);
256 } else if (!arch_is_native) {
257 return error.MissingOperatingSystem;
258 }
259
260 const opt_abi_text = it.next();
261 if (opt_abi_text) |abi_text| {
262 var abi_it = mem.splitScalar(u8, abi_text, '.');
263 const abi = std.meta.stringToEnum(Target.Abi, abi_it.first()) orelse
264 return error.UnknownApplicationBinaryInterface;
265 result.abi = abi;
266 diags.abi = abi;
267
268 const abi_ver_text = abi_it.rest();
269 if (abi_it.next() != null) {
270 if (result.isGnuLibC()) {
271 result.glibc_version = parseVersion(abi_ver_text) catch |err| switch (err) {
272 error.Overflow => return error.InvalidAbiVersion,
273 error.InvalidVersion => return error.InvalidAbiVersion,
274 };
275 } else {
276 return error.InvalidAbiVersion;
277 }
278 }
279 }
280
281 if (it.next() != null) return error.UnexpectedExtraField;
282
283 if (args.cpu_features) |cpu_features| {
284 const all_features = arch.allFeaturesList();
285 var index: usize = 0;
286 while (index < cpu_features.len and
287 cpu_features[index] != '+' and
288 cpu_features[index] != '-')
289 {
290 index += 1;
291 }
292 const cpu_name = cpu_features[0..index];
293 diags.cpu_name = cpu_name;
294
295 const add_set = &result.cpu_features_add;
296 const sub_set = &result.cpu_features_sub;
297 if (mem.eql(u8, cpu_name, "native")) {
298 result.cpu_model = .native;
299 } else if (mem.eql(u8, cpu_name, "baseline")) {
300 result.cpu_model = .baseline;
301 } else {
302 result.cpu_model = .{ .explicit = try arch.parseCpuModel(cpu_name) };
303 }
304
305 while (index < cpu_features.len) {
306 const op = cpu_features[index];
307 const set = switch (op) {
308 '+' => add_set,
309 '-' => sub_set,
310 else => unreachable,
311 };
312 index += 1;
313 const start = index;
314 while (index < cpu_features.len and
315 cpu_features[index] != '+' and
316 cpu_features[index] != '-')
317 {
318 index += 1;
319 }
320 const feature_name = cpu_features[start..index];
321 for (all_features, 0..) |feature, feat_index_usize| {
322 const feat_index = @as(Target.Cpu.Feature.Set.Index, @intCast(feat_index_usize));
323 if (mem.eql(u8, feature_name, feature.name)) {
324 set.addFeature(feat_index);
325 break;
326 }
327 } else {
328 diags.unknown_feature_name = feature_name;
329 return error.UnknownCpuFeature;
330 }
331 }
332 }
333
334 if (args.object_format) |ofmt_name| {
335 result.ofmt = std.meta.stringToEnum(Target.ObjectFormat, ofmt_name) orelse
336 return error.UnknownObjectFormat;
337 }
338
339 return result;
340}
341
342/// Similar to `parse` except instead of fully parsing, it only determines the CPU
343/// architecture and returns it if it can be determined, and returns `null` otherwise.
344/// This is intended to be used if the API user of CrossTarget needs to learn the
345/// target CPU architecture in order to fully populate `ParseOptions`.
346pub fn parseCpuArch(args: ParseOptions) ?Target.Cpu.Arch {
347 var it = mem.splitScalar(u8, args.arch_os_abi, '-');
348 const arch_name = it.first();
349 const arch_is_native = mem.eql(u8, arch_name, "native");
350 if (arch_is_native) {
351 return builtin.cpu.arch;
352 } else {
353 return std.meta.stringToEnum(Target.Cpu.Arch, arch_name);
354 }
355}
356
357/// Similar to `SemanticVersion.parse`, but with following changes:
358/// * Leading zeroes are allowed.
359/// * Supports only 2 or 3 version components (major, minor, [patch]). If 3-rd component is omitted, it will be 0.
360pub fn parseVersion(ver: []const u8) error{ InvalidVersion, Overflow }!SemanticVersion {
361 const parseVersionComponentFn = (struct {
362 fn parseVersionComponentInner(component: []const u8) error{ InvalidVersion, Overflow }!usize {
363 return std.fmt.parseUnsigned(usize, component, 10) catch |err| switch (err) {
364 error.InvalidCharacter => return error.InvalidVersion,
365 error.Overflow => return error.Overflow,
366 };
367 }
368 }).parseVersionComponentInner;
369 var version_components = mem.splitScalar(u8, ver, '.');
370 const major = version_components.first();
371 const minor = version_components.next() orelse return error.InvalidVersion;
372 const patch = version_components.next() orelse "0";
373 if (version_components.next() != null) return error.InvalidVersion;
374 return .{
375 .major = try parseVersionComponentFn(major),
376 .minor = try parseVersionComponentFn(minor),
377 .patch = try parseVersionComponentFn(patch),
378 };
379}
380
381test parseVersion {
382 try std.testing.expectError(error.InvalidVersion, parseVersion("1"));
383 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 0 }, try parseVersion("1.2"));
384 try std.testing.expectEqual(SemanticVersion{ .major = 1, .minor = 2, .patch = 3 }, try parseVersion("1.2.3"));
385 try std.testing.expectError(error.InvalidVersion, parseVersion("1.2.3.4"));
386}
387
388/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
389pub fn getCpu(self: CrossTarget) Target.Cpu {
390 switch (self.cpu_model) {
391 .native => {
392 // This works when doing `zig build` because Zig generates a build executable using
393 // native CPU model & features. However this will not be accurate otherwise, and
394 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
395 return builtin.cpu;
396 },
397 .baseline => {
398 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
399 self.updateCpuFeatures(&adjusted_baseline.features);
400 return adjusted_baseline;
401 },
402 .determined_by_cpu_arch => if (self.cpu_arch == null) {
403 // This works when doing `zig build` because Zig generates a build executable using
404 // native CPU model & features. However this will not be accurate otherwise, and
405 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
406 return builtin.cpu;
407 } else {
408 var adjusted_baseline = Target.Cpu.baseline(self.getCpuArch());
409 self.updateCpuFeatures(&adjusted_baseline.features);
410 return adjusted_baseline;
411 },
412 .explicit => |model| {
413 var adjusted_model = model.toCpu(self.getCpuArch());
414 self.updateCpuFeatures(&adjusted_model.features);
415 return adjusted_model;
416 },
417 }
418}
419
420pub fn getCpuArch(self: CrossTarget) Target.Cpu.Arch {
421 return self.cpu_arch orelse builtin.cpu.arch;
422}
423
424pub fn getCpuModel(self: CrossTarget) *const Target.Cpu.Model {
425 return switch (self.cpu_model) {
426 .explicit => |cpu_model| cpu_model,
427 else => self.getCpu().model,
428 };
429}
430
431pub fn getCpuFeatures(self: CrossTarget) Target.Cpu.Feature.Set {
432 return self.getCpu().features;
433}
434
435/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
436pub fn getOs(self: CrossTarget) Target.Os {
437 // `builtin.os` works when doing `zig build` because Zig generates a build executable using
438 // native OS version range. However this will not be accurate otherwise, and
439 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
440 var adjusted_os = if (self.os_tag) |os_tag| os_tag.defaultVersionRange(self.getCpuArch()) else builtin.os;
441
442 if (self.os_version_min) |min| switch (min) {
443 .none => {},
444 .semver => |semver| switch (self.getOsTag()) {
445 .linux => adjusted_os.version_range.linux.range.min = semver,
446 else => adjusted_os.version_range.semver.min = semver,
447 },
448 .windows => |win_ver| adjusted_os.version_range.windows.min = win_ver,
449 };
450
451 if (self.os_version_max) |max| switch (max) {
452 .none => {},
453 .semver => |semver| switch (self.getOsTag()) {
454 .linux => adjusted_os.version_range.linux.range.max = semver,
455 else => adjusted_os.version_range.semver.max = semver,
456 },
457 .windows => |win_ver| adjusted_os.version_range.windows.max = win_ver,
458 };
459
460 if (self.glibc_version) |glibc| {
461 assert(self.isGnuLibC());
462 adjusted_os.version_range.linux.glibc = glibc;
463 }
464
465 return adjusted_os;
466}
467
468pub fn getOsTag(self: CrossTarget) Target.Os.Tag {
469 return self.os_tag orelse builtin.os.tag;
470}
471
472/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
473pub fn getOsVersionMin(self: CrossTarget) OsVersion {
474 if (self.os_version_min) |version_min| return version_min;
475 var tmp: CrossTarget = undefined;
476 tmp.updateOsVersionRange(self.getOs());
477 return tmp.os_version_min.?;
478}
479
480/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
481pub fn getOsVersionMax(self: CrossTarget) OsVersion {
482 if (self.os_version_max) |version_max| return version_max;
483 var tmp: CrossTarget = undefined;
484 tmp.updateOsVersionRange(self.getOs());
485 return tmp.os_version_max.?;
486}
487
488/// TODO deprecated, use `std.zig.system.NativeTargetInfo.detect`.
489pub fn getAbi(self: CrossTarget) Target.Abi {
490 if (self.abi) |abi| return abi;
491
492 if (self.os_tag == null) {
493 // This works when doing `zig build` because Zig generates a build executable using
494 // native CPU model & features. However this will not be accurate otherwise, and
495 // will need to be integrated with `std.zig.system.NativeTargetInfo.detect`.
496 return builtin.abi;
497 }
498
499 return Target.Abi.default(self.getCpuArch(), self.getOs());
500}
501
502pub fn isFreeBSD(self: CrossTarget) bool {
503 return self.getOsTag() == .freebsd;
504}
505
506pub fn isDarwin(self: CrossTarget) bool {
507 return self.getOsTag().isDarwin();
508}
509
510pub fn isNetBSD(self: CrossTarget) bool {
511 return self.getOsTag() == .netbsd;
512}
513
514pub fn isOpenBSD(self: CrossTarget) bool {
515 return self.getOsTag() == .openbsd;
516}
517
518pub fn isUefi(self: CrossTarget) bool {
519 return self.getOsTag() == .uefi;
520}
521
522pub fn isDragonFlyBSD(self: CrossTarget) bool {
523 return self.getOsTag() == .dragonfly;
524}
525
526pub fn isLinux(self: CrossTarget) bool {
527 return self.getOsTag() == .linux;
528}
529
530pub fn isWindows(self: CrossTarget) bool {
531 return self.getOsTag() == .windows;
532}
533
534pub fn exeFileExt(self: CrossTarget) [:0]const u8 {
535 return Target.exeFileExtSimple(self.getCpuArch(), self.getOsTag());
536}
537
538pub fn staticLibSuffix(self: CrossTarget) [:0]const u8 {
539 return Target.staticLibSuffix_os_abi(self.getOsTag(), self.getAbi());
540}
541
542pub fn dynamicLibSuffix(self: CrossTarget) [:0]const u8 {
543 return self.getOsTag().dynamicLibSuffix();
544}
545
546pub fn libPrefix(self: CrossTarget) [:0]const u8 {
547 return Target.libPrefix_os_abi(self.getOsTag(), self.getAbi());
548}
549
550pub fn isNativeCpu(self: CrossTarget) bool {
551 return self.cpu_arch == null and
552 (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and
553 self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty();
554}
555
556pub fn isNativeOs(self: CrossTarget) bool {
557 return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and
558 self.dynamic_linker.get() == null and self.glibc_version == null;
559}
560
561pub fn isNativeAbi(self: CrossTarget) bool {
562 return self.os_tag == null and self.abi == null;
563}
564
565pub fn isNative(self: CrossTarget) bool {
566 return self.isNativeCpu() and self.isNativeOs() and self.isNativeAbi();
567}
568
569/// Formats a version with the patch component omitted if it is zero,
570/// unlike SemanticVersion.format which formats all its version components regardless.
571fn formatVersion(version: SemanticVersion, writer: anytype) !void {
572 if (version.patch == 0) {
573 try writer.print("{d}.{d}", .{ version.major, version.minor });
574 } else {
575 try writer.print("{d}.{d}.{d}", .{ version.major, version.minor, version.patch });
576 }
577}
578
579pub fn zigTriple(self: CrossTarget, allocator: mem.Allocator) error{OutOfMemory}![]u8 {
580 if (self.isNative()) {
581 return allocator.dupe(u8, "native");
582 }
583
584 const arch_name = if (self.cpu_arch) |arch| @tagName(arch) else "native";
585 const os_name = if (self.os_tag) |os_tag| @tagName(os_tag) else "native";
586
587 var result = std.ArrayList(u8).init(allocator);
588 defer result.deinit();
589
590 try result.writer().print("{s}-{s}", .{ arch_name, os_name });
591
592 // The zig target syntax does not allow specifying a max os version with no min, so
593 // if either are present, we need the min.
594 if (self.os_version_min != null or self.os_version_max != null) {
595 switch (self.getOsVersionMin()) {
596 .none => {},
597 .semver => |v| {
598 try result.writer().writeAll(".");
599 try formatVersion(v, result.writer());
600 },
601 .windows => |v| try result.writer().print("{s}", .{v}),
602 }
603 }
604 if (self.os_version_max) |max| {
605 switch (max) {
606 .none => {},
607 .semver => |v| {
608 try result.writer().writeAll("...");
609 try formatVersion(v, result.writer());
610 },
611 .windows => |v| try result.writer().print("..{s}", .{v}),
612 }
613 }
614
615 if (self.glibc_version) |v| {
616 try result.writer().print("-{s}.", .{@tagName(self.getAbi())});
617 try formatVersion(v, result.writer());
618 } else if (self.abi) |abi| {
619 try result.writer().print("-{s}", .{@tagName(abi)});
620 }
621
622 return result.toOwnedSlice();
623}
624
625pub fn allocDescription(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
626 // TODO is there anything else worthy of the description that is not
627 // already captured in the triple?
628 return self.zigTriple(allocator);
629}
630
631pub fn linuxTriple(self: CrossTarget, allocator: mem.Allocator) ![]u8 {
632 return Target.linuxTripleSimple(allocator, self.getCpuArch(), self.getOsTag(), self.getAbi());
633}
634
635pub fn wantSharedLibSymLinks(self: CrossTarget) bool {
636 return self.getOsTag() != .windows;
637}
638
639pub const VcpkgLinkage = std.builtin.LinkMode;
640
641/// Returned slice must be freed by the caller.
642pub fn vcpkgTriplet(self: CrossTarget, allocator: mem.Allocator, linkage: VcpkgLinkage) ![]u8 {
643 const arch = switch (self.getCpuArch()) {
644 .x86 => "x86",
645 .x86_64 => "x64",
646
647 .arm,
648 .armeb,
649 .thumb,
650 .thumbeb,
651 .aarch64_32,
652 => "arm",
653
654 .aarch64,
655 .aarch64_be,
656 => "arm64",
657
658 else => return error.UnsupportedVcpkgArchitecture,
659 };
660
661 const os = switch (self.getOsTag()) {
662 .windows => "windows",
663 .linux => "linux",
664 .macos => "macos",
665 else => return error.UnsupportedVcpkgOperatingSystem,
666 };
667
668 const static_suffix = switch (linkage) {
669 .Static => "-static",
670 .Dynamic => "",
671 };
672
673 return std.fmt.allocPrint(allocator, "{s}-{s}{s}", .{ arch, os, static_suffix });
674}
675
676pub fn isGnuLibC(self: CrossTarget) bool {
677 return Target.isGnuLibC_os_tag_abi(self.getOsTag(), self.getAbi());
678}
679
680pub fn setGnuLibCVersion(self: *CrossTarget, major: u32, minor: u32, patch: u32) void {
681 assert(self.isGnuLibC());
682 self.glibc_version = SemanticVersion{ .major = major, .minor = minor, .patch = patch };
683}
684
685pub fn getObjectFormat(self: CrossTarget) Target.ObjectFormat {
686 return self.ofmt orelse Target.ObjectFormat.default(self.getOsTag(), self.getCpuArch());
687}
688
689pub fn updateCpuFeatures(self: CrossTarget, set: *Target.Cpu.Feature.Set) void {
690 set.removeFeatureSet(self.cpu_features_sub);
691 set.addFeatureSet(self.cpu_features_add);
692 set.populateDependencies(self.getCpuArch().allFeaturesList());
693 set.removeFeatureSet(self.cpu_features_sub);
694}
695
696fn parseOs(result: *CrossTarget, diags: *ParseOptions.Diagnostics, text: []const u8) !void {
697 var it = mem.splitScalar(u8, text, '.');
698 const os_name = it.first();
699 diags.os_name = os_name;
700 const os_is_native = mem.eql(u8, os_name, "native");
701 if (!os_is_native) {
702 result.os_tag = std.meta.stringToEnum(Target.Os.Tag, os_name) orelse
703 return error.UnknownOperatingSystem;
704 }
705 const tag = result.getOsTag();
706 diags.os_tag = tag;
707
708 const version_text = it.rest();
709 if (it.next() == null) return;
710
711 switch (tag) {
712 .freestanding,
713 .ananas,
714 .cloudabi,
715 .fuchsia,
716 .kfreebsd,
717 .lv2,
718 .solaris,
719 .illumos,
720 .zos,
721 .haiku,
722 .minix,
723 .rtems,
724 .nacl,
725 .aix,
726 .cuda,
727 .nvcl,
728 .amdhsa,
729 .ps4,
730 .ps5,
731 .elfiamcu,
732 .mesa3d,
733 .contiki,
734 .amdpal,
735 .hermit,
736 .hurd,
737 .wasi,
738 .emscripten,
739 .uefi,
740 .opencl,
741 .glsl450,
742 .vulkan,
743 .plan9,
744 .driverkit,
745 .shadermodel,
746 .liteos,
747 .other,
748 => return error.InvalidOperatingSystemVersion,
749
750 .freebsd,
751 .macos,
752 .ios,
753 .tvos,
754 .watchos,
755 .netbsd,
756 .openbsd,
757 .linux,
758 .dragonfly,
759 => {
760 var range_it = mem.splitSequence(u8, version_text, "...");
761
762 const min_text = range_it.next().?;
763 const min_ver = parseVersion(min_text) catch |err| switch (err) {
764 error.Overflow => return error.InvalidOperatingSystemVersion,
765 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
766 };
767 result.os_version_min = .{ .semver = min_ver };
768
769 const max_text = range_it.next() orelse return;
770 const max_ver = parseVersion(max_text) catch |err| switch (err) {
771 error.Overflow => return error.InvalidOperatingSystemVersion,
772 error.InvalidVersion => return error.InvalidOperatingSystemVersion,
773 };
774 result.os_version_max = .{ .semver = max_ver };
775 },
776
777 .windows => {
778 var range_it = mem.splitSequence(u8, version_text, "...");
779
780 const min_text = range_it.first();
781 const min_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, min_text) orelse
782 return error.InvalidOperatingSystemVersion;
783 result.os_version_min = .{ .windows = min_ver };
784
785 const max_text = range_it.next() orelse return;
786 const max_ver = std.meta.stringToEnum(Target.Os.WindowsVersion, max_text) orelse
787 return error.InvalidOperatingSystemVersion;
788 result.os_version_max = .{ .windows = max_ver };
789 },
790 }
791}
792
793test "CrossTarget.parse" {
794 if (builtin.target.isGnuLibC()) {
795 var cross_target = try CrossTarget.parse(.{});
796 cross_target.setGnuLibCVersion(2, 1, 1);
797
798 const text = try cross_target.zigTriple(std.testing.allocator);
799 defer std.testing.allocator.free(text);
800
801 var buf: [256]u8 = undefined;
802 const triple = std.fmt.bufPrint(
803 buf[0..],
804 "native-native-{s}.2.1.1",
805 .{@tagName(builtin.abi)},
806 ) catch unreachable;
807
808 try std.testing.expectEqualSlices(u8, triple, text);
809 }
810 {
811 const cross_target = try CrossTarget.parse(.{
812 .arch_os_abi = "aarch64-linux",
813 .cpu_features = "native",
814 });
815
816 try std.testing.expect(cross_target.cpu_arch.? == .aarch64);
817 try std.testing.expect(cross_target.cpu_model == .native);
818 }
819 {
820 const cross_target = try CrossTarget.parse(.{ .arch_os_abi = "native" });
821
822 try std.testing.expect(cross_target.cpu_arch == null);
823 try std.testing.expect(cross_target.isNative());
824
825 const text = try cross_target.zigTriple(std.testing.allocator);
826 defer std.testing.allocator.free(text);
827 try std.testing.expectEqualSlices(u8, "native", text);
828 }
829 {
830 const cross_target = try CrossTarget.parse(.{
831 .arch_os_abi = "x86_64-linux-gnu",
832 .cpu_features = "x86_64-sse-sse2-avx-cx8",
833 });
834 const target = cross_target.toTarget();
835
836 try std.testing.expect(target.os.tag == .linux);
837 try std.testing.expect(target.abi == .gnu);
838 try std.testing.expect(target.cpu.arch == .x86_64);
839 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
840 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
841 try std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
842 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
843 try std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
844
845 try std.testing.expect(Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx, .cmov }));
846 try std.testing.expect(!Target.x86.featureSetHasAny(target.cpu.features, .{ .sse, .avx }));
847 try std.testing.expect(Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87 }));
848 try std.testing.expect(!Target.x86.featureSetHasAll(target.cpu.features, .{ .mmx, .x87, .sse }));
849
850 const text = try cross_target.zigTriple(std.testing.allocator);
851 defer std.testing.allocator.free(text);
852 try std.testing.expectEqualSlices(u8, "x86_64-linux-gnu", text);
853 }
854 {
855 const cross_target = try CrossTarget.parse(.{
856 .arch_os_abi = "arm-linux-musleabihf",
857 .cpu_features = "generic+v8a",
858 });
859 const target = cross_target.toTarget();
860
861 try std.testing.expect(target.os.tag == .linux);
862 try std.testing.expect(target.abi == .musleabihf);
863 try std.testing.expect(target.cpu.arch == .arm);
864 try std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
865 try std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
866
867 const text = try cross_target.zigTriple(std.testing.allocator);
868 defer std.testing.allocator.free(text);
869 try std.testing.expectEqualSlices(u8, "arm-linux-musleabihf", text);
870 }
871 {
872 const cross_target = try CrossTarget.parse(.{
873 .arch_os_abi = "aarch64-linux.3.10...4.4.1-gnu.2.27",
874 .cpu_features = "generic+v8a",
875 });
876 const target = cross_target.toTarget();
877
878 try std.testing.expect(target.cpu.arch == .aarch64);
879 try std.testing.expect(target.os.tag == .linux);
880 try std.testing.expect(target.os.version_range.linux.range.min.major == 3);
881 try std.testing.expect(target.os.version_range.linux.range.min.minor == 10);
882 try std.testing.expect(target.os.version_range.linux.range.min.patch == 0);
883 try std.testing.expect(target.os.version_range.linux.range.max.major == 4);
884 try std.testing.expect(target.os.version_range.linux.range.max.minor == 4);
885 try std.testing.expect(target.os.version_range.linux.range.max.patch == 1);
886 try std.testing.expect(target.os.version_range.linux.glibc.major == 2);
887 try std.testing.expect(target.os.version_range.linux.glibc.minor == 27);
888 try std.testing.expect(target.os.version_range.linux.glibc.patch == 0);
889 try std.testing.expect(target.abi == .gnu);
890
891 const text = try cross_target.zigTriple(std.testing.allocator);
892 defer std.testing.allocator.free(text);
893 try std.testing.expectEqualSlices(u8, "aarch64-linux.3.10...4.4.1-gnu.2.27", text);
894 }
895}
lib/std/zig/system.zig+1133-2
......@@ -1,13 +1,1144 @@
11pub const NativePaths = @import("system/NativePaths.zig");
2pub const NativeTargetInfo = @import("system/NativeTargetInfo.zig");
32
43pub const windows = @import("system/windows.zig");
54pub const darwin = @import("system/darwin.zig");
65pub const linux = @import("system/linux.zig");
76
7pub const Executor = union(enum) {
8 native,
9 rosetta,
10 qemu: []const u8,
11 wine: []const u8,
12 wasmtime: []const u8,
13 darling: []const u8,
14 bad_dl: []const u8,
15 bad_os_or_cpu,
16};
17
18pub const GetExternalExecutorOptions = struct {
19 allow_darling: bool = true,
20 allow_qemu: bool = true,
21 allow_rosetta: bool = true,
22 allow_wasmtime: bool = true,
23 allow_wine: bool = true,
24 qemu_fixes_dl: bool = false,
25 link_libc: bool = false,
26};
27
28/// Return whether or not the given host is capable of running executables of
29/// the other target.
30pub fn getExternalExecutor(
31 host: std.Target,
32 candidate: *const std.Target,
33 options: GetExternalExecutorOptions,
34) Executor {
35 const os_match = host.os.tag == candidate.os.tag;
36 const cpu_ok = cpu_ok: {
37 if (host.cpu.arch == candidate.cpu.arch)
38 break :cpu_ok true;
39
40 if (host.cpu.arch == .x86_64 and candidate.cpu.arch == .x86)
41 break :cpu_ok true;
42
43 if (host.cpu.arch == .aarch64 and candidate.cpu.arch == .arm)
44 break :cpu_ok true;
45
46 if (host.cpu.arch == .aarch64_be and candidate.cpu.arch == .armeb)
47 break :cpu_ok true;
48
49 // TODO additionally detect incompatible CPU features.
50 // Note that in some cases the OS kernel will emulate missing CPU features
51 // when an illegal instruction is encountered.
52
53 break :cpu_ok false;
54 };
55
56 var bad_result: Executor = .bad_os_or_cpu;
57
58 if (os_match and cpu_ok) native: {
59 if (options.link_libc) {
60 if (candidate.dynamic_linker.get()) |candidate_dl| {
61 fs.cwd().access(candidate_dl, .{}) catch {
62 bad_result = .{ .bad_dl = candidate_dl };
63 break :native;
64 };
65 }
66 }
67 return .native;
68 }
69
70 // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2
71 // to emulate the foreign architecture.
72 if (options.allow_rosetta and os_match and
73 host.os.tag == .macos and host.cpu.arch == .aarch64)
74 {
75 switch (candidate.cpu.arch) {
76 .x86_64 => return .rosetta,
77 else => return bad_result,
78 }
79 }
80
81 // If the OS matches, we can use QEMU to emulate a foreign architecture.
82 if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) {
83 return switch (candidate.cpu.arch) {
84 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
85 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
86 .arm => Executor{ .qemu = "qemu-arm" },
87 .armeb => Executor{ .qemu = "qemu-armeb" },
88 .hexagon => Executor{ .qemu = "qemu-hexagon" },
89 .x86 => Executor{ .qemu = "qemu-i386" },
90 .m68k => Executor{ .qemu = "qemu-m68k" },
91 .mips => Executor{ .qemu = "qemu-mips" },
92 .mipsel => Executor{ .qemu = "qemu-mipsel" },
93 .mips64 => Executor{ .qemu = "qemu-mips64" },
94 .mips64el => Executor{ .qemu = "qemu-mips64el" },
95 .powerpc => Executor{ .qemu = "qemu-ppc" },
96 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
97 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
98 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
99 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
100 .s390x => Executor{ .qemu = "qemu-s390x" },
101 .sparc => Executor{ .qemu = "qemu-sparc" },
102 .sparc64 => Executor{ .qemu = "qemu-sparc64" },
103 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
104 else => return bad_result,
105 };
106 }
107
108 switch (candidate.os.tag) {
109 .windows => {
110 if (options.allow_wine) {
111 // x86_64 wine does not support emulating aarch64-windows and
112 // vice versa.
113 if (candidate.cpu.arch != builtin.cpu.arch) {
114 return bad_result;
115 }
116 switch (candidate.ptrBitWidth()) {
117 32 => return Executor{ .wine = "wine" },
118 64 => return Executor{ .wine = "wine64" },
119 else => return bad_result,
120 }
121 }
122 return bad_result;
123 },
124 .wasi => {
125 if (options.allow_wasmtime) {
126 switch (candidate.ptrBitWidth()) {
127 32 => return Executor{ .wasmtime = "wasmtime" },
128 else => return bad_result,
129 }
130 }
131 return bad_result;
132 },
133 .macos => {
134 if (options.allow_darling) {
135 // This check can be loosened once darling adds a QEMU-based emulation
136 // layer for non-host architectures:
137 // https://github.com/darlinghq/darling/issues/863
138 if (candidate.cpu.arch != builtin.cpu.arch) {
139 return bad_result;
140 }
141 return Executor{ .darling = "darling" };
142 }
143 return bad_result;
144 },
145 else => return bad_result,
146 }
147}
148
149pub const DetectError = error{
150 FileSystem,
151 SystemResources,
152 SymLinkLoop,
153 ProcessFdQuotaExceeded,
154 SystemFdQuotaExceeded,
155 DeviceBusy,
156 OSVersionDetectionFail,
157 Unexpected,
158};
159
160/// Given a `Target.Query`, which specifies in detail which parts of the
161/// target should be detected natively, which should be standard or default,
162/// and which are provided explicitly, this function resolves the native
163/// components by detecting the native system, and then resolves
164/// standard/default parts relative to that.
165pub fn resolveTargetQuery(query: Target.Query) DetectError!Target {
166 const query_os_tag = query.os_tag orelse builtin.os.tag;
167 var os = query_os_tag.defaultVersionRange(query.cpu_arch orelse builtin.cpu.arch);
168 if (query.os_tag == null) {
169 switch (builtin.target.os.tag) {
170 .linux => {
171 const uts = std.os.uname();
172 const release = mem.sliceTo(&uts.release, 0);
173 // The release field sometimes has a weird format,
174 // `Version.parse` will attempt to find some meaningful interpretation.
175 if (std.SemanticVersion.parse(release)) |ver| {
176 os.version_range.linux.range.min = ver;
177 os.version_range.linux.range.max = ver;
178 } else |err| switch (err) {
179 error.Overflow => {},
180 error.InvalidVersion => {},
181 }
182 },
183 .solaris, .illumos => {
184 const uts = std.os.uname();
185 const release = mem.sliceTo(&uts.release, 0);
186 if (std.SemanticVersion.parse(release)) |ver| {
187 os.version_range.semver.min = ver;
188 os.version_range.semver.max = ver;
189 } else |err| switch (err) {
190 error.Overflow => {},
191 error.InvalidVersion => {},
192 }
193 },
194 .windows => {
195 const detected_version = windows.detectRuntimeVersion();
196 os.version_range.windows.min = detected_version;
197 os.version_range.windows.max = detected_version;
198 },
199 .macos => try darwin.macos.detect(&os),
200 .freebsd, .netbsd, .dragonfly => {
201 const key = switch (builtin.target.os.tag) {
202 .freebsd => "kern.osreldate",
203 .netbsd, .dragonfly => "kern.osrevision",
204 else => unreachable,
205 };
206 var value: u32 = undefined;
207 var len: usize = @sizeOf(@TypeOf(value));
208
209 std.os.sysctlbynameZ(key, &value, &len, null, 0) catch |err| switch (err) {
210 error.NameTooLong => unreachable, // constant, known good value
211 error.PermissionDenied => unreachable, // only when setting values,
212 error.SystemResources => unreachable, // memory already on the stack
213 error.UnknownName => unreachable, // constant, known good value
214 error.Unexpected => return error.OSVersionDetectionFail,
215 };
216
217 switch (builtin.target.os.tag) {
218 .freebsd => {
219 // https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html
220 // Major * 100,000 has been convention since FreeBSD 2.2 (1997)
221 // Minor * 1(0),000 summed has been convention since FreeBSD 2.2 (1997)
222 // e.g. 492101 = 4.11-STABLE = 4.(9+2)
223 const major = value / 100_000;
224 const minor1 = value % 100_000 / 10_000; // usually 0 since 5.1
225 const minor2 = value % 10_000 / 1_000; // 0 before 5.1, minor version since
226 const patch = value % 1_000;
227 os.version_range.semver.min = .{ .major = major, .minor = minor1 + minor2, .patch = patch };
228 os.version_range.semver.max = os.version_range.semver.min;
229 },
230 .netbsd => {
231 // #define __NetBSD_Version__ MMmmrrpp00
232 //
233 // M = major version
234 // m = minor version; a minor number of 99 indicates current.
235 // r = 0 (*)
236 // p = patchlevel
237 const major = value / 100_000_000;
238 const minor = value % 100_000_000 / 1_000_000;
239 const patch = value % 10_000 / 100;
240 os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch };
241 os.version_range.semver.max = os.version_range.semver.min;
242 },
243 .dragonfly => {
244 // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/cb2cde83771754aeef9bb3251ee48959138dec87/Makefile.inc1#L15-L17
245 // flat base10 format: Mmmmpp
246 // M = major
247 // m = minor; odd-numbers indicate current dev branch
248 // p = patch
249 const major = value / 100_000;
250 const minor = value % 100_000 / 100;
251 const patch = value % 100;
252 os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch };
253 os.version_range.semver.max = os.version_range.semver.min;
254 },
255 else => unreachable,
256 }
257 },
258 .openbsd => {
259 const mib: [2]c_int = [_]c_int{
260 std.os.CTL.KERN,
261 std.os.KERN.OSRELEASE,
262 };
263 var buf: [64]u8 = undefined;
264 // consider that sysctl result includes null-termination
265 // reserve 1 byte to ensure we never overflow when appending ".0"
266 var len: usize = buf.len - 1;
267
268 std.os.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
269 error.NameTooLong => unreachable, // constant, known good value
270 error.PermissionDenied => unreachable, // only when setting values,
271 error.SystemResources => unreachable, // memory already on the stack
272 error.UnknownName => unreachable, // constant, known good value
273 error.Unexpected => return error.OSVersionDetectionFail,
274 };
275
276 // append ".0" to satisfy semver
277 buf[len - 1] = '.';
278 buf[len] = '0';
279 len += 1;
280
281 if (std.SemanticVersion.parse(buf[0..len])) |ver| {
282 os.version_range.semver.min = ver;
283 os.version_range.semver.max = ver;
284 } else |_| {
285 return error.OSVersionDetectionFail;
286 }
287 },
288 else => {
289 // Unimplemented, fall back to default version range.
290 },
291 }
292 }
293
294 if (query.os_version_min) |min| switch (min) {
295 .none => {},
296 .semver => |semver| switch (os.tag) {
297 .linux => os.version_range.linux.range.min = semver,
298 else => os.version_range.semver.min = semver,
299 },
300 .windows => |win_ver| os.version_range.windows.min = win_ver,
301 };
302
303 if (query.os_version_max) |max| switch (max) {
304 .none => {},
305 .semver => |semver| switch (os.tag) {
306 .linux => os.version_range.linux.range.max = semver,
307 else => os.version_range.semver.max = semver,
308 },
309 .windows => |win_ver| os.version_range.windows.max = win_ver,
310 };
311
312 if (query.glibc_version) |glibc| {
313 os.version_range.linux.glibc = glibc;
314 }
315
316 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
317 // native CPU architecture as being different than the current target), we use this:
318 const cpu_arch = query.cpu_arch orelse builtin.cpu.arch;
319
320 const cpu = switch (query.cpu_model) {
321 .native => detectNativeCpuAndFeatures(cpu_arch, os, query),
322 .baseline => Target.Cpu.baseline(cpu_arch),
323 .determined_by_cpu_arch => if (query.cpu_arch == null)
324 detectNativeCpuAndFeatures(cpu_arch, os, query)
325 else
326 Target.Cpu.baseline(cpu_arch),
327 .explicit => |model| model.toCpu(cpu_arch),
328 } orelse backup_cpu_detection: {
329 break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
330 };
331 var result = try detectAbiAndDynamicLinker(cpu, os, query);
332 // For x86, we need to populate some CPU feature flags depending on architecture
333 // and mode:
334 // * 16bit_mode => if the abi is code16
335 // * 32bit_mode => if the arch is x86
336 // However, the "mode" flags can be used as overrides, so if the user explicitly
337 // sets one of them, that takes precedence.
338 switch (cpu_arch) {
339 .x86 => {
340 if (!Target.x86.featureSetHasAny(query.cpu_features_add, .{
341 .@"16bit_mode", .@"32bit_mode",
342 })) {
343 switch (result.abi) {
344 .code16 => result.cpu.features.addFeature(
345 @intFromEnum(Target.x86.Feature.@"16bit_mode"),
346 ),
347 else => result.cpu.features.addFeature(
348 @intFromEnum(Target.x86.Feature.@"32bit_mode"),
349 ),
350 }
351 }
352 },
353 .arm, .armeb => {
354 // XXX What do we do if the target has the noarm feature?
355 // What do we do if the user specifies +thumb_mode?
356 },
357 .thumb, .thumbeb => {
358 result.cpu.features.addFeature(
359 @intFromEnum(Target.arm.Feature.thumb_mode),
360 );
361 },
362 else => {},
363 }
364 updateCpuFeatures(
365 &result.cpu.features,
366 cpu_arch.allFeaturesList(),
367 query.cpu_features_add,
368 query.cpu_features_sub,
369 );
370 return result;
371}
372
373fn updateCpuFeatures(
374 set: *Target.Cpu.Feature.Set,
375 all_features_list: []const Target.Cpu.Feature,
376 add_set: Target.Cpu.Feature.Set,
377 sub_set: Target.Cpu.Feature.Set,
378) void {
379 set.removeFeatureSet(sub_set);
380 set.addFeatureSet(add_set);
381 set.populateDependencies(all_features_list);
382 set.removeFeatureSet(sub_set);
383}
384
385fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) ?Target.Cpu {
386 // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`,
387 // although it is a runtime value, is guaranteed to be one of the architectures in the set
388 // of the respective switch prong.
389 switch (builtin.cpu.arch) {
390 .x86_64, .x86 => {
391 return @import("system/x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, query);
392 },
393 else => {},
394 }
395
396 switch (builtin.os.tag) {
397 .linux => return linux.detectNativeCpuAndFeatures(),
398 .macos => return darwin.macos.detectNativeCpuAndFeatures(),
399 .windows => return windows.detectNativeCpuAndFeatures(),
400 else => {},
401 }
402
403 // This architecture does not have CPU model & feature detection yet.
404 // See https://github.com/ziglang/zig/issues/4591
405 return null;
406}
407
408pub const AbiAndDynamicLinkerFromFileError = error{
409 FileSystem,
410 SystemResources,
411 SymLinkLoop,
412 ProcessFdQuotaExceeded,
413 SystemFdQuotaExceeded,
414 UnableToReadElfFile,
415 InvalidElfClass,
416 InvalidElfVersion,
417 InvalidElfEndian,
418 InvalidElfFile,
419 InvalidElfMagic,
420 Unexpected,
421 UnexpectedEndOfFile,
422 NameTooLong,
423};
424
425pub fn abiAndDynamicLinkerFromFile(
426 file: fs.File,
427 cpu: Target.Cpu,
428 os: Target.Os,
429 ld_info_list: []const LdInfo,
430 query: Target.Query,
431) AbiAndDynamicLinkerFromFileError!Target {
432 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
433 _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
434 const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf));
435 const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf));
436 if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic;
437 const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) {
438 elf.ELFDATA2LSB => .little,
439 elf.ELFDATA2MSB => .big,
440 else => return error.InvalidElfEndian,
441 };
442 const need_bswap = elf_endian != native_endian;
443 if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
444
445 const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) {
446 elf.ELFCLASS32 => false,
447 elf.ELFCLASS64 => true,
448 else => return error.InvalidElfClass,
449 };
450 var phoff = elfInt(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff);
451 const phentsize = elfInt(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize);
452 const phnum = elfInt(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum);
453
454 var result: Target = .{
455 .cpu = cpu,
456 .os = os,
457 .abi = query.abi orelse Target.Abi.default(cpu.arch, os),
458 .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
459 .dynamic_linker = query.dynamic_linker,
460 };
461 var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC
462 const look_for_ld = query.dynamic_linker.get() == null;
463
464 var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined;
465 if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile;
466
467 var ph_i: u16 = 0;
468 while (ph_i < phnum) {
469 // Reserve some bytes so that we can deref the 64-bit struct fields
470 // even when the ELF file is 32-bits.
471 const ph_reserve: usize = @sizeOf(elf.Elf64_Phdr) - @sizeOf(elf.Elf32_Phdr);
472 const ph_read_byte_len = try preadMin(file, ph_buf[0 .. ph_buf.len - ph_reserve], phoff, phentsize);
473 var ph_buf_i: usize = 0;
474 while (ph_buf_i < ph_read_byte_len and ph_i < phnum) : ({
475 ph_i += 1;
476 phoff += phentsize;
477 ph_buf_i += phentsize;
478 }) {
479 const ph32: *elf.Elf32_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i]));
480 const ph64: *elf.Elf64_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i]));
481 const p_type = elfInt(is_64, need_bswap, ph32.p_type, ph64.p_type);
482 switch (p_type) {
483 elf.PT_INTERP => if (look_for_ld) {
484 const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset);
485 const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz);
486 if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong;
487 const filesz = @as(usize, @intCast(p_filesz));
488 _ = try preadMin(file, result.dynamic_linker.buffer[0..filesz], p_offset, filesz);
489 // PT_INTERP includes a null byte in filesz.
490 const len = filesz - 1;
491 // dynamic_linker.max_byte is "max", not "len".
492 // We know it will fit in u8 because we check against dynamic_linker.buffer.len above.
493 result.dynamic_linker.max_byte = @as(u8, @intCast(len - 1));
494
495 // Use it to determine ABI.
496 const full_ld_path = result.dynamic_linker.buffer[0..len];
497 for (ld_info_list) |ld_info| {
498 const standard_ld_basename = fs.path.basename(ld_info.ld.get().?);
499 if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) {
500 result.abi = ld_info.abi;
501 break;
502 }
503 }
504 },
505 // We only need this for detecting glibc version.
506 elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.isGnuLibC() and
507 query.glibc_version == null)
508 {
509 var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset);
510 const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz);
511 const dyn_size: usize = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn);
512 const dyn_num = p_filesz / dyn_size;
513 var dyn_buf: [16 * @sizeOf(elf.Elf64_Dyn)]u8 align(@alignOf(elf.Elf64_Dyn)) = undefined;
514 var dyn_i: usize = 0;
515 dyn: while (dyn_i < dyn_num) {
516 // Reserve some bytes so that we can deref the 64-bit struct fields
517 // even when the ELF file is 32-bits.
518 const dyn_reserve: usize = @sizeOf(elf.Elf64_Dyn) - @sizeOf(elf.Elf32_Dyn);
519 const dyn_read_byte_len = try preadMin(
520 file,
521 dyn_buf[0 .. dyn_buf.len - dyn_reserve],
522 dyn_off,
523 dyn_size,
524 );
525 var dyn_buf_i: usize = 0;
526 while (dyn_buf_i < dyn_read_byte_len and dyn_i < dyn_num) : ({
527 dyn_i += 1;
528 dyn_off += dyn_size;
529 dyn_buf_i += dyn_size;
530 }) {
531 const dyn32: *elf.Elf32_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i]));
532 const dyn64: *elf.Elf64_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i]));
533 const tag = elfInt(is_64, need_bswap, dyn32.d_tag, dyn64.d_tag);
534 const val = elfInt(is_64, need_bswap, dyn32.d_val, dyn64.d_val);
535 if (tag == elf.DT_RUNPATH) {
536 rpath_offset = val;
537 break :dyn;
538 }
539 }
540 }
541 },
542 else => continue,
543 }
544 }
545 }
546
547 if (builtin.target.os.tag == .linux and result.isGnuLibC() and
548 query.glibc_version == null)
549 {
550 const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx);
551
552 var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff);
553 const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize);
554 const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx);
555
556 var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined;
557 if (sh_buf.len < shentsize) return error.InvalidElfFile;
558
559 _ = try preadMin(file, &sh_buf, str_section_off, shentsize);
560 const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf));
561 const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf));
562 const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset);
563 const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size);
564 var strtab_buf: [4096:0]u8 = undefined;
565 const shstrtab_len = @min(shstrtab_size, strtab_buf.len);
566 const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len);
567 const shstrtab = strtab_buf[0..shstrtab_read_len];
568
569 const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum);
570 var sh_i: u16 = 0;
571 const dynstr: ?struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) {
572 // Reserve some bytes so that we can deref the 64-bit struct fields
573 // even when the ELF file is 32-bits.
574 const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr);
575 const sh_read_byte_len = try preadMin(
576 file,
577 sh_buf[0 .. sh_buf.len - sh_reserve],
578 shoff,
579 shentsize,
580 );
581 var sh_buf_i: usize = 0;
582 while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({
583 sh_i += 1;
584 shoff += shentsize;
585 sh_buf_i += shentsize;
586 }) {
587 const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
588 const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
589 const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name);
590 const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0);
591 if (mem.eql(u8, sh_name, ".dynstr")) {
592 break :find_dyn_str .{
593 .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset),
594 .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size),
595 };
596 }
597 }
598 } else null;
599
600 if (dynstr) |ds| {
601 if (rpath_offset) |rpoff| {
602 if (rpoff > ds.size) return error.InvalidElfFile;
603 const rpoff_file = ds.offset + rpoff;
604 const rp_max_size = ds.size - rpoff;
605
606 const strtab_len = @min(rp_max_size, strtab_buf.len);
607 const strtab_read_len = try preadMin(file, &strtab_buf, rpoff_file, strtab_len);
608 const strtab = strtab_buf[0..strtab_read_len];
609
610 const rpath_list = mem.sliceTo(strtab, 0);
611 var it = mem.tokenizeScalar(u8, rpath_list, ':');
612 while (it.next()) |rpath| {
613 if (glibcVerFromRPath(rpath)) |ver| {
614 result.os.version_range.linux.glibc = ver;
615 return result;
616 } else |err| switch (err) {
617 error.GLibCNotFound => continue,
618 else => |e| return e,
619 }
620 }
621 }
622 }
623
624 if (result.dynamic_linker.get()) |dl_path| glibc_ver: {
625 // There is no DT_RUNPATH so we try to find libc.so.6 inside the same
626 // directory as the dynamic linker.
627 if (fs.path.dirname(dl_path)) |rpath| {
628 if (glibcVerFromRPath(rpath)) |ver| {
629 result.os.version_range.linux.glibc = ver;
630 return result;
631 } else |err| switch (err) {
632 error.GLibCNotFound => {},
633 else => |e| return e,
634 }
635 }
636
637 // So far, no luck. Next we try to see if the information is
638 // present in the symlink data for the dynamic linker path.
639 var link_buf: [std.os.PATH_MAX]u8 = undefined;
640 const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) {
641 error.NameTooLong => unreachable,
642 error.InvalidUtf8 => unreachable, // Windows only
643 error.BadPathName => unreachable, // Windows only
644 error.UnsupportedReparsePointType => unreachable, // Windows only
645 error.NetworkNotFound => unreachable, // Windows only
646
647 error.AccessDenied,
648 error.FileNotFound,
649 error.NotLink,
650 error.NotDir,
651 => break :glibc_ver,
652
653 error.SystemResources,
654 error.FileSystem,
655 error.SymLinkLoop,
656 error.Unexpected,
657 => |e| return e,
658 };
659 result.os.version_range.linux.glibc = glibcVerFromLinkName(
660 fs.path.basename(link_name),
661 "ld-",
662 ) catch |err| switch (err) {
663 error.UnrecognizedGnuLibCFileName,
664 error.InvalidGnuLibCVersion,
665 => break :glibc_ver,
666 };
667 return result;
668 }
669
670 // Nothing worked so far. Finally we fall back to hard-coded search paths.
671 // Some distros such as Debian keep their libc.so.6 in `/lib/$triple/`.
672 var path_buf: [std.os.PATH_MAX]u8 = undefined;
673 var index: usize = 0;
674 const prefix = "/lib/";
675 const cpu_arch = @tagName(result.cpu.arch);
676 const os_tag = @tagName(result.os.tag);
677 const abi = @tagName(result.abi);
678 @memcpy(path_buf[index..][0..prefix.len], prefix);
679 index += prefix.len;
680 @memcpy(path_buf[index..][0..cpu_arch.len], cpu_arch);
681 index += cpu_arch.len;
682 path_buf[index] = '-';
683 index += 1;
684 @memcpy(path_buf[index..][0..os_tag.len], os_tag);
685 index += os_tag.len;
686 path_buf[index] = '-';
687 index += 1;
688 @memcpy(path_buf[index..][0..abi.len], abi);
689 index += abi.len;
690 const rpath = path_buf[0..index];
691 if (glibcVerFromRPath(rpath)) |ver| {
692 result.os.version_range.linux.glibc = ver;
693 return result;
694 } else |err| switch (err) {
695 error.GLibCNotFound => {},
696 else => |e| return e,
697 }
698 }
699
700 return result;
701}
702
703fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ UnrecognizedGnuLibCFileName, InvalidGnuLibCVersion }!std.SemanticVersion {
704 // example: "libc-2.3.4.so"
705 // example: "libc-2.27.so"
706 // example: "ld-2.33.so"
707 const suffix = ".so";
708 if (!mem.startsWith(u8, link_name, prefix) or !mem.endsWith(u8, link_name, suffix)) {
709 return error.UnrecognizedGnuLibCFileName;
710 }
711 // chop off "libc-" and ".so"
712 const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len];
713 return Target.Query.parseVersion(link_name_chopped) catch |err| switch (err) {
714 error.Overflow => return error.InvalidGnuLibCVersion,
715 error.InvalidVersion => return error.InvalidGnuLibCVersion,
716 };
717}
718
719test glibcVerFromLinkName {
720 try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("ld-2.37.so", "this-prefix-does-not-exist"));
721 try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("libc-2.37.so-is-not-end", "libc-"));
722
723 try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.so", "ld-"));
724 try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.so", "ld-"));
725 try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.0.so", "ld-"));
726 try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 1 }, try glibcVerFromLinkName("ld-2.37.1.so", "ld-"));
727 try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.37.4.5.so", "ld-"));
728}
729
730fn glibcVerFromRPath(rpath: []const u8) !std.SemanticVersion {
731 var dir = fs.cwd().openDir(rpath, .{}) catch |err| switch (err) {
732 error.NameTooLong => unreachable,
733 error.InvalidUtf8 => unreachable,
734 error.BadPathName => unreachable,
735 error.DeviceBusy => unreachable,
736 error.NetworkNotFound => unreachable, // Windows-only
737
738 error.FileNotFound,
739 error.NotDir,
740 error.InvalidHandle,
741 error.AccessDenied,
742 error.NoDevice,
743 => return error.GLibCNotFound,
744
745 error.ProcessFdQuotaExceeded,
746 error.SystemFdQuotaExceeded,
747 error.SystemResources,
748 error.SymLinkLoop,
749 error.Unexpected,
750 => |e| return e,
751 };
752 defer dir.close();
753
754 // Now we have a candidate for the path to libc shared object. In
755 // the past, we used readlink() here because the link name would
756 // reveal the glibc version. However, in more recent GNU/Linux
757 // installations, there is no symlink. Thus we instead use a more
758 // robust check of opening the libc shared object and looking at the
759 // .dynstr section, and finding the max version number of symbols
760 // that start with "GLIBC_2.".
761 const glibc_so_basename = "libc.so.6";
762 var f = dir.openFile(glibc_so_basename, .{}) catch |err| switch (err) {
763 error.NameTooLong => unreachable,
764 error.InvalidUtf8 => unreachable, // Windows only
765 error.BadPathName => unreachable, // Windows only
766 error.PipeBusy => unreachable, // Windows-only
767 error.SharingViolation => unreachable, // Windows-only
768 error.NetworkNotFound => unreachable, // Windows-only
769 error.FileLocksNotSupported => unreachable, // No lock requested.
770 error.NoSpaceLeft => unreachable, // read-only
771 error.PathAlreadyExists => unreachable, // read-only
772 error.DeviceBusy => unreachable, // read-only
773 error.FileBusy => unreachable, // read-only
774 error.InvalidHandle => unreachable, // should not be in the error set
775 error.WouldBlock => unreachable, // not using O_NONBLOCK
776 error.NoDevice => unreachable, // not asking for a special device
777
778 error.AccessDenied,
779 error.FileNotFound,
780 error.NotDir,
781 error.IsDir,
782 => return error.GLibCNotFound,
783
784 error.FileTooBig => return error.Unexpected,
785
786 error.ProcessFdQuotaExceeded,
787 error.SystemFdQuotaExceeded,
788 error.SystemResources,
789 error.SymLinkLoop,
790 error.Unexpected,
791 => |e| return e,
792 };
793 defer f.close();
794
795 return glibcVerFromSoFile(f) catch |err| switch (err) {
796 error.InvalidElfMagic,
797 error.InvalidElfEndian,
798 error.InvalidElfClass,
799 error.InvalidElfFile,
800 error.InvalidElfVersion,
801 error.InvalidGnuLibCVersion,
802 error.UnexpectedEndOfFile,
803 => return error.GLibCNotFound,
804
805 error.SystemResources,
806 error.UnableToReadElfFile,
807 error.Unexpected,
808 error.FileSystem,
809 => |e| return e,
810 };
811}
812
813fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion {
814 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
815 _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
816 const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf));
817 const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf));
818 if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic;
819 const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) {
820 elf.ELFDATA2LSB => .little,
821 elf.ELFDATA2MSB => .big,
822 else => return error.InvalidElfEndian,
823 };
824 const need_bswap = elf_endian != native_endian;
825 if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
826
827 const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) {
828 elf.ELFCLASS32 => false,
829 elf.ELFCLASS64 => true,
830 else => return error.InvalidElfClass,
831 };
832 const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx);
833 var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff);
834 const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize);
835 const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx);
836 var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined;
837 if (sh_buf.len < shentsize) return error.InvalidElfFile;
838
839 _ = try preadMin(file, &sh_buf, str_section_off, shentsize);
840 const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf));
841 const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf));
842 const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset);
843 const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size);
844 var strtab_buf: [4096:0]u8 = undefined;
845 const shstrtab_len = @min(shstrtab_size, strtab_buf.len);
846 const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len);
847 const shstrtab = strtab_buf[0..shstrtab_read_len];
848 const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum);
849 var sh_i: u16 = 0;
850 const dynstr: struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) {
851 // Reserve some bytes so that we can deref the 64-bit struct fields
852 // even when the ELF file is 32-bits.
853 const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr);
854 const sh_read_byte_len = try preadMin(
855 file,
856 sh_buf[0 .. sh_buf.len - sh_reserve],
857 shoff,
858 shentsize,
859 );
860 var sh_buf_i: usize = 0;
861 while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({
862 sh_i += 1;
863 shoff += shentsize;
864 sh_buf_i += shentsize;
865 }) {
866 const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
867 const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
868 const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name);
869 const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0);
870 if (mem.eql(u8, sh_name, ".dynstr")) {
871 break :find_dyn_str .{
872 .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset),
873 .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size),
874 };
875 }
876 }
877 } else return error.InvalidGnuLibCVersion;
878
879 // Here we loop over all the strings in the dynstr string table, assuming that any
880 // strings that start with "GLIBC_2." indicate the existence of such a glibc version,
881 // and furthermore, that the system-installed glibc is at minimum that version.
882
883 // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system.
884 // Here I use double this value plus some headroom. This makes it only need
885 // a single read syscall here.
886 var buf: [80000]u8 = undefined;
887 if (buf.len < dynstr.size) return error.InvalidGnuLibCVersion;
888
889 const dynstr_size: usize = @intCast(dynstr.size);
890 const dynstr_bytes = buf[0..dynstr_size];
891 _ = try preadMin(file, dynstr_bytes, dynstr.offset, dynstr_bytes.len);
892 var it = mem.splitScalar(u8, dynstr_bytes, 0);
893 var max_ver: std.SemanticVersion = .{ .major = 2, .minor = 2, .patch = 5 };
894 while (it.next()) |s| {
895 if (mem.startsWith(u8, s, "GLIBC_2.")) {
896 const chopped = s["GLIBC_".len..];
897 const ver = Target.Query.parseVersion(chopped) catch |err| switch (err) {
898 error.Overflow => return error.InvalidGnuLibCVersion,
899 error.InvalidVersion => return error.InvalidGnuLibCVersion,
900 };
901 switch (ver.order(max_ver)) {
902 .gt => max_ver = ver,
903 .lt, .eq => continue,
904 }
905 }
906 }
907 return max_ver;
908}
909
910/// In the past, this function attempted to use the executable's own binary if it was dynamically
911/// linked to answer both the C ABI question and the dynamic linker question. However, this
912/// could be problematic on a system that uses a RUNPATH for the compiler binary, locking
913/// it to an older glibc version, while system binaries such as /usr/bin/env use a newer glibc
914/// version. The problem is that libc.so.6 glibc version will match that of the system while
915/// the dynamic linker will match that of the compiler binary. Executables with these versions
916/// mismatching will fail to run.
917///
918/// Therefore, this function works the same regardless of whether the compiler binary is
919/// dynamically or statically linked. It inspects `/usr/bin/env` as an ELF file to find the
920/// answer to these questions, or if there is a shebang line, then it chases the referenced
921/// file recursively. If that does not provide the answer, then the function falls back to
922/// defaults.
923fn detectAbiAndDynamicLinker(
924 cpu: Target.Cpu,
925 os: Target.Os,
926 query: Target.Query,
927) DetectError!Target {
928 const native_target_has_ld = comptime builtin.target.hasDynamicLinker();
929 const is_linux = builtin.target.os.tag == .linux;
930 const is_solarish = builtin.target.os.tag.isSolarish();
931 const have_all_info = query.dynamic_linker.get() != null and
932 query.abi != null and (!is_linux or query.abi.?.isGnu());
933 const os_is_non_native = query.os_tag != null;
934 // The Solaris/illumos environment is always the same.
935 if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {
936 return defaultAbiAndDynamicLinker(cpu, os, query);
937 }
938 if (query.abi) |abi| {
939 if (abi.isMusl()) {
940 // musl implies static linking.
941 return defaultAbiAndDynamicLinker(cpu, os, query);
942 }
943 }
944 // The current target's ABI cannot be relied on for this. For example, we may build the zig
945 // compiler for target riscv64-linux-musl and provide a tarball for users to download.
946 // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined
947 // and supported by Zig. But that means that we must detect the system ABI here rather than
948 // relying on `builtin.target`.
949 const all_abis = comptime blk: {
950 assert(@intFromEnum(Target.Abi.none) == 0);
951 const fields = std.meta.fields(Target.Abi)[1..];
952 var array: [fields.len]Target.Abi = undefined;
953 for (fields, 0..) |field, i| {
954 array[i] = @field(Target.Abi, field.name);
955 }
956 break :blk array;
957 };
958 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
959 var ld_info_list_len: usize = 0;
960 const ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
961
962 for (all_abis) |abi| {
963 // This may be a nonsensical parameter. We detect this with
964 // error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`.
965 const target: Target = .{
966 .cpu = cpu,
967 .os = os,
968 .abi = abi,
969 .ofmt = ofmt,
970 };
971 const ld = target.standardDynamicLinkerPath();
972 if (ld.get() == null) continue;
973
974 ld_info_list_buffer[ld_info_list_len] = .{
975 .ld = ld,
976 .abi = abi,
977 };
978 ld_info_list_len += 1;
979 }
980 const ld_info_list = ld_info_list_buffer[0..ld_info_list_len];
981
982 // Best case scenario: the executable is dynamically linked, and we can iterate
983 // over our own shared objects and find a dynamic linker.
984 const elf_file = blk: {
985 // This block looks for a shebang line in /usr/bin/env,
986 // if it finds one, then instead of using /usr/bin/env as the ELF file to examine, it uses the file it references instead,
987 // doing the same logic recursively in case it finds another shebang line.
988
989 // Since /usr/bin/env is hard-coded into the shebang line of many portable scripts, it's a
990 // reasonably reliable path to start with.
991 var file_name: []const u8 = "/usr/bin/env";
992 // #! (2) + 255 (max length of shebang line since Linux 5.1) + \n (1)
993 var buffer: [258]u8 = undefined;
994 while (true) {
995 const file = fs.openFileAbsolute(file_name, .{}) catch |err| switch (err) {
996 error.NoSpaceLeft => unreachable,
997 error.NameTooLong => unreachable,
998 error.PathAlreadyExists => unreachable,
999 error.SharingViolation => unreachable,
1000 error.InvalidUtf8 => unreachable,
1001 error.BadPathName => unreachable,
1002 error.PipeBusy => unreachable,
1003 error.FileLocksNotSupported => unreachable,
1004 error.WouldBlock => unreachable,
1005 error.FileBusy => unreachable, // opened without write permissions
1006
1007 error.IsDir,
1008 error.NotDir,
1009 error.InvalidHandle,
1010 error.AccessDenied,
1011 error.NoDevice,
1012 error.FileNotFound,
1013 error.NetworkNotFound,
1014 error.FileTooBig,
1015 error.Unexpected,
1016 => |e| {
1017 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});
1018 return defaultAbiAndDynamicLinker(cpu, os, query);
1019 },
1020
1021 else => |e| return e,
1022 };
1023 errdefer file.close();
1024
1025 const len = preadMin(file, &buffer, 0, buffer.len) catch |err| switch (err) {
1026 error.UnexpectedEndOfFile,
1027 error.UnableToReadElfFile,
1028 => break :blk file,
1029
1030 else => |e| return e,
1031 };
1032 const newline = mem.indexOfScalar(u8, buffer[0..len], '\n') orelse break :blk file;
1033 const line = buffer[0..newline];
1034 if (!mem.startsWith(u8, line, "#!")) break :blk file;
1035 var it = mem.tokenizeScalar(u8, line[2..], ' ');
1036 file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, query);
1037 file.close();
1038 }
1039 };
1040 defer elf_file.close();
1041
1042 // If Zig is statically linked, such as via distributed binary static builds, the above
1043 // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file.
1044 // TODO: inline this function and combine the buffer we already read above to find
1045 // the possible shebang line with the buffer we use for the ELF header.
1046 return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, query) catch |err| switch (err) {
1047 error.FileSystem,
1048 error.SystemResources,
1049 error.SymLinkLoop,
1050 error.ProcessFdQuotaExceeded,
1051 error.SystemFdQuotaExceeded,
1052 => |e| return e,
1053
1054 error.UnableToReadElfFile,
1055 error.InvalidElfClass,
1056 error.InvalidElfVersion,
1057 error.InvalidElfEndian,
1058 error.InvalidElfFile,
1059 error.InvalidElfMagic,
1060 error.Unexpected,
1061 error.UnexpectedEndOfFile,
1062 error.NameTooLong,
1063 // Finally, we fall back on the standard path.
1064 => |e| {
1065 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});
1066 return defaultAbiAndDynamicLinker(cpu, os, query);
1067 },
1068 };
1069}
1070
1071fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, query: Target.Query) !Target {
1072 const abi = query.abi orelse Target.Abi.default(cpu.arch, os);
1073 return .{
1074 .cpu = cpu,
1075 .os = os,
1076 .abi = abi,
1077 .ofmt = query.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
1078 .dynamic_linker = if (query.dynamic_linker.get() == null)
1079 Target.standardDynamicLinkerPath_cpu_os_abi(cpu, os.tag, abi)
1080 else
1081 query.dynamic_linker,
1082 };
1083}
1084
1085const LdInfo = struct {
1086 ld: Target.DynamicLinker,
1087 abi: Target.Abi,
1088};
1089
1090fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {
1091 var i: usize = 0;
1092 while (i < min_read_len) {
1093 const len = file.pread(buf[i..], offset + i) catch |err| switch (err) {
1094 error.OperationAborted => unreachable, // Windows-only
1095 error.WouldBlock => unreachable, // Did not request blocking mode
1096 error.NotOpenForReading => unreachable,
1097 error.SystemResources => return error.SystemResources,
1098 error.IsDir => return error.UnableToReadElfFile,
1099 error.BrokenPipe => return error.UnableToReadElfFile,
1100 error.Unseekable => return error.UnableToReadElfFile,
1101 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
1102 error.ConnectionTimedOut => return error.UnableToReadElfFile,
1103 error.SocketNotConnected => return error.UnableToReadElfFile,
1104 error.NetNameDeleted => return error.UnableToReadElfFile,
1105 error.Unexpected => return error.Unexpected,
1106 error.InputOutput => return error.FileSystem,
1107 error.AccessDenied => return error.Unexpected,
1108 };
1109 if (len == 0) return error.UnexpectedEndOfFile;
1110 i += len;
1111 }
1112 return i;
1113}
1114
1115fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {
1116 if (is_64) {
1117 if (need_bswap) {
1118 return @byteSwap(int_64);
1119 } else {
1120 return int_64;
1121 }
1122 } else {
1123 if (need_bswap) {
1124 return @byteSwap(int_32);
1125 } else {
1126 return int_32;
1127 }
1128 }
1129}
1130
1131const builtin = @import("builtin");
1132const std = @import("../std.zig");
1133const mem = std.mem;
1134const elf = std.elf;
1135const fs = std.fs;
1136const assert = std.debug.assert;
1137const Target = std.Target;
1138const native_endian = builtin.cpu.arch.endian();
1139
81140test {
91141 _ = NativePaths;
10 _ = NativeTargetInfo;
111142
121143 _ = darwin;
131144 _ = linux;
lib/std/zig/system/NativePaths.zig+1-3
......@@ -5,7 +5,6 @@ const process = std.process;
55const mem = std.mem;
66
77const NativePaths = @This();
8const NativeTargetInfo = std.zig.system.NativeTargetInfo;
98
109arena: Allocator,
1110include_dirs: std.ArrayListUnmanaged([]const u8) = .{},
......@@ -14,8 +13,7 @@ framework_dirs: std.ArrayListUnmanaged([]const u8) = .{},
1413rpaths: std.ArrayListUnmanaged([]const u8) = .{},
1514warnings: std.ArrayListUnmanaged([]const u8) = .{},
1615
17pub fn detect(arena: Allocator, native_info: NativeTargetInfo) !NativePaths {
18 const native_target = native_info.target;
16pub fn detect(arena: Allocator, native_target: std.Target) !NativePaths {
1917 var self: NativePaths = .{ .arena = arena };
2018 var is_nix = false;
2119 if (process.getEnvVarOwned(arena, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
lib/std/zig/system/NativeTargetInfo.zig deleted-1130
......@@ -1,1130 +0,0 @@
1const std = @import("../../std.zig");
2const builtin = @import("builtin");
3const mem = std.mem;
4const assert = std.debug.assert;
5const fs = std.fs;
6const elf = std.elf;
7const native_endian = builtin.cpu.arch.endian();
8
9const NativeTargetInfo = @This();
10const Target = std.Target;
11const Allocator = std.mem.Allocator;
12const CrossTarget = std.zig.CrossTarget;
13const windows = std.zig.system.windows;
14const darwin = std.zig.system.darwin;
15const linux = std.zig.system.linux;
16
17target: Target,
18dynamic_linker: DynamicLinker = DynamicLinker{},
19
20pub const DynamicLinker = Target.DynamicLinker;
21
22pub const DetectError = error{
23 FileSystem,
24 SystemResources,
25 SymLinkLoop,
26 ProcessFdQuotaExceeded,
27 SystemFdQuotaExceeded,
28 DeviceBusy,
29 OSVersionDetectionFail,
30 Unexpected,
31};
32
33/// Given a `CrossTarget`, which specifies in detail which parts of the target should be detected
34/// natively, which should be standard or default, and which are provided explicitly, this function
35/// resolves the native components by detecting the native system, and then resolves standard/default parts
36/// relative to that.
37pub fn detect(cross_target: CrossTarget) DetectError!NativeTargetInfo {
38 var os = cross_target.getOsTag().defaultVersionRange(cross_target.getCpuArch());
39 if (cross_target.os_tag == null) {
40 switch (builtin.target.os.tag) {
41 .linux => {
42 const uts = std.os.uname();
43 const release = mem.sliceTo(&uts.release, 0);
44 // The release field sometimes has a weird format,
45 // `Version.parse` will attempt to find some meaningful interpretation.
46 if (std.SemanticVersion.parse(release)) |ver| {
47 os.version_range.linux.range.min = ver;
48 os.version_range.linux.range.max = ver;
49 } else |err| switch (err) {
50 error.Overflow => {},
51 error.InvalidVersion => {},
52 }
53 },
54 .solaris, .illumos => {
55 const uts = std.os.uname();
56 const release = mem.sliceTo(&uts.release, 0);
57 if (std.SemanticVersion.parse(release)) |ver| {
58 os.version_range.semver.min = ver;
59 os.version_range.semver.max = ver;
60 } else |err| switch (err) {
61 error.Overflow => {},
62 error.InvalidVersion => {},
63 }
64 },
65 .windows => {
66 const detected_version = windows.detectRuntimeVersion();
67 os.version_range.windows.min = detected_version;
68 os.version_range.windows.max = detected_version;
69 },
70 .macos => try darwin.macos.detect(&os),
71 .freebsd, .netbsd, .dragonfly => {
72 const key = switch (builtin.target.os.tag) {
73 .freebsd => "kern.osreldate",
74 .netbsd, .dragonfly => "kern.osrevision",
75 else => unreachable,
76 };
77 var value: u32 = undefined;
78 var len: usize = @sizeOf(@TypeOf(value));
79
80 std.os.sysctlbynameZ(key, &value, &len, null, 0) catch |err| switch (err) {
81 error.NameTooLong => unreachable, // constant, known good value
82 error.PermissionDenied => unreachable, // only when setting values,
83 error.SystemResources => unreachable, // memory already on the stack
84 error.UnknownName => unreachable, // constant, known good value
85 error.Unexpected => return error.OSVersionDetectionFail,
86 };
87
88 switch (builtin.target.os.tag) {
89 .freebsd => {
90 // https://www.freebsd.org/doc/en_US.ISO8859-1/books/porters-handbook/versions.html
91 // Major * 100,000 has been convention since FreeBSD 2.2 (1997)
92 // Minor * 1(0),000 summed has been convention since FreeBSD 2.2 (1997)
93 // e.g. 492101 = 4.11-STABLE = 4.(9+2)
94 const major = value / 100_000;
95 const minor1 = value % 100_000 / 10_000; // usually 0 since 5.1
96 const minor2 = value % 10_000 / 1_000; // 0 before 5.1, minor version since
97 const patch = value % 1_000;
98 os.version_range.semver.min = .{ .major = major, .minor = minor1 + minor2, .patch = patch };
99 os.version_range.semver.max = os.version_range.semver.min;
100 },
101 .netbsd => {
102 // #define __NetBSD_Version__ MMmmrrpp00
103 //
104 // M = major version
105 // m = minor version; a minor number of 99 indicates current.
106 // r = 0 (*)
107 // p = patchlevel
108 const major = value / 100_000_000;
109 const minor = value % 100_000_000 / 1_000_000;
110 const patch = value % 10_000 / 100;
111 os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch };
112 os.version_range.semver.max = os.version_range.semver.min;
113 },
114 .dragonfly => {
115 // https://github.com/DragonFlyBSD/DragonFlyBSD/blob/cb2cde83771754aeef9bb3251ee48959138dec87/Makefile.inc1#L15-L17
116 // flat base10 format: Mmmmpp
117 // M = major
118 // m = minor; odd-numbers indicate current dev branch
119 // p = patch
120 const major = value / 100_000;
121 const minor = value % 100_000 / 100;
122 const patch = value % 100;
123 os.version_range.semver.min = .{ .major = major, .minor = minor, .patch = patch };
124 os.version_range.semver.max = os.version_range.semver.min;
125 },
126 else => unreachable,
127 }
128 },
129 .openbsd => {
130 const mib: [2]c_int = [_]c_int{
131 std.os.CTL.KERN,
132 std.os.KERN.OSRELEASE,
133 };
134 var buf: [64]u8 = undefined;
135 // consider that sysctl result includes null-termination
136 // reserve 1 byte to ensure we never overflow when appending ".0"
137 var len: usize = buf.len - 1;
138
139 std.os.sysctl(&mib, &buf, &len, null, 0) catch |err| switch (err) {
140 error.NameTooLong => unreachable, // constant, known good value
141 error.PermissionDenied => unreachable, // only when setting values,
142 error.SystemResources => unreachable, // memory already on the stack
143 error.UnknownName => unreachable, // constant, known good value
144 error.Unexpected => return error.OSVersionDetectionFail,
145 };
146
147 // append ".0" to satisfy semver
148 buf[len - 1] = '.';
149 buf[len] = '0';
150 len += 1;
151
152 if (std.SemanticVersion.parse(buf[0..len])) |ver| {
153 os.version_range.semver.min = ver;
154 os.version_range.semver.max = ver;
155 } else |_| {
156 return error.OSVersionDetectionFail;
157 }
158 },
159 else => {
160 // Unimplemented, fall back to default version range.
161 },
162 }
163 }
164
165 if (cross_target.os_version_min) |min| switch (min) {
166 .none => {},
167 .semver => |semver| switch (cross_target.getOsTag()) {
168 .linux => os.version_range.linux.range.min = semver,
169 else => os.version_range.semver.min = semver,
170 },
171 .windows => |win_ver| os.version_range.windows.min = win_ver,
172 };
173
174 if (cross_target.os_version_max) |max| switch (max) {
175 .none => {},
176 .semver => |semver| switch (cross_target.getOsTag()) {
177 .linux => os.version_range.linux.range.max = semver,
178 else => os.version_range.semver.max = semver,
179 },
180 .windows => |win_ver| os.version_range.windows.max = win_ver,
181 };
182
183 if (cross_target.glibc_version) |glibc| {
184 assert(cross_target.isGnuLibC());
185 os.version_range.linux.glibc = glibc;
186 }
187
188 // Until https://github.com/ziglang/zig/issues/4592 is implemented (support detecting the
189 // native CPU architecture as being different than the current target), we use this:
190 const cpu_arch = cross_target.getCpuArch();
191
192 const cpu = switch (cross_target.cpu_model) {
193 .native => detectNativeCpuAndFeatures(cpu_arch, os, cross_target),
194 .baseline => Target.Cpu.baseline(cpu_arch),
195 .determined_by_cpu_arch => if (cross_target.cpu_arch == null)
196 detectNativeCpuAndFeatures(cpu_arch, os, cross_target)
197 else
198 Target.Cpu.baseline(cpu_arch),
199 .explicit => |model| model.toCpu(cpu_arch),
200 } orelse backup_cpu_detection: {
201 break :backup_cpu_detection Target.Cpu.baseline(cpu_arch);
202 };
203 var result = try detectAbiAndDynamicLinker(cpu, os, cross_target);
204 // For x86, we need to populate some CPU feature flags depending on architecture
205 // and mode:
206 // * 16bit_mode => if the abi is code16
207 // * 32bit_mode => if the arch is x86
208 // However, the "mode" flags can be used as overrides, so if the user explicitly
209 // sets one of them, that takes precedence.
210 switch (cpu_arch) {
211 .x86 => {
212 if (!std.Target.x86.featureSetHasAny(cross_target.cpu_features_add, .{
213 .@"16bit_mode", .@"32bit_mode",
214 })) {
215 switch (result.target.abi) {
216 .code16 => result.target.cpu.features.addFeature(
217 @intFromEnum(std.Target.x86.Feature.@"16bit_mode"),
218 ),
219 else => result.target.cpu.features.addFeature(
220 @intFromEnum(std.Target.x86.Feature.@"32bit_mode"),
221 ),
222 }
223 }
224 },
225 .arm, .armeb => {
226 // XXX What do we do if the target has the noarm feature?
227 // What do we do if the user specifies +thumb_mode?
228 },
229 .thumb, .thumbeb => {
230 result.target.cpu.features.addFeature(
231 @intFromEnum(std.Target.arm.Feature.thumb_mode),
232 );
233 },
234 else => {},
235 }
236 cross_target.updateCpuFeatures(&result.target.cpu.features);
237 return result;
238}
239
240/// In the past, this function attempted to use the executable's own binary if it was dynamically
241/// linked to answer both the C ABI question and the dynamic linker question. However, this
242/// could be problematic on a system that uses a RUNPATH for the compiler binary, locking
243/// it to an older glibc version, while system binaries such as /usr/bin/env use a newer glibc
244/// version. The problem is that libc.so.6 glibc version will match that of the system while
245/// the dynamic linker will match that of the compiler binary. Executables with these versions
246/// mismatching will fail to run.
247///
248/// Therefore, this function works the same regardless of whether the compiler binary is
249/// dynamically or statically linked. It inspects `/usr/bin/env` as an ELF file to find the
250/// answer to these questions, or if there is a shebang line, then it chases the referenced
251/// file recursively. If that does not provide the answer, then the function falls back to
252/// defaults.
253fn detectAbiAndDynamicLinker(
254 cpu: Target.Cpu,
255 os: Target.Os,
256 cross_target: CrossTarget,
257) DetectError!NativeTargetInfo {
258 const native_target_has_ld = comptime builtin.target.hasDynamicLinker();
259 const is_linux = builtin.target.os.tag == .linux;
260 const is_solarish = builtin.target.os.tag.isSolarish();
261 const have_all_info = cross_target.dynamic_linker.get() != null and
262 cross_target.abi != null and (!is_linux or cross_target.abi.?.isGnu());
263 const os_is_non_native = cross_target.os_tag != null;
264 // The Solaris/illumos environment is always the same.
265 if (!native_target_has_ld or have_all_info or os_is_non_native or is_solarish) {
266 return defaultAbiAndDynamicLinker(cpu, os, cross_target);
267 }
268 if (cross_target.abi) |abi| {
269 if (abi.isMusl()) {
270 // musl implies static linking.
271 return defaultAbiAndDynamicLinker(cpu, os, cross_target);
272 }
273 }
274 // The current target's ABI cannot be relied on for this. For example, we may build the zig
275 // compiler for target riscv64-linux-musl and provide a tarball for users to download.
276 // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined
277 // and supported by Zig. But that means that we must detect the system ABI here rather than
278 // relying on `builtin.target`.
279 const all_abis = comptime blk: {
280 assert(@intFromEnum(Target.Abi.none) == 0);
281 const fields = std.meta.fields(Target.Abi)[1..];
282 var array: [fields.len]Target.Abi = undefined;
283 for (fields, 0..) |field, i| {
284 array[i] = @field(Target.Abi, field.name);
285 }
286 break :blk array;
287 };
288 var ld_info_list_buffer: [all_abis.len]LdInfo = undefined;
289 var ld_info_list_len: usize = 0;
290 const ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch);
291
292 for (all_abis) |abi| {
293 // This may be a nonsensical parameter. We detect this with
294 // error.UnknownDynamicLinkerPath and skip adding it to `ld_info_list`.
295 const target: Target = .{
296 .cpu = cpu,
297 .os = os,
298 .abi = abi,
299 .ofmt = ofmt,
300 };
301 const ld = target.standardDynamicLinkerPath();
302 if (ld.get() == null) continue;
303
304 ld_info_list_buffer[ld_info_list_len] = .{
305 .ld = ld,
306 .abi = abi,
307 };
308 ld_info_list_len += 1;
309 }
310 const ld_info_list = ld_info_list_buffer[0..ld_info_list_len];
311
312 // Best case scenario: the executable is dynamically linked, and we can iterate
313 // over our own shared objects and find a dynamic linker.
314 const elf_file = blk: {
315 // This block looks for a shebang line in /usr/bin/env,
316 // if it finds one, then instead of using /usr/bin/env as the ELF file to examine, it uses the file it references instead,
317 // doing the same logic recursively in case it finds another shebang line.
318
319 // Since /usr/bin/env is hard-coded into the shebang line of many portable scripts, it's a
320 // reasonably reliable path to start with.
321 var file_name: []const u8 = "/usr/bin/env";
322 // #! (2) + 255 (max length of shebang line since Linux 5.1) + \n (1)
323 var buffer: [258]u8 = undefined;
324 while (true) {
325 const file = fs.openFileAbsolute(file_name, .{}) catch |err| switch (err) {
326 error.NoSpaceLeft => unreachable,
327 error.NameTooLong => unreachable,
328 error.PathAlreadyExists => unreachable,
329 error.SharingViolation => unreachable,
330 error.InvalidUtf8 => unreachable,
331 error.BadPathName => unreachable,
332 error.PipeBusy => unreachable,
333 error.FileLocksNotSupported => unreachable,
334 error.WouldBlock => unreachable,
335 error.FileBusy => unreachable, // opened without write permissions
336
337 error.IsDir,
338 error.NotDir,
339 error.InvalidHandle,
340 error.AccessDenied,
341 error.NoDevice,
342 error.FileNotFound,
343 error.NetworkNotFound,
344 error.FileTooBig,
345 error.Unexpected,
346 => |e| {
347 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});
348 return defaultAbiAndDynamicLinker(cpu, os, cross_target);
349 },
350
351 else => |e| return e,
352 };
353 errdefer file.close();
354
355 const len = preadMin(file, &buffer, 0, buffer.len) catch |err| switch (err) {
356 error.UnexpectedEndOfFile,
357 error.UnableToReadElfFile,
358 => break :blk file,
359
360 else => |e| return e,
361 };
362 const newline = mem.indexOfScalar(u8, buffer[0..len], '\n') orelse break :blk file;
363 const line = buffer[0..newline];
364 if (!mem.startsWith(u8, line, "#!")) break :blk file;
365 var it = mem.tokenizeScalar(u8, line[2..], ' ');
366 file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, cross_target);
367 file.close();
368 }
369 };
370 defer elf_file.close();
371
372 // If Zig is statically linked, such as via distributed binary static builds, the above
373 // trick (block self_exe) won't work. The next thing we fall back to is the same thing, but for elf_file.
374 // TODO: inline this function and combine the buffer we already read above to find
375 // the possible shebang line with the buffer we use for the ELF header.
376 return abiAndDynamicLinkerFromFile(elf_file, cpu, os, ld_info_list, cross_target) catch |err| switch (err) {
377 error.FileSystem,
378 error.SystemResources,
379 error.SymLinkLoop,
380 error.ProcessFdQuotaExceeded,
381 error.SystemFdQuotaExceeded,
382 => |e| return e,
383
384 error.UnableToReadElfFile,
385 error.InvalidElfClass,
386 error.InvalidElfVersion,
387 error.InvalidElfEndian,
388 error.InvalidElfFile,
389 error.InvalidElfMagic,
390 error.Unexpected,
391 error.UnexpectedEndOfFile,
392 error.NameTooLong,
393 // Finally, we fall back on the standard path.
394 => |e| {
395 std.log.warn("Encountered error: {s}, falling back to default ABI and dynamic linker.\n", .{@errorName(e)});
396 return defaultAbiAndDynamicLinker(cpu, os, cross_target);
397 },
398 };
399}
400
401fn glibcVerFromRPath(rpath: []const u8) !std.SemanticVersion {
402 var dir = fs.cwd().openDir(rpath, .{}) catch |err| switch (err) {
403 error.NameTooLong => unreachable,
404 error.InvalidUtf8 => unreachable,
405 error.BadPathName => unreachable,
406 error.DeviceBusy => unreachable,
407 error.NetworkNotFound => unreachable, // Windows-only
408
409 error.FileNotFound,
410 error.NotDir,
411 error.InvalidHandle,
412 error.AccessDenied,
413 error.NoDevice,
414 => return error.GLibCNotFound,
415
416 error.ProcessFdQuotaExceeded,
417 error.SystemFdQuotaExceeded,
418 error.SystemResources,
419 error.SymLinkLoop,
420 error.Unexpected,
421 => |e| return e,
422 };
423 defer dir.close();
424
425 // Now we have a candidate for the path to libc shared object. In
426 // the past, we used readlink() here because the link name would
427 // reveal the glibc version. However, in more recent GNU/Linux
428 // installations, there is no symlink. Thus we instead use a more
429 // robust check of opening the libc shared object and looking at the
430 // .dynstr section, and finding the max version number of symbols
431 // that start with "GLIBC_2.".
432 const glibc_so_basename = "libc.so.6";
433 var f = dir.openFile(glibc_so_basename, .{}) catch |err| switch (err) {
434 error.NameTooLong => unreachable,
435 error.InvalidUtf8 => unreachable, // Windows only
436 error.BadPathName => unreachable, // Windows only
437 error.PipeBusy => unreachable, // Windows-only
438 error.SharingViolation => unreachable, // Windows-only
439 error.NetworkNotFound => unreachable, // Windows-only
440 error.FileLocksNotSupported => unreachable, // No lock requested.
441 error.NoSpaceLeft => unreachable, // read-only
442 error.PathAlreadyExists => unreachable, // read-only
443 error.DeviceBusy => unreachable, // read-only
444 error.FileBusy => unreachable, // read-only
445 error.InvalidHandle => unreachable, // should not be in the error set
446 error.WouldBlock => unreachable, // not using O_NONBLOCK
447 error.NoDevice => unreachable, // not asking for a special device
448
449 error.AccessDenied,
450 error.FileNotFound,
451 error.NotDir,
452 error.IsDir,
453 => return error.GLibCNotFound,
454
455 error.FileTooBig => return error.Unexpected,
456
457 error.ProcessFdQuotaExceeded,
458 error.SystemFdQuotaExceeded,
459 error.SystemResources,
460 error.SymLinkLoop,
461 error.Unexpected,
462 => |e| return e,
463 };
464 defer f.close();
465
466 return glibcVerFromSoFile(f) catch |err| switch (err) {
467 error.InvalidElfMagic,
468 error.InvalidElfEndian,
469 error.InvalidElfClass,
470 error.InvalidElfFile,
471 error.InvalidElfVersion,
472 error.InvalidGnuLibCVersion,
473 error.UnexpectedEndOfFile,
474 => return error.GLibCNotFound,
475
476 error.SystemResources,
477 error.UnableToReadElfFile,
478 error.Unexpected,
479 error.FileSystem,
480 => |e| return e,
481 };
482}
483
484fn glibcVerFromSoFile(file: fs.File) !std.SemanticVersion {
485 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
486 _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
487 const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf));
488 const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf));
489 if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic;
490 const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) {
491 elf.ELFDATA2LSB => .little,
492 elf.ELFDATA2MSB => .big,
493 else => return error.InvalidElfEndian,
494 };
495 const need_bswap = elf_endian != native_endian;
496 if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
497
498 const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) {
499 elf.ELFCLASS32 => false,
500 elf.ELFCLASS64 => true,
501 else => return error.InvalidElfClass,
502 };
503 const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx);
504 var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff);
505 const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize);
506 const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx);
507 var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined;
508 if (sh_buf.len < shentsize) return error.InvalidElfFile;
509
510 _ = try preadMin(file, &sh_buf, str_section_off, shentsize);
511 const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf));
512 const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf));
513 const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset);
514 const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size);
515 var strtab_buf: [4096:0]u8 = undefined;
516 const shstrtab_len = @min(shstrtab_size, strtab_buf.len);
517 const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len);
518 const shstrtab = strtab_buf[0..shstrtab_read_len];
519 const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum);
520 var sh_i: u16 = 0;
521 const dynstr: struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) {
522 // Reserve some bytes so that we can deref the 64-bit struct fields
523 // even when the ELF file is 32-bits.
524 const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr);
525 const sh_read_byte_len = try preadMin(
526 file,
527 sh_buf[0 .. sh_buf.len - sh_reserve],
528 shoff,
529 shentsize,
530 );
531 var sh_buf_i: usize = 0;
532 while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({
533 sh_i += 1;
534 shoff += shentsize;
535 sh_buf_i += shentsize;
536 }) {
537 const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
538 const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
539 const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name);
540 const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0);
541 if (mem.eql(u8, sh_name, ".dynstr")) {
542 break :find_dyn_str .{
543 .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset),
544 .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size),
545 };
546 }
547 }
548 } else return error.InvalidGnuLibCVersion;
549
550 // Here we loop over all the strings in the dynstr string table, assuming that any
551 // strings that start with "GLIBC_2." indicate the existence of such a glibc version,
552 // and furthermore, that the system-installed glibc is at minimum that version.
553
554 // Empirically, glibc 2.34 libc.so .dynstr section is 32441 bytes on my system.
555 // Here I use double this value plus some headroom. This makes it only need
556 // a single read syscall here.
557 var buf: [80000]u8 = undefined;
558 if (buf.len < dynstr.size) return error.InvalidGnuLibCVersion;
559
560 const dynstr_size: usize = @intCast(dynstr.size);
561 const dynstr_bytes = buf[0..dynstr_size];
562 _ = try preadMin(file, dynstr_bytes, dynstr.offset, dynstr_bytes.len);
563 var it = mem.splitScalar(u8, dynstr_bytes, 0);
564 var max_ver: std.SemanticVersion = .{ .major = 2, .minor = 2, .patch = 5 };
565 while (it.next()) |s| {
566 if (mem.startsWith(u8, s, "GLIBC_2.")) {
567 const chopped = s["GLIBC_".len..];
568 const ver = CrossTarget.parseVersion(chopped) catch |err| switch (err) {
569 error.Overflow => return error.InvalidGnuLibCVersion,
570 error.InvalidVersion => return error.InvalidGnuLibCVersion,
571 };
572 switch (ver.order(max_ver)) {
573 .gt => max_ver = ver,
574 .lt, .eq => continue,
575 }
576 }
577 }
578 return max_ver;
579}
580
581fn glibcVerFromLinkName(link_name: []const u8, prefix: []const u8) error{ UnrecognizedGnuLibCFileName, InvalidGnuLibCVersion }!std.SemanticVersion {
582 // example: "libc-2.3.4.so"
583 // example: "libc-2.27.so"
584 // example: "ld-2.33.so"
585 const suffix = ".so";
586 if (!mem.startsWith(u8, link_name, prefix) or !mem.endsWith(u8, link_name, suffix)) {
587 return error.UnrecognizedGnuLibCFileName;
588 }
589 // chop off "libc-" and ".so"
590 const link_name_chopped = link_name[prefix.len .. link_name.len - suffix.len];
591 return CrossTarget.parseVersion(link_name_chopped) catch |err| switch (err) {
592 error.Overflow => return error.InvalidGnuLibCVersion,
593 error.InvalidVersion => return error.InvalidGnuLibCVersion,
594 };
595}
596
597test glibcVerFromLinkName {
598 try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("ld-2.37.so", "this-prefix-does-not-exist"));
599 try std.testing.expectError(error.UnrecognizedGnuLibCFileName, glibcVerFromLinkName("libc-2.37.so-is-not-end", "libc-"));
600
601 try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.so", "ld-"));
602 try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.so", "ld-"));
603 try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 0 }, try glibcVerFromLinkName("ld-2.37.0.so", "ld-"));
604 try std.testing.expectEqual(std.SemanticVersion{ .major = 2, .minor = 37, .patch = 1 }, try glibcVerFromLinkName("ld-2.37.1.so", "ld-"));
605 try std.testing.expectError(error.InvalidGnuLibCVersion, glibcVerFromLinkName("ld-2.37.4.5.so", "ld-"));
606}
607
608pub const AbiAndDynamicLinkerFromFileError = error{
609 FileSystem,
610 SystemResources,
611 SymLinkLoop,
612 ProcessFdQuotaExceeded,
613 SystemFdQuotaExceeded,
614 UnableToReadElfFile,
615 InvalidElfClass,
616 InvalidElfVersion,
617 InvalidElfEndian,
618 InvalidElfFile,
619 InvalidElfMagic,
620 Unexpected,
621 UnexpectedEndOfFile,
622 NameTooLong,
623};
624
625pub fn abiAndDynamicLinkerFromFile(
626 file: fs.File,
627 cpu: Target.Cpu,
628 os: Target.Os,
629 ld_info_list: []const LdInfo,
630 cross_target: CrossTarget,
631) AbiAndDynamicLinkerFromFileError!NativeTargetInfo {
632 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 align(@alignOf(elf.Elf64_Ehdr)) = undefined;
633 _ = try preadMin(file, &hdr_buf, 0, hdr_buf.len);
634 const hdr32 = @as(*elf.Elf32_Ehdr, @ptrCast(&hdr_buf));
635 const hdr64 = @as(*elf.Elf64_Ehdr, @ptrCast(&hdr_buf));
636 if (!mem.eql(u8, hdr32.e_ident[0..4], elf.MAGIC)) return error.InvalidElfMagic;
637 const elf_endian: std.builtin.Endian = switch (hdr32.e_ident[elf.EI_DATA]) {
638 elf.ELFDATA2LSB => .little,
639 elf.ELFDATA2MSB => .big,
640 else => return error.InvalidElfEndian,
641 };
642 const need_bswap = elf_endian != native_endian;
643 if (hdr32.e_ident[elf.EI_VERSION] != 1) return error.InvalidElfVersion;
644
645 const is_64 = switch (hdr32.e_ident[elf.EI_CLASS]) {
646 elf.ELFCLASS32 => false,
647 elf.ELFCLASS64 => true,
648 else => return error.InvalidElfClass,
649 };
650 var phoff = elfInt(is_64, need_bswap, hdr32.e_phoff, hdr64.e_phoff);
651 const phentsize = elfInt(is_64, need_bswap, hdr32.e_phentsize, hdr64.e_phentsize);
652 const phnum = elfInt(is_64, need_bswap, hdr32.e_phnum, hdr64.e_phnum);
653
654 var result: NativeTargetInfo = .{
655 .target = .{
656 .cpu = cpu,
657 .os = os,
658 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
659 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
660 },
661 .dynamic_linker = cross_target.dynamic_linker,
662 };
663 var rpath_offset: ?u64 = null; // Found inside PT_DYNAMIC
664 const look_for_ld = cross_target.dynamic_linker.get() == null;
665
666 var ph_buf: [16 * @sizeOf(elf.Elf64_Phdr)]u8 align(@alignOf(elf.Elf64_Phdr)) = undefined;
667 if (phentsize > @sizeOf(elf.Elf64_Phdr)) return error.InvalidElfFile;
668
669 var ph_i: u16 = 0;
670 while (ph_i < phnum) {
671 // Reserve some bytes so that we can deref the 64-bit struct fields
672 // even when the ELF file is 32-bits.
673 const ph_reserve: usize = @sizeOf(elf.Elf64_Phdr) - @sizeOf(elf.Elf32_Phdr);
674 const ph_read_byte_len = try preadMin(file, ph_buf[0 .. ph_buf.len - ph_reserve], phoff, phentsize);
675 var ph_buf_i: usize = 0;
676 while (ph_buf_i < ph_read_byte_len and ph_i < phnum) : ({
677 ph_i += 1;
678 phoff += phentsize;
679 ph_buf_i += phentsize;
680 }) {
681 const ph32: *elf.Elf32_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i]));
682 const ph64: *elf.Elf64_Phdr = @ptrCast(@alignCast(&ph_buf[ph_buf_i]));
683 const p_type = elfInt(is_64, need_bswap, ph32.p_type, ph64.p_type);
684 switch (p_type) {
685 elf.PT_INTERP => if (look_for_ld) {
686 const p_offset = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset);
687 const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz);
688 if (p_filesz > result.dynamic_linker.buffer.len) return error.NameTooLong;
689 const filesz = @as(usize, @intCast(p_filesz));
690 _ = try preadMin(file, result.dynamic_linker.buffer[0..filesz], p_offset, filesz);
691 // PT_INTERP includes a null byte in filesz.
692 const len = filesz - 1;
693 // dynamic_linker.max_byte is "max", not "len".
694 // We know it will fit in u8 because we check against dynamic_linker.buffer.len above.
695 result.dynamic_linker.max_byte = @as(u8, @intCast(len - 1));
696
697 // Use it to determine ABI.
698 const full_ld_path = result.dynamic_linker.buffer[0..len];
699 for (ld_info_list) |ld_info| {
700 const standard_ld_basename = fs.path.basename(ld_info.ld.get().?);
701 if (std.mem.endsWith(u8, full_ld_path, standard_ld_basename)) {
702 result.target.abi = ld_info.abi;
703 break;
704 }
705 }
706 },
707 // We only need this for detecting glibc version.
708 elf.PT_DYNAMIC => if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and
709 cross_target.glibc_version == null)
710 {
711 var dyn_off = elfInt(is_64, need_bswap, ph32.p_offset, ph64.p_offset);
712 const p_filesz = elfInt(is_64, need_bswap, ph32.p_filesz, ph64.p_filesz);
713 const dyn_size: usize = if (is_64) @sizeOf(elf.Elf64_Dyn) else @sizeOf(elf.Elf32_Dyn);
714 const dyn_num = p_filesz / dyn_size;
715 var dyn_buf: [16 * @sizeOf(elf.Elf64_Dyn)]u8 align(@alignOf(elf.Elf64_Dyn)) = undefined;
716 var dyn_i: usize = 0;
717 dyn: while (dyn_i < dyn_num) {
718 // Reserve some bytes so that we can deref the 64-bit struct fields
719 // even when the ELF file is 32-bits.
720 const dyn_reserve: usize = @sizeOf(elf.Elf64_Dyn) - @sizeOf(elf.Elf32_Dyn);
721 const dyn_read_byte_len = try preadMin(
722 file,
723 dyn_buf[0 .. dyn_buf.len - dyn_reserve],
724 dyn_off,
725 dyn_size,
726 );
727 var dyn_buf_i: usize = 0;
728 while (dyn_buf_i < dyn_read_byte_len and dyn_i < dyn_num) : ({
729 dyn_i += 1;
730 dyn_off += dyn_size;
731 dyn_buf_i += dyn_size;
732 }) {
733 const dyn32: *elf.Elf32_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i]));
734 const dyn64: *elf.Elf64_Dyn = @ptrCast(@alignCast(&dyn_buf[dyn_buf_i]));
735 const tag = elfInt(is_64, need_bswap, dyn32.d_tag, dyn64.d_tag);
736 const val = elfInt(is_64, need_bswap, dyn32.d_val, dyn64.d_val);
737 if (tag == elf.DT_RUNPATH) {
738 rpath_offset = val;
739 break :dyn;
740 }
741 }
742 }
743 },
744 else => continue,
745 }
746 }
747 }
748
749 if (builtin.target.os.tag == .linux and result.target.isGnuLibC() and
750 cross_target.glibc_version == null)
751 {
752 const shstrndx = elfInt(is_64, need_bswap, hdr32.e_shstrndx, hdr64.e_shstrndx);
753
754 var shoff = elfInt(is_64, need_bswap, hdr32.e_shoff, hdr64.e_shoff);
755 const shentsize = elfInt(is_64, need_bswap, hdr32.e_shentsize, hdr64.e_shentsize);
756 const str_section_off = shoff + @as(u64, shentsize) * @as(u64, shstrndx);
757
758 var sh_buf: [16 * @sizeOf(elf.Elf64_Shdr)]u8 align(@alignOf(elf.Elf64_Shdr)) = undefined;
759 if (sh_buf.len < shentsize) return error.InvalidElfFile;
760
761 _ = try preadMin(file, &sh_buf, str_section_off, shentsize);
762 const shstr32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf));
763 const shstr64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf));
764 const shstrtab_off = elfInt(is_64, need_bswap, shstr32.sh_offset, shstr64.sh_offset);
765 const shstrtab_size = elfInt(is_64, need_bswap, shstr32.sh_size, shstr64.sh_size);
766 var strtab_buf: [4096:0]u8 = undefined;
767 const shstrtab_len = @min(shstrtab_size, strtab_buf.len);
768 const shstrtab_read_len = try preadMin(file, &strtab_buf, shstrtab_off, shstrtab_len);
769 const shstrtab = strtab_buf[0..shstrtab_read_len];
770
771 const shnum = elfInt(is_64, need_bswap, hdr32.e_shnum, hdr64.e_shnum);
772 var sh_i: u16 = 0;
773 const dynstr: ?struct { offset: u64, size: u64 } = find_dyn_str: while (sh_i < shnum) {
774 // Reserve some bytes so that we can deref the 64-bit struct fields
775 // even when the ELF file is 32-bits.
776 const sh_reserve: usize = @sizeOf(elf.Elf64_Shdr) - @sizeOf(elf.Elf32_Shdr);
777 const sh_read_byte_len = try preadMin(
778 file,
779 sh_buf[0 .. sh_buf.len - sh_reserve],
780 shoff,
781 shentsize,
782 );
783 var sh_buf_i: usize = 0;
784 while (sh_buf_i < sh_read_byte_len and sh_i < shnum) : ({
785 sh_i += 1;
786 shoff += shentsize;
787 sh_buf_i += shentsize;
788 }) {
789 const sh32: *elf.Elf32_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
790 const sh64: *elf.Elf64_Shdr = @ptrCast(@alignCast(&sh_buf[sh_buf_i]));
791 const sh_name_off = elfInt(is_64, need_bswap, sh32.sh_name, sh64.sh_name);
792 const sh_name = mem.sliceTo(shstrtab[sh_name_off..], 0);
793 if (mem.eql(u8, sh_name, ".dynstr")) {
794 break :find_dyn_str .{
795 .offset = elfInt(is_64, need_bswap, sh32.sh_offset, sh64.sh_offset),
796 .size = elfInt(is_64, need_bswap, sh32.sh_size, sh64.sh_size),
797 };
798 }
799 }
800 } else null;
801
802 if (dynstr) |ds| {
803 if (rpath_offset) |rpoff| {
804 if (rpoff > ds.size) return error.InvalidElfFile;
805 const rpoff_file = ds.offset + rpoff;
806 const rp_max_size = ds.size - rpoff;
807
808 const strtab_len = @min(rp_max_size, strtab_buf.len);
809 const strtab_read_len = try preadMin(file, &strtab_buf, rpoff_file, strtab_len);
810 const strtab = strtab_buf[0..strtab_read_len];
811
812 const rpath_list = mem.sliceTo(strtab, 0);
813 var it = mem.tokenizeScalar(u8, rpath_list, ':');
814 while (it.next()) |rpath| {
815 if (glibcVerFromRPath(rpath)) |ver| {
816 result.target.os.version_range.linux.glibc = ver;
817 return result;
818 } else |err| switch (err) {
819 error.GLibCNotFound => continue,
820 else => |e| return e,
821 }
822 }
823 }
824 }
825
826 if (result.dynamic_linker.get()) |dl_path| glibc_ver: {
827 // There is no DT_RUNPATH so we try to find libc.so.6 inside the same
828 // directory as the dynamic linker.
829 if (fs.path.dirname(dl_path)) |rpath| {
830 if (glibcVerFromRPath(rpath)) |ver| {
831 result.target.os.version_range.linux.glibc = ver;
832 return result;
833 } else |err| switch (err) {
834 error.GLibCNotFound => {},
835 else => |e| return e,
836 }
837 }
838
839 // So far, no luck. Next we try to see if the information is
840 // present in the symlink data for the dynamic linker path.
841 var link_buf: [std.os.PATH_MAX]u8 = undefined;
842 const link_name = std.os.readlink(dl_path, &link_buf) catch |err| switch (err) {
843 error.NameTooLong => unreachable,
844 error.InvalidUtf8 => unreachable, // Windows only
845 error.BadPathName => unreachable, // Windows only
846 error.UnsupportedReparsePointType => unreachable, // Windows only
847 error.NetworkNotFound => unreachable, // Windows only
848
849 error.AccessDenied,
850 error.FileNotFound,
851 error.NotLink,
852 error.NotDir,
853 => break :glibc_ver,
854
855 error.SystemResources,
856 error.FileSystem,
857 error.SymLinkLoop,
858 error.Unexpected,
859 => |e| return e,
860 };
861 result.target.os.version_range.linux.glibc = glibcVerFromLinkName(
862 fs.path.basename(link_name),
863 "ld-",
864 ) catch |err| switch (err) {
865 error.UnrecognizedGnuLibCFileName,
866 error.InvalidGnuLibCVersion,
867 => break :glibc_ver,
868 };
869 return result;
870 }
871
872 // Nothing worked so far. Finally we fall back to hard-coded search paths.
873 // Some distros such as Debian keep their libc.so.6 in `/lib/$triple/`.
874 var path_buf: [std.os.PATH_MAX]u8 = undefined;
875 var index: usize = 0;
876 const prefix = "/lib/";
877 const cpu_arch = @tagName(result.target.cpu.arch);
878 const os_tag = @tagName(result.target.os.tag);
879 const abi = @tagName(result.target.abi);
880 @memcpy(path_buf[index..][0..prefix.len], prefix);
881 index += prefix.len;
882 @memcpy(path_buf[index..][0..cpu_arch.len], cpu_arch);
883 index += cpu_arch.len;
884 path_buf[index] = '-';
885 index += 1;
886 @memcpy(path_buf[index..][0..os_tag.len], os_tag);
887 index += os_tag.len;
888 path_buf[index] = '-';
889 index += 1;
890 @memcpy(path_buf[index..][0..abi.len], abi);
891 index += abi.len;
892 const rpath = path_buf[0..index];
893 if (glibcVerFromRPath(rpath)) |ver| {
894 result.target.os.version_range.linux.glibc = ver;
895 return result;
896 } else |err| switch (err) {
897 error.GLibCNotFound => {},
898 else => |e| return e,
899 }
900 }
901
902 return result;
903}
904
905fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {
906 var i: usize = 0;
907 while (i < min_read_len) {
908 const len = file.pread(buf[i..], offset + i) catch |err| switch (err) {
909 error.OperationAborted => unreachable, // Windows-only
910 error.WouldBlock => unreachable, // Did not request blocking mode
911 error.NotOpenForReading => unreachable,
912 error.SystemResources => return error.SystemResources,
913 error.IsDir => return error.UnableToReadElfFile,
914 error.BrokenPipe => return error.UnableToReadElfFile,
915 error.Unseekable => return error.UnableToReadElfFile,
916 error.ConnectionResetByPeer => return error.UnableToReadElfFile,
917 error.ConnectionTimedOut => return error.UnableToReadElfFile,
918 error.SocketNotConnected => return error.UnableToReadElfFile,
919 error.NetNameDeleted => return error.UnableToReadElfFile,
920 error.Unexpected => return error.Unexpected,
921 error.InputOutput => return error.FileSystem,
922 error.AccessDenied => return error.Unexpected,
923 };
924 if (len == 0) return error.UnexpectedEndOfFile;
925 i += len;
926 }
927 return i;
928}
929
930fn defaultAbiAndDynamicLinker(cpu: Target.Cpu, os: Target.Os, cross_target: CrossTarget) !NativeTargetInfo {
931 const target: Target = .{
932 .cpu = cpu,
933 .os = os,
934 .abi = cross_target.abi orelse Target.Abi.default(cpu.arch, os),
935 .ofmt = cross_target.ofmt orelse Target.ObjectFormat.default(os.tag, cpu.arch),
936 };
937 return NativeTargetInfo{
938 .target = target,
939 .dynamic_linker = if (cross_target.dynamic_linker.get() == null)
940 target.standardDynamicLinkerPath()
941 else
942 cross_target.dynamic_linker,
943 };
944}
945
946pub const LdInfo = struct {
947 ld: DynamicLinker,
948 abi: Target.Abi,
949};
950
951pub fn elfInt(is_64: bool, need_bswap: bool, int_32: anytype, int_64: anytype) @TypeOf(int_64) {
952 if (is_64) {
953 if (need_bswap) {
954 return @byteSwap(int_64);
955 } else {
956 return int_64;
957 }
958 } else {
959 if (need_bswap) {
960 return @byteSwap(int_32);
961 } else {
962 return int_32;
963 }
964 }
965}
966
967fn detectNativeCpuAndFeatures(cpu_arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) ?Target.Cpu {
968 // Here we switch on a comptime value rather than `cpu_arch`. This is valid because `cpu_arch`,
969 // although it is a runtime value, is guaranteed to be one of the architectures in the set
970 // of the respective switch prong.
971 switch (builtin.cpu.arch) {
972 .x86_64, .x86 => {
973 return @import("x86.zig").detectNativeCpuAndFeatures(cpu_arch, os, cross_target);
974 },
975 else => {},
976 }
977
978 switch (builtin.os.tag) {
979 .linux => return linux.detectNativeCpuAndFeatures(),
980 .macos => return darwin.macos.detectNativeCpuAndFeatures(),
981 .windows => return windows.detectNativeCpuAndFeatures(),
982 else => {},
983 }
984
985 // This architecture does not have CPU model & feature detection yet.
986 // See https://github.com/ziglang/zig/issues/4591
987 return null;
988}
989
990pub const Executor = union(enum) {
991 native,
992 rosetta,
993 qemu: []const u8,
994 wine: []const u8,
995 wasmtime: []const u8,
996 darling: []const u8,
997 bad_dl: []const u8,
998 bad_os_or_cpu,
999};
1000
1001pub const GetExternalExecutorOptions = struct {
1002 allow_darling: bool = true,
1003 allow_qemu: bool = true,
1004 allow_rosetta: bool = true,
1005 allow_wasmtime: bool = true,
1006 allow_wine: bool = true,
1007 qemu_fixes_dl: bool = false,
1008 link_libc: bool = false,
1009};
1010
1011/// Return whether or not the given host target is capable of executing natively executables
1012/// of the other target.
1013pub fn getExternalExecutor(
1014 host: NativeTargetInfo,
1015 candidate: *const NativeTargetInfo,
1016 options: GetExternalExecutorOptions,
1017) Executor {
1018 const os_match = host.target.os.tag == candidate.target.os.tag;
1019 const cpu_ok = cpu_ok: {
1020 if (host.target.cpu.arch == candidate.target.cpu.arch)
1021 break :cpu_ok true;
1022
1023 if (host.target.cpu.arch == .x86_64 and candidate.target.cpu.arch == .x86)
1024 break :cpu_ok true;
1025
1026 if (host.target.cpu.arch == .aarch64 and candidate.target.cpu.arch == .arm)
1027 break :cpu_ok true;
1028
1029 if (host.target.cpu.arch == .aarch64_be and candidate.target.cpu.arch == .armeb)
1030 break :cpu_ok true;
1031
1032 // TODO additionally detect incompatible CPU features.
1033 // Note that in some cases the OS kernel will emulate missing CPU features
1034 // when an illegal instruction is encountered.
1035
1036 break :cpu_ok false;
1037 };
1038
1039 var bad_result: Executor = .bad_os_or_cpu;
1040
1041 if (os_match and cpu_ok) native: {
1042 if (options.link_libc) {
1043 if (candidate.dynamic_linker.get()) |candidate_dl| {
1044 fs.cwd().access(candidate_dl, .{}) catch {
1045 bad_result = .{ .bad_dl = candidate_dl };
1046 break :native;
1047 };
1048 }
1049 }
1050 return .native;
1051 }
1052
1053 // If the OS match and OS is macOS and CPU is arm64, we can use Rosetta 2
1054 // to emulate the foreign architecture.
1055 if (options.allow_rosetta and os_match and
1056 host.target.os.tag == .macos and host.target.cpu.arch == .aarch64)
1057 {
1058 switch (candidate.target.cpu.arch) {
1059 .x86_64 => return .rosetta,
1060 else => return bad_result,
1061 }
1062 }
1063
1064 // If the OS matches, we can use QEMU to emulate a foreign architecture.
1065 if (options.allow_qemu and os_match and (!cpu_ok or options.qemu_fixes_dl)) {
1066 return switch (candidate.target.cpu.arch) {
1067 .aarch64 => Executor{ .qemu = "qemu-aarch64" },
1068 .aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
1069 .arm => Executor{ .qemu = "qemu-arm" },
1070 .armeb => Executor{ .qemu = "qemu-armeb" },
1071 .hexagon => Executor{ .qemu = "qemu-hexagon" },
1072 .x86 => Executor{ .qemu = "qemu-i386" },
1073 .m68k => Executor{ .qemu = "qemu-m68k" },
1074 .mips => Executor{ .qemu = "qemu-mips" },
1075 .mipsel => Executor{ .qemu = "qemu-mipsel" },
1076 .mips64 => Executor{ .qemu = "qemu-mips64" },
1077 .mips64el => Executor{ .qemu = "qemu-mips64el" },
1078 .powerpc => Executor{ .qemu = "qemu-ppc" },
1079 .powerpc64 => Executor{ .qemu = "qemu-ppc64" },
1080 .powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
1081 .riscv32 => Executor{ .qemu = "qemu-riscv32" },
1082 .riscv64 => Executor{ .qemu = "qemu-riscv64" },
1083 .s390x => Executor{ .qemu = "qemu-s390x" },
1084 .sparc => Executor{ .qemu = "qemu-sparc" },
1085 .sparc64 => Executor{ .qemu = "qemu-sparc64" },
1086 .x86_64 => Executor{ .qemu = "qemu-x86_64" },
1087 else => return bad_result,
1088 };
1089 }
1090
1091 switch (candidate.target.os.tag) {
1092 .windows => {
1093 if (options.allow_wine) {
1094 // x86_64 wine does not support emulating aarch64-windows and
1095 // vice versa.
1096 if (candidate.target.cpu.arch != builtin.cpu.arch) {
1097 return bad_result;
1098 }
1099 switch (candidate.target.ptrBitWidth()) {
1100 32 => return Executor{ .wine = "wine" },
1101 64 => return Executor{ .wine = "wine64" },
1102 else => return bad_result,
1103 }
1104 }
1105 return bad_result;
1106 },
1107 .wasi => {
1108 if (options.allow_wasmtime) {
1109 switch (candidate.target.ptrBitWidth()) {
1110 32 => return Executor{ .wasmtime = "wasmtime" },
1111 else => return bad_result,
1112 }
1113 }
1114 return bad_result;
1115 },
1116 .macos => {
1117 if (options.allow_darling) {
1118 // This check can be loosened once darling adds a QEMU-based emulation
1119 // layer for non-host architectures:
1120 // https://github.com/darlinghq/darling/issues/863
1121 if (candidate.target.cpu.arch != builtin.cpu.arch) {
1122 return bad_result;
1123 }
1124 return Executor{ .darling = "darling" };
1125 }
1126 return bad_result;
1127 },
1128 else => return bad_result,
1129 }
1130}
lib/std/zig/system/darwin/macos.zig+1-1
......@@ -87,7 +87,7 @@ fn parseSystemVersion(buf: []const u8) !std.SemanticVersion {
8787 const ver = try svt.expectContent();
8888 try svt.skipUntilTag(.end, "string");
8989
90 return try std.zig.CrossTarget.parseVersion(ver);
90 return try std.Target.Query.parseVersion(ver);
9191}
9292
9393const SystemVersionTokenizer = struct {
lib/std/zig/system/linux.zig-3
......@@ -5,10 +5,7 @@ const io = std.io;
55const fs = std.fs;
66const fmt = std.fmt;
77const testing = std.testing;
8
98const Target = std.Target;
10const CrossTarget = std.zig.CrossTarget;
11
129const assert = std.debug.assert;
1310
1411const SparcCpuinfoImpl = struct {
lib/std/zig/system/x86.zig+2-3
......@@ -1,7 +1,6 @@
11const std = @import("std");
22const builtin = @import("builtin");
33const Target = std.Target;
4const CrossTarget = std.zig.CrossTarget;
54
65const XCR0_XMM = 0x02;
76const XCR0_YMM = 0x04;
......@@ -23,8 +22,8 @@ inline fn hasMask(input: u32, mask: u32) bool {
2322 return (input & mask) == mask;
2423}
2524
26pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, cross_target: CrossTarget) Target.Cpu {
27 _ = cross_target;
25pub fn detectNativeCpuAndFeatures(arch: Target.Cpu.Arch, os: Target.Os, query: Target.Query) Target.Cpu {
26 _ = query;
2827 var cpu = Target.Cpu{
2928 .arch = arch,
3029 .model = Target.Cpu.Model.generic(arch),
src/Builtin.zig created+314
......@@ -0,0 +1,314 @@
1target: std.Target,
2zig_backend: std.builtin.CompilerBackend,
3output_mode: std.builtin.OutputMode,
4link_mode: std.builtin.LinkMode,
5is_test: bool,
6test_evented_io: bool,
7single_threaded: bool,
8link_libc: bool,
9link_libcpp: bool,
10optimize_mode: std.builtin.OptimizeMode,
11error_tracing: bool,
12valgrind: bool,
13sanitize_thread: bool,
14pic: bool,
15pie: bool,
16strip: bool,
17code_model: std.builtin.CodeModel,
18omit_frame_pointer: bool,
19wasi_exec_model: std.builtin.WasiExecModel,
20
21pub fn generate(opts: @This(), allocator: Allocator) Allocator.Error![:0]u8 {
22 var buffer = std.ArrayList(u8).init(allocator);
23 try append(opts, &buffer);
24 return buffer.toOwnedSliceSentinel(0);
25}
26
27pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
28 const target = opts.target;
29 const generic_arch_name = target.cpu.arch.genericName();
30 const zig_backend = opts.zig_backend;
31
32 @setEvalBranchQuota(4000);
33 try buffer.writer().print(
34 \\const std = @import("std");
35 \\/// Zig version. When writing code that supports multiple versions of Zig, prefer
36 \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
37 \\pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable;
38 \\pub const zig_version_string = "{s}";
39 \\pub const zig_backend = std.builtin.CompilerBackend.{};
40 \\
41 \\pub const output_mode = std.builtin.OutputMode.{};
42 \\pub const link_mode = std.builtin.LinkMode.{};
43 \\pub const is_test = {};
44 \\pub const single_threaded = {};
45 \\pub const abi = std.Target.Abi.{};
46 \\pub const cpu: std.Target.Cpu = .{{
47 \\ .arch = .{},
48 \\ .model = &std.Target.{}.cpu.{},
49 \\ .features = std.Target.{}.featureSet(&[_]std.Target.{}.Feature{{
50 \\
51 , .{
52 build_options.version,
53 std.zig.fmtId(@tagName(zig_backend)),
54 std.zig.fmtId(@tagName(opts.output_mode)),
55 std.zig.fmtId(@tagName(opts.link_mode)),
56 opts.is_test,
57 opts.single_threaded,
58 std.zig.fmtId(@tagName(target.abi)),
59 std.zig.fmtId(@tagName(target.cpu.arch)),
60 std.zig.fmtId(generic_arch_name),
61 std.zig.fmtId(target.cpu.model.name),
62 std.zig.fmtId(generic_arch_name),
63 std.zig.fmtId(generic_arch_name),
64 });
65
66 for (target.cpu.arch.allFeaturesList(), 0..) |feature, index_usize| {
67 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
68 const is_enabled = target.cpu.features.isEnabled(index);
69 if (is_enabled) {
70 try buffer.writer().print(" .{},\n", .{std.zig.fmtId(feature.name)});
71 }
72 }
73 try buffer.writer().print(
74 \\ }}),
75 \\}};
76 \\pub const os = std.Target.Os{{
77 \\ .tag = .{},
78 \\ .version_range = .{{
79 ,
80 .{std.zig.fmtId(@tagName(target.os.tag))},
81 );
82
83 switch (target.os.getVersionRange()) {
84 .none => try buffer.appendSlice(" .none = {} },\n"),
85 .semver => |semver| try buffer.writer().print(
86 \\ .semver = .{{
87 \\ .min = .{{
88 \\ .major = {},
89 \\ .minor = {},
90 \\ .patch = {},
91 \\ }},
92 \\ .max = .{{
93 \\ .major = {},
94 \\ .minor = {},
95 \\ .patch = {},
96 \\ }},
97 \\ }}}},
98 \\
99 , .{
100 semver.min.major,
101 semver.min.minor,
102 semver.min.patch,
103
104 semver.max.major,
105 semver.max.minor,
106 semver.max.patch,
107 }),
108 .linux => |linux| try buffer.writer().print(
109 \\ .linux = .{{
110 \\ .range = .{{
111 \\ .min = .{{
112 \\ .major = {},
113 \\ .minor = {},
114 \\ .patch = {},
115 \\ }},
116 \\ .max = .{{
117 \\ .major = {},
118 \\ .minor = {},
119 \\ .patch = {},
120 \\ }},
121 \\ }},
122 \\ .glibc = .{{
123 \\ .major = {},
124 \\ .minor = {},
125 \\ .patch = {},
126 \\ }},
127 \\ }}}},
128 \\
129 , .{
130 linux.range.min.major,
131 linux.range.min.minor,
132 linux.range.min.patch,
133
134 linux.range.max.major,
135 linux.range.max.minor,
136 linux.range.max.patch,
137
138 linux.glibc.major,
139 linux.glibc.minor,
140 linux.glibc.patch,
141 }),
142 .windows => |windows| try buffer.writer().print(
143 \\ .windows = .{{
144 \\ .min = {s},
145 \\ .max = {s},
146 \\ }}}},
147 \\
148 ,
149 .{ windows.min, windows.max },
150 ),
151 }
152 try buffer.appendSlice(
153 \\};
154 \\pub const target: std.Target = .{
155 \\ .cpu = cpu,
156 \\ .os = os,
157 \\ .abi = abi,
158 \\ .ofmt = object_format,
159 \\
160 );
161
162 if (target.dynamic_linker.get()) |dl| {
163 try buffer.writer().print(
164 \\ .dynamic_linker = std.Target.DynamicLinker.init("{s}"),
165 \\}};
166 \\
167 , .{dl});
168 } else {
169 try buffer.appendSlice(
170 \\ .dynamic_linker = std.Target.DynamicLinker.none,
171 \\};
172 \\
173 );
174 }
175
176 // This is so that compiler_rt and libc.zig libraries know whether they
177 // will eventually be linked with libc. They make different decisions
178 // about what to export depending on whether another libc will be linked
179 // in. For example, compiler_rt will not export the __chkstk symbol if it
180 // knows libc will provide it, and likewise c.zig will not export memcpy.
181 const link_libc = opts.link_libc;
182
183 try buffer.writer().print(
184 \\pub const object_format = std.Target.ObjectFormat.{};
185 \\pub const mode = std.builtin.OptimizeMode.{};
186 \\pub const link_libc = {};
187 \\pub const link_libcpp = {};
188 \\pub const have_error_return_tracing = {};
189 \\pub const valgrind_support = {};
190 \\pub const sanitize_thread = {};
191 \\pub const position_independent_code = {};
192 \\pub const position_independent_executable = {};
193 \\pub const strip_debug_info = {};
194 \\pub const code_model = std.builtin.CodeModel.{};
195 \\pub const omit_frame_pointer = {};
196 \\
197 , .{
198 std.zig.fmtId(@tagName(target.ofmt)),
199 std.zig.fmtId(@tagName(opts.optimize_mode)),
200 link_libc,
201 opts.link_libcpp,
202 opts.error_tracing,
203 opts.valgrind,
204 opts.sanitize_thread,
205 opts.pic,
206 opts.pie,
207 opts.strip,
208 std.zig.fmtId(@tagName(opts.code_model)),
209 opts.omit_frame_pointer,
210 });
211
212 if (target.os.tag == .wasi) {
213 const wasi_exec_model_fmt = std.zig.fmtId(@tagName(opts.wasi_exec_model));
214 try buffer.writer().print(
215 \\pub const wasi_exec_model = std.builtin.WasiExecModel.{};
216 \\
217 , .{wasi_exec_model_fmt});
218 }
219
220 if (opts.is_test) {
221 try buffer.appendSlice(
222 \\pub var test_functions: []const std.builtin.TestFn = undefined; // overwritten later
223 \\
224 );
225 if (opts.test_evented_io) {
226 try buffer.appendSlice(
227 \\pub const test_io_mode = .evented;
228 \\
229 );
230 } else {
231 try buffer.appendSlice(
232 \\pub const test_io_mode = .blocking;
233 \\
234 );
235 }
236 }
237}
238
239pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void {
240 assert(file.source_loaded == true);
241
242 if (mod.root.statFile(mod.root_src_path)) |stat| {
243 if (stat.size != file.source.len) {
244 std.log.warn(
245 "the cached file '{}{s}' had the wrong size. Expected {d}, found {d}. " ++
246 "Overwriting with correct file contents now",
247 .{ mod.root, mod.root_src_path, file.source.len, stat.size },
248 );
249
250 try writeFile(file, mod);
251 } else {
252 file.stat = .{
253 .size = stat.size,
254 .inode = stat.inode,
255 .mtime = stat.mtime,
256 };
257 }
258 } else |err| switch (err) {
259 error.BadPathName => unreachable, // it's always "builtin.zig"
260 error.NameTooLong => unreachable, // it's always "builtin.zig"
261 error.PipeBusy => unreachable, // it's not a pipe
262 error.WouldBlock => unreachable, // not asking for non-blocking I/O
263
264 error.FileNotFound => try writeFile(file, mod),
265
266 else => |e| return e,
267 }
268
269 log.debug("parsing and generating '{s}'", .{mod.root_src_path});
270
271 file.tree = try std.zig.Ast.parse(comp.gpa, file.source, .zig);
272 assert(file.tree.errors.len == 0); // builtin.zig must parse
273 file.tree_loaded = true;
274
275 file.zir = try AstGen.generate(comp.gpa, file.tree);
276 assert(!file.zir.hasCompileErrors()); // builtin.zig must not have astgen errors
277 file.zir_loaded = true;
278 file.status = .success_zir;
279}
280
281fn writeFile(file: *File, mod: *Module) !void {
282 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
283 var af = try mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf);
284 defer af.deinit();
285 try af.file.writeAll(file.source);
286 af.finish() catch |err| switch (err) {
287 error.AccessDenied => switch (builtin.os.tag) {
288 .windows => {
289 // Very likely happened due to another process or thread
290 // simultaneously creating the same, correct builtin.zig file.
291 // This is not a problem; ignore it.
292 },
293 else => return err,
294 },
295 else => return err,
296 };
297
298 file.stat = .{
299 .size = file.source.len,
300 .inode = 0, // dummy value
301 .mtime = 0, // dummy value
302 };
303}
304
305const builtin = @import("builtin");
306const std = @import("std");
307const Allocator = std.mem.Allocator;
308const build_options = @import("build_options");
309const Module = @import("Package/Module.zig");
310const assert = std.debug.assert;
311const AstGen = @import("AstGen.zig");
312const File = @import("Module.zig").File;
313const Compilation = @import("Compilation.zig");
314const log = std.log.scoped(.builtin);
src/Compilation.zig+1447-1825
......@@ -28,31 +28,79 @@ const libcxx = @import("libcxx.zig");
2828const wasi_libc = @import("wasi_libc.zig");
2929const fatal = @import("main.zig").fatal;
3030const clangMain = @import("main.zig").clangMain;
31const Module = @import("Module.zig");
31const Zcu = @import("Module.zig");
32/// Deprecated; use `Zcu`.
33const Module = Zcu;
3234const InternPool = @import("InternPool.zig");
33const BuildId = std.Build.CompileStep.BuildId;
3435const Cache = std.Build.Cache;
3536const c_codegen = @import("codegen/c.zig");
3637const libtsan = @import("libtsan.zig");
3738const Zir = @import("Zir.zig");
3839const Autodoc = @import("Autodoc.zig");
39const Color = @import("main.zig").Color;
4040const resinator = @import("resinator.zig");
41const Builtin = @import("Builtin.zig");
42const LlvmObject = @import("codegen/llvm.zig").Object;
43
44pub const Config = @import("Compilation/Config.zig");
4145
4246/// General-purpose allocator. Used for both temporary and long-term storage.
4347gpa: Allocator,
44/// Arena-allocated memory, mostly used during initialization. However, it can be used
45/// for other things requiring the same lifetime as the `Compilation`.
46arena: std.heap.ArenaAllocator,
47bin_file: *link.File,
48/// Arena-allocated memory, mostly used during initialization. However, it can
49/// be used for other things requiring the same lifetime as the `Compilation`.
50arena: Allocator,
51/// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
52/// TODO: rename to zcu: ?*Zcu
53module: ?*Module,
54/// Contains different state depending on whether the Compilation uses
55/// incremental or whole cache mode.
56cache_use: CacheUse,
57/// All compilations have a root module because this is where some important
58/// settings are stored, such as target and optimization mode. This module
59/// might not have any .zig code associated with it, however.
60root_mod: *Package.Module,
61
62/// User-specified settings that have all the defaults resolved into concrete values.
63config: Config,
64
65/// The main output file.
66/// In whole cache mode, this is null except for during the body of the update
67/// function. In incremental cache mode, this is a long-lived object.
68/// In both cases, this is `null` when `-fno-emit-bin` is used.
69bin_file: ?*link.File,
70
71/// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin)
72sysroot: ?[]const u8,
73/// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used.
74implib_emit: ?Emit,
75/// This is non-null when `-femit-docs` is provided.
76docs_emit: ?Emit,
77root_name: [:0]const u8,
78include_compiler_rt: bool,
79objects: []Compilation.LinkObject,
80/// Needed only for passing -F args to clang.
81framework_dirs: []const []const u8,
82/// These are *always* dynamically linked. Static libraries will be
83/// provided as positional arguments.
84system_libs: std.StringArrayHashMapUnmanaged(SystemLib),
85version: ?std.SemanticVersion,
86libc_installation: ?*const LibCInstallation,
87skip_linker_dependencies: bool,
88no_builtin: bool,
89function_sections: bool,
90data_sections: bool,
91link_eh_frame_hdr: bool,
92native_system_include_paths: []const []const u8,
93/// List of symbols forced as undefined in the symbol table
94/// thus forcing their resolution by the linker.
95/// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE.
96force_undefined_symbols: std.StringArrayHashMapUnmanaged(void),
97
4898c_object_table: std.AutoArrayHashMapUnmanaged(*CObject, void) = .{},
4999win32_resource_table: if (build_options.only_core_functionality) void else std.AutoArrayHashMapUnmanaged(*Win32Resource, void) =
50100 if (build_options.only_core_functionality) {} else .{},
51/// This is a pointer to a local variable inside `update()`.
52whole_cache_manifest: ?*Cache.Manifest = null,
53whole_cache_manifest_mutex: std.Thread.Mutex = .{},
54101
55102link_error_flags: link.File.ErrorFlags = .{},
103link_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},
56104lld_errors: std.ArrayListUnmanaged(LldError) = .{},
57105
58106work_queue: std.fifo.LinearFifo(Job, .Dynamic),
......@@ -87,9 +135,6 @@ failed_win32_resources: if (build_options.only_core_functionality) void else std
87135/// Miscellaneous things that can fail.
88136misc_failures: std.AutoArrayHashMapUnmanaged(MiscTask, MiscError) = .{},
89137
90keep_source_files_loaded: bool,
91c_frontend: CFrontend,
92sanitize_c: bool,
93138/// When this is `true` it means invoking clang as a sub-process is expected to inherit
94139/// stdin, stdout, stderr, and if it returns non success, to forward the exit code.
95140/// Otherwise we attempt to parse the error messages and expose them via the Compilation API.
......@@ -105,33 +150,25 @@ verbose_llvm_ir: ?[]const u8,
105150verbose_llvm_bc: ?[]const u8,
106151verbose_cimport: bool,
107152verbose_llvm_cpu_features: bool,
153verbose_link: bool,
108154disable_c_depfile: bool,
109155time_report: bool,
110156stack_report: bool,
111unwind_tables: bool,
112test_evented_io: bool,
113157debug_compiler_runtime_libs: bool,
114158debug_compile_errors: bool,
115159job_queued_compiler_rt_lib: bool = false,
116160job_queued_compiler_rt_obj: bool = false,
161job_queued_update_builtin_zig: bool,
117162alloc_failure_occurred: bool = false,
118163formatted_panics: bool = false,
119164last_update_was_cache_hit: bool = false,
120165
121166c_source_files: []const CSourceFile,
122clang_argv: []const []const u8,
123167rc_source_files: []const RcSourceFile,
168global_cc_argv: []const []const u8,
124169cache_parent: *Cache,
125170/// Path to own executable for invoking `zig clang`.
126171self_exe_path: ?[]const u8,
127/// null means -fno-emit-bin.
128/// This is mutable memory allocated into the Compilation-lifetime arena (`arena`)
129/// of exactly the correct size for "o/[digest]/[basename]".
130/// The basename is of the outputted binary file in case we don't know the directory yet.
131whole_bin_sub_path: ?[]u8,
132/// Same as `whole_bin_sub_path` but for implibs.
133whole_implib_sub_path: ?[]u8,
134whole_docs_sub_path: ?[]u8,
135172zig_lib_directory: Directory,
136173local_cache_directory: Directory,
137174global_cache_directory: Directory,
......@@ -163,19 +200,13 @@ compiler_rt_lib: ?CRTFile = null,
163200compiler_rt_obj: ?CRTFile = null,
164201
165202glibc_so_files: ?glibc.BuiltSharedObjects = null,
203wasi_emulated_libs: []const wasi_libc.CRTFile,
166204
167205/// For example `Scrt1.o` and `libc_nonshared.a`. These are populated after building libc from source,
168206/// The set of needed CRT (C runtime) files differs depending on the target and compilation settings.
169207/// The key is the basename, and the value is the absolute path to the completed build artifact.
170208crt_files: std.StringHashMapUnmanaged(CRTFile) = .{},
171209
172/// Keeping track of this possibly open resource so we can close it later.
173owned_link_dir: ?std.fs.Dir,
174
175/// This is for stage1 and should be deleted upon completion of self-hosting.
176/// Don't use this for anything other than stage1 compatibility.
177color: Color = .auto,
178
179210/// How many lines of reference trace should be included per compile error.
180211/// Null means only show snippet on first error.
181212reference_trace: ?u32 = null,
......@@ -195,7 +226,31 @@ emit_llvm_bc: ?EmitLoc,
195226work_queue_wait_group: WaitGroup = .{},
196227astgen_wait_group: WaitGroup = .{},
197228
198pub const default_stack_protector_buffer_size = 4;
229llvm_opt_bisect_limit: c_int,
230
231pub const Emit = struct {
232 /// Where the output will go.
233 directory: Directory,
234 /// Path to the output file, relative to `directory`.
235 sub_path: []const u8,
236
237 /// Returns the full path to `basename` if it were in the same directory as the
238 /// `Emit` sub_path.
239 pub fn basenamePath(emit: Emit, arena: Allocator, basename: []const u8) ![:0]const u8 {
240 const full_path = if (emit.directory.path) |p|
241 try std.fs.path.join(arena, &[_][]const u8{ p, emit.sub_path })
242 else
243 emit.sub_path;
244
245 if (std.fs.path.dirname(full_path)) |dirname| {
246 return try std.fs.path.joinZ(arena, &.{ dirname, basename });
247 } else {
248 return try arena.dupeZ(u8, basename);
249 }
250 }
251};
252
253pub const default_stack_protector_buffer_size = target_util.default_stack_protector_buffer_size;
199254pub const SemaError = Module.SemaError;
200255
201256pub const CRTFile = struct {
......@@ -209,8 +264,8 @@ pub const CRTFile = struct {
209264 }
210265};
211266
212// supported languages for "zig clang -x <lang>".
213// Loosely based on llvm-project/clang/include/clang/Driver/Types.def
267/// Supported languages for "zig clang -x <lang>".
268/// Loosely based on llvm-project/clang/include/clang/Driver/Types.def
214269pub const LangToExt = std.ComptimeStringMap(FileExt, .{
215270 .{ "c", .c },
216271 .{ "c-header", .h },
......@@ -227,16 +282,20 @@ pub const LangToExt = std.ComptimeStringMap(FileExt, .{
227282
228283/// For passing to a C compiler.
229284pub const CSourceFile = struct {
285 /// Many C compiler flags are determined by settings contained in the owning Module.
286 owner: *Package.Module,
230287 src_path: []const u8,
231288 extra_flags: []const []const u8 = &.{},
232289 /// Same as extra_flags except they are not added to the Cache hash.
233290 cache_exempt_flags: []const []const u8 = &.{},
234 // this field is non-null iff language was explicitly set with "-x lang".
291 /// This field is non-null if and only if the language was explicitly set
292 /// with "-x lang".
235293 ext: ?FileExt = null,
236294};
237295
238296/// For passing to resinator.
239297pub const RcSourceFile = struct {
298 owner: *Package.Module,
240299 src_path: []const u8,
241300 extra_flags: []const []const u8 = &.{},
242301};
......@@ -289,7 +348,7 @@ const Job = union(enum) {
289348 /// one of WASI libc static objects
290349 wasi_libc_crt_file: wasi_libc.CRTFile,
291350
292 /// The value is the index into `link.File.Options.system_libs`.
351 /// The value is the index into `system_libs`.
293352 windows_import_lib: usize,
294353};
295354
......@@ -659,6 +718,8 @@ pub const Win32Resource = struct {
659718
660719pub const MiscTask = enum {
661720 write_builtin_zig,
721 rename_results,
722 check_whole_cache,
662723 glibc_crt_file,
663724 glibc_shared_objects,
664725 musl_crt_file,
......@@ -743,6 +804,41 @@ pub const EmitLoc = struct {
743804};
744805
745806pub const cache_helpers = struct {
807 pub fn addModule(hh: *Cache.HashHelper, mod: *const Package.Module) void {
808 addResolvedTarget(hh, mod.resolved_target);
809 hh.add(mod.optimize_mode);
810 hh.add(mod.code_model);
811 hh.add(mod.single_threaded);
812 hh.add(mod.error_tracing);
813 hh.add(mod.valgrind);
814 hh.add(mod.pic);
815 hh.add(mod.strip);
816 hh.add(mod.omit_frame_pointer);
817 hh.add(mod.stack_check);
818 hh.add(mod.red_zone);
819 hh.add(mod.sanitize_c);
820 hh.add(mod.sanitize_thread);
821 hh.add(mod.unwind_tables);
822 hh.add(mod.structured_cfg);
823 hh.addListOfBytes(mod.cc_argv);
824 }
825
826 pub fn addResolvedTarget(
827 hh: *Cache.HashHelper,
828 resolved_target: Package.Module.ResolvedTarget,
829 ) void {
830 const target = resolved_target.result;
831 hh.add(target.cpu.arch);
832 hh.addBytes(target.cpu.model.name);
833 hh.add(target.cpu.features.ints);
834 hh.add(target.os.tag);
835 hh.add(target.os.getVersionRange());
836 hh.add(target.abi);
837 hh.add(target.ofmt);
838 hh.add(resolved_target.is_native_os);
839 hh.add(resolved_target.is_native_abi);
840 }
841
746842 pub fn addEmitLoc(hh: *Cache.HashHelper, emit_loc: EmitLoc) void {
747843 hh.addBytes(emit_loc.basename);
748844 }
......@@ -752,7 +848,21 @@ pub const cache_helpers = struct {
752848 addEmitLoc(hh, optional_emit_loc orelse return);
753849 }
754850
755 pub fn hashCSource(self: *Cache.Manifest, c_source: Compilation.CSourceFile) !void {
851 pub fn addOptionalDebugFormat(hh: *Cache.HashHelper, x: ?Config.DebugFormat) void {
852 hh.add(x != null);
853 addDebugFormat(hh, x orelse return);
854 }
855
856 pub fn addDebugFormat(hh: *Cache.HashHelper, x: Config.DebugFormat) void {
857 const tag: @typeInfo(Config.DebugFormat).Union.tag_type.? = x;
858 hh.add(tag);
859 switch (x) {
860 .strip, .code_view => {},
861 .dwarf => |f| hh.add(f),
862 }
863 }
864
865 pub fn hashCSource(self: *Cache.Manifest, c_source: CSourceFile) !void {
756866 _ = try self.addFile(c_source.src_path, null);
757867 // Hash the extra flags, with special care to call addFile for file parameters.
758868 // TODO this logic can likely be improved by utilizing clang_options_data.zig.
......@@ -771,8 +881,6 @@ pub const cache_helpers = struct {
771881 }
772882};
773883
774pub const CFrontend = enum { clang, aro };
775
776884pub const ClangPreprocessorMode = enum {
777885 no,
778886 /// This means we are doing `zig cc -E -o <path>`.
......@@ -781,9 +889,62 @@ pub const ClangPreprocessorMode = enum {
781889 stdout,
782890};
783891
784pub const Framework = link.Framework;
892pub const Framework = link.File.MachO.Framework;
785893pub const SystemLib = link.SystemLib;
786pub const CacheMode = link.CacheMode;
894
895pub const CacheMode = enum { incremental, whole };
896
897const CacheUse = union(CacheMode) {
898 incremental: *Incremental,
899 whole: *Whole,
900
901 const Whole = struct {
902 /// This is a pointer to a local variable inside `update()`.
903 cache_manifest: ?*Cache.Manifest = null,
904 cache_manifest_mutex: std.Thread.Mutex = .{},
905 /// null means -fno-emit-bin.
906 /// This is mutable memory allocated into the Compilation-lifetime arena (`arena`)
907 /// of exactly the correct size for "o/[digest]/[basename]".
908 /// The basename is of the outputted binary file in case we don't know the directory yet.
909 bin_sub_path: ?[]u8,
910 /// Same as `bin_sub_path` but for implibs.
911 implib_sub_path: ?[]u8,
912 docs_sub_path: ?[]u8,
913 lf_open_opts: link.File.OpenOptions,
914 tmp_artifact_directory: ?Cache.Directory,
915 /// Prevents other processes from clobbering files in the output directory.
916 lock: ?Cache.Lock,
917
918 fn releaseLock(whole: *Whole) void {
919 if (whole.lock) |*lock| {
920 lock.release();
921 whole.lock = null;
922 }
923 }
924
925 fn moveLock(whole: *Whole) Cache.Lock {
926 const result = whole.lock.?;
927 whole.lock = null;
928 return result;
929 }
930 };
931
932 const Incremental = struct {
933 /// Where build artifacts and incremental compilation metadata serialization go.
934 artifact_directory: Compilation.Directory,
935 };
936
937 fn deinit(cu: CacheUse) void {
938 switch (cu) {
939 .incremental => |incremental| {
940 incremental.artifact_directory.handle.close();
941 },
942 .whole => |whole| {
943 whole.releaseLock();
944 },
945 }
946 }
947};
787948
788949pub const LinkObject = struct {
789950 path: []const u8,
......@@ -795,16 +956,27 @@ pub const LinkObject = struct {
795956 loption: bool = false,
796957};
797958
798pub const InitOptions = struct {
959pub const CreateOptions = struct {
799960 zig_lib_directory: Directory,
800961 local_cache_directory: Directory,
801962 global_cache_directory: Directory,
802 target: Target,
803 root_name: []const u8,
804 main_mod: ?*Package.Module,
805 output_mode: std.builtin.OutputMode,
806963 thread_pool: *ThreadPool,
807 dynamic_linker: ?[]const u8 = null,
964 self_exe_path: ?[]const u8 = null,
965
966 /// Options that have been resolved by calling `resolveDefaults`.
967 config: Compilation.Config,
968
969 root_mod: *Package.Module,
970 /// Normally, `main_mod` and `root_mod` are the same. The exception is `zig
971 /// test`, in which `root_mod` is the test runner, and `main_mod` is the
972 /// user's source file which has the tests.
973 main_mod: ?*Package.Module = null,
974 /// This is provided so that the API user has a chance to tweak the
975 /// per-module settings of the standard library.
976 /// When this is null, a default configuration of the std lib is created
977 /// based on the settings of root_mod.
978 std_mod: ?*Package.Module = null,
979 root_name: []const u8,
808980 sysroot: ?[]const u8 = null,
809981 /// `null` means to not emit a binary file.
810982 emit_bin: ?EmitLoc,
......@@ -820,8 +992,6 @@ pub const InitOptions = struct {
820992 emit_docs: ?EmitLoc = null,
821993 /// `null` means to not emit an import lib.
822994 emit_implib: ?EmitLoc = null,
823 link_mode: ?std.builtin.LinkMode = null,
824 dll_export_fns: ?bool = false,
825995 /// Normally when using LLD to link, Zig uses a file named "lld.id" in the
826996 /// same directory as the output binary which contains the hash of the link
827997 /// operation, allowing Zig to skip linking when the hash would be unchanged.
......@@ -830,14 +1000,11 @@ pub const InitOptions = struct {
8301000 /// this flag would be set to disable this machinery to avoid false positives.
8311001 disable_lld_caching: bool = false,
8321002 cache_mode: CacheMode = .incremental,
833 optimize_mode: std.builtin.OptimizeMode = .Debug,
834 keep_source_files_loaded: bool = false,
835 clang_argv: []const []const u8 = &[0][]const u8{},
8361003 lib_dirs: []const []const u8 = &[0][]const u8{},
8371004 rpath_list: []const []const u8 = &[0][]const u8{},
8381005 symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{},
839 c_source_files: []const CSourceFile = &[0]CSourceFile{},
840 rc_source_files: []const RcSourceFile = &[0]RcSourceFile{},
1006 c_source_files: []const CSourceFile = &.{},
1007 rc_source_files: []const RcSourceFile = &.{},
8411008 manifest_file: ?[]const u8 = null,
8421009 rc_includes: RcIncludes = .any,
8431010 link_objects: []LinkObject = &[0]LinkObject{},
......@@ -850,41 +1017,16 @@ pub const InitOptions = struct {
8501017 /// * getpid
8511018 /// * mman
8521019 /// * signal
853 wasi_emulated_libs: []const wasi_libc.CRTFile = &[0]wasi_libc.CRTFile{},
854 link_libc: bool = false,
855 link_libcpp: bool = false,
856 link_libunwind: bool = false,
857 want_pic: ?bool = null,
1020 wasi_emulated_libs: []const wasi_libc.CRTFile = &.{},
8581021 /// This means that if the output mode is an executable it will be a
8591022 /// Position Independent Executable. If the output mode is not an
8601023 /// executable this field is ignored.
861 want_pie: ?bool = null,
862 want_sanitize_c: ?bool = null,
863 want_stack_check: ?bool = null,
864 /// null means default.
865 /// 0 means no stack protector.
866 /// other number means stack protection with that buffer size.
867 want_stack_protector: ?u32 = null,
868 want_red_zone: ?bool = null,
869 omit_frame_pointer: ?bool = null,
870 want_valgrind: ?bool = null,
871 want_tsan: ?bool = null,
8721024 want_compiler_rt: ?bool = null,
8731025 want_lto: ?bool = null,
874 want_unwind_tables: ?bool = null,
875 use_llvm: ?bool = null,
876 use_lib_llvm: ?bool = null,
877 use_lld: ?bool = null,
878 use_clang: ?bool = null,
879 single_threaded: ?bool = null,
880 strip: ?bool = null,
8811026 formatted_panics: ?bool = null,
882 rdynamic: bool = false,
8831027 function_sections: bool = false,
8841028 data_sections: bool = false,
8851029 no_builtin: bool = false,
886 is_native_os: bool,
887 is_native_abi: bool,
8881030 time_report: bool = false,
8891031 stack_report: bool = false,
8901032 link_eh_frame_hdr: bool = false,
......@@ -895,22 +1037,19 @@ pub const InitOptions = struct {
8951037 linker_gc_sections: ?bool = null,
8961038 linker_allow_shlib_undefined: ?bool = null,
8971039 linker_bind_global_refs_locally: ?bool = null,
898 linker_import_memory: ?bool = null,
899 linker_export_memory: ?bool = null,
9001040 linker_import_symbols: bool = false,
9011041 linker_import_table: bool = false,
9021042 linker_export_table: bool = false,
9031043 linker_initial_memory: ?u64 = null,
9041044 linker_max_memory: ?u64 = null,
905 linker_shared_memory: bool = false,
9061045 linker_global_base: ?u64 = null,
9071046 linker_export_symbol_names: []const []const u8 = &.{},
9081047 linker_print_gc_sections: bool = false,
9091048 linker_print_icf_sections: bool = false,
9101049 linker_print_map: bool = false,
911 linker_opt_bisect_limit: i32 = -1,
1050 llvm_opt_bisect_limit: i32 = -1,
9121051 each_lib_rpath: ?bool = null,
913 build_id: ?BuildId = null,
1052 build_id: ?std.zig.BuildId = null,
9141053 disable_c_depfile: bool = false,
9151054 linker_z_nodelete: bool = false,
9161055 linker_z_notext: bool = false,
......@@ -924,12 +1063,11 @@ pub const InitOptions = struct {
9241063 linker_tsaware: bool = false,
9251064 linker_nxcompat: bool = false,
9261065 linker_dynamicbase: bool = true,
927 linker_optimization: ?u8 = null,
928 linker_compress_debug_sections: ?link.CompressDebugSections = null,
1066 linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null,
9291067 linker_module_definition_file: ?[]const u8 = null,
930 linker_sort_section: ?link.SortSection = null,
931 major_subsystem_version: ?u32 = null,
932 minor_subsystem_version: ?u32 = null,
1068 linker_sort_section: ?link.File.Elf.SortSection = null,
1069 major_subsystem_version: ?u16 = null,
1070 minor_subsystem_version: ?u16 = null,
9331071 clang_passthrough_mode: bool = false,
9341072 verbose_cc: bool = false,
9351073 verbose_link: bool = false,
......@@ -940,8 +1078,6 @@ pub const InitOptions = struct {
9401078 verbose_llvm_bc: ?[]const u8 = null,
9411079 verbose_cimport: bool = false,
9421080 verbose_llvm_cpu_features: bool = false,
943 is_test: bool = false,
944 test_evented_io: bool = false,
9451081 debug_compiler_runtime_libs: bool = false,
9461082 debug_compile_errors: bool = false,
9471083 /// Normally when you create a `Compilation`, Zig will automatically build
......@@ -949,28 +1085,21 @@ pub const InitOptions = struct {
9491085 /// building such dependencies themselves, this flag must be set to avoid
9501086 /// infinite recursion.
9511087 skip_linker_dependencies: bool = false,
952 hash_style: link.HashStyle = .both,
953 entry: ?[]const u8 = null,
1088 hash_style: link.File.Elf.HashStyle = .both,
1089 entry: Entry = .default,
9541090 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{},
955 stack_size_override: ?u64 = null,
956 image_base_override: ?u64 = null,
957 self_exe_path: ?[]const u8 = null,
1091 stack_size: ?u64 = null,
1092 image_base: ?u64 = null,
9581093 version: ?std.SemanticVersion = null,
9591094 compatibility_version: ?std.SemanticVersion = null,
9601095 libc_installation: ?*const LibCInstallation = null,
961 machine_code_model: std.builtin.CodeModel = .default,
1096 native_system_include_paths: []const []const u8 = &.{},
9621097 clang_preprocessor_mode: ClangPreprocessorMode = .no,
963 /// This is for stage1 and should be deleted upon completion of self-hosting.
964 color: Color = .auto,
9651098 reference_trace: ?u32 = null,
966 error_tracing: ?bool = null,
9671099 test_filter: ?[]const u8 = null,
9681100 test_name_prefix: ?[]const u8 = null,
9691101 test_runner_path: ?[]const u8 = null,
9701102 subsystem: ?std.Target.SubSystem = null,
971 dwarf_format: ?std.dwarf.Format = null,
972 /// WASI-only. Type of WASI execution model ("command" or "reactor").
973 wasi_exec_model: ?std.builtin.WasiExecModel = null,
9741103 /// (Zig compiler development) Enable dumping linker's state as JSON.
9751104 enable_link_snapshots: bool = false,
9761105 /// (Darwin) Install name of the dylib
......@@ -991,449 +1120,223 @@ pub const InitOptions = struct {
9911120 pdb_source_path: ?[]const u8 = null,
9921121 /// (Windows) PDB output path
9931122 pdb_out_path: ?[]const u8 = null,
994 error_limit: ?Module.ErrorInt = null,
995 /// (SPIR-V) whether to generate a structured control flow graph or not
996 want_structured_cfg: ?bool = null,
1123 error_limit: ?Compilation.Module.ErrorInt = null,
1124 global_cc_argv: []const []const u8 = &.{},
1125
1126 pub const Entry = link.File.OpenOptions.Entry;
9971127};
9981128
9991129fn addModuleTableToCacheHash(
1130 gpa: Allocator,
1131 arena: Allocator,
10001132 hash: *Cache.HashHelper,
1001 arena: *std.heap.ArenaAllocator,
1002 mod_table: Package.Module.Deps,
1003 seen_table: *std.AutoHashMap(*Package.Module, void),
1133 root_mod: *Package.Module,
10041134 hash_type: union(enum) { path_bytes, files: *Cache.Manifest },
10051135) (error{OutOfMemory} || std.os.GetCwdError)!void {
1006 const allocator = arena.allocator();
1007
1008 const module_indices = try allocator.alloc(u32, mod_table.count());
1009 // Copy over the hashmap entries to our slice
1010 for (module_indices, 0..) |*module_index, index| module_index.* = @intCast(index);
1011 // Sort the slice by package name
1012 mem.sortUnstable(u32, module_indices, &mod_table, struct {
1013 fn lessThan(deps: *const Package.Module.Deps, lhs: u32, rhs: u32) bool {
1014 const keys = deps.keys();
1015 return std.mem.lessThan(u8, keys[lhs], keys[rhs]);
1136 var seen_table: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .{};
1137 defer seen_table.deinit(gpa);
1138 try seen_table.put(gpa, root_mod, {});
1139
1140 const SortByName = struct {
1141 names: []const []const u8,
1142
1143 pub fn lessThan(ctx: @This(), lhs_index: usize, rhs_index: usize) bool {
1144 const lhs_key = ctx.names[lhs_index];
1145 const rhs_key = ctx.names[rhs_index];
1146 return mem.lessThan(u8, lhs_key, rhs_key);
10161147 }
1017 }.lessThan);
1148 };
10181149
1019 for (module_indices) |module_index| {
1020 const module = mod_table.values()[module_index];
1021 if ((try seen_table.getOrPut(module)).found_existing) continue;
1150 var i: usize = 0;
1151 while (i < seen_table.count()) : (i += 1) {
1152 const mod = seen_table.keys()[i];
1153 if (mod.isBuiltin()) {
1154 // Skip builtin.zig; it is useless as an input, and we don't want to
1155 // have to write it before checking for a cache hit.
1156 continue;
1157 }
1158
1159 cache_helpers.addModule(hash, mod);
10221160
1023 // Finally insert the package name and path to the cache hash.
1024 hash.addBytes(mod_table.keys()[module_index]);
10251161 switch (hash_type) {
10261162 .path_bytes => {
1027 hash.addBytes(module.root_src_path);
1028 hash.addOptionalBytes(module.root.root_dir.path);
1029 hash.addBytes(module.root.sub_path);
1163 hash.addBytes(mod.root_src_path);
1164 hash.addOptionalBytes(mod.root.root_dir.path);
1165 hash.addBytes(mod.root.sub_path);
10301166 },
10311167 .files => |man| {
1032 const pkg_zig_file = try module.root.joinString(
1033 allocator,
1034 module.root_src_path,
1035 );
1168 const pkg_zig_file = try mod.root.joinString(arena, mod.root_src_path);
10361169 _ = try man.addFile(pkg_zig_file, null);
10371170 },
10381171 }
1039 // Recurse to handle the module's dependencies
1040 try addModuleTableToCacheHash(hash, arena, module.deps, seen_table, hash_type);
1172
1173 mod.deps.sortUnstable(SortByName{ .names = mod.deps.keys() });
1174
1175 hash.addListOfBytes(mod.deps.keys());
1176
1177 const deps = mod.deps.values();
1178 try seen_table.ensureUnusedCapacity(gpa, deps.len);
1179 for (deps) |dep| seen_table.putAssumeCapacity(dep, {});
10411180 }
10421181}
10431182
1044pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
1045 const is_dyn_lib = switch (options.output_mode) {
1183pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compilation {
1184 const output_mode = options.config.output_mode;
1185 const is_dyn_lib = switch (output_mode) {
10461186 .Obj, .Exe => false,
1047 .Lib => (options.link_mode orelse .Static) == .Dynamic,
1187 .Lib => options.config.link_mode == .Dynamic,
10481188 };
1049 const is_exe_or_dyn_lib = switch (options.output_mode) {
1189 const is_exe_or_dyn_lib = switch (output_mode) {
10501190 .Obj => false,
10511191 .Lib => is_dyn_lib,
10521192 .Exe => true,
10531193 };
10541194
1055 // WASI-only. Resolve the optional exec-model option, defaults to command.
1056 const wasi_exec_model = if (options.target.os.tag != .wasi) undefined else options.wasi_exec_model orelse .command;
1057
10581195 if (options.linker_export_table and options.linker_import_table) {
10591196 return error.ExportTableAndImportTableConflict;
10601197 }
10611198
1062 const comp: *Compilation = comp: {
1063 // For allocations that have the same lifetime as Compilation. This arena is used only during this
1064 // initialization and then is freed in deinit().
1065 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
1066 errdefer arena_allocator.deinit();
1067 const arena = arena_allocator.allocator();
1199 const have_zcu = options.config.have_zcu;
10681200
1201 const comp: *Compilation = comp: {
10691202 // We put the `Compilation` itself in the arena. Freeing the arena will free the module.
10701203 // It's initialized later after we prepare the initialization options.
1071 const comp = try arena.create(Compilation);
10721204 const root_name = try arena.dupeZ(u8, options.root_name);
10731205
1074 // Make a decision on whether to use LLVM or our own backend.
1075 const use_lib_llvm = options.use_lib_llvm orelse build_options.have_llvm;
1076 const use_llvm = blk: {
1077 if (options.use_llvm) |explicit|
1078 break :blk explicit;
1079
1080 // If emitting to LLVM bitcode object format, must use LLVM backend.
1081 if (options.emit_llvm_ir != null or options.emit_llvm_bc != null)
1082 break :blk true;
1083
1084 // If we have no zig code to compile, no need for LLVM.
1085 if (options.main_mod == null)
1086 break :blk false;
1087
1088 // If we cannot use LLVM libraries, then our own backends will be a
1089 // better default since the LLVM backend can only produce bitcode
1090 // and not an object file or executable.
1091 if (!use_lib_llvm)
1092 break :blk false;
1093
1094 // If LLVM does not support the target, then we can't use it.
1095 if (!target_util.hasLlvmSupport(options.target, options.target.ofmt))
1096 break :blk false;
1097
1098 // Prefer LLVM for release builds.
1099 if (options.optimize_mode != .Debug)
1100 break :blk true;
1101
1102 // At this point we would prefer to use our own self-hosted backend,
1103 // because the compilation speed is better than LLVM. But only do it if
1104 // we are confident in the robustness of the backend.
1105 break :blk !target_util.selfHostedBackendIsAsRobustAsLlvm(options.target);
1106 };
1107 if (!use_llvm) {
1108 if (options.use_llvm == true) {
1109 return error.ZigCompilerNotBuiltWithLLVMExtensions;
1110 }
1111 if (options.emit_llvm_ir != null or options.emit_llvm_bc != null) {
1112 return error.EmittingLlvmModuleRequiresUsingLlvmBackend;
1113 }
1114 }
1115
1116 // TODO: once we support incremental compilation for the LLVM backend via
1117 // saving the LLVM module into a bitcode file and restoring it, along with
1118 // compiler state, the second clause here can be removed so that incremental
1119 // cache mode is used for LLVM backend too. We need some fuzz testing before
1120 // that can be enabled.
1121 const cache_mode = if ((use_llvm or options.main_mod == null) and !options.disable_lld_caching)
1122 CacheMode.whole
1123 else
1124 options.cache_mode;
1125
1126 const tsan = options.want_tsan orelse false;
1127 // TSAN is implemented in C++ so it requires linking libc++.
1128 const link_libcpp = options.link_libcpp or tsan;
1129 const link_libc = link_libcpp or options.link_libc or options.link_libunwind or
1130 target_util.osRequiresLibC(options.target);
1131
1132 const link_libunwind = options.link_libunwind or
1133 (link_libcpp and target_util.libcNeedsLibUnwind(options.target));
1134 const unwind_tables = options.want_unwind_tables orelse
1135 (link_libunwind or target_util.needUnwindTables(options.target));
1136 const link_eh_frame_hdr = options.link_eh_frame_hdr or unwind_tables;
1137 const build_id = options.build_id orelse .none;
1206 const use_llvm = options.config.use_llvm;
11381207
1139 // Make a decision on whether to use LLD or our own linker.
1140 const use_lld = options.use_lld orelse blk: {
1141 if (options.target.isDarwin()) {
1142 break :blk false;
1143 }
1208 // The "any" values provided by resolved config only account for
1209 // explicitly-provided settings. We now make them additionally account
1210 // for default setting resolution.
1211 const any_unwind_tables = options.config.any_unwind_tables or options.root_mod.unwind_tables;
1212 const any_non_single_threaded = options.config.any_non_single_threaded or !options.root_mod.single_threaded;
1213 const any_sanitize_thread = options.config.any_sanitize_thread or options.root_mod.sanitize_thread;
11441214
1145 if (!build_options.have_llvm)
1146 break :blk false;
1147
1148 if (options.target.ofmt == .c)
1149 break :blk false;
1150
1151 if (options.want_lto) |lto| {
1152 if (lto) {
1153 break :blk true;
1154 }
1155 }
1156
1157 // Our linker can't handle objects or most advanced options yet.
1158 if (options.link_objects.len != 0 or
1159 options.c_source_files.len != 0 or
1160 options.frameworks.len != 0 or
1161 options.system_lib_names.len != 0 or
1162 options.link_libc or options.link_libcpp or
1163 link_eh_frame_hdr or
1164 options.link_emit_relocs or
1165 options.output_mode == .Lib or
1166 options.linker_script != null or options.version_script != null or
1167 options.emit_implib != null or
1168 build_id != .none or
1169 options.symbol_wrap_set.count() > 0)
1170 {
1171 break :blk true;
1172 }
1173
1174 if (use_llvm) {
1175 // If stage1 generates an object file, self-hosted linker is not
1176 // yet sophisticated enough to handle that.
1177 break :blk options.main_mod != null;
1178 }
1179
1180 break :blk false;
1181 };
1182
1183 const lto = blk: {
1184 if (options.want_lto) |want_lto| {
1185 if (want_lto and !use_lld and !options.target.isDarwin())
1186 return error.LtoUnavailableWithoutLld;
1187 break :blk want_lto;
1188 } else if (!use_lld) {
1189 // zig ld LTO support is tracked by
1190 // https://github.com/ziglang/zig/issues/8680
1191 break :blk false;
1192 } else if (options.c_source_files.len == 0) {
1193 break :blk false;
1194 } else if (options.target.cpu.arch.isRISCV()) {
1195 // Clang and LLVM currently don't support RISC-V target-abi for LTO.
1196 // Compiling with LTO may fail or produce undesired results.
1197 // See https://reviews.llvm.org/D71387
1198 // See https://reviews.llvm.org/D102582
1199 break :blk false;
1200 } else switch (options.output_mode) {
1201 .Lib, .Obj => break :blk false,
1202 .Exe => switch (options.optimize_mode) {
1203 .Debug => break :blk false,
1204 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => break :blk true,
1205 },
1206 }
1207 };
1208
1209 const must_dynamic_link = dl: {
1210 if (target_util.cannotDynamicLink(options.target))
1211 break :dl false;
1212 if (is_exe_or_dyn_lib and link_libc and
1213 (options.target.isGnuLibC() or target_util.osRequiresLibC(options.target)))
1214 {
1215 break :dl true;
1216 }
1217 const any_dyn_libs: bool = x: {
1218 if (options.system_lib_names.len != 0)
1219 break :x true;
1220 for (options.link_objects) |obj| {
1221 switch (classifyFileExt(obj.path)) {
1222 .shared_library => break :x true,
1223 else => continue,
1224 }
1225 }
1226 break :x false;
1227 };
1228 if (any_dyn_libs) {
1229 // When creating a executable that links to system libraries,
1230 // we require dynamic linking, but we must not link static libraries
1231 // or object files dynamically!
1232 break :dl (options.output_mode == .Exe);
1233 }
1234
1235 break :dl false;
1236 };
1237 const default_link_mode: std.builtin.LinkMode = blk: {
1238 if (must_dynamic_link) {
1239 break :blk .Dynamic;
1240 } else if (is_exe_or_dyn_lib and link_libc and
1241 options.is_native_abi and options.target.abi.isMusl())
1242 {
1243 // If targeting the system's native ABI and the system's
1244 // libc is musl, link dynamically by default.
1245 break :blk .Dynamic;
1246 } else {
1247 break :blk .Static;
1248 }
1249 };
1250 const link_mode: std.builtin.LinkMode = if (options.link_mode) |lm| blk: {
1251 if (lm == .Static and must_dynamic_link) {
1252 return error.UnableToStaticLink;
1253 }
1254 break :blk lm;
1255 } else default_link_mode;
1215 const link_eh_frame_hdr = options.link_eh_frame_hdr or any_unwind_tables;
1216 const build_id = options.build_id orelse .none;
12561217
1257 const dll_export_fns = options.dll_export_fns orelse (is_dyn_lib or options.rdynamic);
1218 const link_libc = options.config.link_libc;
12581219
12591220 const libc_dirs = try detectLibCIncludeDirs(
12601221 arena,
12611222 options.zig_lib_directory.path.?,
1262 options.target,
1263 options.is_native_abi,
1223 options.root_mod.resolved_target.result,
1224 options.root_mod.resolved_target.is_native_abi,
12641225 link_libc,
12651226 options.libc_installation,
12661227 );
12671228
1268 const rc_dirs = try detectWin32ResourceIncludeDirs(
1269 arena,
1270 options,
1271 );
1272
1273 const sysroot = options.sysroot orelse libc_dirs.sysroot;
1274
1275 const pie: bool = pie: {
1276 if (is_dyn_lib) {
1277 if (options.want_pie == true) return error.OutputModeForbidsPie;
1278 break :pie false;
1279 }
1280 if (target_util.requiresPIE(options.target)) {
1281 if (options.want_pie == false) return error.TargetRequiresPie;
1282 break :pie true;
1283 }
1284 if (tsan) {
1285 if (options.want_pie == false) return error.TsanRequiresPie;
1286 break :pie true;
1287 }
1288 if (options.want_pie) |want_pie| {
1289 break :pie want_pie;
1290 }
1291 break :pie false;
1292 };
1293
1294 const must_pic: bool = b: {
1295 if (target_util.requiresPIC(options.target, link_libc))
1296 break :b true;
1297 break :b link_mode == .Dynamic;
1298 };
1299 const pic = if (options.want_pic) |explicit| pic: {
1300 if (!explicit) {
1301 if (must_pic) {
1302 return error.TargetRequiresPIC;
1303 }
1304 if (pie) {
1305 return error.PIERequiresPIC;
1229 // The include directories used when preprocessing .rc files are separate from the
1230 // target. Which include directories are used is determined by `options.rc_includes`.
1231 //
1232 // Note: It should be okay that the include directories used when compiling .rc
1233 // files differ from the include directories used when compiling the main
1234 // binary, since the .res format is not dependent on anything ABI-related. The
1235 // only relevant differences would be things like `#define` constants being
1236 // different in the MinGW headers vs the MSVC headers, but any such
1237 // differences would likely be a MinGW bug.
1238 const rc_dirs = b: {
1239 // Set the includes to .none here when there are no rc files to compile
1240 var includes = if (options.rc_source_files.len > 0) options.rc_includes else .none;
1241 const target = options.root_mod.resolved_target.result;
1242 if (!options.root_mod.resolved_target.is_native_os or target.os.tag != .windows) {
1243 switch (includes) {
1244 // MSVC can't be found when the host isn't Windows, so short-circuit.
1245 .msvc => return error.WindowsSdkNotFound,
1246 // Skip straight to gnu since we won't be able to detect
1247 // MSVC on non-Windows hosts.
1248 .any => includes = .gnu,
1249 .none, .gnu => {},
13061250 }
13071251 }
1308 break :pic explicit;
1309 } else pie or must_pic;
1310
1311 // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
1312 const c_frontend: CFrontend = blk: {
1313 if (options.use_clang) |want_clang| {
1314 break :blk if (want_clang) .clang else .aro;
1315 }
1316 break :blk if (build_options.have_llvm) .clang else .aro;
1317 };
1318 if (!build_options.have_llvm and c_frontend == .clang) {
1319 return error.ZigCompilerNotBuiltWithLLVMExtensions;
1320 }
1321
1322 const is_safe_mode = switch (options.optimize_mode) {
1323 .Debug, .ReleaseSafe => true,
1324 .ReleaseFast, .ReleaseSmall => false,
1325 };
1326
1327 const sanitize_c = options.want_sanitize_c orelse is_safe_mode;
1328
1329 const stack_check: bool = options.want_stack_check orelse b: {
1330 if (!target_util.supportsStackProbing(options.target)) break :b false;
1331 break :b is_safe_mode;
1252 while (true) switch (includes) {
1253 .any, .msvc => break :b detectLibCIncludeDirs(
1254 arena,
1255 options.zig_lib_directory.path.?,
1256 .{
1257 .cpu = target.cpu,
1258 .os = target.os,
1259 .abi = .msvc,
1260 .ofmt = target.ofmt,
1261 },
1262 options.root_mod.resolved_target.is_native_abi,
1263 // The .rc preprocessor will need to know the libc include dirs even if we
1264 // are not linking libc, so force 'link_libc' to true
1265 true,
1266 options.libc_installation,
1267 ) catch |err| {
1268 if (includes == .any) {
1269 // fall back to mingw
1270 includes = .gnu;
1271 continue;
1272 }
1273 return err;
1274 },
1275 .gnu => break :b try detectLibCFromBuilding(arena, options.zig_lib_directory.path.?, .{
1276 .cpu = target.cpu,
1277 .os = target.os,
1278 .abi = .gnu,
1279 .ofmt = target.ofmt,
1280 }),
1281 .none => break :b LibCDirs{
1282 .libc_include_dir_list = &[0][]u8{},
1283 .libc_installation = null,
1284 .libc_framework_dir_list = &.{},
1285 .sysroot = null,
1286 .darwin_sdk_layout = null,
1287 },
1288 };
13321289 };
1333 if (stack_check and !target_util.supportsStackProbing(options.target))
1334 return error.StackCheckUnsupportedByTarget;
1335
1336 const stack_protector: u32 = sp: {
1337 const zig_backend = zigBackend(options.target, use_llvm);
1338 if (!target_util.supportsStackProtector(options.target, zig_backend)) {
1339 if (options.want_stack_protector) |x| {
1340 if (x > 0) return error.StackProtectorUnsupportedByTarget;
1341 }
1342 break :sp 0;
1343 }
13441290
1345 // This logic is checking for linking libc because otherwise our start code
1346 // which is trying to set up TLS (i.e. the fs/gs registers) but the stack
1347 // protection code depends on fs/gs registers being already set up.
1348 // If we were able to annotate start code, or perhaps the entire std lib,
1349 // as being exempt from stack protection checks, we could change this logic
1350 // to supporting stack protection even when not linking libc.
1351 // TODO file issue about this
1352 if (!link_libc) {
1353 if (options.want_stack_protector) |x| {
1354 if (x > 0) return error.StackProtectorUnavailableWithoutLibC;
1355 }
1356 break :sp 0;
1357 }
1358
1359 if (options.want_stack_protector) |x| break :sp x;
1360 if (is_safe_mode) break :sp default_stack_protector_buffer_size;
1361 break :sp 0;
1362 };
1291 const sysroot = options.sysroot orelse libc_dirs.sysroot;
13631292
13641293 const include_compiler_rt = options.want_compiler_rt orelse
13651294 (!options.skip_linker_dependencies and is_exe_or_dyn_lib);
13661295
1367 const single_threaded = st: {
1368 if (target_util.isSingleThreaded(options.target)) {
1369 if (options.single_threaded == false)
1370 return error.TargetRequiresSingleThreaded;
1371 break :st true;
1372 }
1373 if (options.main_mod != null) {
1374 const zig_backend = zigBackend(options.target, use_llvm);
1375 if (!target_util.supportsThreads(options.target, zig_backend)) {
1376 if (options.single_threaded == false)
1377 return error.BackendRequiresSingleThreaded;
1378 break :st true;
1379 }
1380 }
1381 break :st options.single_threaded orelse false;
1382 };
1383
1384 const llvm_cpu_features: ?[*:0]const u8 = if (use_llvm) blk: {
1385 var buf = std.ArrayList(u8).init(arena);
1386 for (options.target.cpu.arch.allFeaturesList(), 0..) |feature, index_usize| {
1387 const index = @as(Target.Cpu.Feature.Set.Index, @intCast(index_usize));
1388 const is_enabled = options.target.cpu.features.isEnabled(index);
1389
1390 if (feature.llvm_name) |llvm_name| {
1391 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
1392 try buf.ensureUnusedCapacity(2 + llvm_name.len);
1393 buf.appendAssumeCapacity(plus_or_minus);
1394 buf.appendSliceAssumeCapacity(llvm_name);
1395 buf.appendSliceAssumeCapacity(",");
1396 }
1397 }
1398 if (buf.items.len == 0) break :blk "";
1399 assert(mem.endsWith(u8, buf.items, ","));
1400 buf.items[buf.items.len - 1] = 0;
1401 buf.shrinkAndFree(buf.items.len);
1402 break :blk buf.items[0 .. buf.items.len - 1 :0].ptr;
1403 } else null;
1296 if (include_compiler_rt and output_mode == .Obj) {
1297 // For objects, this mechanism relies on essentially `_ = @import("compiler-rt");`
1298 // injected into the object.
1299 const compiler_rt_mod = try Package.Module.create(arena, .{
1300 .global_cache_directory = options.global_cache_directory,
1301 .paths = .{
1302 .root = .{
1303 .root_dir = options.zig_lib_directory,
1304 },
1305 .root_src_path = "compiler_rt.zig",
1306 },
1307 .fully_qualified_name = "compiler_rt",
1308 .cc_argv = &.{},
1309 .inherited = .{},
1310 .global = options.config,
1311 .parent = options.root_mod,
1312 .builtin_mod = options.root_mod.getBuiltinDependency(),
1313 });
1314 try options.root_mod.deps.putNoClobber(arena, "compiler_rt", compiler_rt_mod);
1315 }
14041316
14051317 if (options.verbose_llvm_cpu_features) {
1406 if (llvm_cpu_features) |cf| print: {
1318 if (options.root_mod.resolved_target.llvm_cpu_features) |cf| print: {
1319 const target = options.root_mod.resolved_target.result;
14071320 std.debug.getStderrMutex().lock();
14081321 defer std.debug.getStderrMutex().unlock();
14091322 const stderr = std.io.getStdErr().writer();
1410 nosuspend stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print;
1411 nosuspend stderr.print(" target: {s}\n", .{try options.target.zigTriple(arena)}) catch break :print;
1412 nosuspend stderr.print(" cpu: {s}\n", .{options.target.cpu.model.name}) catch break :print;
1413 nosuspend stderr.print(" features: {s}\n", .{cf}) catch {};
1323 nosuspend {
1324 stderr.print("compilation: {s}\n", .{options.root_name}) catch break :print;
1325 stderr.print(" target: {s}\n", .{try target.zigTriple(arena)}) catch break :print;
1326 stderr.print(" cpu: {s}\n", .{target.cpu.model.name}) catch break :print;
1327 stderr.print(" features: {s}\n", .{cf}) catch {};
1328 }
14141329 }
14151330 }
14161331
1417 const strip = options.strip orelse !target_util.hasDebugInfo(options.target);
1418 const valgrind: bool = b: {
1419 if (!target_util.hasValgrindSupport(options.target)) break :b false;
1420 if (options.want_valgrind) |explicit| break :b explicit;
1421 if (strip) break :b false;
1422 break :b options.optimize_mode == .Debug;
1423 };
1424 if (!valgrind and options.want_valgrind == true)
1425 return error.ValgrindUnsupportedOnTarget;
1426
1427 const red_zone = options.want_red_zone orelse target_util.hasRedZone(options.target);
1428 const omit_frame_pointer = options.omit_frame_pointer orelse (options.optimize_mode != .Debug);
1429 const linker_optimization: u8 = options.linker_optimization orelse switch (options.optimize_mode) {
1430 .Debug => @as(u8, 0),
1431 else => @as(u8, 3),
1432 };
1433 const formatted_panics = options.formatted_panics orelse (options.optimize_mode == .Debug);
1332 // TODO: https://github.com/ziglang/zig/issues/17969
1333 const formatted_panics = options.formatted_panics orelse (options.root_mod.optimize_mode == .Debug);
14341334
14351335 const error_limit = options.error_limit orelse (std.math.maxInt(u16) - 1);
14361336
1337 const each_lib_rpath = options.each_lib_rpath orelse
1338 options.root_mod.resolved_target.is_native_os;
1339
14371340 // We put everything into the cache hash that *cannot be modified
14381341 // during an incremental update*. For example, one cannot change the
14391342 // target between updates, but one can change source files, so the
......@@ -1455,197 +1358,27 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
14551358 // This is shared hasher state common to zig source and all C source files.
14561359 cache.hash.addBytes(build_options.version);
14571360 cache.hash.add(builtin.zig_backend);
1458 cache.hash.add(options.optimize_mode);
1459 cache.hash.add(options.target.cpu.arch);
1460 cache.hash.addBytes(options.target.cpu.model.name);
1461 cache.hash.add(options.target.cpu.features.ints);
1462 cache.hash.add(options.target.os.tag);
1463 cache.hash.add(options.target.os.getVersionRange());
1464 cache.hash.add(options.is_native_os);
1465 cache.hash.add(options.target.abi);
1466 cache.hash.add(options.target.ofmt);
1467 cache.hash.add(pic);
1468 cache.hash.add(pie);
1469 cache.hash.add(lto);
1470 cache.hash.add(unwind_tables);
1471 cache.hash.add(tsan);
1472 cache.hash.add(stack_check);
1473 cache.hash.add(stack_protector);
1474 cache.hash.add(red_zone);
1475 cache.hash.add(omit_frame_pointer);
1476 cache.hash.add(link_mode);
1361 cache.hash.add(options.config.pie);
1362 cache.hash.add(options.config.lto);
1363 cache.hash.add(options.config.link_mode);
14771364 cache.hash.add(options.function_sections);
14781365 cache.hash.add(options.data_sections);
14791366 cache.hash.add(options.no_builtin);
1480 cache.hash.add(strip);
14811367 cache.hash.add(link_libc);
1482 cache.hash.add(link_libcpp);
1483 cache.hash.add(link_libunwind);
1484 cache.hash.add(options.output_mode);
1485 cache.hash.add(options.machine_code_model);
1486 cache.hash.addOptional(options.dwarf_format);
1368 cache.hash.add(options.config.link_libcpp);
1369 cache.hash.add(options.config.link_libunwind);
1370 cache.hash.add(output_mode);
1371 cache_helpers.addDebugFormat(&cache.hash, options.config.debug_format);
14871372 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_bin);
14881373 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_implib);
14891374 cache_helpers.addOptionalEmitLoc(&cache.hash, options.emit_docs);
14901375 cache.hash.addBytes(options.root_name);
1491 if (options.target.os.tag == .wasi) cache.hash.add(wasi_exec_model);
1376 cache.hash.add(options.config.wasi_exec_model);
14921377 // TODO audit this and make sure everything is in it
14931378
1494 const module: ?*Module = if (options.main_mod) |main_mod| blk: {
1495 // Options that are specific to zig source files, that cannot be
1496 // modified between incremental updates.
1497 var hash = cache.hash;
1498
1499 switch (cache_mode) {
1500 .incremental => {
1501 // Here we put the root source file path name, but *not* with addFile.
1502 // We want the hash to be the same regardless of the contents of the
1503 // source file, because incremental compilation will handle it, but we
1504 // do want to namespace different source file names because they are
1505 // likely different compilations and therefore this would be likely to
1506 // cause cache hits.
1507 hash.addBytes(main_mod.root_src_path);
1508 hash.addOptionalBytes(main_mod.root.root_dir.path);
1509 hash.addBytes(main_mod.root.sub_path);
1510 {
1511 var seen_table = std.AutoHashMap(*Package.Module, void).init(arena);
1512 try addModuleTableToCacheHash(&hash, &arena_allocator, main_mod.deps, &seen_table, .path_bytes);
1513 }
1514 },
1515 .whole => {
1516 // In this case, we postpone adding the input source file until
1517 // we create the cache manifest, in update(), because we want to
1518 // track it and packages as files.
1519 },
1520 }
1521
1522 // Synchronize with other matching comments: ZigOnlyHashStuff
1523 hash.add(valgrind);
1524 hash.add(single_threaded);
1525 hash.add(use_llvm);
1526 hash.add(use_lib_llvm);
1527 hash.add(dll_export_fns);
1528 hash.add(options.is_test);
1529 hash.add(options.test_evented_io);
1530 hash.addOptionalBytes(options.test_filter);
1531 hash.addOptionalBytes(options.test_name_prefix);
1532 hash.add(options.skip_linker_dependencies);
1533 hash.add(formatted_panics);
1534 hash.add(options.emit_h != null);
1535 hash.add(error_limit);
1536 hash.addOptional(options.want_structured_cfg);
1537
1538 // In the case of incremental cache mode, this `zig_cache_artifact_directory`
1539 // is computed based on a hash of non-linker inputs, and it is where all
1540 // build artifacts are stored (even while in-progress).
1541 //
1542 // For whole cache mode, it is still used for builtin.zig so that the file
1543 // path to builtin.zig can remain consistent during a debugging session at
1544 // runtime. However, we don't know where to put outputs from the linker
1545 // until the final cache hash, which is available after the
1546 // compilation is complete.
1547 //
1548 // Therefore, in whole cache mode, we additionally create a temporary cache
1549 // directory for these two kinds of build artifacts, and then rename it
1550 // into place after the final hash is known. However, we don't want
1551 // to create the temporary directory here, because in the case of a cache hit,
1552 // this would have been wasted syscalls to make the directory and then not
1553 // use it (or delete it).
1554 //
1555 // In summary, for whole cache mode, we simulate `-fno-emit-bin` in this
1556 // function, and `zig_cache_artifact_directory` is *wrong* except for builtin.zig,
1557 // and then at the beginning of `update()` when we find out whether we need
1558 // a temporary directory, we patch up all the places that the incorrect
1559 // `zig_cache_artifact_directory` was passed to various components of the compiler.
1560
1561 const digest = hash.final();
1562 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
1563 var artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});
1564 errdefer artifact_dir.close();
1565 const zig_cache_artifact_directory: Directory = .{
1566 .handle = artifact_dir,
1567 .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),
1568 };
1569
1570 const builtin_mod = try Package.Module.create(arena, .{
1571 .root = .{ .root_dir = zig_cache_artifact_directory },
1572 .root_src_path = "builtin.zig",
1573 .fully_qualified_name = "builtin",
1574 });
1575
1576 // When you're testing std, the main module is std. In that case,
1577 // we'll just set the std module to the main one, since avoiding
1578 // the errors caused by duplicating it is more effort than it's
1579 // worth.
1580 const main_mod_is_std = m: {
1581 const std_path = try std.fs.path.resolve(arena, &[_][]const u8{
1582 options.zig_lib_directory.path orelse ".",
1583 "std",
1584 "std.zig",
1585 });
1586 const main_path = try std.fs.path.resolve(arena, &[_][]const u8{
1587 main_mod.root.root_dir.path orelse ".",
1588 main_mod.root.sub_path,
1589 main_mod.root_src_path,
1590 });
1591 break :m mem.eql(u8, main_path, std_path);
1592 };
1593
1594 const std_mod = if (main_mod_is_std)
1595 main_mod
1596 else
1597 try Package.Module.create(arena, .{
1598 .root = .{
1599 .root_dir = options.zig_lib_directory,
1600 .sub_path = "std",
1601 },
1602 .root_src_path = "std.zig",
1603 .fully_qualified_name = "std",
1604 });
1605
1606 const root_mod = if (options.is_test) root_mod: {
1607 const test_mod = if (options.test_runner_path) |test_runner| test_mod: {
1608 const pkg = try Package.Module.create(arena, .{
1609 .root = .{
1610 .root_dir = Directory.cwd(),
1611 .sub_path = std.fs.path.dirname(test_runner) orelse "",
1612 },
1613 .root_src_path = std.fs.path.basename(test_runner),
1614 .fully_qualified_name = "root",
1615 });
1616
1617 pkg.deps = try main_mod.deps.clone(arena);
1618 break :test_mod pkg;
1619 } else try Package.Module.create(arena, .{
1620 .root = .{
1621 .root_dir = options.zig_lib_directory,
1622 },
1623 .root_src_path = "test_runner.zig",
1624 .fully_qualified_name = "root",
1625 });
1626
1627 break :root_mod test_mod;
1628 } else main_mod;
1629
1630 const compiler_rt_mod = if (include_compiler_rt and options.output_mode == .Obj) compiler_rt_mod: {
1631 break :compiler_rt_mod try Package.Module.create(arena, .{
1632 .root = .{
1633 .root_dir = options.zig_lib_directory,
1634 },
1635 .root_src_path = "compiler_rt.zig",
1636 .fully_qualified_name = "compiler_rt",
1637 });
1638 } else null;
1639
1640 {
1641 try main_mod.deps.ensureUnusedCapacity(arena, 4);
1642 main_mod.deps.putAssumeCapacity("builtin", builtin_mod);
1643 main_mod.deps.putAssumeCapacity("root", root_mod);
1644 main_mod.deps.putAssumeCapacity("std", std_mod);
1645 if (compiler_rt_mod) |m|
1646 main_mod.deps.putAssumeCapacity("compiler_rt", m);
1647 }
1648
1379 const main_mod = options.main_mod orelse options.root_mod;
1380 const comp = try arena.create(Compilation);
1381 const opt_zcu: ?*Module = if (have_zcu) blk: {
16491382 // Pre-open the directory handles for cached ZIR code so that it does not need
16501383 // to redundantly happen for each AstGen operation.
16511384 const zir_sub_dir = "z";
......@@ -1664,277 +1397,183 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
16641397 };
16651398
16661399 const emit_h: ?*Module.GlobalEmitH = if (options.emit_h) |loc| eh: {
1667 const eh = try gpa.create(Module.GlobalEmitH);
1400 const eh = try arena.create(Module.GlobalEmitH);
16681401 eh.* = .{ .loc = loc };
16691402 break :eh eh;
16701403 } else null;
1671 errdefer if (emit_h) |eh| gpa.destroy(eh);
16721404
1673 // TODO when we implement serialization and deserialization of incremental
1674 // compilation metadata, this is where we would load it. We have open a handle
1675 // to the directory where the output either already is, or will be.
1676 // However we currently do not have serialization of such metadata, so for now
1677 // we set up an empty Module that does the entire compilation fresh.
1405 const std_mod = options.std_mod orelse try Package.Module.create(arena, .{
1406 .global_cache_directory = options.global_cache_directory,
1407 .paths = .{
1408 .root = .{
1409 .root_dir = options.zig_lib_directory,
1410 .sub_path = "std",
1411 },
1412 .root_src_path = "std.zig",
1413 },
1414 .fully_qualified_name = "std",
1415 .cc_argv = &.{},
1416 .inherited = .{},
1417 .global = options.config,
1418 .parent = options.root_mod,
1419 .builtin_mod = options.root_mod.getBuiltinDependency(),
1420 });
16781421
1679 const module = try arena.create(Module);
1680 errdefer module.deinit();
1681 module.* = .{
1422 const zcu = try arena.create(Module);
1423 zcu.* = .{
16821424 .gpa = gpa,
16831425 .comp = comp,
16841426 .main_mod = main_mod,
1685 .root_mod = root_mod,
1686 .zig_cache_artifact_directory = zig_cache_artifact_directory,
1427 .root_mod = options.root_mod,
1428 .std_mod = std_mod,
16871429 .global_zir_cache = global_zir_cache,
16881430 .local_zir_cache = local_zir_cache,
16891431 .emit_h = emit_h,
16901432 .tmp_hack_arena = std.heap.ArenaAllocator.init(gpa),
16911433 .error_limit = error_limit,
1434 .llvm_object = null,
16921435 };
1693 try module.init();
1694
1695 break :blk module;
1436 try zcu.init();
1437 break :blk zcu;
16961438 } else blk: {
16971439 if (options.emit_h != null) return error.NoZigModuleForCHeader;
16981440 break :blk null;
16991441 };
1700 errdefer if (module) |zm| zm.deinit();
1701
1702 const error_return_tracing = !strip and switch (options.optimize_mode) {
1703 .Debug, .ReleaseSafe => (!options.target.isWasm() or options.target.os.tag == .emscripten) and
1704 !options.target.cpu.arch.isBpf() and (options.error_tracing orelse true),
1705 .ReleaseFast => options.error_tracing orelse false,
1706 .ReleaseSmall => false,
1707 };
1708
1709 // For resource management purposes.
1710 var owned_link_dir: ?std.fs.Dir = null;
1711 errdefer if (owned_link_dir) |*dir| dir.close();
1712
1713 const bin_file_emit: ?link.Emit = blk: {
1714 const emit_bin = options.emit_bin orelse break :blk null;
1715
1716 if (emit_bin.directory) |directory| {
1717 break :blk link.Emit{
1718 .directory = directory,
1719 .sub_path = emit_bin.basename,
1720 };
1721 }
1722
1723 // In case of whole cache mode, `whole_bin_sub_path` is used to distinguish
1724 // between -femit-bin and -fno-emit-bin.
1725 switch (cache_mode) {
1726 .whole => break :blk null,
1727 .incremental => {},
1728 }
1729
1730 if (module) |zm| {
1731 break :blk link.Emit{
1732 .directory = zm.zig_cache_artifact_directory,
1733 .sub_path = emit_bin.basename,
1734 };
1735 }
1736
1737 // We could use the cache hash as is no problem, however, we increase
1738 // the likelihood of cache hits by adding the first C source file
1739 // path name (not contents) to the hash. This way if the user is compiling
1740 // foo.c and bar.c as separate compilations, they get different cache
1741 // directories.
1742 var hash = cache.hash;
1743 if (options.c_source_files.len >= 1) {
1744 hash.addBytes(options.c_source_files[0].src_path);
1745 } else if (options.link_objects.len >= 1) {
1746 hash.addBytes(options.link_objects[0].path);
1747 }
1748
1749 const digest = hash.final();
1750 const artifact_sub_dir = try std.fs.path.join(arena, &[_][]const u8{ "o", &digest });
1751 const artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});
1752 owned_link_dir = artifact_dir;
1753 const link_artifact_directory: Directory = .{
1754 .handle = artifact_dir,
1755 .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),
1756 };
1757 break :blk link.Emit{
1758 .directory = link_artifact_directory,
1759 .sub_path = emit_bin.basename,
1760 };
1761 };
1762
1763 const implib_emit: ?link.Emit = blk: {
1764 const emit_implib = options.emit_implib orelse break :blk null;
1765
1766 if (emit_implib.directory) |directory| {
1767 break :blk link.Emit{
1768 .directory = directory,
1769 .sub_path = emit_implib.basename,
1770 };
1771 }
1772
1773 // This is here for the same reason as in `bin_file_emit` above.
1774 switch (cache_mode) {
1775 .whole => break :blk null,
1776 .incremental => {},
1777 }
1778
1779 // Use the same directory as the bin. The CLI already emits an
1780 // error if -fno-emit-bin is combined with -femit-implib.
1781 break :blk link.Emit{
1782 .directory = bin_file_emit.?.directory,
1783 .sub_path = emit_implib.basename,
1784 };
1785 };
1786
1787 const docs_emit: ?link.Emit = blk: {
1788 const emit_docs = options.emit_docs orelse break :blk null;
1789
1790 if (emit_docs.directory) |directory| {
1791 break :blk .{
1792 .directory = directory,
1793 .sub_path = emit_docs.basename,
1794 };
1795 }
1796
1797 // This is here for the same reason as in `bin_file_emit` above.
1798 switch (cache_mode) {
1799 .whole => break :blk null,
1800 .incremental => {},
1801 }
1802
1803 // Use the same directory as the bin, if possible.
1804 if (bin_file_emit) |x| break :blk .{
1805 .directory = x.directory,
1806 .sub_path = emit_docs.basename,
1807 };
1808
1809 break :blk .{
1810 .directory = module.?.zig_cache_artifact_directory,
1811 .sub_path = emit_docs.basename,
1812 };
1813 };
1442 errdefer if (opt_zcu) |zcu| zcu.deinit();
18141443
1815 // This is so that when doing `CacheMode.whole`, the mechanism in update()
1816 // can use it for communicating the result directory via `bin_file.emit`.
1817 // This is used to distinguish between -fno-emit-bin and -femit-bin
1818 // for `CacheMode.whole`.
1819 // This memory will be overwritten with the real digest in update() but
1820 // the basename will be preserved.
1821 const whole_bin_sub_path: ?[]u8 = try prepareWholeEmitSubPath(arena, options.emit_bin);
1822 // Same thing but for implibs.
1823 const whole_implib_sub_path: ?[]u8 = try prepareWholeEmitSubPath(arena, options.emit_implib);
1824 const whole_docs_sub_path: ?[]u8 = try prepareWholeEmitSubPath(arena, options.emit_docs);
1825
1826 var system_libs: std.StringArrayHashMapUnmanaged(SystemLib) = .{};
1444 var system_libs = try std.StringArrayHashMapUnmanaged(SystemLib).init(
1445 gpa,
1446 options.system_lib_names,
1447 options.system_lib_infos,
1448 );
18271449 errdefer system_libs.deinit(gpa);
1828 try system_libs.ensureTotalCapacity(gpa, options.system_lib_names.len);
1829 for (options.system_lib_names, 0..) |lib_name, i| {
1830 system_libs.putAssumeCapacity(lib_name, options.system_lib_infos[i]);
1831 }
18321450
1833 const bin_file = try link.File.openPath(gpa, .{
1834 .emit = bin_file_emit,
1835 .implib_emit = implib_emit,
1836 .docs_emit = docs_emit,
1451 comp.* = .{
1452 .gpa = gpa,
1453 .arena = arena,
1454 .module = opt_zcu,
1455 .cache_use = undefined, // populated below
1456 .bin_file = null, // populated below
1457 .implib_emit = null, // handled below
1458 .docs_emit = null, // handled below
1459 .root_mod = options.root_mod,
1460 .config = options.config,
1461 .zig_lib_directory = options.zig_lib_directory,
1462 .local_cache_directory = options.local_cache_directory,
1463 .global_cache_directory = options.global_cache_directory,
1464 .emit_asm = options.emit_asm,
1465 .emit_llvm_ir = options.emit_llvm_ir,
1466 .emit_llvm_bc = options.emit_llvm_bc,
1467 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1468 .anon_work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1469 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),
1470 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),
1471 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
1472 .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
1473 .c_source_files = options.c_source_files,
1474 .rc_source_files = options.rc_source_files,
1475 .cache_parent = cache,
1476 .self_exe_path = options.self_exe_path,
1477 .libc_include_dir_list = libc_dirs.libc_include_dir_list,
1478 .libc_framework_dir_list = libc_dirs.libc_framework_dir_list,
1479 .rc_include_dir_list = rc_dirs.libc_include_dir_list,
1480 .thread_pool = options.thread_pool,
1481 .clang_passthrough_mode = options.clang_passthrough_mode,
1482 .clang_preprocessor_mode = options.clang_preprocessor_mode,
1483 .verbose_cc = options.verbose_cc,
1484 .verbose_air = options.verbose_air,
1485 .verbose_intern_pool = options.verbose_intern_pool,
1486 .verbose_generic_instances = options.verbose_generic_instances,
1487 .verbose_llvm_ir = options.verbose_llvm_ir,
1488 .verbose_llvm_bc = options.verbose_llvm_bc,
1489 .verbose_cimport = options.verbose_cimport,
1490 .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
1491 .verbose_link = options.verbose_link,
1492 .disable_c_depfile = options.disable_c_depfile,
1493 .reference_trace = options.reference_trace,
1494 .formatted_panics = formatted_panics,
1495 .time_report = options.time_report,
1496 .stack_report = options.stack_report,
1497 .test_filter = options.test_filter,
1498 .test_name_prefix = options.test_name_prefix,
1499 .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
1500 .debug_compile_errors = options.debug_compile_errors,
1501 .libcxx_abi_version = options.libcxx_abi_version,
18371502 .root_name = root_name,
1838 .module = module,
1839 .target = options.target,
1840 .dynamic_linker = options.dynamic_linker,
18411503 .sysroot = sysroot,
1842 .output_mode = options.output_mode,
1843 .link_mode = link_mode,
1844 .optimize_mode = options.optimize_mode,
1845 .use_lld = use_lld,
1846 .use_llvm = use_llvm,
1847 .use_lib_llvm = use_lib_llvm,
1848 .link_libc = link_libc,
1849 .link_libcpp = link_libcpp,
1850 .link_libunwind = link_libunwind,
1851 .darwin_sdk_layout = libc_dirs.darwin_sdk_layout,
1504 .system_libs = system_libs,
1505 .version = options.version,
1506 .libc_installation = libc_dirs.libc_installation,
1507 .include_compiler_rt = include_compiler_rt,
18521508 .objects = options.link_objects,
1853 .frameworks = options.frameworks,
18541509 .framework_dirs = options.framework_dirs,
1855 .system_libs = system_libs,
1510 .llvm_opt_bisect_limit = options.llvm_opt_bisect_limit,
1511 .skip_linker_dependencies = options.skip_linker_dependencies,
1512 .no_builtin = options.no_builtin,
1513 .job_queued_update_builtin_zig = have_zcu,
1514 .function_sections = options.function_sections,
1515 .data_sections = options.data_sections,
1516 .native_system_include_paths = options.native_system_include_paths,
18561517 .wasi_emulated_libs = options.wasi_emulated_libs,
1518 .force_undefined_symbols = options.force_undefined_symbols,
1519 .link_eh_frame_hdr = link_eh_frame_hdr,
1520 .global_cc_argv = options.global_cc_argv,
1521 };
1522
1523 // Prevent some footguns by making the "any" fields of config reflect
1524 // the default Module settings.
1525 comp.config.any_unwind_tables = any_unwind_tables;
1526 comp.config.any_non_single_threaded = any_non_single_threaded;
1527 comp.config.any_sanitize_thread = any_sanitize_thread;
1528
1529 const lf_open_opts: link.File.OpenOptions = .{
1530 .linker_script = options.linker_script,
1531 .z_nodelete = options.linker_z_nodelete,
1532 .z_notext = options.linker_z_notext,
1533 .z_defs = options.linker_z_defs,
1534 .z_origin = options.linker_z_origin,
1535 .z_nocopyreloc = options.linker_z_nocopyreloc,
1536 .z_now = options.linker_z_now,
1537 .z_relro = options.linker_z_relro,
1538 .z_common_page_size = options.linker_z_common_page_size,
1539 .z_max_page_size = options.linker_z_max_page_size,
1540 .darwin_sdk_layout = libc_dirs.darwin_sdk_layout,
1541 .frameworks = options.frameworks,
18571542 .lib_dirs = options.lib_dirs,
18581543 .rpath_list = options.rpath_list,
18591544 .symbol_wrap_set = options.symbol_wrap_set,
1860 .strip = strip,
1861 .is_native_os = options.is_native_os,
1862 .is_native_abi = options.is_native_abi,
1863 .function_sections = options.function_sections,
1864 .data_sections = options.data_sections,
1865 .no_builtin = options.no_builtin,
18661545 .allow_shlib_undefined = options.linker_allow_shlib_undefined,
18671546 .bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
18681547 .compress_debug_sections = options.linker_compress_debug_sections orelse .none,
18691548 .module_definition_file = options.linker_module_definition_file,
18701549 .sort_section = options.linker_sort_section,
1871 .import_memory = options.linker_import_memory orelse false,
1872 .export_memory = options.linker_export_memory orelse !(options.linker_import_memory orelse false),
18731550 .import_symbols = options.linker_import_symbols,
18741551 .import_table = options.linker_import_table,
18751552 .export_table = options.linker_export_table,
18761553 .initial_memory = options.linker_initial_memory,
18771554 .max_memory = options.linker_max_memory,
1878 .shared_memory = options.linker_shared_memory,
18791555 .global_base = options.linker_global_base,
18801556 .export_symbol_names = options.linker_export_symbol_names,
18811557 .print_gc_sections = options.linker_print_gc_sections,
18821558 .print_icf_sections = options.linker_print_icf_sections,
18831559 .print_map = options.linker_print_map,
1884 .opt_bisect_limit = options.linker_opt_bisect_limit,
1885 .z_nodelete = options.linker_z_nodelete,
1886 .z_notext = options.linker_z_notext,
1887 .z_defs = options.linker_z_defs,
1888 .z_origin = options.linker_z_origin,
1889 .z_nocopyreloc = options.linker_z_nocopyreloc,
1890 .z_now = options.linker_z_now,
1891 .z_relro = options.linker_z_relro,
1892 .z_common_page_size = options.linker_z_common_page_size,
1893 .z_max_page_size = options.linker_z_max_page_size,
18941560 .tsaware = options.linker_tsaware,
18951561 .nxcompat = options.linker_nxcompat,
18961562 .dynamicbase = options.linker_dynamicbase,
1897 .linker_optimization = linker_optimization,
18981563 .major_subsystem_version = options.major_subsystem_version,
18991564 .minor_subsystem_version = options.minor_subsystem_version,
19001565 .entry = options.entry,
1901 .stack_size_override = options.stack_size_override,
1902 .image_base_override = options.image_base_override,
1903 .include_compiler_rt = include_compiler_rt,
1904 .linker_script = options.linker_script,
1566 .stack_size = options.stack_size,
1567 .image_base = options.image_base,
19051568 .version_script = options.version_script,
19061569 .gc_sections = options.linker_gc_sections,
1907 .eh_frame_hdr = link_eh_frame_hdr,
19081570 .emit_relocs = options.link_emit_relocs,
1909 .rdynamic = options.rdynamic,
19101571 .soname = options.soname,
1911 .version = options.version,
19121572 .compatibility_version = options.compatibility_version,
1913 .libc_installation = libc_dirs.libc_installation,
1914 .pic = pic,
1915 .pie = pie,
1916 .lto = lto,
1917 .valgrind = valgrind,
1918 .tsan = tsan,
1919 .stack_check = stack_check,
1920 .stack_protector = stack_protector,
1921 .red_zone = red_zone,
1922 .omit_frame_pointer = omit_frame_pointer,
1923 .single_threaded = single_threaded,
1924 .verbose_link = options.verbose_link,
1925 .machine_code_model = options.machine_code_model,
1926 .dll_export_fns = dll_export_fns,
1927 .error_return_tracing = error_return_tracing,
1928 .llvm_cpu_features = llvm_cpu_features,
1929 .skip_linker_dependencies = options.skip_linker_dependencies,
1930 .each_lib_rpath = options.each_lib_rpath orelse options.is_native_os,
1573 .each_lib_rpath = each_lib_rpath,
19311574 .build_id = build_id,
1932 .cache_mode = cache_mode,
1933 .disable_lld_caching = options.disable_lld_caching or cache_mode == .whole,
1575 .disable_lld_caching = options.disable_lld_caching or options.cache_mode == .whole,
19341576 .subsystem = options.subsystem,
1935 .is_test = options.is_test,
1936 .dwarf_format = options.dwarf_format,
1937 .wasi_exec_model = wasi_exec_model,
19381577 .hash_style = options.hash_style,
19391578 .enable_link_snapshots = options.enable_link_snapshots,
19401579 .install_name = options.install_name,
......@@ -1943,76 +1582,125 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
19431582 .headerpad_size = options.headerpad_size,
19441583 .headerpad_max_install_names = options.headerpad_max_install_names,
19451584 .dead_strip_dylibs = options.dead_strip_dylibs,
1946 .force_undefined_symbols = options.force_undefined_symbols,
19471585 .pdb_source_path = options.pdb_source_path,
19481586 .pdb_out_path = options.pdb_out_path,
1949 .want_structured_cfg = options.want_structured_cfg,
1950 });
1951 errdefer bin_file.destroy();
1952 comp.* = .{
1953 .gpa = gpa,
1954 .arena = arena_allocator,
1955 .zig_lib_directory = options.zig_lib_directory,
1956 .local_cache_directory = options.local_cache_directory,
1957 .global_cache_directory = options.global_cache_directory,
1958 .bin_file = bin_file,
1959 .whole_bin_sub_path = whole_bin_sub_path,
1960 .whole_implib_sub_path = whole_implib_sub_path,
1961 .whole_docs_sub_path = whole_docs_sub_path,
1962 .emit_asm = options.emit_asm,
1963 .emit_llvm_ir = options.emit_llvm_ir,
1964 .emit_llvm_bc = options.emit_llvm_bc,
1965 .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1966 .anon_work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa),
1967 .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa),
1968 .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa),
1969 .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa),
1970 .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa),
1971 .keep_source_files_loaded = options.keep_source_files_loaded,
1972 .c_frontend = c_frontend,
1973 .clang_argv = options.clang_argv,
1974 .c_source_files = options.c_source_files,
1975 .rc_source_files = options.rc_source_files,
1976 .cache_parent = cache,
1977 .self_exe_path = options.self_exe_path,
1978 .libc_include_dir_list = libc_dirs.libc_include_dir_list,
1979 .libc_framework_dir_list = libc_dirs.libc_framework_dir_list,
1980 .rc_include_dir_list = rc_dirs.libc_include_dir_list,
1981 .sanitize_c = sanitize_c,
1982 .thread_pool = options.thread_pool,
1983 .clang_passthrough_mode = options.clang_passthrough_mode,
1984 .clang_preprocessor_mode = options.clang_preprocessor_mode,
1985 .verbose_cc = options.verbose_cc,
1986 .verbose_air = options.verbose_air,
1987 .verbose_intern_pool = options.verbose_intern_pool,
1988 .verbose_generic_instances = options.verbose_generic_instances,
1989 .verbose_llvm_ir = options.verbose_llvm_ir,
1990 .verbose_llvm_bc = options.verbose_llvm_bc,
1991 .verbose_cimport = options.verbose_cimport,
1992 .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
1993 .disable_c_depfile = options.disable_c_depfile,
1994 .owned_link_dir = owned_link_dir,
1995 .color = options.color,
1996 .reference_trace = options.reference_trace,
1997 .formatted_panics = formatted_panics,
1998 .time_report = options.time_report,
1999 .stack_report = options.stack_report,
2000 .unwind_tables = unwind_tables,
2001 .test_filter = options.test_filter,
2002 .test_name_prefix = options.test_name_prefix,
2003 .test_evented_io = options.test_evented_io,
2004 .debug_compiler_runtime_libs = options.debug_compiler_runtime_libs,
2005 .debug_compile_errors = options.debug_compile_errors,
2006 .libcxx_abi_version = options.libcxx_abi_version,
1587 .entry_addr = null, // CLI does not expose this option (yet?)
20071588 };
1589
1590 switch (options.cache_mode) {
1591 .incremental => {
1592 // Options that are specific to zig source files, that cannot be
1593 // modified between incremental updates.
1594 var hash = cache.hash;
1595
1596 // Synchronize with other matching comments: ZigOnlyHashStuff
1597 hash.add(use_llvm);
1598 hash.add(options.config.use_lib_llvm);
1599 hash.add(options.config.dll_export_fns);
1600 hash.add(options.config.is_test);
1601 hash.add(options.config.test_evented_io);
1602 hash.addOptionalBytes(options.test_filter);
1603 hash.addOptionalBytes(options.test_name_prefix);
1604 hash.add(options.skip_linker_dependencies);
1605 hash.add(formatted_panics);
1606 hash.add(options.emit_h != null);
1607 hash.add(error_limit);
1608
1609 // Here we put the root source file path name, but *not* with addFile.
1610 // We want the hash to be the same regardless of the contents of the
1611 // source file, because incremental compilation will handle it, but we
1612 // do want to namespace different source file names because they are
1613 // likely different compilations and therefore this would be likely to
1614 // cause cache hits.
1615 try addModuleTableToCacheHash(gpa, arena, &hash, main_mod, .path_bytes);
1616
1617 // In the case of incremental cache mode, this `artifact_directory`
1618 // is computed based on a hash of non-linker inputs, and it is where all
1619 // build artifacts are stored (even while in-progress).
1620 const digest = hash.final();
1621 const artifact_sub_dir = "o" ++ std.fs.path.sep_str ++ digest;
1622 var artifact_dir = try options.local_cache_directory.handle.makeOpenPath(artifact_sub_dir, .{});
1623 errdefer artifact_dir.close();
1624 const artifact_directory: Directory = .{
1625 .handle = artifact_dir,
1626 .path = try options.local_cache_directory.join(arena, &[_][]const u8{artifact_sub_dir}),
1627 };
1628
1629 const incremental = try arena.create(CacheUse.Incremental);
1630 incremental.* = .{
1631 .artifact_directory = artifact_directory,
1632 };
1633 comp.cache_use = .{ .incremental = incremental };
1634
1635 if (options.emit_bin) |emit_bin| {
1636 const emit: Emit = .{
1637 .directory = emit_bin.directory orelse artifact_directory,
1638 .sub_path = emit_bin.basename,
1639 };
1640 comp.bin_file = try link.File.open(arena, comp, emit, lf_open_opts);
1641 }
1642
1643 if (options.emit_implib) |emit_implib| {
1644 comp.implib_emit = .{
1645 .directory = emit_implib.directory orelse artifact_directory,
1646 .sub_path = emit_implib.basename,
1647 };
1648 }
1649
1650 if (options.emit_docs) |emit_docs| {
1651 comp.docs_emit = .{
1652 .directory = emit_docs.directory orelse artifact_directory,
1653 .sub_path = emit_docs.basename,
1654 };
1655 }
1656 },
1657 .whole => {
1658 // For whole cache mode, we don't know where to put outputs from
1659 // the linker until the final cache hash, which is available after
1660 // the compilation is complete.
1661 //
1662 // Therefore, bin_file is left null until the beginning of update(),
1663 // where it may find a cache hit, or use a temporary directory to
1664 // hold output artifacts.
1665 const whole = try arena.create(CacheUse.Whole);
1666 whole.* = .{
1667 // This is kept here so that link.File.open can be called later.
1668 .lf_open_opts = lf_open_opts,
1669 // This is so that when doing `CacheMode.whole`, the mechanism in update()
1670 // can use it for communicating the result directory via `bin_file.emit`.
1671 // This is used to distinguish between -fno-emit-bin and -femit-bin
1672 // for `CacheMode.whole`.
1673 // This memory will be overwritten with the real digest in update() but
1674 // the basename will be preserved.
1675 .bin_sub_path = try prepareWholeEmitSubPath(arena, options.emit_bin),
1676 .implib_sub_path = try prepareWholeEmitSubPath(arena, options.emit_implib),
1677 .docs_sub_path = try prepareWholeEmitSubPath(arena, options.emit_docs),
1678 .tmp_artifact_directory = null,
1679 .lock = null,
1680 };
1681 comp.cache_use = .{ .whole = whole };
1682 },
1683 }
1684
1685 // Handle the case of e.g. -fno-emit-bin -femit-llvm-ir.
1686 if (options.emit_bin == null and (comp.verbose_llvm_ir != null or
1687 comp.verbose_llvm_bc != null or
1688 (use_llvm and comp.emit_asm != null) or
1689 comp.emit_llvm_ir != null or
1690 comp.emit_llvm_bc != null))
1691 {
1692 if (build_options.only_c) unreachable;
1693 if (opt_zcu) |zcu| zcu.llvm_object = try LlvmObject.create(arena, comp);
1694 }
1695
20081696 break :comp comp;
20091697 };
20101698 errdefer comp.destroy();
20111699
2012 const target = comp.getTarget();
1700 const target = comp.root_mod.resolved_target.result;
20131701
2014 const capable_of_building_compiler_rt = canBuildLibCompilerRt(target, comp.bin_file.options.use_llvm);
2015 const capable_of_building_zig_libc = canBuildZigLibC(target, comp.bin_file.options.use_llvm);
1702 const capable_of_building_compiler_rt = canBuildLibCompilerRt(target, comp.config.use_llvm);
1703 const capable_of_building_zig_libc = canBuildZigLibC(target, comp.config.use_llvm);
20161704
20171705 // Add a `CObject` for each `c_source_files`.
20181706 try comp.c_object_table.ensureTotalCapacity(gpa, options.c_source_files.len);
......@@ -2052,9 +1740,12 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
20521740 }
20531741 }
20541742
2055 const have_bin_emit = comp.bin_file.options.emit != null or comp.whole_bin_sub_path != null;
1743 const have_bin_emit = switch (comp.cache_use) {
1744 .whole => |whole| whole.bin_sub_path != null,
1745 .incremental => comp.bin_file != null,
1746 };
20561747
2057 if (have_bin_emit and !comp.bin_file.options.skip_linker_dependencies and target.ofmt != .c) {
1748 if (have_bin_emit and !comp.skip_linker_dependencies and target.ofmt != .c) {
20581749 if (target.isDarwin()) {
20591750 switch (target.abi) {
20601751 .none,
......@@ -2095,27 +1786,30 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
20951786 .{ .musl_crt_file = .crt1_o },
20961787 .{ .musl_crt_file = .scrt1_o },
20971788 .{ .musl_crt_file = .rcrt1_o },
2098 switch (comp.bin_file.options.link_mode) {
1789 switch (comp.config.link_mode) {
20991790 .Static => .{ .musl_crt_file = .libc_a },
21001791 .Dynamic => .{ .musl_crt_file = .libc_so },
21011792 },
21021793 });
21031794 }
1795
21041796 if (comp.wantBuildWasiLibcFromSource()) {
21051797 if (!target_util.canBuildLibC(target)) return error.LibCUnavailable;
21061798
2107 const wasi_emulated_libs = comp.bin_file.options.wasi_emulated_libs;
2108 try comp.work_queue.ensureUnusedCapacity(wasi_emulated_libs.len + 2); // worst-case we need all components
2109 for (wasi_emulated_libs) |crt_file| {
1799 // worst-case we need all components
1800 try comp.work_queue.ensureUnusedCapacity(comp.wasi_emulated_libs.len + 2);
1801
1802 for (comp.wasi_emulated_libs) |crt_file| {
21101803 comp.work_queue.writeItemAssumeCapacity(.{
21111804 .wasi_libc_crt_file = crt_file,
21121805 });
21131806 }
21141807 comp.work_queue.writeAssumeCapacity(&[_]Job{
2115 .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(wasi_exec_model) },
1808 .{ .wasi_libc_crt_file = wasi_libc.execModelCrtFile(comp.config.wasi_exec_model) },
21161809 .{ .wasi_libc_crt_file = .libc_a },
21171810 });
21181811 }
1812
21191813 if (comp.wantBuildMinGWFromSource()) {
21201814 if (!target_util.canBuildLibC(target)) return error.LibCUnavailable;
21211815
......@@ -2132,7 +1826,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
21321826
21331827 // When linking mingw-w64 there are some import libs we always need.
21341828 for (mingw.always_link_libs) |name| {
2135 try comp.bin_file.options.system_libs.put(comp.gpa, name, .{
1829 try comp.system_libs.put(comp.gpa, name, .{
21361830 .needed = false,
21371831 .weak = false,
21381832 .path = null,
......@@ -2141,7 +1835,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
21411835 }
21421836 // Generate Windows import libs.
21431837 if (target.os.tag == .windows) {
2144 const count = comp.bin_file.options.system_libs.count();
1838 const count = comp.system_libs.count();
21451839 try comp.work_queue.ensureUnusedCapacity(count);
21461840 for (0..count) |i| {
21471841 comp.work_queue.writeItemAssumeCapacity(.{ .windows_import_lib = i });
......@@ -2150,31 +1844,31 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
21501844 if (comp.wantBuildLibUnwindFromSource()) {
21511845 try comp.work_queue.writeItem(.{ .libunwind = {} });
21521846 }
2153 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.bin_file.options.link_libcpp) {
1847 if (build_options.have_llvm and is_exe_or_dyn_lib and comp.config.link_libcpp) {
21541848 try comp.work_queue.writeItem(.libcxx);
21551849 try comp.work_queue.writeItem(.libcxxabi);
21561850 }
2157 if (build_options.have_llvm and comp.bin_file.options.tsan) {
1851 if (build_options.have_llvm and comp.config.any_sanitize_thread) {
21581852 try comp.work_queue.writeItem(.libtsan);
21591853 }
21601854
2161 if (comp.getTarget().isMinGW() and !comp.bin_file.options.single_threaded) {
1855 if (target.isMinGW() and comp.config.any_non_single_threaded) {
21621856 // LLD might drop some symbols as unused during LTO and GCing, therefore,
21631857 // we force mark them for resolution here.
21641858
2165 const tls_index_sym = switch (comp.getTarget().cpu.arch) {
1859 const tls_index_sym = switch (target.cpu.arch) {
21661860 .x86 => "__tls_index",
21671861 else => "_tls_index",
21681862 };
21691863
2170 try comp.bin_file.options.force_undefined_symbols.put(comp.gpa, tls_index_sym, {});
1864 try comp.force_undefined_symbols.put(comp.gpa, tls_index_sym, {});
21711865 }
21721866
2173 if (comp.bin_file.options.include_compiler_rt and capable_of_building_compiler_rt) {
1867 if (comp.include_compiler_rt and capable_of_building_compiler_rt) {
21741868 if (is_exe_or_dyn_lib) {
21751869 log.debug("queuing a job to build compiler_rt_lib", .{});
21761870 comp.job_queued_compiler_rt_lib = true;
2177 } else if (options.output_mode != .Obj) {
1871 } else if (output_mode != .Obj) {
21781872 log.debug("queuing a job to build compiler_rt_obj", .{});
21791873 // In this case we are making a static library, so we ask
21801874 // for a compiler-rt object to put in it.
......@@ -2182,8 +1876,8 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
21821876 }
21831877 }
21841878
2185 if (!comp.bin_file.options.skip_linker_dependencies and is_exe_or_dyn_lib and
2186 !comp.bin_file.options.link_libc and capable_of_building_zig_libc)
1879 if (!comp.skip_linker_dependencies and is_exe_or_dyn_lib and
1880 !comp.config.link_libc and capable_of_building_zig_libc)
21871881 {
21881882 try comp.work_queue.writeItem(.{ .zig_libc = {} });
21891883 }
......@@ -2192,88 +1886,87 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
21921886 return comp;
21931887}
21941888
2195pub fn destroy(self: *Compilation) void {
2196 const optional_module = self.bin_file.options.module;
2197 self.bin_file.destroy();
2198 if (optional_module) |module| module.deinit();
2199
2200 const gpa = self.gpa;
2201 self.work_queue.deinit();
2202 self.anon_work_queue.deinit();
2203 self.c_object_work_queue.deinit();
1889pub fn destroy(comp: *Compilation) void {
1890 if (comp.bin_file) |lf| lf.destroy();
1891 if (comp.module) |zcu| zcu.deinit();
1892 comp.cache_use.deinit();
1893 comp.work_queue.deinit();
1894 comp.anon_work_queue.deinit();
1895 comp.c_object_work_queue.deinit();
22041896 if (!build_options.only_core_functionality) {
2205 self.win32_resource_work_queue.deinit();
1897 comp.win32_resource_work_queue.deinit();
22061898 }
2207 self.astgen_work_queue.deinit();
2208 self.embed_file_work_queue.deinit();
1899 comp.astgen_work_queue.deinit();
1900 comp.embed_file_work_queue.deinit();
1901
1902 const gpa = comp.gpa;
1903 comp.system_libs.deinit(gpa);
22091904
22101905 {
2211 var it = self.crt_files.iterator();
1906 var it = comp.crt_files.iterator();
22121907 while (it.next()) |entry| {
22131908 gpa.free(entry.key_ptr.*);
22141909 entry.value_ptr.deinit(gpa);
22151910 }
2216 self.crt_files.deinit(gpa);
1911 comp.crt_files.deinit(gpa);
22171912 }
22181913
2219 if (self.libunwind_static_lib) |*crt_file| {
1914 if (comp.libunwind_static_lib) |*crt_file| {
22201915 crt_file.deinit(gpa);
22211916 }
2222 if (self.libcxx_static_lib) |*crt_file| {
1917 if (comp.libcxx_static_lib) |*crt_file| {
22231918 crt_file.deinit(gpa);
22241919 }
2225 if (self.libcxxabi_static_lib) |*crt_file| {
1920 if (comp.libcxxabi_static_lib) |*crt_file| {
22261921 crt_file.deinit(gpa);
22271922 }
2228 if (self.compiler_rt_lib) |*crt_file| {
1923 if (comp.compiler_rt_lib) |*crt_file| {
22291924 crt_file.deinit(gpa);
22301925 }
2231 if (self.compiler_rt_obj) |*crt_file| {
1926 if (comp.compiler_rt_obj) |*crt_file| {
22321927 crt_file.deinit(gpa);
22331928 }
2234 if (self.libc_static_lib) |*crt_file| {
1929 if (comp.libc_static_lib) |*crt_file| {
22351930 crt_file.deinit(gpa);
22361931 }
22371932
2238 if (self.glibc_so_files) |*glibc_file| {
1933 if (comp.glibc_so_files) |*glibc_file| {
22391934 glibc_file.deinit(gpa);
22401935 }
22411936
2242 for (self.c_object_table.keys()) |key| {
1937 for (comp.c_object_table.keys()) |key| {
22431938 key.destroy(gpa);
22441939 }
2245 self.c_object_table.deinit(gpa);
1940 comp.c_object_table.deinit(gpa);
22461941
2247 for (self.failed_c_objects.values()) |bundle| {
1942 for (comp.failed_c_objects.values()) |bundle| {
22481943 bundle.destroy(gpa);
22491944 }
2250 self.failed_c_objects.deinit(gpa);
1945 comp.failed_c_objects.deinit(gpa);
22511946
22521947 if (!build_options.only_core_functionality) {
2253 for (self.win32_resource_table.keys()) |key| {
1948 for (comp.win32_resource_table.keys()) |key| {
22541949 key.destroy(gpa);
22551950 }
2256 self.win32_resource_table.deinit(gpa);
1951 comp.win32_resource_table.deinit(gpa);
22571952
2258 for (self.failed_win32_resources.values()) |*value| {
1953 for (comp.failed_win32_resources.values()) |*value| {
22591954 value.deinit(gpa);
22601955 }
2261 self.failed_win32_resources.deinit(gpa);
1956 comp.failed_win32_resources.deinit(gpa);
22621957 }
22631958
2264 for (self.lld_errors.items) |*lld_error| {
1959 for (comp.link_errors.items) |*item| item.deinit(gpa);
1960 comp.link_errors.deinit(gpa);
1961
1962 for (comp.lld_errors.items) |*lld_error| {
22651963 lld_error.deinit(gpa);
22661964 }
2267 self.lld_errors.deinit(gpa);
2268
2269 self.clearMiscFailures();
1965 comp.lld_errors.deinit(gpa);
22701966
2271 self.cache_parent.manifest_dir.close();
2272 if (self.owned_link_dir) |*dir| dir.close();
1967 comp.clearMiscFailures();
22731968
2274 // This destroys `self`.
2275 var arena_instance = self.arena;
2276 arena_instance.deinit();
1969 comp.cache_parent.manifest_dir.close();
22771970}
22781971
22791972pub fn clearMiscFailures(comp: *Compilation) void {
......@@ -2286,135 +1979,142 @@ pub fn clearMiscFailures(comp: *Compilation) void {
22861979}
22871980
22881981pub fn getTarget(self: Compilation) Target {
2289 return self.bin_file.options.target;
1982 return self.root_mod.resolved_target.result;
22901983}
22911984
2292fn restorePrevZigCacheArtifactDirectory(comp: *Compilation, directory: *Directory) void {
2293 if (directory.path) |p| comp.gpa.free(p);
2294
2295 // Restore the Module's previous zig_cache_artifact_directory
2296 // This is only for cleanup purposes; Module.deinit calls close
2297 // on the handle of zig_cache_artifact_directory.
2298 if (comp.bin_file.options.module) |module| {
2299 const builtin_mod = module.main_mod.deps.get("builtin").?;
2300 module.zig_cache_artifact_directory = builtin_mod.root.root_dir;
2301 }
1985/// Only legal to call when cache mode is incremental and a link file is present.
1986pub fn hotCodeSwap(
1987 comp: *Compilation,
1988 prog_node: *std.Progress.Node,
1989 pid: std.ChildProcess.Id,
1990) !void {
1991 const lf = comp.bin_file.?;
1992 lf.child_pid = pid;
1993 try lf.makeWritable();
1994 try comp.update(prog_node);
1995 try lf.makeExecutable();
23021996}
23031997
2304fn cleanupTmpArtifactDirectory(
2305 comp: *Compilation,
2306 tmp_artifact_directory: *?Directory,
2307 tmp_dir_sub_path: []const u8,
2308) void {
2309 comp.gpa.free(tmp_dir_sub_path);
2310 if (tmp_artifact_directory.*) |*directory| {
2311 directory.handle.close();
2312 restorePrevZigCacheArtifactDirectory(comp, directory);
1998fn cleanupAfterUpdate(comp: *Compilation) void {
1999 switch (comp.cache_use) {
2000 .incremental => return,
2001 .whole => |whole| {
2002 if (whole.cache_manifest) |man| {
2003 man.deinit();
2004 whole.cache_manifest = null;
2005 }
2006 if (comp.bin_file) |lf| {
2007 lf.destroy();
2008 comp.bin_file = null;
2009 }
2010 if (whole.tmp_artifact_directory) |*directory| {
2011 directory.handle.close();
2012 if (directory.path) |p| comp.gpa.free(p);
2013 whole.tmp_artifact_directory = null;
2014 }
2015 },
23132016 }
23142017}
23152018
2316pub fn hotCodeSwap(comp: *Compilation, prog_node: *std.Progress.Node, pid: std.ChildProcess.Id) !void {
2317 comp.bin_file.child_pid = pid;
2318 try comp.makeBinFileWritable();
2319 try comp.update(prog_node);
2320 try comp.makeBinFileExecutable();
2321}
2322
23232019/// Detect changes to source files, perform semantic analysis, and update the output files.
23242020pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void {
23252021 const tracy_trace = trace(@src());
23262022 defer tracy_trace.end();
23272023
2024 // This arena is scoped to this one update.
2025 const gpa = comp.gpa;
2026 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
2027 defer arena_allocator.deinit();
2028 const arena = arena_allocator.allocator();
2029
23282030 comp.clearMiscFailures();
23292031 comp.last_update_was_cache_hit = false;
23302032
23312033 var man: Cache.Manifest = undefined;
2332 defer if (comp.whole_cache_manifest != null) man.deinit();
2034 defer cleanupAfterUpdate(comp);
23332035
2334 var tmp_dir_sub_path: []const u8 = &.{};
2335 var tmp_artifact_directory: ?Directory = null;
2336 defer cleanupTmpArtifactDirectory(comp, &tmp_artifact_directory, tmp_dir_sub_path);
2036 var tmp_dir_rand_int: u64 = undefined;
23372037
23382038 // If using the whole caching strategy, we check for *everything* up front, including
23392039 // C source files.
2340 if (comp.bin_file.options.cache_mode == .whole) {
2341 // We are about to obtain this lock, so here we give other processes a chance first.
2342 comp.bin_file.releaseLock();
2343
2344 man = comp.cache_parent.obtain();
2345 comp.whole_cache_manifest = &man;
2346 try comp.addNonIncrementalStuffToCacheManifest(&man);
2347
2348 const is_hit = man.hit() catch |err| {
2349 // TODO properly bubble these up instead of emitting a warning
2350 const i = man.failed_file_index orelse return err;
2351 const pp = man.files.items[i].prefixed_path orelse return err;
2352 const prefix = man.cache.prefixes()[pp.prefix].path orelse "";
2353 std.log.warn("{s}: {s}{s}", .{ @errorName(err), prefix, pp.sub_path });
2354 return err;
2355 };
2356 if (is_hit) {
2357 comp.last_update_was_cache_hit = true;
2358 log.debug("CacheMode.whole cache hit for {s}", .{comp.bin_file.options.root_name});
2359 const digest = man.final();
2360
2361 comp.wholeCacheModeSetBinFilePath(&digest);
2040 switch (comp.cache_use) {
2041 .whole => |whole| {
2042 assert(comp.bin_file == null);
2043 // We are about to obtain this lock, so here we give other processes a chance first.
2044 whole.releaseLock();
2045
2046 man = comp.cache_parent.obtain();
2047 whole.cache_manifest = &man;
2048 try addNonIncrementalStuffToCacheManifest(comp, arena, &man);
2049
2050 const is_hit = man.hit() catch |err| {
2051 const i = man.failed_file_index orelse return err;
2052 const pp = man.files.items[i].prefixed_path orelse return err;
2053 const prefix = man.cache.prefixes()[pp.prefix].path orelse "";
2054 return comp.setMiscFailure(
2055 .check_whole_cache,
2056 "unable to check cache: stat file '{}{s}{s}' failed: {s}",
2057 .{ comp.local_cache_directory, prefix, pp.sub_path, @errorName(err) },
2058 );
2059 };
2060 if (is_hit) {
2061 comp.last_update_was_cache_hit = true;
2062 log.debug("CacheMode.whole cache hit for {s}", .{comp.root_name});
2063 const digest = man.final();
23622064
2363 assert(comp.bin_file.lock == null);
2364 comp.bin_file.lock = man.toOwnedLock();
2365 return;
2366 }
2367 log.debug("CacheMode.whole cache miss for {s}", .{comp.bin_file.options.root_name});
2065 comp.wholeCacheModeSetBinFilePath(whole, &digest);
23682066
2369 // Initialize `bin_file.emit` with a temporary Directory so that compilation can
2370 // continue on the same path as incremental, using the temporary Directory.
2371 tmp_artifact_directory = d: {
2372 const s = std.fs.path.sep_str;
2373 const rand_int = std.crypto.random.int(u64);
2067 assert(whole.lock == null);
2068 whole.lock = man.toOwnedLock();
2069 return;
2070 }
2071 log.debug("CacheMode.whole cache miss for {s}", .{comp.root_name});
23742072
2375 tmp_dir_sub_path = try std.fmt.allocPrint(comp.gpa, "tmp" ++ s ++ "{x}", .{rand_int});
2073 // Compile the artifacts to a temporary directory.
2074 const tmp_artifact_directory = d: {
2075 const s = std.fs.path.sep_str;
2076 tmp_dir_rand_int = std.crypto.random.int(u64);
2077 const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int);
23762078
2377 const path = try comp.local_cache_directory.join(comp.gpa, &.{tmp_dir_sub_path});
2378 errdefer comp.gpa.free(path);
2079 const path = try comp.local_cache_directory.join(gpa, &.{tmp_dir_sub_path});
2080 errdefer gpa.free(path);
23792081
2380 const handle = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
2381 errdefer handle.close();
2082 const handle = try comp.local_cache_directory.handle.makeOpenPath(tmp_dir_sub_path, .{});
2083 errdefer handle.close();
23822084
2383 break :d .{
2384 .path = path,
2385 .handle = handle,
2085 break :d .{
2086 .path = path,
2087 .handle = handle,
2088 };
23862089 };
2387 };
2090 whole.tmp_artifact_directory = tmp_artifact_directory;
23882091
2389 // This updates the output directory for linker outputs.
2390 if (comp.bin_file.options.module) |module| {
2391 module.zig_cache_artifact_directory = tmp_artifact_directory.?;
2392 }
2092 // Now that the directory is known, it is time to create the Emit
2093 // objects and call link.File.open.
23932094
2394 // This resets the link.File to operate as if we called openPath() in create()
2395 // instead of simulating -fno-emit-bin.
2396 var options = comp.bin_file.options.move();
2397 if (comp.whole_bin_sub_path) |sub_path| {
2398 options.emit = .{
2399 .directory = tmp_artifact_directory.?,
2400 .sub_path = std.fs.path.basename(sub_path),
2401 };
2402 }
2403 if (comp.whole_implib_sub_path) |sub_path| {
2404 options.implib_emit = .{
2405 .directory = tmp_artifact_directory.?,
2406 .sub_path = std.fs.path.basename(sub_path),
2407 };
2408 }
2409 if (comp.whole_docs_sub_path) |sub_path| {
2410 options.docs_emit = .{
2411 .directory = tmp_artifact_directory.?,
2412 .sub_path = std.fs.path.basename(sub_path),
2413 };
2414 }
2415 var old_bin_file = comp.bin_file;
2416 comp.bin_file = try link.File.openPath(comp.gpa, options);
2417 old_bin_file.destroy();
2095 if (whole.implib_sub_path) |sub_path| {
2096 comp.implib_emit = .{
2097 .directory = tmp_artifact_directory,
2098 .sub_path = std.fs.path.basename(sub_path),
2099 };
2100 }
2101
2102 if (whole.docs_sub_path) |sub_path| {
2103 comp.docs_emit = .{
2104 .directory = tmp_artifact_directory,
2105 .sub_path = std.fs.path.basename(sub_path),
2106 };
2107 }
2108
2109 if (whole.bin_sub_path) |sub_path| {
2110 const emit: Emit = .{
2111 .directory = tmp_artifact_directory,
2112 .sub_path = std.fs.path.basename(sub_path),
2113 };
2114 comp.bin_file = try link.File.createEmpty(arena, comp, emit, whole.lf_open_opts);
2115 }
2116 },
2117 .incremental => {},
24182118 }
24192119
24202120 // For compiling C objects, we rely on the cache hash system to avoid duplicating work.
......@@ -2433,13 +2133,13 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
24332133 }
24342134 }
24352135
2436 if (comp.bin_file.options.module) |module| {
2437 module.compile_log_text.shrinkAndFree(module.gpa, 0);
2136 if (comp.module) |module| {
2137 module.compile_log_text.shrinkAndFree(gpa, 0);
24382138 module.generation += 1;
24392139
24402140 // Make sure std.zig is inside the import_table. We unconditionally need
24412141 // it for start.zig.
2442 const std_mod = module.main_mod.deps.get("std").?;
2142 const std_mod = module.std_mod;
24432143 _ = try module.importPkg(std_mod);
24442144
24452145 // Normally we rely on importing std to in turn import the root source file
......@@ -2448,22 +2148,21 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
24482148 // import_table here.
24492149 // Likewise, in the case of `zig test`, the test runner is the root source file,
24502150 // and so there is nothing to import the main file.
2451 if (comp.bin_file.options.is_test) {
2151 if (comp.config.is_test) {
24522152 _ = try module.importPkg(module.main_mod);
24532153 }
24542154
2455 if (module.main_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
2155 if (module.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
24562156 _ = try module.importPkg(compiler_rt_mod);
24572157 }
24582158
24592159 // Put a work item in for every known source file to detect if
24602160 // it changed, and, if so, re-compute ZIR and then queue the job
24612161 // to update it.
2462 // We still want AstGen work items for stage1 so that we expose compile errors
2463 // that are implemented in stage2 but not stage1.
24642162 try comp.astgen_work_queue.ensureUnusedCapacity(module.import_table.count());
2465 for (module.import_table.values()) |value| {
2466 comp.astgen_work_queue.writeItemAssumeCapacity(value);
2163 for (module.import_table.values()) |file| {
2164 if (file.mod.isBuiltin()) continue;
2165 comp.astgen_work_queue.writeItemAssumeCapacity(file);
24672166 }
24682167
24692168 // Put a work item in for checking if any files used with `@embedFile` changed.
......@@ -2473,34 +2172,34 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
24732172 }
24742173
24752174 try comp.work_queue.writeItem(.{ .analyze_mod = std_mod });
2476 if (comp.bin_file.options.is_test) {
2175 if (comp.config.is_test) {
24772176 try comp.work_queue.writeItem(.{ .analyze_mod = module.main_mod });
24782177 }
24792178
2480 if (module.main_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
2179 if (module.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
24812180 try comp.work_queue.writeItem(.{ .analyze_mod = compiler_rt_mod });
24822181 }
24832182 }
24842183
24852184 try comp.performAllTheWork(main_progress_node);
24862185
2487 if (comp.bin_file.options.module) |module| {
2186 if (comp.module) |module| {
24882187 if (builtin.mode == .Debug and comp.verbose_intern_pool) {
24892188 std.debug.print("intern pool stats for '{s}':\n", .{
2490 comp.bin_file.options.root_name,
2189 comp.root_name,
24912190 });
24922191 module.intern_pool.dump();
24932192 }
24942193
24952194 if (builtin.mode == .Debug and comp.verbose_generic_instances) {
24962195 std.debug.print("generic instances for '{s}:0x{x}':\n", .{
2497 comp.bin_file.options.root_name,
2196 comp.root_name,
24982197 @as(usize, @intFromPtr(module)),
24992198 });
2500 module.intern_pool.dumpGenericInstances(comp.gpa);
2199 module.intern_pool.dumpGenericInstances(gpa);
25012200 }
25022201
2503 if (comp.bin_file.options.is_test and comp.totalErrorCount() == 0) {
2202 if (comp.config.is_test and comp.totalErrorCount() == 0) {
25042203 // The `test_functions` decl has been intentionally postponed until now,
25052204 // at which point we must populate it with the list of test functions that
25062205 // have been discovered and not filtered out.
......@@ -2516,106 +2215,188 @@ pub fn update(comp: *Compilation, main_progress_node: *std.Progress.Node) !void
25162215 return;
25172216 }
25182217
2519 // Flush takes care of -femit-bin, but we still have -femit-llvm-ir, -femit-llvm-bc, and
2520 // -femit-asm to handle, in the case of C objects.
2218 // Flush below handles -femit-bin but there is still -femit-llvm-ir,
2219 // -femit-llvm-bc, and -femit-asm, in the case of C objects.
25212220 comp.emitOthers();
25222221
2523 if (comp.whole_cache_manifest != null) {
2524 const digest = man.final();
2222 switch (comp.cache_use) {
2223 .whole => |whole| {
2224 const digest = man.final();
25252225
2526 // Rename the temporary directory into place.
2527 var directory = tmp_artifact_directory.?;
2528 tmp_artifact_directory = null;
2529
2530 directory.handle.close();
2531 defer restorePrevZigCacheArtifactDirectory(comp, &directory);
2532
2533 const o_sub_path = try std.fs.path.join(comp.gpa, &[_][]const u8{ "o", &digest });
2534 defer comp.gpa.free(o_sub_path);
2535
2536 // Work around windows `AccessDenied` if any files within this directory are open
2537 // by closing and reopening the file handles.
2538 const need_writable_dance = builtin.os.tag == .windows and comp.bin_file.file != null;
2539 if (need_writable_dance) {
2540 // We cannot just call `makeExecutable` as it makes a false assumption that we have a
2541 // file handle open only when linking an executable file. This used to be true when
2542 // our linkers were incapable of emitting relocatables and static archive. Now that
2543 // they are capable, we need to unconditionally close the file handle and re-open it
2544 // in the follow up call to `makeWritable`.
2545 comp.bin_file.file.?.close();
2546 comp.bin_file.file = null;
2547 }
2226 // Rename the temporary directory into place.
2227 // Close tmp dir and link.File to avoid open handle during rename.
2228 if (whole.tmp_artifact_directory) |*tmp_directory| {
2229 tmp_directory.handle.close();
2230 if (tmp_directory.path) |p| gpa.free(p);
2231 whole.tmp_artifact_directory = null;
2232 } else unreachable;
25482233
2549 try comp.bin_file.renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path);
2550 comp.wholeCacheModeSetBinFilePath(&digest);
2234 const s = std.fs.path.sep_str;
2235 const tmp_dir_sub_path = "tmp" ++ s ++ Package.Manifest.hex64(tmp_dir_rand_int);
2236 const o_sub_path = "o" ++ s ++ digest;
2237
2238 // Work around windows `AccessDenied` if any files within this
2239 // directory are open by closing and reopening the file handles.
2240 const need_writable_dance = w: {
2241 if (builtin.os.tag == .windows) {
2242 if (comp.bin_file) |lf| {
2243 // We cannot just call `makeExecutable` as it makes a false
2244 // assumption that we have a file handle open only when linking
2245 // an executable file. This used to be true when our linkers
2246 // were incapable of emitting relocatables and static archive.
2247 // Now that they are capable, we need to unconditionally close
2248 // the file handle and re-open it in the follow up call to
2249 // `makeWritable`.
2250 if (lf.file) |f| {
2251 f.close();
2252 lf.file = null;
2253 break :w true;
2254 }
2255 }
2256 }
2257 break :w false;
2258 };
25512259
2552 // Has to be after the `wholeCacheModeSetBinFilePath` above.
2553 if (need_writable_dance) {
2554 try comp.bin_file.makeWritable();
2555 }
2260 renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path) catch |err| {
2261 return comp.setMiscFailure(
2262 .rename_results,
2263 "failed to rename compilation results ('{}{s}') into local cache ('{}{s}'): {s}",
2264 .{
2265 comp.local_cache_directory, tmp_dir_sub_path,
2266 comp.local_cache_directory, o_sub_path,
2267 @errorName(err),
2268 },
2269 );
2270 };
2271 comp.wholeCacheModeSetBinFilePath(whole, &digest);
2272
2273 // The linker flush functions need to know the final output path
2274 // for debug info purposes because executable debug info contains
2275 // references object file paths.
2276 if (comp.bin_file) |lf| {
2277 lf.emit = .{
2278 .directory = comp.local_cache_directory,
2279 .sub_path = whole.bin_sub_path.?,
2280 };
25562281
2557 // This is intentionally sandwiched between renameTmpIntoCache() and writeManifest().
2558 if (comp.bin_file.options.module) |module| {
2559 // We need to set the zig_cache_artifact_directory for -femit-asm, -femit-llvm-ir,
2560 // etc to know where to output to.
2561 var artifact_dir = try comp.local_cache_directory.handle.openDir(o_sub_path, .{});
2562 defer artifact_dir.close();
2282 // Has to be after the `wholeCacheModeSetBinFilePath` above.
2283 if (need_writable_dance) {
2284 try lf.makeWritable();
2285 }
2286 }
25632287
2564 const dir_path = try comp.local_cache_directory.join(comp.gpa, &.{o_sub_path});
2565 defer comp.gpa.free(dir_path);
2288 try flush(comp, arena, main_progress_node);
2289 if (comp.totalErrorCount() != 0) return;
25662290
2567 module.zig_cache_artifact_directory = .{
2568 .handle = artifact_dir,
2569 .path = dir_path,
2291 // Failure here only means an unnecessary cache miss.
2292 man.writeManifest() catch |err| {
2293 log.warn("failed to write cache manifest: {s}", .{@errorName(err)});
25702294 };
25712295
2572 try comp.flush(main_progress_node);
2573 if (comp.totalErrorCount() != 0) return;
2296 if (comp.bin_file) |lf| {
2297 lf.destroy();
2298 comp.bin_file = null;
2299 }
25742300
2575 // Note the placement of this logic is relying on the call to
2576 // `wholeCacheModeSetBinFilePath` above.
2577 try maybeGenerateAutodocs(comp, main_progress_node);
2578 } else {
2579 try comp.flush(main_progress_node);
2301 assert(whole.lock == null);
2302 whole.lock = man.toOwnedLock();
2303 },
2304 .incremental => {
2305 try flush(comp, arena, main_progress_node);
25802306 if (comp.totalErrorCount() != 0) return;
2581 }
2307 },
2308 }
2309}
25822310
2583 // Failure here only means an unnecessary cache miss.
2584 man.writeManifest() catch |err| {
2585 log.warn("failed to write cache manifest: {s}", .{@errorName(err)});
2311fn flush(comp: *Compilation, arena: Allocator, prog_node: *std.Progress.Node) !void {
2312 if (comp.bin_file) |lf| {
2313 // This is needed before reading the error flags.
2314 lf.flush(arena, prog_node) catch |err| switch (err) {
2315 error.FlushFailure => {}, // error reported through link_error_flags
2316 error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
2317 else => |e| return e,
25862318 };
2319 }
25872320
2588 assert(comp.bin_file.lock == null);
2589 comp.bin_file.lock = man.toOwnedLock();
2590 } else {
2591 try comp.flush(main_progress_node);
2321 if (comp.module) |zcu| {
2322 try link.File.C.flushEmitH(zcu);
25922323
2593 if (comp.totalErrorCount() == 0) {
2594 try maybeGenerateAutodocs(comp, main_progress_node);
2324 if (zcu.llvm_object) |llvm_object| {
2325 if (build_options.only_c) unreachable;
2326 const default_emit = switch (comp.cache_use) {
2327 .whole => |whole| .{
2328 .directory = whole.tmp_artifact_directory.?,
2329 .sub_path = "dummy",
2330 },
2331 .incremental => |incremental| .{
2332 .directory = incremental.artifact_directory,
2333 .sub_path = "dummy",
2334 },
2335 };
2336 try emitLlvmObject(comp, arena, default_emit, null, llvm_object, prog_node);
25952337 }
25962338 }
25972339
2598 // Unload all source files to save memory.
2599 // The ZIR needs to stay loaded in memory because (1) Decl objects contain references
2600 // to it, and (2) generic instantiations, comptime calls, inline calls will need
2601 // to reference the ZIR.
2602 if (!comp.keep_source_files_loaded) {
2603 if (comp.bin_file.options.module) |module| {
2604 for (module.import_table.values()) |file| {
2605 file.unloadTree(comp.gpa);
2606 file.unloadSource(comp.gpa);
2607 }
2608 }
2340 if (comp.totalErrorCount() == 0) {
2341 try maybeGenerateAutodocs(comp, prog_node);
2342 }
2343}
2344
2345/// This function is called by the frontend before flush(). It communicates that
2346/// `options.bin_file.emit` directory needs to be renamed from
2347/// `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`.
2348/// The frontend would like to simply perform a file system rename, however,
2349/// some linker backends care about the file paths of the objects they are linking.
2350/// So this function call tells linker backends to rename the paths of object files
2351/// to observe the new directory path.
2352/// Linker backends which do not have this requirement can fall back to the simple
2353/// implementation at the bottom of this function.
2354/// This function is only called when CacheMode is `whole`.
2355fn renameTmpIntoCache(
2356 cache_directory: Compilation.Directory,
2357 tmp_dir_sub_path: []const u8,
2358 o_sub_path: []const u8,
2359) !void {
2360 var seen_eaccess = false;
2361 while (true) {
2362 std.fs.rename(
2363 cache_directory.handle,
2364 tmp_dir_sub_path,
2365 cache_directory.handle,
2366 o_sub_path,
2367 ) catch |err| switch (err) {
2368 // On Windows, rename fails with `AccessDenied` rather than `PathAlreadyExists`.
2369 // See https://github.com/ziglang/zig/issues/8362
2370 error.AccessDenied => switch (builtin.os.tag) {
2371 .windows => {
2372 if (!seen_eaccess) return error.AccessDenied;
2373 seen_eaccess = true;
2374 try cache_directory.handle.deleteTree(o_sub_path);
2375 continue;
2376 },
2377 else => return error.AccessDenied,
2378 },
2379 error.PathAlreadyExists => {
2380 try cache_directory.handle.deleteTree(o_sub_path);
2381 continue;
2382 },
2383 error.FileNotFound => {
2384 try cache_directory.handle.makePath("o");
2385 continue;
2386 },
2387 else => |e| return e,
2388 };
2389 break;
26092390 }
26102391}
26112392
26122393fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !void {
2613 const mod = comp.bin_file.options.module orelse return;
2394 const mod = comp.module orelse return;
26142395 // TODO: do this in a separate job during performAllTheWork(). The
26152396 // file copies at the end of generate() can also be extracted to
26162397 // separate jobs
26172398 if (!build_options.only_c and !build_options.only_core_functionality) {
2618 if (comp.bin_file.options.docs_emit) |emit| {
2399 if (comp.docs_emit) |emit| {
26192400 var dir = try emit.directory.handle.makeOpenPath(emit.sub_path, .{});
26202401 defer dir.close();
26212402
......@@ -2629,46 +2410,31 @@ fn maybeGenerateAutodocs(comp: *Compilation, prog_node: *std.Progress.Node) !voi
26292410 }
26302411}
26312412
2632fn flush(comp: *Compilation, prog_node: *std.Progress.Node) !void {
2633 // This is needed before reading the error flags.
2634 comp.bin_file.flush(comp, prog_node) catch |err| switch (err) {
2635 error.FlushFailure => {}, // error reported through link_error_flags
2636 error.LLDReportedFailure => {}, // error reported via lockAndParseLldStderr
2637 else => |e| return e,
2638 };
2639 comp.link_error_flags = comp.bin_file.errorFlags();
2640
2641 if (comp.bin_file.options.module) |module| {
2642 try link.File.C.flushEmitH(module);
2643 }
2644}
2645
26462413/// Communicate the output binary location to parent Compilations.
2647fn wholeCacheModeSetBinFilePath(comp: *Compilation, digest: *const [Cache.hex_digest_len]u8) void {
2414fn wholeCacheModeSetBinFilePath(
2415 comp: *Compilation,
2416 whole: *CacheUse.Whole,
2417 digest: *const [Cache.hex_digest_len]u8,
2418) void {
26482419 const digest_start = 2; // "o/[digest]/[basename]"
26492420
2650 if (comp.whole_bin_sub_path) |sub_path| {
2421 if (whole.bin_sub_path) |sub_path| {
26512422 @memcpy(sub_path[digest_start..][0..digest.len], digest);
2652
2653 comp.bin_file.options.emit = .{
2654 .directory = comp.local_cache_directory,
2655 .sub_path = sub_path,
2656 };
26572423 }
26582424
2659 if (comp.whole_implib_sub_path) |sub_path| {
2425 if (whole.implib_sub_path) |sub_path| {
26602426 @memcpy(sub_path[digest_start..][0..digest.len], digest);
26612427
2662 comp.bin_file.options.implib_emit = .{
2428 comp.implib_emit = .{
26632429 .directory = comp.local_cache_directory,
26642430 .sub_path = sub_path,
26652431 };
26662432 }
26672433
2668 if (comp.whole_docs_sub_path) |sub_path| {
2434 if (whole.docs_sub_path) |sub_path| {
26692435 @memcpy(sub_path[digest_start..][0..digest.len], digest);
26702436
2671 comp.bin_file.options.docs_emit = .{
2437 comp.docs_emit = .{
26722438 .directory = comp.local_cache_directory,
26732439 .sub_path = sub_path,
26742440 };
......@@ -2689,51 +2455,33 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo
26892455/// anything from the link cache manifest.
26902456pub const link_hash_implementation_version = 10;
26912457
2692fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void {
2458fn addNonIncrementalStuffToCacheManifest(
2459 comp: *Compilation,
2460 arena: Allocator,
2461 man: *Cache.Manifest,
2462) !void {
26932463 const gpa = comp.gpa;
2694 const target = comp.getTarget();
2695
2696 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
2697 defer arena_allocator.deinit();
2698 const arena = arena_allocator.allocator();
26992464
27002465 comptime assert(link_hash_implementation_version == 10);
27012466
2702 if (comp.bin_file.options.module) |mod| {
2467 if (comp.module) |mod| {
27032468 const main_zig_file = try mod.main_mod.root.joinString(arena, mod.main_mod.root_src_path);
27042469 _ = try man.addFile(main_zig_file, null);
2705 {
2706 var seen_table = std.AutoHashMap(*Package.Module, void).init(arena);
2707
2708 // Skip builtin.zig; it is useless as an input, and we don't want to have to
2709 // write it before checking for a cache hit.
2710 const builtin_mod = mod.main_mod.deps.get("builtin").?;
2711 try seen_table.put(builtin_mod, {});
2712
2713 try addModuleTableToCacheHash(&man.hash, &arena_allocator, mod.main_mod.deps, &seen_table, .{ .files = man });
2714 }
2470 try addModuleTableToCacheHash(gpa, arena, &man.hash, mod.main_mod, .{ .files = man });
27152471
27162472 // Synchronize with other matching comments: ZigOnlyHashStuff
2717 man.hash.add(comp.bin_file.options.valgrind);
2718 man.hash.add(comp.bin_file.options.single_threaded);
2719 man.hash.add(comp.bin_file.options.use_llvm);
2720 man.hash.add(comp.bin_file.options.use_lib_llvm);
2721 man.hash.add(comp.bin_file.options.dll_export_fns);
2722 man.hash.add(comp.bin_file.options.is_test);
2723 man.hash.add(comp.test_evented_io);
2473 man.hash.add(comp.config.test_evented_io);
27242474 man.hash.addOptionalBytes(comp.test_filter);
27252475 man.hash.addOptionalBytes(comp.test_name_prefix);
2726 man.hash.add(comp.bin_file.options.skip_linker_dependencies);
2476 man.hash.add(comp.skip_linker_dependencies);
27272477 man.hash.add(comp.formatted_panics);
27282478 man.hash.add(mod.emit_h != null);
27292479 man.hash.add(mod.error_limit);
2730 man.hash.addOptional(comp.bin_file.options.want_structured_cfg);
2480 } else {
2481 cache_helpers.addModule(&man.hash, comp.root_mod);
27312482 }
27322483
2733 try man.addOptionalFile(comp.bin_file.options.linker_script);
2734 try man.addOptionalFile(comp.bin_file.options.version_script);
2735
2736 for (comp.bin_file.options.objects) |obj| {
2484 for (comp.objects) |obj| {
27372485 _ = try man.addFile(obj.path, null);
27382486 man.hash.add(obj.must_link);
27392487 man.hash.add(obj.loption);
......@@ -2759,88 +2507,99 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes
27592507 }
27602508 }
27612509
2510 man.hash.add(comp.config.use_llvm);
2511 man.hash.add(comp.config.use_lib_llvm);
2512 man.hash.add(comp.config.is_test);
2513 man.hash.add(comp.config.import_memory);
2514 man.hash.add(comp.config.export_memory);
2515 man.hash.add(comp.config.shared_memory);
2516 man.hash.add(comp.config.dll_export_fns);
2517 man.hash.add(comp.config.rdynamic);
2518
2519 man.hash.addOptionalBytes(comp.sysroot);
2520 man.hash.addOptional(comp.version);
2521 man.hash.add(comp.link_eh_frame_hdr);
2522 man.hash.add(comp.skip_linker_dependencies);
2523 man.hash.add(comp.include_compiler_rt);
27622524 man.hash.addListOfBytes(comp.rc_include_dir_list);
2525 man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
2526 man.hash.addListOfBytes(comp.framework_dirs);
2527 try link.hashAddSystemLibs(man, comp.system_libs);
27632528
27642529 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_asm);
27652530 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_ir);
27662531 cache_helpers.addOptionalEmitLoc(&man.hash, comp.emit_llvm_bc);
27672532
2768 man.hash.addListOfBytes(comp.clang_argv);
2769
2770 man.hash.addOptional(comp.bin_file.options.stack_size_override);
2771 man.hash.addOptional(comp.bin_file.options.image_base_override);
2772 man.hash.addOptional(comp.bin_file.options.gc_sections);
2773 man.hash.add(comp.bin_file.options.eh_frame_hdr);
2774 man.hash.add(comp.bin_file.options.emit_relocs);
2775 man.hash.add(comp.bin_file.options.rdynamic);
2776 man.hash.addListOfBytes(comp.bin_file.options.lib_dirs);
2777 man.hash.addListOfBytes(comp.bin_file.options.rpath_list);
2778 man.hash.addListOfBytes(comp.bin_file.options.symbol_wrap_set.keys());
2779 man.hash.add(comp.bin_file.options.each_lib_rpath);
2780 man.hash.add(comp.bin_file.options.build_id);
2781 man.hash.add(comp.bin_file.options.skip_linker_dependencies);
2782 man.hash.add(comp.bin_file.options.z_nodelete);
2783 man.hash.add(comp.bin_file.options.z_notext);
2784 man.hash.add(comp.bin_file.options.z_defs);
2785 man.hash.add(comp.bin_file.options.z_origin);
2786 man.hash.add(comp.bin_file.options.z_nocopyreloc);
2787 man.hash.add(comp.bin_file.options.z_now);
2788 man.hash.add(comp.bin_file.options.z_relro);
2789 man.hash.add(comp.bin_file.options.z_common_page_size orelse 0);
2790 man.hash.add(comp.bin_file.options.z_max_page_size orelse 0);
2791 man.hash.add(comp.bin_file.options.hash_style);
2792 man.hash.add(comp.bin_file.options.compress_debug_sections);
2793 man.hash.add(comp.bin_file.options.include_compiler_rt);
2794 man.hash.addOptional(comp.bin_file.options.sort_section);
2795 if (comp.bin_file.options.link_libc) {
2796 man.hash.add(comp.bin_file.options.libc_installation != null);
2797 if (comp.bin_file.options.libc_installation) |libc_installation| {
2533 man.hash.addListOfBytes(comp.global_cc_argv);
2534
2535 const opts = comp.cache_use.whole.lf_open_opts;
2536
2537 try man.addOptionalFile(opts.linker_script);
2538 try man.addOptionalFile(opts.version_script);
2539
2540 man.hash.addOptional(opts.stack_size);
2541 man.hash.addOptional(opts.image_base);
2542 man.hash.addOptional(opts.gc_sections);
2543 man.hash.add(opts.emit_relocs);
2544 man.hash.addListOfBytes(opts.lib_dirs);
2545 man.hash.addListOfBytes(opts.rpath_list);
2546 man.hash.addListOfBytes(opts.symbol_wrap_set.keys());
2547 man.hash.add(opts.each_lib_rpath);
2548 if (comp.config.link_libc) {
2549 man.hash.add(comp.libc_installation != null);
2550 const target = comp.root_mod.resolved_target.result;
2551 if (comp.libc_installation) |libc_installation| {
27982552 man.hash.addOptionalBytes(libc_installation.crt_dir);
27992553 if (target.abi == .msvc) {
28002554 man.hash.addOptionalBytes(libc_installation.msvc_lib_dir);
28012555 man.hash.addOptionalBytes(libc_installation.kernel32_lib_dir);
28022556 }
28032557 }
2804 man.hash.addOptionalBytes(comp.bin_file.options.dynamic_linker);
2805 }
2806 man.hash.addOptionalBytes(comp.bin_file.options.soname);
2807 man.hash.addOptional(comp.bin_file.options.version);
2808 try link.hashAddSystemLibs(man, comp.bin_file.options.system_libs);
2809 man.hash.addListOfBytes(comp.bin_file.options.force_undefined_symbols.keys());
2810 man.hash.addOptional(comp.bin_file.options.allow_shlib_undefined);
2811 man.hash.add(comp.bin_file.options.bind_global_refs_locally);
2812 man.hash.add(comp.bin_file.options.tsan);
2813 man.hash.addOptionalBytes(comp.bin_file.options.sysroot);
2814 man.hash.add(comp.bin_file.options.linker_optimization);
2558 man.hash.addOptionalBytes(target.dynamic_linker.get());
2559 }
2560 man.hash.addOptional(opts.allow_shlib_undefined);
2561 man.hash.add(opts.bind_global_refs_locally);
2562
2563 // ELF specific stuff
2564 man.hash.add(opts.z_nodelete);
2565 man.hash.add(opts.z_notext);
2566 man.hash.add(opts.z_defs);
2567 man.hash.add(opts.z_origin);
2568 man.hash.add(opts.z_nocopyreloc);
2569 man.hash.add(opts.z_now);
2570 man.hash.add(opts.z_relro);
2571 man.hash.add(opts.z_common_page_size orelse 0);
2572 man.hash.add(opts.z_max_page_size orelse 0);
2573 man.hash.add(opts.hash_style);
2574 man.hash.add(opts.compress_debug_sections);
2575 man.hash.addOptional(opts.sort_section);
2576 man.hash.addOptionalBytes(opts.soname);
2577 man.hash.add(opts.build_id);
28152578
28162579 // WASM specific stuff
2817 man.hash.add(comp.bin_file.options.import_memory);
2818 man.hash.add(comp.bin_file.options.export_memory);
2819 man.hash.addOptional(comp.bin_file.options.initial_memory);
2820 man.hash.addOptional(comp.bin_file.options.max_memory);
2821 man.hash.add(comp.bin_file.options.shared_memory);
2822 man.hash.addOptional(comp.bin_file.options.global_base);
2580 man.hash.addOptional(opts.initial_memory);
2581 man.hash.addOptional(opts.max_memory);
2582 man.hash.addOptional(opts.global_base);
28232583
28242584 // Mach-O specific stuff
2825 man.hash.addListOfBytes(comp.bin_file.options.framework_dirs);
2826 try link.hashAddFrameworks(man, comp.bin_file.options.frameworks);
2827 try man.addOptionalFile(comp.bin_file.options.entitlements);
2828 man.hash.addOptional(comp.bin_file.options.pagezero_size);
2829 man.hash.addOptional(comp.bin_file.options.headerpad_size);
2830 man.hash.add(comp.bin_file.options.headerpad_max_install_names);
2831 man.hash.add(comp.bin_file.options.dead_strip_dylibs);
2585 try link.File.MachO.hashAddFrameworks(man, opts.frameworks);
2586 try man.addOptionalFile(opts.entitlements);
2587 man.hash.addOptional(opts.pagezero_size);
2588 man.hash.addOptional(opts.headerpad_size);
2589 man.hash.add(opts.headerpad_max_install_names);
2590 man.hash.add(opts.dead_strip_dylibs);
28322591
28332592 // COFF specific stuff
2834 man.hash.addOptional(comp.bin_file.options.subsystem);
2835 man.hash.add(comp.bin_file.options.tsaware);
2836 man.hash.add(comp.bin_file.options.nxcompat);
2837 man.hash.add(comp.bin_file.options.dynamicbase);
2838 man.hash.addOptional(comp.bin_file.options.major_subsystem_version);
2839 man.hash.addOptional(comp.bin_file.options.minor_subsystem_version);
2593 man.hash.addOptional(opts.subsystem);
2594 man.hash.add(opts.tsaware);
2595 man.hash.add(opts.nxcompat);
2596 man.hash.add(opts.dynamicbase);
2597 man.hash.addOptional(opts.major_subsystem_version);
2598 man.hash.addOptional(opts.minor_subsystem_version);
28402599}
28412600
28422601fn emitOthers(comp: *Compilation) void {
2843 if (comp.bin_file.options.output_mode != .Obj or comp.bin_file.options.module != null or
2602 if (comp.config.output_mode != .Obj or comp.module != null or
28442603 comp.c_object_table.count() == 0)
28452604 {
28462605 return;
......@@ -2877,6 +2636,50 @@ fn emitOthers(comp: *Compilation) void {
28772636 }
28782637}
28792638
2639pub fn emitLlvmObject(
2640 comp: *Compilation,
2641 arena: Allocator,
2642 default_emit: Emit,
2643 bin_emit_loc: ?EmitLoc,
2644 llvm_object: *LlvmObject,
2645 prog_node: *std.Progress.Node,
2646) !void {
2647 if (build_options.only_c) @compileError("unreachable");
2648
2649 var sub_prog_node = prog_node.start("LLVM Emit Object", 0);
2650 sub_prog_node.activate();
2651 sub_prog_node.context.refresh();
2652 defer sub_prog_node.end();
2653
2654 try llvm_object.emit(.{
2655 .pre_ir_path = comp.verbose_llvm_ir,
2656 .pre_bc_path = comp.verbose_llvm_bc,
2657 .bin_path = try resolveEmitLoc(arena, default_emit, bin_emit_loc),
2658 .asm_path = try resolveEmitLoc(arena, default_emit, comp.emit_asm),
2659 .post_ir_path = try resolveEmitLoc(arena, default_emit, comp.emit_llvm_ir),
2660 .post_bc_path = try resolveEmitLoc(arena, default_emit, comp.emit_llvm_bc),
2661
2662 .is_debug = comp.root_mod.optimize_mode == .Debug,
2663 .is_small = comp.root_mod.optimize_mode == .ReleaseSmall,
2664 .time_report = comp.time_report,
2665 .sanitize_thread = comp.config.any_sanitize_thread,
2666 .lto = comp.config.lto,
2667 });
2668}
2669
2670fn resolveEmitLoc(
2671 arena: Allocator,
2672 default_emit: Emit,
2673 opt_loc: ?EmitLoc,
2674) Allocator.Error!?[*:0]const u8 {
2675 const loc = opt_loc orelse return null;
2676 const slice = if (loc.directory) |directory|
2677 try directory.joinZ(arena, &.{loc.basename})
2678 else
2679 try default_emit.basenamePath(arena, loc.basename);
2680 return slice.ptr;
2681}
2682
28802683fn reportMultiModuleErrors(mod: *Module) !void {
28812684 // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to
28822685 // print all of, so we'll cap the number of these to emit.
......@@ -2982,12 +2785,14 @@ fn reportMultiModuleErrors(mod: *Module) !void {
29822785/// binary is concerned. This will remove the write flag, or close the file,
29832786/// or whatever is needed so that it can be executed.
29842787/// After this, one must call` makeFileWritable` before calling `update`.
2985pub fn makeBinFileExecutable(self: *Compilation) !void {
2986 return self.bin_file.makeExecutable();
2788pub fn makeBinFileExecutable(comp: *Compilation) !void {
2789 const lf = comp.bin_file orelse return;
2790 return lf.makeExecutable();
29872791}
29882792
2989pub fn makeBinFileWritable(self: *Compilation) !void {
2990 return self.bin_file.makeWritable();
2793pub fn makeBinFileWritable(comp: *Compilation) !void {
2794 const lf = comp.bin_file orelse return;
2795 return lf.makeWritable();
29912796}
29922797
29932798const Header = extern struct {
......@@ -3006,10 +2811,10 @@ pub fn saveState(comp: *Compilation) !void {
30062811 var bufs_list: [6]std.os.iovec_const = undefined;
30072812 var bufs_len: usize = 0;
30082813
3009 const emit = comp.bin_file.options.emit orelse return;
2814 const lf = comp.bin_file orelse return;
30102815
3011 if (comp.bin_file.options.module) |mod| {
3012 const ip = &mod.intern_pool;
2816 if (comp.module) |zcu| {
2817 const ip = &zcu.intern_pool;
30132818 const header: Header = .{
30142819 .intern_pool = .{
30152820 .items_len = @intCast(ip.items.len),
......@@ -3033,7 +2838,7 @@ pub fn saveState(comp: *Compilation) !void {
30332838 }
30342839 var basename_buf: [255]u8 = undefined;
30352840 const basename = std.fmt.bufPrint(&basename_buf, "{s}.zcs", .{
3036 comp.bin_file.options.root_name,
2841 comp.root_name,
30372842 }) catch o: {
30382843 basename_buf[basename_buf.len - 4 ..].* = ".zcs".*;
30392844 break :o &basename_buf;
......@@ -3041,7 +2846,7 @@ pub fn saveState(comp: *Compilation) !void {
30412846
30422847 // Using an atomic file prevents a crash or power failure from corrupting
30432848 // the previous incremental compilation state.
3044 var af = try emit.directory.handle.atomicFile(basename, .{});
2849 var af = try lf.emit.directory.handle.atomicFile(basename, .{});
30452850 defer af.deinit();
30462851 try af.file.pwritevAll(bufs_list[0..bufs_len], 0);
30472852 try af.finish();
......@@ -3057,23 +2862,23 @@ fn addBuf(bufs_list: []std.os.iovec_const, bufs_len: *usize, buf: []const u8) vo
30572862}
30582863
30592864/// This function is temporally single-threaded.
3060pub fn totalErrorCount(self: *Compilation) u32 {
2865pub fn totalErrorCount(comp: *Compilation) u32 {
30612866 var total: usize =
3062 self.misc_failures.count() +
3063 @intFromBool(self.alloc_failure_occurred) +
3064 self.lld_errors.items.len;
2867 comp.misc_failures.count() +
2868 @intFromBool(comp.alloc_failure_occurred) +
2869 comp.lld_errors.items.len;
30652870
3066 for (self.failed_c_objects.values()) |bundle| {
2871 for (comp.failed_c_objects.values()) |bundle| {
30672872 total += bundle.diags.len;
30682873 }
30692874
30702875 if (!build_options.only_core_functionality) {
3071 for (self.failed_win32_resources.values()) |errs| {
2876 for (comp.failed_win32_resources.values()) |errs| {
30722877 total += errs.errorMessageCount();
30732878 }
30742879 }
30752880
3076 if (self.bin_file.options.module) |module| {
2881 if (comp.module) |module| {
30772882 total += module.failed_exports.count();
30782883 total += module.failed_embed_files.count();
30792884
......@@ -3116,16 +2921,15 @@ pub fn totalErrorCount(self: *Compilation) u32 {
31162921
31172922 // The "no entry point found" error only counts if there are no semantic analysis errors.
31182923 if (total == 0) {
3119 total += @intFromBool(self.link_error_flags.no_entry_point_found);
2924 total += @intFromBool(comp.link_error_flags.no_entry_point_found);
31202925 }
3121 total += @intFromBool(self.link_error_flags.missing_libc);
2926 total += @intFromBool(comp.link_error_flags.missing_libc);
31222927
3123 // Misc linker errors
3124 total += self.bin_file.miscErrors().len;
2928 total += comp.link_errors.items.len;
31252929
31262930 // Compile log errors only count if there are no other errors.
31272931 if (total == 0) {
3128 if (self.bin_file.options.module) |module| {
2932 if (comp.module) |module| {
31292933 total += @intFromBool(module.compile_log_decls.count() != 0);
31302934 }
31312935 }
......@@ -3134,24 +2938,24 @@ pub fn totalErrorCount(self: *Compilation) u32 {
31342938}
31352939
31362940/// This function is temporally single-threaded.
3137pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
3138 const gpa = self.gpa;
2941pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
2942 const gpa = comp.gpa;
31392943
31402944 var bundle: ErrorBundle.Wip = undefined;
31412945 try bundle.init(gpa);
31422946 defer bundle.deinit();
31432947
3144 for (self.failed_c_objects.values()) |diag_bundle| {
2948 for (comp.failed_c_objects.values()) |diag_bundle| {
31452949 try diag_bundle.addToErrorBundle(&bundle);
31462950 }
31472951
31482952 if (!build_options.only_core_functionality) {
3149 for (self.failed_win32_resources.values()) |error_bundle| {
2953 for (comp.failed_win32_resources.values()) |error_bundle| {
31502954 try bundle.addBundleAsRoots(error_bundle);
31512955 }
31522956 }
31532957
3154 for (self.lld_errors.items) |lld_error| {
2958 for (comp.lld_errors.items) |lld_error| {
31552959 const notes_len = @as(u32, @intCast(lld_error.context_lines.len));
31562960
31572961 try bundle.addRootErrorMessage(.{
......@@ -3165,19 +2969,19 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
31652969 }));
31662970 }
31672971 }
3168 for (self.misc_failures.values()) |*value| {
2972 for (comp.misc_failures.values()) |*value| {
31692973 try bundle.addRootErrorMessage(.{
31702974 .msg = try bundle.addString(value.msg),
31712975 .notes_len = if (value.children) |b| b.errorMessageCount() else 0,
31722976 });
31732977 if (value.children) |b| try bundle.addBundleAsNotes(b);
31742978 }
3175 if (self.alloc_failure_occurred) {
2979 if (comp.alloc_failure_occurred) {
31762980 try bundle.addRootErrorMessage(.{
31772981 .msg = try bundle.addString("memory allocation failure"),
31782982 });
31792983 }
3180 if (self.bin_file.options.module) |module| {
2984 if (comp.module) |module| {
31812985 for (module.failed_files.keys(), module.failed_files.values()) |file, error_msg| {
31822986 if (error_msg) |msg| {
31832987 try addModuleErrorMsg(module, &bundle, msg.*);
......@@ -3249,14 +3053,14 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
32493053 }
32503054
32513055 if (bundle.root_list.items.len == 0) {
3252 if (self.link_error_flags.no_entry_point_found) {
3056 if (comp.link_error_flags.no_entry_point_found) {
32533057 try bundle.addRootErrorMessage(.{
32543058 .msg = try bundle.addString("no entry point found"),
32553059 });
32563060 }
32573061 }
32583062
3259 if (self.link_error_flags.missing_libc) {
3063 if (comp.link_error_flags.missing_libc) {
32603064 try bundle.addRootErrorMessage(.{
32613065 .msg = try bundle.addString("libc not available"),
32623066 .notes_len = 2,
......@@ -3270,7 +3074,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
32703074 }));
32713075 }
32723076
3273 for (self.bin_file.miscErrors()) |link_err| {
3077 for (comp.link_errors.items) |link_err| {
32743078 try bundle.addRootErrorMessage(.{
32753079 .msg = try bundle.addString(link_err.msg),
32763080 .notes_len = @intCast(link_err.notes.len),
......@@ -3283,7 +3087,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
32833087 }
32843088 }
32853089
3286 if (self.bin_file.options.module) |module| {
3090 if (comp.module) |module| {
32873091 if (bundle.root_list.items.len == 0 and module.compile_log_decls.count() != 0) {
32883092 const keys = module.compile_log_decls.keys();
32893093 const values = module.compile_log_decls.values();
......@@ -3309,9 +3113,9 @@ pub fn getAllErrorsAlloc(self: *Compilation) !ErrorBundle {
33093113 }
33103114 }
33113115
3312 assert(self.totalErrorCount() == bundle.root_list.items.len);
3116 assert(comp.totalErrorCount() == bundle.root_list.items.len);
33133117
3314 const compile_log_text = if (self.bin_file.options.module) |m| m.compile_log_text.items else "";
3118 const compile_log_text = if (comp.module) |m| m.compile_log_text.items else "";
33153119 return bundle.toOwnedBundle(compile_log_text);
33163120}
33173121
......@@ -3344,7 +3148,7 @@ pub const ErrorNoteHashContext = struct {
33443148 const eb = ctx.eb.tmpBundle();
33453149 const msg_a = eb.nullTerminatedString(a.msg);
33463150 const msg_b = eb.nullTerminatedString(b.msg);
3347 if (!std.mem.eql(u8, msg_a, msg_b)) return false;
3151 if (!mem.eql(u8, msg_a, msg_b)) return false;
33483152
33493153 if (a.src_loc == .none and b.src_loc == .none) return true;
33503154 if (a.src_loc == .none or b.src_loc == .none) return false;
......@@ -3354,7 +3158,7 @@ pub const ErrorNoteHashContext = struct {
33543158 const src_path_a = eb.nullTerminatedString(src_a.src_path);
33553159 const src_path_b = eb.nullTerminatedString(src_b.src_path);
33563160
3357 return std.mem.eql(u8, src_path_a, src_path_b) and
3161 return mem.eql(u8, src_path_a, src_path_b) and
33583162 src_a.line == src_b.line and
33593163 src_a.column == src_b.column and
33603164 src_a.span_main == src_b.span_main;
......@@ -3595,13 +3399,25 @@ pub fn performAllTheWork(
35953399 // 1. to avoid race condition of zig processes truncating each other's builtin.zig files
35963400 // 2. optimization; in the hot path it only incurs a stat() syscall, which happens
35973401 // in the `astgen_wait_group`.
3598 if (comp.bin_file.options.module) |mod| {
3599 if (mod.job_queued_update_builtin_zig) {
3600 mod.job_queued_update_builtin_zig = false;
3402 if (comp.job_queued_update_builtin_zig) b: {
3403 comp.job_queued_update_builtin_zig = false;
3404 const zcu = comp.module orelse break :b;
3405 _ = zcu;
3406 // TODO put all the modules in a flat array to make them easy to iterate.
3407 var seen: std.AutoArrayHashMapUnmanaged(*Package.Module, void) = .{};
3408 defer seen.deinit(comp.gpa);
3409 try seen.put(comp.gpa, comp.root_mod, {});
3410 var i: usize = 0;
3411 while (i < seen.count()) : (i += 1) {
3412 const mod = seen.keys()[i];
3413 for (mod.deps.values()) |dep|
3414 try seen.put(comp.gpa, dep, {});
3415
3416 const file = mod.builtin_file orelse continue;
36013417
36023418 comp.astgen_wait_group.start();
36033419 try comp.thread_pool.spawn(workerUpdateBuiltinZigFile, .{
3604 comp, mod, &comp.astgen_wait_group,
3420 comp, mod, file, &comp.astgen_wait_group,
36053421 });
36063422 }
36073423 }
......@@ -3637,15 +3453,15 @@ pub fn performAllTheWork(
36373453 }
36383454 }
36393455
3640 if (comp.bin_file.options.module) |mod| {
3456 if (comp.module) |mod| {
36413457 try reportMultiModuleErrors(mod);
36423458 }
36433459
3644 if (comp.bin_file.options.module) |mod| {
3460 if (comp.module) |mod| {
36453461 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
36463462 mod.sema_prog_node.activate();
36473463 }
3648 defer if (comp.bin_file.options.module) |mod| {
3464 defer if (comp.module) |mod| {
36493465 mod.sema_prog_node.end();
36503466 mod.sema_prog_node = undefined;
36513467 };
......@@ -3679,7 +3495,7 @@ pub fn performAllTheWork(
36793495fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !void {
36803496 switch (job) {
36813497 .codegen_decl => |decl_index| {
3682 const module = comp.bin_file.options.module.?;
3498 const module = comp.module.?;
36833499 const decl = module.declPtr(decl_index);
36843500
36853501 switch (decl.analysis) {
......@@ -3717,14 +3533,14 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
37173533 const named_frame = tracy.namedFrame("codegen_func");
37183534 defer named_frame.end();
37193535
3720 const module = comp.bin_file.options.module.?;
3536 const module = comp.module.?;
37213537 module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
37223538 error.OutOfMemory => return error.OutOfMemory,
37233539 error.AnalysisFail => return,
37243540 };
37253541 },
37263542 .emit_h_decl => |decl_index| {
3727 const module = comp.bin_file.options.module.?;
3543 const module = comp.module.?;
37283544 const decl = module.declPtr(decl_index);
37293545
37303546 switch (decl.analysis) {
......@@ -3783,13 +3599,13 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
37833599 }
37843600 },
37853601 .analyze_decl => |decl_index| {
3786 const module = comp.bin_file.options.module.?;
3602 const module = comp.module.?;
37873603 module.ensureDeclAnalyzed(decl_index) catch |err| switch (err) {
37883604 error.OutOfMemory => return error.OutOfMemory,
37893605 error.AnalysisFail => return,
37903606 };
37913607 const decl = module.declPtr(decl_index);
3792 if (decl.kind == .@"test" and comp.bin_file.options.is_test) {
3608 if (decl.kind == .@"test" and comp.config.is_test) {
37933609 // Tests are always emitted in test binaries. The decl_refs are created by
37943610 // Module.populateTestFunctions, but this will not queue body analysis, so do
37953611 // that now.
......@@ -3801,9 +3617,10 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
38013617 defer named_frame.end();
38023618
38033619 const gpa = comp.gpa;
3804 const module = comp.bin_file.options.module.?;
3620 const module = comp.module.?;
38053621 const decl = module.declPtr(decl_index);
3806 comp.bin_file.updateDeclLineNumber(module, decl_index) catch |err| {
3622 const lf = comp.bin_file.?;
3623 lf.updateDeclLineNumber(module, decl_index) catch |err| {
38073624 try module.failed_decls.ensureUnusedCapacity(gpa, 1);
38083625 module.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
38093626 gpa,
......@@ -3818,7 +3635,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
38183635 const named_frame = tracy.namedFrame("analyze_mod");
38193636 defer named_frame.end();
38203637
3821 const module = comp.bin_file.options.module.?;
3638 const module = comp.module.?;
38223639 module.semaPkg(pkg) catch |err| switch (err) {
38233640 error.OutOfMemory => return error.OutOfMemory,
38243641 error.AnalysisFail => return,
......@@ -3875,10 +3692,13 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v
38753692 };
38763693 },
38773694 .windows_import_lib => |index| {
3695 if (build_options.only_c)
3696 @panic("building import libs not included in core functionality");
3697
38783698 const named_frame = tracy.namedFrame("windows_import_lib");
38793699 defer named_frame.end();
38803700
3881 const link_lib = comp.bin_file.options.system_libs.keys()[index];
3701 const link_lib = comp.system_libs.keys()[index];
38823702 mingw.buildImportLib(comp, link_lib) catch |err| {
38833703 // TODO Surface more error details.
38843704 comp.lockAndSetMiscFailure(
......@@ -3997,7 +3817,7 @@ fn workerAstGenFile(
39973817 child_prog_node.activate();
39983818 defer child_prog_node.end();
39993819
4000 const mod = comp.bin_file.options.module.?;
3820 const mod = comp.module.?;
40013821 mod.astGenFile(file) catch |err| switch (err) {
40023822 error.AnalysisFail => return,
40033823 else => {
......@@ -4065,19 +3885,17 @@ fn workerAstGenFile(
40653885
40663886fn workerUpdateBuiltinZigFile(
40673887 comp: *Compilation,
4068 mod: *Module,
3888 mod: *Package.Module,
3889 file: *Module.File,
40693890 wg: *WaitGroup,
40703891) void {
40713892 defer wg.finish();
4072
4073 mod.populateBuiltinFile() catch |err| {
4074 const dir_path: []const u8 = mod.zig_cache_artifact_directory.path orelse ".";
4075
3893 Builtin.populateFile(comp, mod, file) catch |err| {
40763894 comp.mutex.lock();
40773895 defer comp.mutex.unlock();
40783896
4079 comp.setMiscFailure(.write_builtin_zig, "unable to write builtin.zig to {s}: {s}", .{
4080 dir_path, @errorName(err),
3897 comp.setMiscFailure(.write_builtin_zig, "unable to write '{}{s}': {s}", .{
3898 mod.root, mod.root_src_path, @errorName(err),
40813899 });
40823900 };
40833901}
......@@ -4100,7 +3918,7 @@ fn workerCheckEmbedFile(
41003918}
41013919
41023920fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Module.EmbedFile) !void {
4103 const mod = comp.bin_file.options.module.?;
3921 const mod = comp.module.?;
41043922 const ip = &mod.intern_pool;
41053923 const sub_file_path = ip.stringToSlice(embed_file.sub_file_path);
41063924 var file = try embed_file.owner.root.openFile(sub_file_path, .{});
......@@ -4118,21 +3936,24 @@ fn detectEmbedFileUpdate(comp: *Compilation, embed_file: *Module.EmbedFile) !voi
41183936 @panic("TODO: handle embed file incremental update");
41193937}
41203938
4121pub fn obtainCObjectCacheManifest(comp: *const Compilation) Cache.Manifest {
3939pub fn obtainCObjectCacheManifest(
3940 comp: *const Compilation,
3941 owner_mod: *Package.Module,
3942) Cache.Manifest {
41223943 var man = comp.cache_parent.obtain();
41233944
41243945 // Only things that need to be added on top of the base hash, and only things
41253946 // that apply both to @cImport and compiling C objects. No linking stuff here!
41263947 // Also nothing that applies only to compiling .zig code.
4127 man.hash.add(comp.sanitize_c);
4128 man.hash.addListOfBytes(comp.clang_argv);
4129 man.hash.add(comp.bin_file.options.link_libcpp);
3948 cache_helpers.addModule(&man.hash, owner_mod);
3949 man.hash.addListOfBytes(comp.global_cc_argv);
3950 man.hash.add(comp.config.link_libcpp);
41303951
41313952 // When libc_installation is null it means that Zig generated this dir list
41323953 // based on the zig library directory alone. The zig lib directory file
41333954 // path is purposefully either in the cache or not in the cache. The
41343955 // decision should not be overridden here.
4135 if (comp.bin_file.options.libc_installation != null) {
3956 if (comp.libc_installation != null) {
41363957 man.hash.addListOfBytes(comp.libc_include_dir_list);
41373958 }
41383959
......@@ -4152,7 +3973,7 @@ pub const CImportResult = struct {
41523973 cache_hit: bool,
41533974 errors: std.zig.ErrorBundle,
41543975
4155 pub fn deinit(result: *CImportResult, gpa: std.mem.Allocator) void {
3976 pub fn deinit(result: *CImportResult, gpa: mem.Allocator) void {
41563977 result.errors.deinit(gpa);
41573978 }
41583979};
......@@ -4160,19 +3981,19 @@ pub const CImportResult = struct {
41603981/// Caller owns returned memory.
41613982/// This API is currently coupled pretty tightly to stage1's needs; it will need to be reworked
41623983/// a bit when we want to start using it from self-hosted.
4163pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
3984pub fn cImport(comp: *Compilation, c_src: []const u8, owner_mod: *Package.Module) !CImportResult {
41643985 if (build_options.only_core_functionality) @panic("@cImport is not available in a zig2.c build");
41653986 const tracy_trace = trace(@src());
41663987 defer tracy_trace.end();
41673988
41683989 const cimport_zig_basename = "cimport.zig";
41693990
4170 var man = comp.obtainCObjectCacheManifest();
3991 var man = comp.obtainCObjectCacheManifest(owner_mod);
41713992 defer man.deinit();
41723993
41733994 man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
41743995 man.hash.addBytes(c_src);
4175 man.hash.add(comp.c_frontend);
3996 man.hash.add(comp.config.c_frontend);
41763997
41773998 // If the previous invocation resulted in clang errors, we will see a hit
41783999 // here with 0 files in the manifest, in which case it is actually a miss.
......@@ -4209,15 +4030,15 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
42094030 var argv = std.ArrayList([]const u8).init(comp.gpa);
42104031 defer argv.deinit();
42114032
4212 try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1]
4213 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path);
4033 try argv.append(@tagName(comp.config.c_frontend)); // argv[0] is program name, actual args start at [1]
4034 try comp.addTranslateCCArgs(arena, &argv, .c, out_dep_path, owner_mod);
42144035
42154036 try argv.append(out_h_path);
42164037
42174038 if (comp.verbose_cc) {
42184039 dump_argv(argv.items);
42194040 }
4220 var tree = switch (comp.c_frontend) {
4041 var tree = switch (comp.config.c_frontend) {
42214042 .aro => tree: {
42224043 const translate_c = @import("aro_translate_c.zig");
42234044 _ = translate_c;
......@@ -4265,10 +4086,13 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
42654086
42664087 const dep_basename = std.fs.path.basename(out_dep_path);
42674088 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4268 if (comp.whole_cache_manifest) |whole_cache_manifest| {
4269 comp.whole_cache_manifest_mutex.lock();
4270 defer comp.whole_cache_manifest_mutex.unlock();
4271 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4089 switch (comp.cache_use) {
4090 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {
4091 whole.cache_manifest_mutex.lock();
4092 defer whole.cache_manifest_mutex.unlock();
4093 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4094 },
4095 .incremental => {},
42724096 }
42734097
42744098 const digest = man.final();
......@@ -4297,7 +4121,7 @@ pub fn cImport(comp: *Compilation, c_src: []const u8) !CImportResult {
42974121 };
42984122 }
42994123
4300 const out_zig_path = try comp.local_cache_directory.join(comp.arena.allocator(), &.{
4124 const out_zig_path = try comp.local_cache_directory.join(comp.arena, &.{
43014125 "o", &digest, cimport_zig_basename,
43024126 });
43034127 if (comp.verbose_cimport) {
......@@ -4423,7 +4247,7 @@ fn reportRetryableAstGenError(
44234247 file: *Module.File,
44244248 err: anyerror,
44254249) error{OutOfMemory}!void {
4426 const mod = comp.bin_file.options.module.?;
4250 const mod = comp.module.?;
44274251 const gpa = mod.gpa;
44284252
44294253 file.status = .retryable_failure;
......@@ -4462,7 +4286,7 @@ fn reportRetryableEmbedFileError(
44624286 embed_file: *Module.EmbedFile,
44634287 err: anyerror,
44644288) error{OutOfMemory}!void {
4465 const mod = comp.bin_file.options.module.?;
4289 const mod = comp.module.?;
44664290 const gpa = mod.gpa;
44674291 const src_loc = embed_file.src_loc;
44684292 const ip = &mod.intern_pool;
......@@ -4482,7 +4306,7 @@ fn reportRetryableEmbedFileError(
44824306}
44834307
44844308fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.Progress.Node) !void {
4485 if (comp.c_frontend == .aro) {
4309 if (comp.config.c_frontend == .aro) {
44864310 return comp.failCObj(c_object, "aro does not support compiling C objects yet", .{});
44874311 }
44884312 if (!build_options.have_llvm) {
......@@ -4505,7 +4329,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
45054329 _ = comp.failed_c_objects.swapRemove(c_object);
45064330 }
45074331
4508 var man = comp.obtainCObjectCacheManifest();
4332 var man = comp.obtainCObjectCacheManifest(c_object.src.owner);
45094333 defer man.deinit();
45104334
45114335 man.hash.add(comp.clang_preprocessor_mode);
......@@ -4529,10 +4353,10 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
45294353 // Special case when doing build-obj for just one C file. When there are more than one object
45304354 // file and building an object we need to link them together, but with just one it should go
45314355 // directly to the output file.
4532 const direct_o = comp.c_source_files.len == 1 and comp.bin_file.options.module == null and
4533 comp.bin_file.options.output_mode == .Obj and comp.bin_file.options.objects.len == 0;
4356 const direct_o = comp.c_source_files.len == 1 and comp.module == null and
4357 comp.config.output_mode == .Obj and comp.objects.len == 0;
45344358 const o_basename_noext = if (direct_o)
4535 comp.bin_file.options.root_name
4359 comp.root_name
45364360 else
45374361 c_source_basename[0 .. c_source_basename.len - std.fs.path.extension(c_source_basename).len];
45384362
......@@ -4582,12 +4406,12 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
45824406 if (std.process.can_execv and direct_o and
45834407 comp.disable_c_depfile and comp.clang_passthrough_mode)
45844408 {
4585 try comp.addCCArgs(arena, &argv, ext, null);
4409 try comp.addCCArgs(arena, &argv, ext, null, c_object.src.owner);
45864410 try argv.appendSlice(c_object.src.extra_flags);
45874411 try argv.appendSlice(c_object.src.cache_exempt_flags);
45884412
4589 const out_obj_path = if (comp.bin_file.options.emit) |emit|
4590 try emit.directory.join(arena, &.{emit.sub_path})
4413 const out_obj_path = if (comp.bin_file) |lf|
4414 try lf.emit.directory.join(arena, &.{lf.emit.sub_path})
45914415 else
45924416 "/dev/null";
45934417
......@@ -4625,7 +4449,7 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
46254449 null
46264450 else
46274451 try std.fmt.allocPrint(arena, "{s}.d", .{out_obj_path});
4628 try comp.addCCArgs(arena, &argv, ext, out_dep_path);
4452 try comp.addCCArgs(arena, &argv, ext, out_dep_path, c_object.src.owner);
46294453 try argv.appendSlice(c_object.src.extra_flags);
46304454 try argv.appendSlice(c_object.src.cache_exempt_flags);
46314455
......@@ -4720,10 +4544,15 @@ fn updateCObject(comp: *Compilation, c_object: *CObject, c_obj_prog_node: *std.P
47204544 const dep_basename = std.fs.path.basename(dep_file_path);
47214545 // Add the files depended on to the cache system.
47224546 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4723 if (comp.whole_cache_manifest) |whole_cache_manifest| {
4724 comp.whole_cache_manifest_mutex.lock();
4725 defer comp.whole_cache_manifest_mutex.unlock();
4726 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4547 switch (comp.cache_use) {
4548 .whole => |whole| {
4549 if (whole.cache_manifest) |whole_cache_manifest| {
4550 whole.cache_manifest_mutex.lock();
4551 defer whole.cache_manifest_mutex.unlock();
4552 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4553 }
4554 },
4555 .incremental => {},
47274556 }
47284557 // Just to save disk space, we delete the file because it is never needed again.
47294558 zig_cache_tmp_dir.deleteFile(dep_basename) catch |err| {
......@@ -4973,7 +4802,7 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
49734802 // mode. While these defines are not normally present when calling rc.exe directly,
49744803 // them being defined matches the behavior of how MSVC calls rc.exe which is the more
49754804 // relevant behavior in this case.
4976 try comp.addCCArgs(arena, &argv, .rc, out_dep_path);
4805 try comp.addCCArgs(arena, &argv, .rc, out_dep_path, rc_src.owner);
49774806
49784807 if (comp.verbose_cc) {
49794808 dump_argv(argv.items);
......@@ -5019,10 +4848,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
50194848 const dep_basename = std.fs.path.basename(out_dep_path);
50204849 // Add the files depended on to the cache system.
50214850 try man.addDepFilePost(zig_cache_tmp_dir, dep_basename);
5022 if (comp.whole_cache_manifest) |whole_cache_manifest| {
5023 comp.whole_cache_manifest_mutex.lock();
5024 defer comp.whole_cache_manifest_mutex.unlock();
5025 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4851 switch (comp.cache_use) {
4852 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {
4853 whole.cache_manifest_mutex.lock();
4854 defer whole.cache_manifest_mutex.unlock();
4855 try whole_cache_manifest.addDepFilePost(zig_cache_tmp_dir, dep_basename);
4856 },
4857 .incremental => {},
50264858 }
50274859 // Just to save disk space, we delete the file because it is never needed again.
50284860 zig_cache_tmp_dir.deleteFile(dep_basename) catch |err| {
......@@ -5094,10 +4926,13 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
50944926
50954927 for (dependencies_list.items) |dep_file_path| {
50964928 try man.addFilePost(dep_file_path);
5097 if (comp.whole_cache_manifest) |whole_cache_manifest| {
5098 comp.whole_cache_manifest_mutex.lock();
5099 defer comp.whole_cache_manifest_mutex.unlock();
5100 try whole_cache_manifest.addFilePost(dep_file_path);
4929 switch (comp.cache_use) {
4930 .whole => |whole| if (whole.cache_manifest) |whole_cache_manifest| {
4931 whole.cache_manifest_mutex.lock();
4932 defer whole.cache_manifest_mutex.unlock();
4933 try whole_cache_manifest.addFilePost(dep_file_path);
4934 },
4935 .incremental => {},
51014936 }
51024937 }
51034938
......@@ -5151,11 +4986,12 @@ pub fn addTranslateCCArgs(
51514986 argv: *std.ArrayList([]const u8),
51524987 ext: FileExt,
51534988 out_dep_path: ?[]const u8,
4989 owner_mod: *Package.Module,
51544990) !void {
5155 try argv.appendSlice(&[_][]const u8{ "-x", "c" });
5156 try comp.addCCArgs(arena, argv, ext, out_dep_path);
4991 try argv.appendSlice(&.{ "-x", "c" });
4992 try comp.addCCArgs(arena, argv, ext, out_dep_path, owner_mod);
51574993 // This gives us access to preprocessing entities, presumably at the cost of performance.
5158 try argv.appendSlice(&[_][]const u8{ "-Xclang", "-detailed-preprocessing-record" });
4994 try argv.appendSlice(&.{ "-Xclang", "-detailed-preprocessing-record" });
51594995}
51604996
51614997/// Add common C compiler args between translate-c and C object compilation.
......@@ -5165,8 +5001,9 @@ pub fn addCCArgs(
51655001 argv: *std.ArrayList([]const u8),
51665002 ext: FileExt,
51675003 out_dep_path: ?[]const u8,
5004 mod: *Package.Module,
51685005) !void {
5169 const target = comp.getTarget();
5006 const target = mod.resolved_target.result;
51705007
51715008 // As of Clang 16.x, it will by default read extra flags from /etc/clang.
51725009 // I'm sure the person who implemented this means well, but they have a lot
......@@ -5187,19 +5024,19 @@ pub fn addCCArgs(
51875024 try argv.append("-fno-caret-diagnostics");
51885025 }
51895026
5190 if (comp.bin_file.options.function_sections) {
5027 if (comp.function_sections) {
51915028 try argv.append("-ffunction-sections");
51925029 }
51935030
5194 if (comp.bin_file.options.data_sections) {
5031 if (comp.data_sections) {
51955032 try argv.append("-fdata-sections");
51965033 }
51975034
5198 if (comp.bin_file.options.no_builtin) {
5035 if (comp.no_builtin) {
51995036 try argv.append("-fno-builtin");
52005037 }
52015038
5202 if (comp.bin_file.options.link_libcpp) {
5039 if (comp.config.link_libcpp) {
52035040 const libcxx_include_path = try std.fs.path.join(arena, &[_][]const u8{
52045041 comp.zig_lib_directory.path.?, "libcxx", "include",
52055042 });
......@@ -5220,7 +5057,7 @@ pub fn addCCArgs(
52205057 try argv.append("-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS");
52215058 try argv.append("-D_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS");
52225059
5223 if (comp.bin_file.options.single_threaded) {
5060 if (!comp.config.any_non_single_threaded) {
52245061 try argv.append("-D_LIBCPP_HAS_NO_THREADS");
52255062 }
52265063
......@@ -5235,7 +5072,7 @@ pub fn addCCArgs(
52355072 }));
52365073 }
52375074
5238 if (comp.bin_file.options.link_libunwind) {
5075 if (comp.config.link_libunwind) {
52395076 const libunwind_include_path = try std.fs.path.join(arena, &[_][]const u8{
52405077 comp.zig_lib_directory.path.?, "libunwind", "include",
52415078 });
......@@ -5244,7 +5081,7 @@ pub fn addCCArgs(
52445081 try argv.append(libunwind_include_path);
52455082 }
52465083
5247 if (comp.bin_file.options.link_libc and target.isGnuLibC()) {
5084 if (comp.config.link_libc and target.isGnuLibC()) {
52485085 const target_version = target.os.version_range.linux.glibc;
52495086 const glibc_minor_define = try std.fmt.allocPrint(arena, "-D__GLIBC_MINOR__={d}", .{
52505087 target_version.minor,
......@@ -5269,7 +5106,7 @@ pub fn addCCArgs(
52695106 "-nostdinc",
52705107 "-fno-spell-checking",
52715108 });
5272 if (comp.bin_file.options.lto) {
5109 if (comp.config.lto) {
52735110 try argv.append("-flto");
52745111 }
52755112
......@@ -5281,7 +5118,7 @@ pub fn addCCArgs(
52815118 try argv.appendSlice(&.{ "-iframework", framework_dir });
52825119 }
52835120
5284 for (comp.bin_file.options.framework_dirs) |framework_dir| {
5121 for (comp.framework_dirs) |framework_dir| {
52855122 try argv.appendSlice(&.{ "-F", framework_dir });
52865123 }
52875124
......@@ -5324,9 +5161,8 @@ pub fn addCCArgs(
53245161 argv.appendAssumeCapacity(arg);
53255162 }
53265163 }
5327 const mcmodel = comp.bin_file.options.machine_code_model;
5328 if (mcmodel != .default) {
5329 try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mcmodel)}));
5164 if (mod.code_model != .default) {
5165 try argv.append(try std.fmt.allocPrint(arena, "-mcmodel={s}", .{@tagName(mod.code_model)}));
53305166 }
53315167
53325168 switch (target.os.tag) {
......@@ -5375,7 +5211,7 @@ pub fn addCCArgs(
53755211 try argv.append("-mthumb");
53765212 }
53775213
5378 if (comp.sanitize_c and !comp.bin_file.options.tsan) {
5214 if (mod.sanitize_c and !mod.sanitize_thread) {
53795215 try argv.append("-fsanitize=undefined");
53805216 try argv.append("-fsanitize-trap=undefined");
53815217 // It is very common, and well-defined, for a pointer on one side of a C ABI
......@@ -5386,27 +5222,27 @@ pub fn addCCArgs(
53865222 // Without this flag, Clang would invoke UBSAN when such an extern
53875223 // function was called.
53885224 try argv.append("-fno-sanitize=function");
5389 } else if (comp.sanitize_c and comp.bin_file.options.tsan) {
5225 } else if (mod.sanitize_c and mod.sanitize_thread) {
53905226 try argv.append("-fsanitize=undefined,thread");
53915227 try argv.append("-fsanitize-trap=undefined");
53925228 try argv.append("-fno-sanitize=function");
5393 } else if (!comp.sanitize_c and comp.bin_file.options.tsan) {
5229 } else if (!mod.sanitize_c and mod.sanitize_thread) {
53945230 try argv.append("-fsanitize=thread");
53955231 }
53965232
5397 if (comp.bin_file.options.red_zone) {
5233 if (mod.red_zone) {
53985234 try argv.append("-mred-zone");
53995235 } else if (target_util.hasRedZone(target)) {
54005236 try argv.append("-mno-red-zone");
54015237 }
54025238
5403 if (comp.bin_file.options.omit_frame_pointer) {
5239 if (mod.omit_frame_pointer) {
54045240 try argv.append("-fomit-frame-pointer");
54055241 } else {
54065242 try argv.append("-fno-omit-frame-pointer");
54075243 }
54085244
5409 const ssp_buf_size = comp.bin_file.options.stack_protector;
5245 const ssp_buf_size = mod.stack_protector;
54105246 if (ssp_buf_size != 0) {
54115247 try argv.appendSlice(&[_][]const u8{
54125248 "-fstack-protector-strong",
......@@ -5417,7 +5253,7 @@ pub fn addCCArgs(
54175253 try argv.append("-fno-stack-protector");
54185254 }
54195255
5420 switch (comp.bin_file.options.optimize_mode) {
5256 switch (mod.optimize_mode) {
54215257 .Debug => {
54225258 // windows c runtime requires -D_DEBUG if using debug libraries
54235259 try argv.append("-D_DEBUG");
......@@ -5447,11 +5283,11 @@ pub fn addCCArgs(
54475283 },
54485284 }
54495285
5450 if (target_util.supports_fpic(target) and comp.bin_file.options.pic) {
5286 if (target_util.supports_fpic(target) and mod.pic) {
54515287 try argv.append("-fPIC");
54525288 }
54535289
5454 if (comp.unwind_tables) {
5290 if (mod.unwind_tables) {
54555291 try argv.append("-funwind-tables");
54565292 } else {
54575293 try argv.append("-fno-unwind-tables");
......@@ -5536,22 +5372,21 @@ pub fn addCCArgs(
55365372 },
55375373 }
55385374
5539 if (!comp.bin_file.options.strip) {
5540 switch (target.ofmt) {
5541 .coff => {
5542 // -g is required here because -gcodeview doesn't trigger debug info
5543 // generation, it only changes the type of information generated.
5544 try argv.appendSlice(&.{ "-g", "-gcodeview" });
5545 },
5546 .elf, .macho => {
5547 try argv.append("-gdwarf-4");
5548 if (comp.bin_file.options.dwarf_format) |f| switch (f) {
5549 .@"32" => try argv.append("-gdwarf32"),
5550 .@"64" => try argv.append("-gdwarf64"),
5551 };
5552 },
5553 else => try argv.append("-g"),
5554 }
5375 try argv.ensureUnusedCapacity(2);
5376 switch (comp.config.debug_format) {
5377 .strip => {},
5378 .code_view => {
5379 // -g is required here because -gcodeview doesn't trigger debug info
5380 // generation, it only changes the type of information generated.
5381 argv.appendSliceAssumeCapacity(&.{ "-g", "-gcodeview" });
5382 },
5383 .dwarf => |f| {
5384 argv.appendAssumeCapacity("-gdwarf-4");
5385 switch (f) {
5386 .@"32" => argv.appendAssumeCapacity("-gdwarf32"),
5387 .@"64" => argv.appendAssumeCapacity("-gdwarf64"),
5388 }
5389 },
55555390 }
55565391
55575392 if (target_util.llvmMachineAbi(target)) |mabi| {
......@@ -5574,7 +5409,16 @@ pub fn addCCArgs(
55745409 try argv.append("-ffreestanding");
55755410 }
55765411
5577 try argv.appendSlice(comp.clang_argv);
5412 if (mod.resolved_target.is_native_os and mod.resolved_target.is_native_abi) {
5413 try argv.ensureUnusedCapacity(comp.native_system_include_paths.len * 2);
5414 for (comp.native_system_include_paths) |include_path| {
5415 argv.appendAssumeCapacity("-isystem");
5416 argv.appendAssumeCapacity(include_path);
5417 }
5418 }
5419
5420 try argv.appendSlice(comp.global_cc_argv);
5421 try argv.appendSlice(mod.cc_argv);
55785422}
55795423
55805424fn failCObj(
......@@ -5621,68 +5465,6 @@ fn failCObjWithOwnedDiagBundle(
56215465 return error.AnalysisFail;
56225466}
56235467
5624/// The include directories used when preprocessing .rc files are separate from the
5625/// target. Which include directories are used is determined by `options.rc_includes`.
5626///
5627/// Note: It should be okay that the include directories used when compiling .rc
5628/// files differ from the include directories used when compiling the main
5629/// binary, since the .res format is not dependent on anything ABI-related. The
5630/// only relevant differences would be things like `#define` constants being
5631/// different in the MinGW headers vs the MSVC headers, but any such
5632/// differences would likely be a MinGW bug.
5633fn detectWin32ResourceIncludeDirs(arena: Allocator, options: InitOptions) !LibCDirs {
5634 // Set the includes to .none here when there are no rc files to compile
5635 var includes = if (options.rc_source_files.len > 0) options.rc_includes else .none;
5636 if (builtin.target.os.tag != .windows) {
5637 switch (includes) {
5638 // MSVC can't be found when the host isn't Windows, so short-circuit.
5639 .msvc => return error.WindowsSdkNotFound,
5640 // Skip straight to gnu since we won't be able to detect MSVC on non-Windows hosts.
5641 .any => includes = .gnu,
5642 .none, .gnu => {},
5643 }
5644 }
5645 while (true) {
5646 switch (includes) {
5647 .any, .msvc => return detectLibCIncludeDirs(
5648 arena,
5649 options.zig_lib_directory.path.?,
5650 .{
5651 .cpu = options.target.cpu,
5652 .os = options.target.os,
5653 .abi = .msvc,
5654 .ofmt = options.target.ofmt,
5655 },
5656 options.is_native_abi,
5657 // The .rc preprocessor will need to know the libc include dirs even if we
5658 // are not linking libc, so force 'link_libc' to true
5659 true,
5660 options.libc_installation,
5661 ) catch |err| {
5662 if (includes == .any) {
5663 // fall back to mingw
5664 includes = .gnu;
5665 continue;
5666 }
5667 return err;
5668 },
5669 .gnu => return detectLibCFromBuilding(arena, options.zig_lib_directory.path.?, .{
5670 .cpu = options.target.cpu,
5671 .os = options.target.os,
5672 .abi = .gnu,
5673 .ofmt = options.target.ofmt,
5674 }),
5675 .none => return LibCDirs{
5676 .libc_include_dir_list = &[0][]u8{},
5677 .libc_installation = null,
5678 .libc_framework_dir_list = &.{},
5679 .sysroot = null,
5680 .darwin_sdk_layout = null,
5681 },
5682 }
5683 }
5684}
5685
56865468fn failWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, comptime format: []const u8, args: anytype) SemaError {
56875469 @setCold(true);
56885470 var bundle: ErrorBundle.Wip = undefined;
......@@ -6064,7 +5846,7 @@ const LibCDirs = struct {
60645846 libc_installation: ?*const LibCInstallation,
60655847 libc_framework_dir_list: []const []const u8,
60665848 sysroot: ?[]const u8,
6067 darwin_sdk_layout: ?link.DarwinSdkLayout,
5849 darwin_sdk_layout: ?link.File.MachO.SdkLayout,
60685850};
60695851
60705852fn getZigShippedLibCIncludeDirsDarwin(arena: Allocator, zig_lib_dir: []const u8) !LibCDirs {
......@@ -6285,21 +6067,21 @@ pub fn get_libc_crt_file(comp: *Compilation, arena: Allocator, basename: []const
62856067 {
62866068 return comp.crt_files.get(basename).?.full_object_path;
62876069 }
6288 const lci = comp.bin_file.options.libc_installation orelse return error.LibCInstallationNotAvailable;
6070 const lci = comp.libc_installation orelse return error.LibCInstallationNotAvailable;
62896071 const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir;
62906072 const full_path = try std.fs.path.join(arena, &[_][]const u8{ crt_dir_path, basename });
62916073 return full_path;
62926074}
62936075
62946076fn wantBuildLibCFromSource(comp: Compilation) bool {
6295 const is_exe_or_dyn_lib = switch (comp.bin_file.options.output_mode) {
6077 const is_exe_or_dyn_lib = switch (comp.config.output_mode) {
62966078 .Obj => false,
6297 .Lib => comp.bin_file.options.link_mode == .Dynamic,
6079 .Lib => comp.config.link_mode == .Dynamic,
62986080 .Exe => true,
62996081 };
6300 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
6301 comp.bin_file.options.libc_installation == null and
6302 comp.bin_file.options.target.ofmt != .c;
6082 const ofmt = comp.root_mod.resolved_target.result.ofmt;
6083 return comp.config.link_libc and is_exe_or_dyn_lib and
6084 comp.libc_installation == null and ofmt != .c;
63036085}
63046086
63056087fn wantBuildGLibCFromSource(comp: Compilation) bool {
......@@ -6321,13 +6103,13 @@ fn wantBuildMinGWFromSource(comp: Compilation) bool {
63216103}
63226104
63236105fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
6324 const is_exe_or_dyn_lib = switch (comp.bin_file.options.output_mode) {
6106 const is_exe_or_dyn_lib = switch (comp.config.output_mode) {
63256107 .Obj => false,
6326 .Lib => comp.bin_file.options.link_mode == .Dynamic,
6108 .Lib => comp.config.link_mode == .Dynamic,
63276109 .Exe => true,
63286110 };
6329 return is_exe_or_dyn_lib and comp.bin_file.options.link_libunwind and
6330 comp.bin_file.options.target.ofmt != .c;
6111 const ofmt = comp.root_mod.resolved_target.result.ofmt;
6112 return is_exe_or_dyn_lib and comp.config.link_libunwind and ofmt != .c;
63316113}
63326114
63336115fn setAllocFailure(comp: *Compilation) void {
......@@ -6377,7 +6159,7 @@ fn parseLldStderr(comp: *Compilation, comptime prefix: []const u8, stderr: []con
63776159 err.context_lines = try context_lines.toOwnedSlice();
63786160 }
63796161
6380 var split = std.mem.splitSequence(u8, line, "error: ");
6162 var split = mem.splitSequence(u8, line, "error: ");
63816163 _ = split.first();
63826164
63836165 const duped_msg = try std.fmt.allocPrint(comp.gpa, "{s}: {s}", .{ prefix, split.rest() });
......@@ -6430,7 +6212,7 @@ fn canBuildLibCompilerRt(target: std.Target, use_llvm: bool) bool {
64306212 .spirv32, .spirv64 => return false,
64316213 else => {},
64326214 }
6433 return switch (zigBackend(target, use_llvm)) {
6215 return switch (target_util.zigBackend(target, use_llvm)) {
64346216 .stage2_llvm => true,
64356217 .stage2_x86_64 => if (target.ofmt == .elf) true else build_options.have_llvm,
64366218 else => build_options.have_llvm,
......@@ -6448,7 +6230,7 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool {
64486230 .spirv32, .spirv64 => return false,
64496231 else => {},
64506232 }
6451 return switch (zigBackend(target, use_llvm)) {
6233 return switch (target_util.zigBackend(target, use_llvm)) {
64526234 .stage2_llvm => true,
64536235 .stage2_x86_64 => if (target.ofmt == .elf) true else build_options.have_llvm,
64546236 else => build_options.have_llvm,
......@@ -6456,222 +6238,8 @@ fn canBuildZigLibC(target: std.Target, use_llvm: bool) bool {
64566238}
64576239
64586240pub fn getZigBackend(comp: Compilation) std.builtin.CompilerBackend {
6459 const target = comp.bin_file.options.target;
6460 return zigBackend(target, comp.bin_file.options.use_llvm);
6461}
6462
6463fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBackend {
6464 if (use_llvm) return .stage2_llvm;
6465 if (target.ofmt == .c) return .stage2_c;
6466 return switch (target.cpu.arch) {
6467 .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,
6468 .arm, .armeb, .thumb, .thumbeb => .stage2_arm,
6469 .x86_64 => .stage2_x86_64,
6470 .x86 => .stage2_x86,
6471 .aarch64, .aarch64_be, .aarch64_32 => .stage2_aarch64,
6472 .riscv64 => .stage2_riscv64,
6473 .sparc64 => .stage2_sparc64,
6474 .spirv64 => .stage2_spirv64,
6475 else => .other,
6476 };
6477}
6478
6479pub fn generateBuiltinZigSource(comp: *Compilation, allocator: Allocator) Allocator.Error![:0]u8 {
6480 const tracy_trace = trace(@src());
6481 defer tracy_trace.end();
6482
6483 var buffer = std.ArrayList(u8).init(allocator);
6484 defer buffer.deinit();
6485
6486 const target = comp.getTarget();
6487 const generic_arch_name = target.cpu.arch.genericName();
6488 const zig_backend = comp.getZigBackend();
6489
6490 @setEvalBranchQuota(4000);
6491 try buffer.writer().print(
6492 \\const std = @import("std");
6493 \\/// Zig version. When writing code that supports multiple versions of Zig, prefer
6494 \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
6495 \\pub const zig_version = std.SemanticVersion.parse(zig_version_string) catch unreachable;
6496 \\pub const zig_version_string = "{s}";
6497 \\pub const zig_backend = std.builtin.CompilerBackend.{};
6498 \\
6499 \\pub const output_mode = std.builtin.OutputMode.{};
6500 \\pub const link_mode = std.builtin.LinkMode.{};
6501 \\pub const is_test = {};
6502 \\pub const single_threaded = {};
6503 \\pub const abi = std.Target.Abi.{};
6504 \\pub const cpu: std.Target.Cpu = .{{
6505 \\ .arch = .{},
6506 \\ .model = &std.Target.{}.cpu.{},
6507 \\ .features = std.Target.{}.featureSet(&[_]std.Target.{}.Feature{{
6508 \\
6509 , .{
6510 build_options.version,
6511 std.zig.fmtId(@tagName(zig_backend)),
6512 std.zig.fmtId(@tagName(comp.bin_file.options.output_mode)),
6513 std.zig.fmtId(@tagName(comp.bin_file.options.link_mode)),
6514 comp.bin_file.options.is_test,
6515 comp.bin_file.options.single_threaded,
6516 std.zig.fmtId(@tagName(target.abi)),
6517 std.zig.fmtId(@tagName(target.cpu.arch)),
6518 std.zig.fmtId(generic_arch_name),
6519 std.zig.fmtId(target.cpu.model.name),
6520 std.zig.fmtId(generic_arch_name),
6521 std.zig.fmtId(generic_arch_name),
6522 });
6523
6524 for (target.cpu.arch.allFeaturesList(), 0..) |feature, index_usize| {
6525 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
6526 const is_enabled = target.cpu.features.isEnabled(index);
6527 if (is_enabled) {
6528 try buffer.writer().print(" .{},\n", .{std.zig.fmtId(feature.name)});
6529 }
6530 }
6531
6532 try buffer.writer().print(
6533 \\ }}),
6534 \\}};
6535 \\pub const os = std.Target.Os{{
6536 \\ .tag = .{},
6537 \\ .version_range = .{{
6538 ,
6539 .{std.zig.fmtId(@tagName(target.os.tag))},
6540 );
6541
6542 switch (target.os.getVersionRange()) {
6543 .none => try buffer.appendSlice(" .none = {} },\n"),
6544 .semver => |semver| try buffer.writer().print(
6545 \\ .semver = .{{
6546 \\ .min = .{{
6547 \\ .major = {},
6548 \\ .minor = {},
6549 \\ .patch = {},
6550 \\ }},
6551 \\ .max = .{{
6552 \\ .major = {},
6553 \\ .minor = {},
6554 \\ .patch = {},
6555 \\ }},
6556 \\ }}}},
6557 \\
6558 , .{
6559 semver.min.major,
6560 semver.min.minor,
6561 semver.min.patch,
6562
6563 semver.max.major,
6564 semver.max.minor,
6565 semver.max.patch,
6566 }),
6567 .linux => |linux| try buffer.writer().print(
6568 \\ .linux = .{{
6569 \\ .range = .{{
6570 \\ .min = .{{
6571 \\ .major = {},
6572 \\ .minor = {},
6573 \\ .patch = {},
6574 \\ }},
6575 \\ .max = .{{
6576 \\ .major = {},
6577 \\ .minor = {},
6578 \\ .patch = {},
6579 \\ }},
6580 \\ }},
6581 \\ .glibc = .{{
6582 \\ .major = {},
6583 \\ .minor = {},
6584 \\ .patch = {},
6585 \\ }},
6586 \\ }}}},
6587 \\
6588 , .{
6589 linux.range.min.major,
6590 linux.range.min.minor,
6591 linux.range.min.patch,
6592
6593 linux.range.max.major,
6594 linux.range.max.minor,
6595 linux.range.max.patch,
6596
6597 linux.glibc.major,
6598 linux.glibc.minor,
6599 linux.glibc.patch,
6600 }),
6601 .windows => |windows| try buffer.writer().print(
6602 \\ .windows = .{{
6603 \\ .min = {s},
6604 \\ .max = {s},
6605 \\ }}}},
6606 \\
6607 ,
6608 .{ windows.min, windows.max },
6609 ),
6610 }
6611 try buffer.appendSlice("};\n");
6612
6613 try buffer.writer().print(
6614 \\pub const target = std.Target{{
6615 \\ .cpu = cpu,
6616 \\ .os = os,
6617 \\ .abi = abi,
6618 \\ .ofmt = object_format,
6619 \\}};
6620 \\pub const object_format = std.Target.ObjectFormat.{};
6621 \\pub const mode = std.builtin.OptimizeMode.{};
6622 \\pub const link_libc = {};
6623 \\pub const link_libcpp = {};
6624 \\pub const have_error_return_tracing = {};
6625 \\pub const valgrind_support = {};
6626 \\pub const sanitize_thread = {};
6627 \\pub const position_independent_code = {};
6628 \\pub const position_independent_executable = {};
6629 \\pub const strip_debug_info = {};
6630 \\pub const code_model = std.builtin.CodeModel.{};
6631 \\pub const omit_frame_pointer = {};
6632 \\
6633 , .{
6634 std.zig.fmtId(@tagName(target.ofmt)),
6635 std.zig.fmtId(@tagName(comp.bin_file.options.optimize_mode)),
6636 comp.bin_file.options.link_libc,
6637 comp.bin_file.options.link_libcpp,
6638 comp.bin_file.options.error_return_tracing,
6639 comp.bin_file.options.valgrind,
6640 comp.bin_file.options.tsan,
6641 comp.bin_file.options.pic,
6642 comp.bin_file.options.pie,
6643 comp.bin_file.options.strip,
6644 std.zig.fmtId(@tagName(comp.bin_file.options.machine_code_model)),
6645 comp.bin_file.options.omit_frame_pointer,
6646 });
6647
6648 if (target.os.tag == .wasi) {
6649 const wasi_exec_model_fmt = std.zig.fmtId(@tagName(comp.bin_file.options.wasi_exec_model));
6650 try buffer.writer().print(
6651 \\pub const wasi_exec_model = std.builtin.WasiExecModel.{};
6652 \\
6653 , .{wasi_exec_model_fmt});
6654 }
6655
6656 if (comp.bin_file.options.is_test) {
6657 try buffer.appendSlice(
6658 \\pub var test_functions: []const std.builtin.TestFn = undefined; // overwritten later
6659 \\
6660 );
6661 if (comp.test_evented_io) {
6662 try buffer.appendSlice(
6663 \\pub const test_io_mode = .evented;
6664 \\
6665 );
6666 } else {
6667 try buffer.appendSlice(
6668 \\pub const test_io_mode = .blocking;
6669 \\
6670 );
6671 }
6672 }
6673
6674 return buffer.toOwnedSliceSentinel(0);
6241 const target = comp.root_mod.resolved_target.result;
6242 return target_util.zigBackend(target, comp.config.use_llvm);
66756243}
66766244
66776245pub fn updateSubCompilation(
......@@ -6718,60 +6286,83 @@ fn buildOutputFromZig(
67186286 const tracy_trace = trace(@src());
67196287 defer tracy_trace.end();
67206288
6289 const gpa = comp.gpa;
6290 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
6291 defer arena_allocator.deinit();
6292 const arena = arena_allocator.allocator();
6293
67216294 assert(output_mode != .Exe);
67226295
6723 var main_mod: Package.Module = .{
6724 .root = .{ .root_dir = comp.zig_lib_directory },
6725 .root_src_path = src_basename,
6296 const unwind_tables = comp.link_eh_frame_hdr;
6297 const strip = comp.compilerRtStrip();
6298 const optimize_mode = comp.compilerRtOptMode();
6299
6300 const config = try Config.resolve(.{
6301 .output_mode = output_mode,
6302 .link_mode = .Static,
6303 .resolved_target = comp.root_mod.resolved_target,
6304 .is_test = false,
6305 .have_zcu = true,
6306 .emit_bin = true,
6307 .root_optimize_mode = optimize_mode,
6308 .root_strip = strip,
6309 .link_libc = comp.config.link_libc,
6310 .any_unwind_tables = unwind_tables,
6311 });
6312
6313 const root_mod = try Package.Module.create(arena, .{
6314 .global_cache_directory = comp.global_cache_directory,
6315 .paths = .{
6316 .root = .{ .root_dir = comp.zig_lib_directory },
6317 .root_src_path = src_basename,
6318 },
67266319 .fully_qualified_name = "root",
6727 };
6320 .inherited = .{
6321 .resolved_target = comp.root_mod.resolved_target,
6322 .strip = strip,
6323 .stack_check = false,
6324 .stack_protector = 0,
6325 .red_zone = comp.root_mod.red_zone,
6326 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
6327 .unwind_tables = unwind_tables,
6328 .pic = comp.root_mod.pic,
6329 .optimize_mode = optimize_mode,
6330 .structured_cfg = comp.root_mod.structured_cfg,
6331 },
6332 .global = config,
6333 .cc_argv = &.{},
6334 .parent = null,
6335 .builtin_mod = null,
6336 });
67286337 const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
67296338 const target = comp.getTarget();
6730 const bin_basename = try std.zig.binNameAlloc(comp.gpa, .{
6339 const bin_basename = try std.zig.binNameAlloc(arena, .{
67316340 .root_name = root_name,
67326341 .target = target,
67336342 .output_mode = output_mode,
67346343 });
6735 defer comp.gpa.free(bin_basename);
67366344
6737 const emit_bin = Compilation.EmitLoc{
6738 .directory = null, // Put it in the cache directory.
6739 .basename = bin_basename,
6740 };
6741 const sub_compilation = try Compilation.create(comp.gpa, .{
6345 const sub_compilation = try Compilation.create(gpa, arena, .{
67426346 .global_cache_directory = comp.global_cache_directory,
67436347 .local_cache_directory = comp.global_cache_directory,
67446348 .zig_lib_directory = comp.zig_lib_directory,
6349 .self_exe_path = comp.self_exe_path,
6350 .config = config,
6351 .root_mod = root_mod,
67456352 .cache_mode = .whole,
6746 .target = target,
67476353 .root_name = root_name,
6748 .main_mod = &main_mod,
6749 .output_mode = output_mode,
67506354 .thread_pool = comp.thread_pool,
6751 .libc_installation = comp.bin_file.options.libc_installation,
6752 .emit_bin = emit_bin,
6753 .optimize_mode = comp.compilerRtOptMode(),
6754 .link_mode = .Static,
6355 .libc_installation = comp.libc_installation,
6356 .emit_bin = .{
6357 .directory = null, // Put it in the cache directory.
6358 .basename = bin_basename,
6359 },
67556360 .function_sections = true,
67566361 .data_sections = true,
67576362 .no_builtin = true,
6758 .want_sanitize_c = false,
6759 .want_stack_check = false,
6760 .want_stack_protector = 0,
6761 .want_red_zone = comp.bin_file.options.red_zone,
6762 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
6763 .want_valgrind = false,
6764 .want_tsan = false,
6765 .want_unwind_tables = comp.bin_file.options.eh_frame_hdr,
6766 .want_pic = comp.bin_file.options.pic,
6767 .want_pie = null,
67686363 .emit_h = null,
6769 .strip = comp.compilerRtStrip(),
6770 .is_native_os = comp.bin_file.options.is_native_os,
6771 .is_native_abi = comp.bin_file.options.is_native_abi,
6772 .self_exe_path = comp.self_exe_path,
67736364 .verbose_cc = comp.verbose_cc,
6774 .verbose_link = comp.bin_file.options.verbose_link,
6365 .verbose_link = comp.verbose_link,
67756366 .verbose_air = comp.verbose_air,
67766367 .verbose_intern_pool = comp.verbose_intern_pool,
67776368 .verbose_generic_instances = comp.verbose_intern_pool,
......@@ -6781,20 +6372,13 @@ fn buildOutputFromZig(
67816372 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
67826373 .clang_passthrough_mode = comp.clang_passthrough_mode,
67836374 .skip_linker_dependencies = true,
6784 .link_libc = comp.bin_file.options.link_libc,
6785 .want_structured_cfg = comp.bin_file.options.want_structured_cfg,
67866375 });
67876376 defer sub_compilation.destroy();
67886377
67896378 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
67906379
67916380 assert(out.* == null);
6792 out.* = Compilation.CRTFile{
6793 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
6794 sub_compilation.bin_file.options.emit.?.sub_path,
6795 }),
6796 .lock = sub_compilation.bin_file.toOwnedLock(),
6797 };
6381 out.* = try sub_compilation.toCrtFile();
67986382}
67996383
68006384pub fn build_crt_file(
......@@ -6803,56 +6387,89 @@ pub fn build_crt_file(
68036387 output_mode: std.builtin.OutputMode,
68046388 misc_task_tag: MiscTask,
68056389 prog_node: *std.Progress.Node,
6806 c_source_files: []const Compilation.CSourceFile,
6390 /// These elements have to get mutated to add the owner module after it is
6391 /// created within this function.
6392 c_source_files: []CSourceFile,
68076393) !void {
68086394 const tracy_trace = trace(@src());
68096395 defer tracy_trace.end();
68106396
6811 const target = comp.getTarget();
6812 const basename = try std.zig.binNameAlloc(comp.gpa, .{
6397 const gpa = comp.gpa;
6398 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
6399 defer arena_allocator.deinit();
6400 const arena = arena_allocator.allocator();
6401
6402 const basename = try std.zig.binNameAlloc(gpa, .{
68136403 .root_name = root_name,
6814 .target = target,
6404 .target = comp.root_mod.resolved_target.result,
68156405 .output_mode = output_mode,
68166406 });
6817 errdefer comp.gpa.free(basename);
68186407
6819 const sub_compilation = try Compilation.create(comp.gpa, .{
6408 const config = try Config.resolve(.{
6409 .output_mode = output_mode,
6410 .resolved_target = comp.root_mod.resolved_target,
6411 .is_test = false,
6412 .have_zcu = false,
6413 .emit_bin = true,
6414 .root_optimize_mode = comp.compilerRtOptMode(),
6415 .root_strip = comp.compilerRtStrip(),
6416 .link_libc = false,
6417 .lto = switch (output_mode) {
6418 .Lib => comp.config.lto,
6419 .Obj, .Exe => false,
6420 },
6421 });
6422 const root_mod = try Package.Module.create(arena, .{
6423 .global_cache_directory = comp.global_cache_directory,
6424 .paths = .{
6425 .root = .{ .root_dir = comp.zig_lib_directory },
6426 .root_src_path = "",
6427 },
6428 .fully_qualified_name = "root",
6429 .inherited = .{
6430 .resolved_target = comp.root_mod.resolved_target,
6431 .strip = comp.compilerRtStrip(),
6432 .stack_check = false,
6433 .stack_protector = 0,
6434 .sanitize_c = false,
6435 .sanitize_thread = false,
6436 .red_zone = comp.root_mod.red_zone,
6437 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
6438 .valgrind = false,
6439 .unwind_tables = false,
6440 .pic = comp.root_mod.pic,
6441 .optimize_mode = comp.compilerRtOptMode(),
6442 .structured_cfg = comp.root_mod.structured_cfg,
6443 },
6444 .global = config,
6445 .cc_argv = &.{},
6446 .parent = null,
6447 .builtin_mod = null,
6448 });
6449
6450 for (c_source_files) |*item| {
6451 item.owner = root_mod;
6452 }
6453
6454 const sub_compilation = try Compilation.create(gpa, arena, .{
68206455 .local_cache_directory = comp.global_cache_directory,
68216456 .global_cache_directory = comp.global_cache_directory,
68226457 .zig_lib_directory = comp.zig_lib_directory,
6458 .self_exe_path = comp.self_exe_path,
68236459 .cache_mode = .whole,
6824 .target = target,
6460 .config = config,
6461 .root_mod = root_mod,
68256462 .root_name = root_name,
6826 .main_mod = null,
6827 .output_mode = output_mode,
68286463 .thread_pool = comp.thread_pool,
6829 .libc_installation = comp.bin_file.options.libc_installation,
6464 .libc_installation = comp.libc_installation,
68306465 .emit_bin = .{
68316466 .directory = null, // Put it in the cache directory.
68326467 .basename = basename,
68336468 },
6834 .optimize_mode = comp.compilerRtOptMode(),
6835 .want_sanitize_c = false,
6836 .want_stack_check = false,
6837 .want_stack_protector = 0,
6838 .want_red_zone = comp.bin_file.options.red_zone,
6839 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
6840 .want_valgrind = false,
6841 .want_tsan = false,
6842 .want_pic = comp.bin_file.options.pic,
6843 .want_pie = null,
6844 .want_lto = switch (output_mode) {
6845 .Lib => comp.bin_file.options.lto,
6846 .Obj, .Exe => false,
6847 },
68486469 .emit_h = null,
6849 .strip = comp.compilerRtStrip(),
6850 .is_native_os = comp.bin_file.options.is_native_os,
6851 .is_native_abi = comp.bin_file.options.is_native_abi,
6852 .self_exe_path = comp.self_exe_path,
68536470 .c_source_files = c_source_files,
68546471 .verbose_cc = comp.verbose_cc,
6855 .verbose_link = comp.bin_file.options.verbose_link,
6472 .verbose_link = comp.verbose_link,
68566473 .verbose_air = comp.verbose_air,
68576474 .verbose_intern_pool = comp.verbose_intern_pool,
68586475 .verbose_generic_instances = comp.verbose_generic_instances,
......@@ -6862,21 +6479,22 @@ pub fn build_crt_file(
68626479 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
68636480 .clang_passthrough_mode = comp.clang_passthrough_mode,
68646481 .skip_linker_dependencies = true,
6865 .link_libc = comp.bin_file.options.link_libc,
6866 .want_structured_cfg = comp.bin_file.options.want_structured_cfg,
68676482 });
68686483 defer sub_compilation.destroy();
68696484
68706485 try comp.updateSubCompilation(sub_compilation, misc_task_tag, prog_node);
68716486
6872 try comp.crt_files.ensureUnusedCapacity(comp.gpa, 1);
6487 try comp.crt_files.ensureUnusedCapacity(gpa, 1);
6488 comp.crt_files.putAssumeCapacityNoClobber(basename, try sub_compilation.toCrtFile());
6489}
68736490
6874 comp.crt_files.putAssumeCapacityNoClobber(basename, .{
6875 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
6876 sub_compilation.bin_file.options.emit.?.sub_path,
6491pub fn toCrtFile(comp: *Compilation) Allocator.Error!CRTFile {
6492 return .{
6493 .full_object_path = try comp.local_cache_directory.join(comp.gpa, &.{
6494 comp.cache_use.whole.bin_sub_path.?,
68776495 }),
6878 .lock = sub_compilation.bin_file.toOwnedLock(),
6879 });
6496 .lock = comp.cache_use.whole.moveLock(),
6497 };
68806498}
68816499
68826500pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
......@@ -6884,21 +6502,24 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
68846502 // This can happen when the user uses `build-exe foo.obj -lkernel32` and
68856503 // then when we create a sub-Compilation for zig libc, it also tries to
68866504 // build kernel32.lib.
6887 if (comp.bin_file.options.skip_linker_dependencies) return;
6505 if (comp.skip_linker_dependencies) return;
68886506
68896507 // This happens when an `extern "foo"` function is referenced.
68906508 // If we haven't seen this library yet and we're targeting Windows, we need
68916509 // to queue up a work item to produce the DLL import library for this.
6892 const gop = try comp.bin_file.options.system_libs.getOrPut(comp.gpa, lib_name);
6893 if (!gop.found_existing and comp.getTarget().os.tag == .windows) {
6510 const gop = try comp.system_libs.getOrPut(comp.gpa, lib_name);
6511 if (!gop.found_existing) {
68946512 gop.value_ptr.* = .{
68956513 .needed = true,
68966514 .weak = false,
68976515 .path = null,
68986516 };
6899 try comp.work_queue.writeItem(.{
6900 .windows_import_lib = comp.bin_file.options.system_libs.count() - 1,
6901 });
6517 const target = comp.root_mod.resolved_target.result;
6518 if (target.os.tag == .windows and target.ofmt != .c) {
6519 try comp.work_queue.writeItem(.{
6520 .windows_import_lib = comp.system_libs.count() - 1,
6521 });
6522 }
69026523 }
69036524}
69046525
......@@ -6906,10 +6527,11 @@ pub fn addLinkLib(comp: *Compilation, lib_name: []const u8) !void {
69066527/// compiler-rt, libcxx, libc, libunwind, etc.
69076528pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {
69086529 if (comp.debug_compiler_runtime_libs) {
6909 return comp.bin_file.options.optimize_mode;
6530 return comp.root_mod.optimize_mode;
69106531 }
6911 switch (comp.bin_file.options.optimize_mode) {
6912 .Debug, .ReleaseSafe => return target_util.defaultCompilerRtOptimizeMode(comp.getTarget()),
6532 const target = comp.root_mod.resolved_target.result;
6533 switch (comp.root_mod.optimize_mode) {
6534 .Debug, .ReleaseSafe => return target_util.defaultCompilerRtOptimizeMode(target),
69136535 .ReleaseFast => return .ReleaseFast,
69146536 .ReleaseSmall => return .ReleaseSmall,
69156537 }
......@@ -6918,5 +6540,5 @@ pub fn compilerRtOptMode(comp: Compilation) std.builtin.OptimizeMode {
69186540/// This decides whether to strip debug info for all zig-provided libraries, including
69196541/// compiler-rt, libcxx, libc, libunwind, etc.
69206542pub fn compilerRtStrip(comp: Compilation) bool {
6921 return comp.bin_file.options.strip;
6543 return comp.root_mod.strip;
69226544}
src/Compilation/Config.zig created+512
......@@ -0,0 +1,512 @@
1//! User-specified settings that have all the defaults resolved into concrete
2//! values. These values are observable before calling Compilation.create for
3//! the benefit of Module creation API, which needs access to these details in
4//! order to resolve per-Module defaults.
5
6have_zcu: bool,
7output_mode: std.builtin.OutputMode,
8link_mode: std.builtin.LinkMode,
9link_libc: bool,
10link_libcpp: bool,
11link_libunwind: bool,
12/// True if and only if the c_source_files field will have nonzero length when
13/// calling Compilation.create.
14any_c_source_files: bool,
15/// This is true if any Module has unwind_tables set explicitly to true. Until
16/// Compilation.create is called, it is possible for this to be false while in
17/// fact all Module instances have unwind_tables=true due to the default
18/// being unwind_tables=true. After Compilation.create is called this will
19/// also take into account the default setting, making this value true if and
20/// only if any Module has unwind_tables set to true.
21any_unwind_tables: bool,
22/// This is true if any Module has single_threaded set explicitly to false. Until
23/// Compilation.create is called, it is possible for this to be false while in
24/// fact all Module instances have single_threaded=false due to the default
25/// being non-single-threaded. After Compilation.create is called this will
26/// also take into account the default setting, making this value true if and
27/// only if any Module has single_threaded set to false.
28any_non_single_threaded: bool,
29/// This is true if and only if any Module has error_tracing set to true.
30/// Function types and function calling convention depend on this global value,
31/// however, other kinds of error tracing are omitted depending on the
32/// per-Module setting.
33any_error_tracing: bool,
34any_sanitize_thread: bool,
35pie: bool,
36/// If this is true then linker code is responsible for making an LLVM IR
37/// Module, outputting it to an object file, and then linking that together
38/// with link options and other objects. Otherwise (depending on `use_lld`)
39/// linker code directly outputs and updates the final binary.
40use_llvm: bool,
41/// Whether or not the LLVM library API will be used by the LLVM backend.
42use_lib_llvm: bool,
43/// If this is true then linker code is responsible for outputting an object
44/// file and then using LLD to link it together with the link options and other
45/// objects. Otherwise (depending on `use_llvm`) linker code directly outputs
46/// and updates the final binary.
47use_lld: bool,
48c_frontend: CFrontend,
49lto: bool,
50/// WASI-only. Type of WASI execution model ("command" or "reactor").
51/// Always set to `command` for non-WASI targets.
52wasi_exec_model: std.builtin.WasiExecModel,
53import_memory: bool,
54export_memory: bool,
55shared_memory: bool,
56is_test: bool,
57test_evented_io: bool,
58debug_format: DebugFormat,
59root_strip: bool,
60root_error_tracing: bool,
61dll_export_fns: bool,
62rdynamic: bool,
63
64pub const CFrontend = enum { clang, aro };
65
66pub const DebugFormat = union(enum) {
67 strip,
68 dwarf: std.dwarf.Format,
69 code_view,
70};
71
72pub const Options = struct {
73 output_mode: std.builtin.OutputMode,
74 resolved_target: Module.ResolvedTarget,
75 is_test: bool,
76 have_zcu: bool,
77 emit_bin: bool,
78 root_optimize_mode: ?std.builtin.OptimizeMode = null,
79 root_strip: ?bool = null,
80 root_error_tracing: ?bool = null,
81 link_mode: ?std.builtin.LinkMode = null,
82 ensure_libc_on_non_freestanding: bool = false,
83 ensure_libcpp_on_non_freestanding: bool = false,
84 any_non_single_threaded: bool = false,
85 any_sanitize_thread: bool = false,
86 any_unwind_tables: bool = false,
87 any_dyn_libs: bool = false,
88 any_c_source_files: bool = false,
89 any_non_stripped: bool = false,
90 any_error_tracing: bool = false,
91 emit_llvm_ir: bool = false,
92 emit_llvm_bc: bool = false,
93 link_libc: ?bool = null,
94 link_libcpp: ?bool = null,
95 link_libunwind: ?bool = null,
96 pie: ?bool = null,
97 use_llvm: ?bool = null,
98 use_lib_llvm: ?bool = null,
99 use_lld: ?bool = null,
100 use_clang: ?bool = null,
101 lto: ?bool = null,
102 /// WASI-only. Type of WASI execution model ("command" or "reactor").
103 wasi_exec_model: ?std.builtin.WasiExecModel = null,
104 import_memory: ?bool = null,
105 export_memory: ?bool = null,
106 shared_memory: ?bool = null,
107 test_evented_io: bool = false,
108 debug_format: ?DebugFormat = null,
109 dll_export_fns: ?bool = null,
110 rdynamic: ?bool = null,
111};
112
113pub const ResolveError = error{
114 WasiExecModelRequiresWasi,
115 SharedMemoryIsWasmOnly,
116 ObjectFilesCannotShareMemory,
117 SharedMemoryRequiresAtomicsAndBulkMemory,
118 ThreadsRequireSharedMemory,
119 EmittingLlvmModuleRequiresLlvmBackend,
120 LlvmLacksTargetSupport,
121 ZigLacksTargetSupport,
122 EmittingBinaryRequiresLlvmLibrary,
123 LldIncompatibleObjectFormat,
124 LtoRequiresLld,
125 SanitizeThreadRequiresLibCpp,
126 LibCppRequiresLibUnwind,
127 OsRequiresLibC,
128 LibCppRequiresLibC,
129 LibUnwindRequiresLibC,
130 TargetCannotDynamicLink,
131 LibCRequiresDynamicLinking,
132 SharedLibrariesRequireDynamicLinking,
133 ExportMemoryAndDynamicIncompatible,
134 DynamicLibraryPrecludesPie,
135 TargetRequiresPie,
136 SanitizeThreadRequiresPie,
137 BackendLacksErrorTracing,
138 LlvmLibraryUnavailable,
139 LldUnavailable,
140 ClangUnavailable,
141 DllExportFnsRequiresWindows,
142};
143
144pub fn resolve(options: Options) ResolveError!Config {
145 const target = options.resolved_target.result;
146
147 // WASI-only. Resolve the optional exec-model option, defaults to command.
148 if (target.os.tag != .wasi and options.wasi_exec_model != null)
149 return error.WasiExecModelRequiresWasi;
150 const wasi_exec_model = options.wasi_exec_model orelse .command;
151
152 const shared_memory = b: {
153 if (!target.cpu.arch.isWasm()) {
154 if (options.shared_memory == true) return error.SharedMemoryIsWasmOnly;
155 break :b false;
156 }
157 if (options.output_mode == .Obj) {
158 if (options.shared_memory == true) return error.ObjectFilesCannotShareMemory;
159 break :b false;
160 }
161 if (!std.Target.wasm.featureSetHasAll(target.cpu.features, .{ .atomics, .bulk_memory })) {
162 if (options.shared_memory == true)
163 return error.SharedMemoryRequiresAtomicsAndBulkMemory;
164 break :b false;
165 }
166 if (options.any_non_single_threaded) {
167 if (options.shared_memory == false)
168 return error.ThreadsRequireSharedMemory;
169 break :b true;
170 }
171 break :b options.shared_memory orelse false;
172 };
173
174 // *If* the LLVM backend were to be selected, should Zig use the LLVM
175 // library to build the LLVM module?
176 const use_lib_llvm = b: {
177 if (!build_options.have_llvm) {
178 if (options.use_lib_llvm == true) return error.LlvmLibraryUnavailable;
179 break :b false;
180 }
181 break :b options.use_lib_llvm orelse true;
182 };
183
184 const root_optimize_mode = options.root_optimize_mode orelse .Debug;
185
186 // Make a decision on whether to use LLVM backend for machine code generation.
187 // Note that using the LLVM backend does not necessarily mean using LLVM libraries.
188 // For example, Zig can emit .bc and .ll files directly, and this is still considered
189 // using "the LLVM backend".
190 const use_llvm = b: {
191 // If we have no zig code to compile, no need for LLVM.
192 if (!options.have_zcu) break :b false;
193
194 // If emitting to LLVM bitcode object format, must use LLVM backend.
195 if (options.emit_llvm_ir or options.emit_llvm_bc) {
196 if (options.use_llvm == false)
197 return error.EmittingLlvmModuleRequiresLlvmBackend;
198 if (!target_util.hasLlvmSupport(target, target.ofmt))
199 return error.LlvmLacksTargetSupport;
200
201 break :b true;
202 }
203
204 // If LLVM does not support the target, then we can't use it.
205 if (!target_util.hasLlvmSupport(target, target.ofmt)) {
206 if (options.use_llvm == true) return error.LlvmLacksTargetSupport;
207 break :b false;
208 }
209
210 // If Zig does not support the target, then we can't use it.
211 if (target_util.zigBackend(target, false) == .other) {
212 if (options.use_llvm == false) return error.ZigLacksTargetSupport;
213 break :b true;
214 }
215
216 if (options.use_llvm) |x| break :b x;
217
218 // If we cannot use LLVM libraries, then our own backends will be a
219 // better default since the LLVM backend can only produce bitcode
220 // and not an object file or executable.
221 if (!use_lib_llvm and options.emit_bin) break :b false;
222
223 // Prefer LLVM for release builds.
224 if (root_optimize_mode != .Debug) break :b true;
225
226 // At this point we would prefer to use our own self-hosted backend,
227 // because the compilation speed is better than LLVM. But only do it if
228 // we are confident in the robustness of the backend.
229 break :b !target_util.selfHostedBackendIsAsRobustAsLlvm(target);
230 };
231
232 if (options.emit_bin and options.have_zcu) {
233 if (!use_lib_llvm and use_llvm) {
234 // Explicit request to use LLVM to produce an object file, but without
235 // using LLVM libraries. Impossible.
236 return error.EmittingBinaryRequiresLlvmLibrary;
237 }
238
239 if (target_util.zigBackend(target, use_llvm) == .other) {
240 // There is no compiler backend available for this target.
241 return error.ZigLacksTargetSupport;
242 }
243 }
244
245 // Make a decision on whether to use LLD or our own linker.
246 const use_lld = b: {
247 if (!target_util.hasLldSupport(target.ofmt)) {
248 if (options.use_lld == true) return error.LldIncompatibleObjectFormat;
249 break :b false;
250 }
251
252 if (!build_options.have_llvm) {
253 if (options.use_lld == true) return error.LldUnavailable;
254 break :b false;
255 }
256
257 if (options.lto == true) {
258 if (options.use_lld == false) return error.LtoRequiresLld;
259 break :b true;
260 }
261
262 if (options.use_lld) |x| break :b x;
263 break :b true;
264 };
265
266 // Make a decision on whether to use Clang or Aro for translate-c and compiling C files.
267 const c_frontend: CFrontend = b: {
268 if (!build_options.have_llvm) {
269 if (options.use_clang == true) return error.ClangUnavailable;
270 break :b .aro;
271 }
272 if (options.use_clang) |clang| {
273 break :b if (clang) .clang else .aro;
274 }
275 break :b .clang;
276 };
277
278 const lto = b: {
279 if (!use_lld) {
280 // zig ld LTO support is tracked by
281 // https://github.com/ziglang/zig/issues/8680
282 if (options.lto == true) return error.LtoRequiresLld;
283 break :b false;
284 }
285
286 if (options.lto) |x| break :b x;
287 if (!options.any_c_source_files) break :b false;
288
289 if (target.cpu.arch.isRISCV()) {
290 // Clang and LLVM currently don't support RISC-V target-abi for LTO.
291 // Compiling with LTO may fail or produce undesired results.
292 // See https://reviews.llvm.org/D71387
293 // See https://reviews.llvm.org/D102582
294 break :b false;
295 }
296
297 break :b switch (options.output_mode) {
298 .Lib, .Obj => false,
299 .Exe => switch (root_optimize_mode) {
300 .Debug => false,
301 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => true,
302 },
303 };
304 };
305
306 const link_libcpp = b: {
307 if (options.link_libcpp == true) break :b true;
308 if (options.any_sanitize_thread) {
309 // TSAN is (for now...) implemented in C++ so it requires linking libc++.
310 if (options.link_libcpp == false) return error.SanitizeThreadRequiresLibCpp;
311 break :b true;
312 }
313 if (options.ensure_libcpp_on_non_freestanding and target.os.tag != .freestanding)
314 break :b true;
315
316 break :b false;
317 };
318
319 const link_libunwind = b: {
320 if (link_libcpp and target_util.libcNeedsLibUnwind(target)) {
321 if (options.link_libunwind == false) return error.LibCppRequiresLibUnwind;
322 break :b true;
323 }
324 break :b options.link_libunwind orelse false;
325 };
326
327 const link_libc = b: {
328 if (target_util.osRequiresLibC(target)) {
329 if (options.link_libc == false) return error.OsRequiresLibC;
330 break :b true;
331 }
332 if (link_libcpp) {
333 if (options.link_libc == false) return error.LibCppRequiresLibC;
334 break :b true;
335 }
336 if (link_libunwind) {
337 if (options.link_libc == false) return error.LibUnwindRequiresLibC;
338 break :b true;
339 }
340 if (options.link_libc) |x| break :b x;
341 if (options.ensure_libc_on_non_freestanding and target.os.tag != .freestanding)
342 break :b true;
343
344 break :b false;
345 };
346
347 const any_unwind_tables = options.any_unwind_tables or
348 link_libunwind or target_util.needUnwindTables(target);
349
350 const link_mode = b: {
351 const explicitly_exe_or_dyn_lib = switch (options.output_mode) {
352 .Obj => false,
353 .Lib => (options.link_mode orelse .Static) == .Dynamic,
354 .Exe => true,
355 };
356
357 if (target_util.cannotDynamicLink(target)) {
358 if (options.link_mode == .Dynamic) return error.TargetCannotDynamicLink;
359 break :b .Static;
360 }
361 if (explicitly_exe_or_dyn_lib and link_libc and
362 (target.isGnuLibC() or target_util.osRequiresLibC(target)))
363 {
364 if (options.link_mode == .Static) return error.LibCRequiresDynamicLinking;
365 break :b .Dynamic;
366 }
367 // When creating a executable that links to system libraries, we
368 // require dynamic linking, but we must not link static libraries
369 // or object files dynamically!
370 if (options.any_dyn_libs and options.output_mode == .Exe) {
371 if (options.link_mode == .Static) return error.SharedLibrariesRequireDynamicLinking;
372 break :b .Dynamic;
373 }
374
375 if (options.link_mode) |link_mode| break :b link_mode;
376
377 if (explicitly_exe_or_dyn_lib and link_libc and
378 options.resolved_target.is_native_abi and target.abi.isMusl())
379 {
380 // If targeting the system's native ABI and the system's libc is
381 // musl, link dynamically by default.
382 break :b .Dynamic;
383 }
384
385 // Static is generally a better default. Fight me.
386 break :b .Static;
387 };
388
389 const import_memory = options.import_memory orelse (options.output_mode == .Obj);
390 const export_memory = b: {
391 if (link_mode == .Dynamic) {
392 if (options.export_memory == true) return error.ExportMemoryAndDynamicIncompatible;
393 break :b false;
394 }
395 if (options.export_memory) |x| break :b x;
396 break :b !import_memory;
397 };
398
399 const pie: bool = b: {
400 switch (options.output_mode) {
401 .Obj, .Exe => {},
402 .Lib => if (link_mode == .Dynamic) {
403 if (options.pie == true) return error.DynamicLibraryPrecludesPie;
404 break :b false;
405 },
406 }
407 if (target_util.requiresPIE(target)) {
408 if (options.pie == false) return error.TargetRequiresPie;
409 break :b true;
410 }
411 if (options.any_sanitize_thread) {
412 if (options.pie == false) return error.SanitizeThreadRequiresPie;
413 break :b true;
414 }
415 if (options.pie) |pie| break :b pie;
416 break :b false;
417 };
418
419 const root_strip = b: {
420 if (options.root_strip) |x| break :b x;
421 if (root_optimize_mode == .ReleaseSmall) break :b true;
422 if (!target_util.hasDebugInfo(target)) break :b true;
423 break :b false;
424 };
425
426 const debug_format: DebugFormat = b: {
427 if (root_strip and !options.any_non_stripped) break :b .strip;
428 break :b switch (target.ofmt) {
429 .elf, .macho, .wasm => .{ .dwarf = .@"32" },
430 .coff => .code_view,
431 .c => switch (target.os.tag) {
432 .windows, .uefi => .code_view,
433 else => .{ .dwarf = .@"32" },
434 },
435 .spirv, .nvptx, .dxcontainer, .hex, .raw, .plan9 => .strip,
436 };
437 };
438
439 const backend_supports_error_tracing = target_util.backendSupportsFeature(
440 target.cpu.arch,
441 target.ofmt,
442 use_llvm,
443 .error_return_trace,
444 );
445
446 const root_error_tracing = b: {
447 if (options.root_error_tracing) |x| break :b x;
448 if (root_strip) break :b false;
449 if (!backend_supports_error_tracing) break :b false;
450 break :b switch (root_optimize_mode) {
451 .Debug => true,
452 .ReleaseSafe, .ReleaseFast, .ReleaseSmall => false,
453 };
454 };
455
456 const any_error_tracing = root_error_tracing or options.any_error_tracing;
457 if (any_error_tracing and !backend_supports_error_tracing)
458 return error.BackendLacksErrorTracing;
459
460 const rdynamic = options.rdynamic orelse false;
461
462 const dll_export_fns = b: {
463 if (target.os.tag != .windows) {
464 if (options.dll_export_fns == true)
465 return error.DllExportFnsRequiresWindows;
466 break :b false;
467 }
468 if (options.dll_export_fns) |x| break :b x;
469 if (rdynamic) break :b true;
470 break :b switch (options.output_mode) {
471 .Obj, .Exe => false,
472 .Lib => link_mode == .Dynamic,
473 };
474 };
475
476 return .{
477 .output_mode = options.output_mode,
478 .have_zcu = options.have_zcu,
479 .is_test = options.is_test,
480 .test_evented_io = options.test_evented_io,
481 .link_mode = link_mode,
482 .link_libc = link_libc,
483 .link_libcpp = link_libcpp,
484 .link_libunwind = link_libunwind,
485 .any_unwind_tables = any_unwind_tables,
486 .any_c_source_files = options.any_c_source_files,
487 .any_non_single_threaded = options.any_non_single_threaded,
488 .any_error_tracing = any_error_tracing,
489 .any_sanitize_thread = options.any_sanitize_thread,
490 .root_error_tracing = root_error_tracing,
491 .pie = pie,
492 .lto = lto,
493 .import_memory = import_memory,
494 .export_memory = export_memory,
495 .shared_memory = shared_memory,
496 .c_frontend = c_frontend,
497 .use_llvm = use_llvm,
498 .use_lib_llvm = use_lib_llvm,
499 .use_lld = use_lld,
500 .wasi_exec_model = wasi_exec_model,
501 .debug_format = debug_format,
502 .root_strip = root_strip,
503 .dll_export_fns = dll_export_fns,
504 .rdynamic = rdynamic,
505 };
506}
507
508const std = @import("std");
509const Module = @import("../Package.zig").Module;
510const Config = @This();
511const target_util = @import("../target.zig");
512const build_options = @import("build_options");
src/Module.zig+258-300
......@@ -14,7 +14,9 @@ const BigIntMutable = std.math.big.int.Mutable;
1414const Target = std.Target;
1515const Ast = std.zig.Ast;
1616
17const Module = @This();
17/// Deprecated, use `Zcu`.
18const Module = Zcu;
19const Zcu = @This();
1820const Compilation = @import("Compilation.zig");
1921const Cache = std.Build.Cache;
2022const Value = @import("value.zig").Value;
......@@ -35,6 +37,7 @@ const clang = @import("clang.zig");
3537const InternPool = @import("InternPool.zig");
3638const Alignment = InternPool.Alignment;
3739const BuiltinFn = std.zig.BuiltinFn;
40const LlvmObject = @import("codegen/llvm.zig").Object;
3841
3942comptime {
4043 @setEvalBranchQuota(4000);
......@@ -51,14 +54,17 @@ comptime {
5154/// General-purpose allocator. Used for both temporary and long-term storage.
5255gpa: Allocator,
5356comp: *Compilation,
57/// Usually, the LlvmObject is managed by linker code, however, in the case
58/// that -fno-emit-bin is specified, the linker code never executes, so we
59/// store the LlvmObject here.
60llvm_object: ?*LlvmObject,
5461
55/// Where build artifacts and incremental compilation metadata serialization go.
56zig_cache_artifact_directory: Compilation.Directory,
5762/// Pointer to externally managed resource.
5863root_mod: *Package.Module,
5964/// Normally, `main_mod` and `root_mod` are the same. The exception is `zig test`, in which
6065/// `root_mod` is the test runner, and `main_mod` is the user's source file which has the tests.
6166main_mod: *Package.Module,
67std_mod: *Package.Module,
6268sema_prog_node: std.Progress.Node = undefined,
6369
6470/// Used by AstGen worker to load and store ZIR cache.
......@@ -153,8 +159,6 @@ stage1_flags: packed struct {
153159 reserved: u2 = 0,
154160} = .{},
155161
156job_queued_update_builtin_zig: bool = true,
157
158162compile_log_text: ArrayListUnmanaged(u8) = .{},
159163
160164emit_h: ?*GlobalEmitH,
......@@ -622,7 +626,8 @@ pub const Decl = struct {
622626 // Sanitize the name for nvptx which is more restrictive.
623627 // TODO This should be handled by the backend, not the frontend. Have a
624628 // look at how the C backend does it for inspiration.
625 if (mod.comp.bin_file.options.target.cpu.arch.isNvptx()) {
629 const cpu_arch = mod.root_mod.resolved_target.result.cpu.arch;
630 if (cpu_arch.isNvptx()) {
626631 for (ip.string_bytes.items[start..]) |*byte| switch (byte.*) {
627632 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
628633 else => {},
......@@ -949,15 +954,21 @@ pub const File = struct {
949954
950955 pub fn deinit(file: *File, mod: *Module) void {
951956 const gpa = mod.gpa;
957 const is_builtin = file.mod.isBuiltin();
952958 log.debug("deinit File {s}", .{file.sub_file_path});
959 if (is_builtin) {
960 file.unloadTree(gpa);
961 file.unloadZir(gpa);
962 } else {
963 gpa.free(file.sub_file_path);
964 file.unload(gpa);
965 }
953966 file.deleted_decls.deinit(gpa);
954967 file.outdated_decls.deinit(gpa);
955968 file.references.deinit(gpa);
956969 if (file.root_decl.unwrap()) |root_decl| {
957970 mod.destroyDecl(root_decl);
958971 }
959 gpa.free(file.sub_file_path);
960 file.unload(gpa);
961972 if (file.prev_zir) |prev_zir| {
962973 prev_zir.deinit(gpa);
963974 gpa.destroy(prev_zir);
......@@ -1019,8 +1030,9 @@ pub const File = struct {
10191030
10201031 pub fn destroy(file: *File, mod: *Module) void {
10211032 const gpa = mod.gpa;
1033 const is_builtin = file.mod.isBuiltin();
10221034 file.deinit(mod);
1023 gpa.destroy(file);
1035 if (!is_builtin) gpa.destroy(file);
10241036 }
10251037
10261038 pub fn renderFullyQualifiedName(file: File, writer: anytype) !void {
......@@ -2469,108 +2481,111 @@ pub fn init(mod: *Module) !void {
24692481 try mod.global_error_set.put(gpa, .empty, {});
24702482}
24712483
2472pub fn deinit(mod: *Module) void {
2473 const gpa = mod.gpa;
2484pub fn deinit(zcu: *Zcu) void {
2485 const gpa = zcu.gpa;
24742486
2475 for (mod.import_table.keys()) |key| {
2487 if (zcu.llvm_object) |llvm_object| {
2488 if (build_options.only_c) unreachable;
2489 llvm_object.deinit();
2490 }
2491
2492 for (zcu.import_table.keys()) |key| {
24762493 gpa.free(key);
24772494 }
2478 var failed_decls = mod.failed_decls;
2479 mod.failed_decls = .{};
2480 for (mod.import_table.values()) |value| {
2481 value.destroy(mod);
2495 var failed_decls = zcu.failed_decls;
2496 zcu.failed_decls = .{};
2497 for (zcu.import_table.values()) |value| {
2498 value.destroy(zcu);
24822499 }
2483 mod.import_table.deinit(gpa);
2500 zcu.import_table.deinit(gpa);
24842501
2485 for (mod.embed_table.keys(), mod.embed_table.values()) |path, embed_file| {
2502 for (zcu.embed_table.keys(), zcu.embed_table.values()) |path, embed_file| {
24862503 gpa.free(path);
24872504 gpa.destroy(embed_file);
24882505 }
2489 mod.embed_table.deinit(gpa);
2506 zcu.embed_table.deinit(gpa);
24902507
2491 mod.compile_log_text.deinit(gpa);
2508 zcu.compile_log_text.deinit(gpa);
24922509
2493 mod.zig_cache_artifact_directory.handle.close();
2494 mod.local_zir_cache.handle.close();
2495 mod.global_zir_cache.handle.close();
2510 zcu.local_zir_cache.handle.close();
2511 zcu.global_zir_cache.handle.close();
24962512
24972513 for (failed_decls.values()) |value| {
24982514 value.destroy(gpa);
24992515 }
25002516 failed_decls.deinit(gpa);
25012517
2502 if (mod.emit_h) |emit_h| {
2518 if (zcu.emit_h) |emit_h| {
25032519 for (emit_h.failed_decls.values()) |value| {
25042520 value.destroy(gpa);
25052521 }
25062522 emit_h.failed_decls.deinit(gpa);
25072523 emit_h.decl_table.deinit(gpa);
25082524 emit_h.allocated_emit_h.deinit(gpa);
2509 gpa.destroy(emit_h);
25102525 }
25112526
2512 for (mod.failed_files.values()) |value| {
2527 for (zcu.failed_files.values()) |value| {
25132528 if (value) |msg| msg.destroy(gpa);
25142529 }
2515 mod.failed_files.deinit(gpa);
2530 zcu.failed_files.deinit(gpa);
25162531
2517 for (mod.failed_embed_files.values()) |msg| {
2532 for (zcu.failed_embed_files.values()) |msg| {
25182533 msg.destroy(gpa);
25192534 }
2520 mod.failed_embed_files.deinit(gpa);
2535 zcu.failed_embed_files.deinit(gpa);
25212536
2522 for (mod.failed_exports.values()) |value| {
2537 for (zcu.failed_exports.values()) |value| {
25232538 value.destroy(gpa);
25242539 }
2525 mod.failed_exports.deinit(gpa);
2540 zcu.failed_exports.deinit(gpa);
25262541
2527 for (mod.cimport_errors.values()) |*errs| {
2542 for (zcu.cimport_errors.values()) |*errs| {
25282543 errs.deinit(gpa);
25292544 }
2530 mod.cimport_errors.deinit(gpa);
2545 zcu.cimport_errors.deinit(gpa);
25312546
2532 mod.compile_log_decls.deinit(gpa);
2547 zcu.compile_log_decls.deinit(gpa);
25332548
2534 for (mod.decl_exports.values()) |*export_list| {
2549 for (zcu.decl_exports.values()) |*export_list| {
25352550 export_list.deinit(gpa);
25362551 }
2537 mod.decl_exports.deinit(gpa);
2552 zcu.decl_exports.deinit(gpa);
25382553
2539 for (mod.value_exports.values()) |*export_list| {
2554 for (zcu.value_exports.values()) |*export_list| {
25402555 export_list.deinit(gpa);
25412556 }
2542 mod.value_exports.deinit(gpa);
2557 zcu.value_exports.deinit(gpa);
25432558
2544 for (mod.export_owners.values()) |*value| {
2559 for (zcu.export_owners.values()) |*value| {
25452560 freeExportList(gpa, value);
25462561 }
2547 mod.export_owners.deinit(gpa);
2562 zcu.export_owners.deinit(gpa);
25482563
2549 mod.global_error_set.deinit(gpa);
2564 zcu.global_error_set.deinit(gpa);
25502565
2551 mod.test_functions.deinit(gpa);
2566 zcu.test_functions.deinit(gpa);
25522567
2553 for (mod.global_assembly.values()) |s| {
2568 for (zcu.global_assembly.values()) |s| {
25542569 gpa.free(s);
25552570 }
2556 mod.global_assembly.deinit(gpa);
2571 zcu.global_assembly.deinit(gpa);
25572572
2558 mod.reference_table.deinit(gpa);
2573 zcu.reference_table.deinit(gpa);
25592574
25602575 {
2561 var it = mod.intern_pool.allocated_namespaces.iterator(0);
2576 var it = zcu.intern_pool.allocated_namespaces.iterator(0);
25622577 while (it.next()) |namespace| {
25632578 namespace.decls.deinit(gpa);
25642579 namespace.usingnamespace_set.deinit(gpa);
25652580 }
25662581 }
25672582
2568 mod.intern_pool.deinit(gpa);
2569 mod.tmp_hack_arena.deinit();
2583 zcu.intern_pool.deinit(gpa);
2584 zcu.tmp_hack_arena.deinit();
25702585
2571 mod.capture_scope_parents.deinit(gpa);
2572 mod.runtime_capture_scopes.deinit(gpa);
2573 mod.comptime_capture_scopes.deinit(gpa);
2586 zcu.capture_scope_parents.deinit(gpa);
2587 zcu.runtime_capture_scopes.deinit(gpa);
2588 zcu.comptime_capture_scopes.deinit(gpa);
25742589}
25752590
25762591pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void {
......@@ -2632,6 +2647,8 @@ comptime {
26322647}
26332648
26342649pub fn astGenFile(mod: *Module, file: *File) !void {
2650 assert(!file.mod.isBuiltin());
2651
26352652 const tracy = trace(@src());
26362653 defer tracy.end();
26372654
......@@ -3076,72 +3093,6 @@ fn updateZirRefs(mod: *Module, file: *File, old_zir: Zir) !void {
30763093 }
30773094}
30783095
3079pub fn populateBuiltinFile(mod: *Module) !void {
3080 const tracy = trace(@src());
3081 defer tracy.end();
3082
3083 const comp = mod.comp;
3084 const builtin_mod, const file = blk: {
3085 comp.mutex.lock();
3086 defer comp.mutex.unlock();
3087
3088 const builtin_mod = mod.main_mod.deps.get("builtin").?;
3089 const result = try mod.importPkg(builtin_mod);
3090 break :blk .{ builtin_mod, result.file };
3091 };
3092 const gpa = mod.gpa;
3093 file.source = try comp.generateBuiltinZigSource(gpa);
3094 file.source_loaded = true;
3095
3096 if (builtin_mod.root.statFile(builtin_mod.root_src_path)) |stat| {
3097 if (stat.size != file.source.len) {
3098 log.warn(
3099 "the cached file '{}{s}' had the wrong size. Expected {d}, found {d}. " ++
3100 "Overwriting with correct file contents now",
3101 .{ builtin_mod.root, builtin_mod.root_src_path, file.source.len, stat.size },
3102 );
3103
3104 try writeBuiltinFile(file, builtin_mod);
3105 } else {
3106 file.stat = .{
3107 .size = stat.size,
3108 .inode = stat.inode,
3109 .mtime = stat.mtime,
3110 };
3111 }
3112 } else |err| switch (err) {
3113 error.BadPathName => unreachable, // it's always "builtin.zig"
3114 error.NameTooLong => unreachable, // it's always "builtin.zig"
3115 error.PipeBusy => unreachable, // it's not a pipe
3116 error.WouldBlock => unreachable, // not asking for non-blocking I/O
3117
3118 error.FileNotFound => try writeBuiltinFile(file, builtin_mod),
3119
3120 else => |e| return e,
3121 }
3122
3123 file.tree = try Ast.parse(gpa, file.source, .zig);
3124 file.tree_loaded = true;
3125 assert(file.tree.errors.len == 0); // builtin.zig must parse
3126
3127 file.zir = try AstGen.generate(gpa, file.tree);
3128 file.zir_loaded = true;
3129 file.status = .success_zir;
3130}
3131
3132fn writeBuiltinFile(file: *File, builtin_mod: *Package.Module) !void {
3133 var af = try builtin_mod.root.atomicFile(builtin_mod.root_src_path, .{});
3134 defer af.deinit();
3135 try af.file.writeAll(file.source);
3136 try af.finish();
3137
3138 file.stat = .{
3139 .size = file.source.len,
3140 .inode = 0, // dummy value
3141 .mtime = 0, // dummy value
3142 };
3143}
3144
31453096pub fn mapOldZirToNew(
31463097 gpa: Allocator,
31473098 old_zir: Zir,
......@@ -3228,6 +3179,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
32283179 .complete => return,
32293180
32303181 .outdated => blk: {
3182 if (build_options.only_c) unreachable;
32313183 // The exports this Decl performs will be re-discovered, so we remove them here
32323184 // prior to re-analysis.
32333185 try mod.deleteDeclExports(decl_index);
......@@ -3280,14 +3232,14 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
32803232 }
32813233}
32823234
3283pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaError!void {
3235pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, func_index: InternPool.Index) SemaError!void {
32843236 const tracy = trace(@src());
32853237 defer tracy.end();
32863238
3287 const ip = &mod.intern_pool;
3288 const func = mod.funcInfo(func_index);
3239 const ip = &zcu.intern_pool;
3240 const func = zcu.funcInfo(func_index);
32893241 const decl_index = func.owner_decl;
3290 const decl = mod.declPtr(decl_index);
3242 const decl = zcu.declPtr(decl_index);
32913243
32923244 switch (decl.analysis) {
32933245 .unreferenced => unreachable,
......@@ -3311,13 +3263,13 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr
33113263 .success => return,
33123264 }
33133265
3314 const gpa = mod.gpa;
3266 const gpa = zcu.gpa;
33153267
33163268 var tmp_arena = std.heap.ArenaAllocator.init(gpa);
33173269 defer tmp_arena.deinit();
33183270 const sema_arena = tmp_arena.allocator();
33193271
3320 var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
3272 var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
33213273 error.AnalysisFail => {
33223274 if (func.analysis(ip).state == .in_progress) {
33233275 // If this decl caused the compile error, the analysis field would
......@@ -3331,25 +3283,22 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr
33313283 };
33323284 defer air.deinit(gpa);
33333285
3334 const comp = mod.comp;
3335
3336 const no_bin_file = (comp.bin_file.options.emit == null and
3337 comp.emit_asm == null and
3338 comp.emit_llvm_ir == null and
3339 comp.emit_llvm_bc == null);
3286 const comp = zcu.comp;
33403287
33413288 const dump_air = builtin.mode == .Debug and comp.verbose_air;
33423289 const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
33433290
3344 if (no_bin_file and !dump_air and !dump_llvm_ir) return;
3291 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
3292 return;
3293 }
33453294
33463295 var liveness = try Liveness.analyze(gpa, air, ip);
33473296 defer liveness.deinit(gpa);
33483297
33493298 if (dump_air) {
3350 const fqn = try decl.getFullyQualifiedName(mod);
3299 const fqn = try decl.getFullyQualifiedName(zcu);
33513300 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
3352 @import("print_air.zig").dump(mod, air, liveness);
3301 @import("print_air.zig").dump(zcu, air, liveness);
33533302 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});
33543303 }
33553304
......@@ -3365,12 +3314,12 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr
33653314 verify.verify() catch |err| switch (err) {
33663315 error.OutOfMemory => return error.OutOfMemory,
33673316 else => {
3368 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
3369 mod.failed_decls.putAssumeCapacityNoClobber(
3317 try zcu.failed_decls.ensureUnusedCapacity(gpa, 1);
3318 zcu.failed_decls.putAssumeCapacityNoClobber(
33703319 decl_index,
33713320 try Module.ErrorMsg.create(
33723321 gpa,
3373 decl.srcLoc(mod),
3322 decl.srcLoc(zcu),
33743323 "invalid liveness: {s}",
33753324 .{@errorName(err)},
33763325 ),
......@@ -3381,27 +3330,32 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func_index: InternPool.Index) SemaEr
33813330 };
33823331 }
33833332
3384 if (no_bin_file and !dump_llvm_ir) return;
3385
3386 comp.bin_file.updateFunc(mod, func_index, air, liveness) catch |err| switch (err) {
3387 error.OutOfMemory => return error.OutOfMemory,
3388 error.AnalysisFail => {
3389 decl.analysis = .codegen_failure;
3390 return;
3391 },
3392 else => {
3393 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
3394 mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
3395 gpa,
3396 decl.srcLoc(mod),
3397 "unable to codegen: {s}",
3398 .{@errorName(err)},
3399 ));
3400 decl.analysis = .codegen_failure_retryable;
3401 return;
3402 },
3403 };
3404 return;
3333 if (comp.bin_file) |lf| {
3334 lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {
3335 error.OutOfMemory => return error.OutOfMemory,
3336 error.AnalysisFail => {
3337 decl.analysis = .codegen_failure;
3338 },
3339 else => {
3340 try zcu.failed_decls.ensureUnusedCapacity(gpa, 1);
3341 zcu.failed_decls.putAssumeCapacityNoClobber(decl_index, try Module.ErrorMsg.create(
3342 gpa,
3343 decl.srcLoc(zcu),
3344 "unable to codegen: {s}",
3345 .{@errorName(err)},
3346 ));
3347 decl.analysis = .codegen_failure_retryable;
3348 },
3349 };
3350 } else if (zcu.llvm_object) |llvm_object| {
3351 if (build_options.only_c) unreachable;
3352 llvm_object.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {
3353 error.OutOfMemory => return error.OutOfMemory,
3354 error.AnalysisFail => {
3355 decl.analysis = .codegen_failure;
3356 },
3357 };
3358 }
34053359 },
34063360 }
34073361}
......@@ -3477,6 +3431,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
34773431 if (file.root_decl != .none) return;
34783432
34793433 const gpa = mod.gpa;
3434 log.debug("semaFile mod={s} sub_file_path={s}", .{
3435 file.mod.fully_qualified_name, file.sub_file_path,
3436 });
34803437
34813438 // Because these three things each reference each other, `undefined`
34823439 // placeholders are used before being set after the struct type gains an
......@@ -3558,25 +3515,29 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
35583515 new_decl.owns_tv = true;
35593516 new_decl.analysis = .complete;
35603517
3561 if (mod.comp.whole_cache_manifest) |whole_cache_manifest| {
3562 const source = file.getSource(gpa) catch |err| {
3563 try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)});
3564 return error.AnalysisFail;
3565 };
3518 const comp = mod.comp;
3519 switch (comp.cache_use) {
3520 .whole => |whole| if (whole.cache_manifest) |man| {
3521 const source = file.getSource(gpa) catch |err| {
3522 try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)});
3523 return error.AnalysisFail;
3524 };
35663525
3567 const resolved_path = std.fs.path.resolve(gpa, &.{
3568 file.mod.root.root_dir.path orelse ".",
3569 file.mod.root.sub_path,
3570 file.sub_file_path,
3571 }) catch |err| {
3572 try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)});
3573 return error.AnalysisFail;
3574 };
3575 errdefer gpa.free(resolved_path);
3526 const resolved_path = std.fs.path.resolve(gpa, &.{
3527 file.mod.root.root_dir.path orelse ".",
3528 file.mod.root.sub_path,
3529 file.sub_file_path,
3530 }) catch |err| {
3531 try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)});
3532 return error.AnalysisFail;
3533 };
3534 errdefer gpa.free(resolved_path);
35763535
3577 mod.comp.whole_cache_manifest_mutex.lock();
3578 defer mod.comp.whole_cache_manifest_mutex.unlock();
3579 try whole_cache_manifest.addFilePostContents(resolved_path, source.bytes, source.stat);
3536 whole.cache_manifest_mutex.lock();
3537 defer whole.cache_manifest_mutex.unlock();
3538 try man.addFilePostContents(resolved_path, source.bytes, source.stat);
3539 },
3540 .incremental => {},
35803541 }
35813542}
35823543
......@@ -3588,6 +3549,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
35883549 defer tracy.end();
35893550
35903551 const decl = mod.declPtr(decl_index);
3552 const ip = &mod.intern_pool;
35913553
35923554 if (decl.getFileScope(mod).status != .success_zir) {
35933555 return error.AnalysisFail;
......@@ -3597,20 +3559,18 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
35973559 const zir = decl.getFileScope(mod).zir;
35983560 const zir_datas = zir.instructions.items(.data);
35993561
3600 // TODO: figure out how this works under incremental changes to builtin.zig!
36013562 const builtin_type_target_index: InternPool.Index = blk: {
3602 const std_mod = mod.main_mod.deps.get("std").?;
3563 const std_mod = mod.std_mod;
36033564 if (decl.getFileScope(mod).mod != std_mod) break :blk .none;
36043565 // We're in the std module.
36053566 const std_file = (try mod.importPkg(std_mod)).file;
36063567 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);
36073568 const std_namespace = std_decl.getInnerNamespace(mod).?;
3608 const builtin_str = try mod.intern_pool.getOrPutString(gpa, "builtin");
3569 const builtin_str = try ip.getOrPutString(gpa, "builtin");
36093570 const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .mod = mod }) orelse break :blk .none);
36103571 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;
36113572 if (decl.src_namespace != builtin_namespace) break :blk .none;
36123573 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
3613 const decl_name = mod.intern_pool.stringToSlice(decl.name);
36143574 for ([_]struct { []const u8, InternPool.Index }{
36153575 .{ "AtomicOrder", .atomic_order_type },
36163576 .{ "AtomicRmwOp", .atomic_rmw_op_type },
......@@ -3624,6 +3584,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
36243584 .{ "ExternOptions", .extern_options_type },
36253585 .{ "Type", .type_info_type },
36263586 }) |pair| {
3587 const decl_name = ip.stringToSlice(decl.name);
36273588 if (std.mem.eql(u8, decl_name, pair[0])) {
36283589 break :blk pair[1];
36293590 }
......@@ -3719,7 +3680,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
37193680 return true;
37203681 }
37213682
3722 const ip = &mod.intern_pool;
37233683 switch (ip.indexToKey(decl_tv.val.toIntern())) {
37243684 .func => |func| {
37253685 const owns_tv = func.owner_decl == decl_index;
......@@ -3863,25 +3823,24 @@ pub const ImportFileResult = struct {
38633823 is_pkg: bool,
38643824};
38653825
3866/// https://github.com/ziglang/zig/issues/14307
3867pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {
3868 const gpa = mod.gpa;
3826pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
3827 const gpa = zcu.gpa;
38693828
38703829 // The resolved path is used as the key in the import table, to detect if
38713830 // an import refers to the same as another, despite different relative paths
38723831 // or differently mapped package names.
38733832 const resolved_path = try std.fs.path.resolve(gpa, &.{
3874 pkg.root.root_dir.path orelse ".",
3875 pkg.root.sub_path,
3876 pkg.root_src_path,
3833 mod.root.root_dir.path orelse ".",
3834 mod.root.sub_path,
3835 mod.root_src_path,
38773836 });
38783837 var keep_resolved_path = false;
38793838 defer if (!keep_resolved_path) gpa.free(resolved_path);
38803839
3881 const gop = try mod.import_table.getOrPut(gpa, resolved_path);
3882 errdefer _ = mod.import_table.pop();
3840 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3841 errdefer _ = zcu.import_table.pop();
38833842 if (gop.found_existing) {
3884 try gop.value_ptr.*.addReference(mod.*, .{ .root = pkg });
3843 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
38853844 return ImportFileResult{
38863845 .file = gop.value_ptr.*,
38873846 .is_new = false,
......@@ -3889,7 +3848,18 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {
38893848 };
38903849 }
38913850
3892 const sub_file_path = try gpa.dupe(u8, pkg.root_src_path);
3851 if (mod.builtin_file) |builtin_file| {
3852 keep_resolved_path = true; // It's now owned by import_table.
3853 gop.value_ptr.* = builtin_file;
3854 try builtin_file.addReference(zcu.*, .{ .root = mod });
3855 return .{
3856 .file = builtin_file,
3857 .is_new = false,
3858 .is_pkg = true,
3859 };
3860 }
3861
3862 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
38933863 errdefer gpa.free(sub_file_path);
38943864
38953865 const new_file = try gpa.create(File);
......@@ -3907,10 +3877,10 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {
39073877 .tree = undefined,
39083878 .zir = undefined,
39093879 .status = .never_loaded,
3910 .mod = pkg,
3880 .mod = mod,
39113881 .root_decl = .none,
39123882 };
3913 try new_file.addReference(mod.*, .{ .root = pkg });
3883 try new_file.addReference(zcu.*, .{ .root = mod });
39143884 return ImportFileResult{
39153885 .file = new_file,
39163886 .is_new = true,
......@@ -3924,10 +3894,7 @@ pub fn importFile(
39243894 import_string: []const u8,
39253895) !ImportFileResult {
39263896 if (std.mem.eql(u8, import_string, "std")) {
3927 return mod.importPkg(mod.main_mod.deps.get("std").?);
3928 }
3929 if (std.mem.eql(u8, import_string, "builtin")) {
3930 return mod.importPkg(mod.main_mod.deps.get("builtin").?);
3897 return mod.importPkg(mod.std_mod);
39313898 }
39323899 if (std.mem.eql(u8, import_string, "root")) {
39333900 return mod.importPkg(mod.root_mod);
......@@ -4118,12 +4085,16 @@ fn newEmbedFile(
41184085 const actual_read = try file.readAll(ptr);
41194086 if (actual_read != size) return error.UnexpectedEndOfFile;
41204087
4121 if (mod.comp.whole_cache_manifest) |whole_cache_manifest| {
4122 const copied_resolved_path = try gpa.dupe(u8, resolved_path);
4123 errdefer gpa.free(copied_resolved_path);
4124 mod.comp.whole_cache_manifest_mutex.lock();
4125 defer mod.comp.whole_cache_manifest_mutex.unlock();
4126 try whole_cache_manifest.addFilePostContents(copied_resolved_path, ptr, stat);
4088 const comp = mod.comp;
4089 switch (comp.cache_use) {
4090 .whole => |whole| if (whole.cache_manifest) |man| {
4091 const copied_resolved_path = try gpa.dupe(u8, resolved_path);
4092 errdefer gpa.free(copied_resolved_path);
4093 whole.cache_manifest_mutex.lock();
4094 defer whole.cache_manifest_mutex.unlock();
4095 try man.addFilePostContents(copied_resolved_path, ptr, stat);
4096 },
4097 .incremental => {},
41274098 }
41284099
41294100 const array_ty = try ip.get(gpa, .{ .array_type = .{
......@@ -4312,14 +4283,14 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
43124283 1 => blk: {
43134284 // test decl with no name. Skip the part where we check against
43144285 // the test name filter.
4315 if (!comp.bin_file.options.is_test) break :blk false;
4286 if (!comp.config.is_test) break :blk false;
43164287 if (decl_mod != mod.main_mod) break :blk false;
43174288 try mod.test_functions.put(gpa, new_decl_index, {});
43184289 break :blk true;
43194290 },
43204291 else => blk: {
43214292 if (!is_named_test) break :blk false;
4322 if (!comp.bin_file.options.is_test) break :blk false;
4293 if (!comp.config.is_test) break :blk false;
43234294 if (decl_mod != mod.main_mod) break :blk false;
43244295 if (comp.test_filter) |test_filter| {
43254296 if (mem.indexOf(u8, ip.stringToSlice(decl_name), test_filter) == null) {
......@@ -4331,6 +4302,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
43314302 },
43324303 };
43334304 if (want_analysis) {
4305 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{s}' decl_index={d}", .{
4306 namespace.file_scope.sub_file_path, ip.stringToSlice(decl_name), new_decl_index,
4307 });
43344308 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });
43354309 }
43364310 new_decl.is_pub = is_pub;
......@@ -4373,14 +4347,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
43734347 decl.has_linksection_or_addrspace = has_linksection_or_addrspace;
43744348 decl.zir_decl_index = @enumFromInt(decl_sub_index);
43754349 if (decl.getOwnedFunction(mod) != null) {
4376 switch (comp.bin_file.tag) {
4377 .coff, .elf, .macho, .plan9 => {
4378 // TODO Look into detecting when this would be unnecessary by storing enough state
4379 // in `Decl` to notice that the line number did not change.
4380 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4381 },
4382 .c, .wasm, .spirv, .nvptx => {},
4383 }
4350 // TODO Look into detecting when this would be unnecessary by storing enough state
4351 // in `Decl` to notice that the line number did not change.
4352 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
43844353 }
43854354}
43864355
......@@ -4466,7 +4435,9 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void
44664435 }
44674436 },
44684437 }
4469 try mod.comp.bin_file.deleteDeclExport(decl_index, exp.opts.name);
4438 if (mod.comp.bin_file) |lf| {
4439 try lf.deleteDeclExport(decl_index, exp.opts.name);
4440 }
44704441 if (mod.failed_exports.fetchSwapRemove(exp)) |failed_kv| {
44714442 failed_kv.value.destroy(mod.gpa);
44724443 }
......@@ -4628,7 +4599,7 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
46284599
46294600 // If we don't get an error return trace from a caller, create our own.
46304601 if (func.analysis(ip).calls_or_awaits_errorable_fn and
4631 mod.comp.bin_file.options.error_return_tracing and
4602 mod.comp.config.any_error_tracing and
46324603 !sema.fn_ret_ty.isError(mod))
46334604 {
46344605 sema.setupErrorReturnTrace(&inner_block, last_arg_index) catch |err| switch (err) {
......@@ -4721,25 +4692,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
47214692 };
47224693}
47234694
4724fn markOutdatedDecl(mod: *Module, decl_index: Decl.Index) !void {
4725 const decl = mod.declPtr(decl_index);
4726 try mod.comp.work_queue.writeItem(.{ .analyze_decl = decl_index });
4727 if (mod.failed_decls.fetchSwapRemove(decl_index)) |kv| {
4728 kv.value.destroy(mod.gpa);
4729 }
4730 if (mod.cimport_errors.fetchSwapRemove(decl_index)) |kv| {
4731 var errors = kv.value;
4732 errors.deinit(mod.gpa);
4733 }
4734 if (mod.emit_h) |emit_h| {
4735 if (emit_h.failed_decls.fetchSwapRemove(decl_index)) |kv| {
4736 kv.value.destroy(mod.gpa);
4737 }
4738 }
4739 _ = mod.compile_log_decls.swapRemove(decl_index);
4740 decl.analysis = .outdated;
4741}
4742
47434695pub fn createNamespace(mod: *Module, initialization: Namespace) !Namespace.Index {
47444696 return mod.intern_pool.createNamespace(mod.gpa, initialization);
47454697}
......@@ -4875,12 +4827,18 @@ pub fn errNoteNonLazy(
48754827 };
48764828}
48774829
4878pub fn getTarget(mod: Module) Target {
4879 return mod.comp.bin_file.options.target;
4830/// Deprecated. There is no global target for a Zig Compilation Unit. Instead,
4831/// look up the target based on the Module that contains the source code being
4832/// analyzed.
4833pub fn getTarget(zcu: Module) Target {
4834 return zcu.root_mod.resolved_target.result;
48804835}
48814836
4882pub fn optimizeMode(mod: Module) std.builtin.OptimizeMode {
4883 return mod.comp.bin_file.options.optimize_mode;
4837/// Deprecated. There is no global optimization mode for a Zig Compilation
4838/// Unit. Instead, look up the optimization mode based on the Module that
4839/// contains the source code being analyzed.
4840pub fn optimizeMode(zcu: Module) std.builtin.OptimizeMode {
4841 return zcu.root_mod.optimize_mode;
48844842}
48854843
48864844fn lockAndClearFileCompileError(mod: *Module, file: *File) void {
......@@ -5288,43 +5246,57 @@ pub fn processExports(mod: *Module) !void {
52885246const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, *Export);
52895247
52905248fn processExportsInner(
5291 mod: *Module,
5249 zcu: *Zcu,
52925250 symbol_exports: *SymbolExports,
52935251 exported: Exported,
52945252 exports: []const *Export,
52955253) error{OutOfMemory}!void {
5296 const gpa = mod.gpa;
5254 const gpa = zcu.gpa;
52975255
52985256 for (exports) |new_export| {
52995257 const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name);
53005258 if (gop.found_existing) {
53015259 new_export.status = .failed_retryable;
5302 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
5303 const src_loc = new_export.getSrcLoc(mod);
5260 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
5261 const src_loc = new_export.getSrcLoc(zcu);
53045262 const msg = try ErrorMsg.create(gpa, src_loc, "exported symbol collision: {}", .{
5305 new_export.opts.name.fmt(&mod.intern_pool),
5263 new_export.opts.name.fmt(&zcu.intern_pool),
53065264 });
53075265 errdefer msg.destroy(gpa);
53085266 const other_export = gop.value_ptr.*;
5309 const other_src_loc = other_export.getSrcLoc(mod);
5310 try mod.errNoteNonLazy(other_src_loc, msg, "other symbol here", .{});
5311 mod.failed_exports.putAssumeCapacityNoClobber(new_export, msg);
5267 const other_src_loc = other_export.getSrcLoc(zcu);
5268 try zcu.errNoteNonLazy(other_src_loc, msg, "other symbol here", .{});
5269 zcu.failed_exports.putAssumeCapacityNoClobber(new_export, msg);
53125270 new_export.status = .failed;
53135271 } else {
53145272 gop.value_ptr.* = new_export;
53155273 }
53165274 }
5317 mod.comp.bin_file.updateExports(mod, exported, exports) catch |err| switch (err) {
5275 if (zcu.comp.bin_file) |lf| {
5276 try handleUpdateExports(zcu, exports, lf.updateExports(zcu, exported, exports));
5277 } else if (zcu.llvm_object) |llvm_object| {
5278 if (build_options.only_c) unreachable;
5279 try handleUpdateExports(zcu, exports, llvm_object.updateExports(zcu, exported, exports));
5280 }
5281}
5282
5283fn handleUpdateExports(
5284 zcu: *Zcu,
5285 exports: []const *Export,
5286 result: link.File.UpdateExportsError!void,
5287) Allocator.Error!void {
5288 const gpa = zcu.gpa;
5289 result catch |err| switch (err) {
53185290 error.OutOfMemory => return error.OutOfMemory,
5319 else => {
5291 error.AnalysisFail => {
53205292 const new_export = exports[0];
53215293 new_export.status = .failed_retryable;
5322 try mod.failed_exports.ensureUnusedCapacity(gpa, 1);
5323 const src_loc = new_export.getSrcLoc(mod);
5294 try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
5295 const src_loc = new_export.getSrcLoc(zcu);
53245296 const msg = try ErrorMsg.create(gpa, src_loc, "unable to export: {s}", .{
53255297 @errorName(err),
53265298 });
5327 mod.failed_exports.putAssumeCapacityNoClobber(new_export, msg);
5299 zcu.failed_exports.putAssumeCapacityNoClobber(new_export, msg);
53285300 },
53295301 };
53305302}
......@@ -5335,7 +5307,7 @@ pub fn populateTestFunctions(
53355307) !void {
53365308 const gpa = mod.gpa;
53375309 const ip = &mod.intern_pool;
5338 const builtin_mod = mod.main_mod.deps.get("builtin").?;
5310 const builtin_mod = mod.root_mod.getBuiltinDependency();
53395311 const builtin_file = (mod.importPkg(builtin_mod) catch unreachable).file;
53405312 const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?);
53415313 const builtin_namespace = mod.namespacePtr(root_decl.src_namespace);
......@@ -5467,39 +5439,39 @@ pub fn populateTestFunctions(
54675439 try mod.linkerUpdateDecl(decl_index);
54685440}
54695441
5470pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void {
5471 const comp = mod.comp;
5472
5473 const no_bin_file = (comp.bin_file.options.emit == null and
5474 comp.emit_asm == null and
5475 comp.emit_llvm_ir == null and
5476 comp.emit_llvm_bc == null);
5442pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void {
5443 const comp = zcu.comp;
54775444
5478 const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
5479
5480 if (no_bin_file and !dump_llvm_ir) return;
5481
5482 const decl = mod.declPtr(decl_index);
5483
5484 comp.bin_file.updateDecl(mod, decl_index) catch |err| switch (err) {
5485 error.OutOfMemory => return error.OutOfMemory,
5486 error.AnalysisFail => {
5487 decl.analysis = .codegen_failure;
5488 return;
5489 },
5490 else => {
5491 const gpa = mod.gpa;
5492 try mod.failed_decls.ensureUnusedCapacity(gpa, 1);
5493 mod.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
5494 gpa,
5495 decl.srcLoc(mod),
5496 "unable to codegen: {s}",
5497 .{@errorName(err)},
5498 ));
5499 decl.analysis = .codegen_failure_retryable;
5500 return;
5501 },
5502 };
5445 if (comp.bin_file) |lf| {
5446 lf.updateDecl(zcu, decl_index) catch |err| switch (err) {
5447 error.OutOfMemory => return error.OutOfMemory,
5448 error.AnalysisFail => {
5449 const decl = zcu.declPtr(decl_index);
5450 decl.analysis = .codegen_failure;
5451 },
5452 else => {
5453 const decl = zcu.declPtr(decl_index);
5454 const gpa = zcu.gpa;
5455 try zcu.failed_decls.ensureUnusedCapacity(gpa, 1);
5456 zcu.failed_decls.putAssumeCapacityNoClobber(decl_index, try ErrorMsg.create(
5457 gpa,
5458 decl.srcLoc(zcu),
5459 "unable to codegen: {s}",
5460 .{@errorName(err)},
5461 ));
5462 decl.analysis = .codegen_failure_retryable;
5463 },
5464 };
5465 } else if (zcu.llvm_object) |llvm_object| {
5466 if (build_options.only_c) unreachable;
5467 llvm_object.updateDecl(zcu, decl_index) catch |err| switch (err) {
5468 error.OutOfMemory => return error.OutOfMemory,
5469 error.AnalysisFail => {
5470 const decl = zcu.declPtr(decl_index);
5471 decl.analysis = .codegen_failure;
5472 },
5473 };
5474 }
55035475}
55045476
55055477fn reportRetryableFileError(
......@@ -5592,10 +5564,6 @@ pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u
55925564 }
55935565}
55945566
5595pub fn wantDllExports(mod: Module) bool {
5596 return mod.comp.bin_file.options.dll_export_fns and mod.getTarget().os.tag == .windows;
5597}
5598
55995567pub fn getDeclExports(mod: Module, decl_index: Decl.Index) []const *Export {
56005568 if (mod.decl_exports.get(decl_index)) |l| {
56015569 return l.items;
......@@ -5622,21 +5590,11 @@ pub const Feature = enum {
56225590 safety_checked_instructions,
56235591};
56245592
5625pub fn backendSupportsFeature(mod: Module, feature: Feature) bool {
5626 return switch (feature) {
5627 .panic_fn => mod.comp.bin_file.options.target.ofmt == .c or
5628 mod.comp.bin_file.options.use_llvm or
5629 mod.comp.bin_file.options.target.cpu.arch == .x86_64,
5630 .panic_unwrap_error => mod.comp.bin_file.options.target.ofmt == .c or
5631 mod.comp.bin_file.options.use_llvm,
5632 .safety_check_formatted => mod.comp.bin_file.options.target.ofmt == .c or
5633 mod.comp.bin_file.options.use_llvm,
5634 .error_return_trace => mod.comp.bin_file.options.use_llvm,
5635 .is_named_enum_value => mod.comp.bin_file.options.use_llvm,
5636 .error_set_has_value => mod.comp.bin_file.options.use_llvm or mod.comp.bin_file.options.target.isWasm(),
5637 .field_reordering => mod.comp.bin_file.options.use_llvm,
5638 .safety_checked_instructions => mod.comp.bin_file.options.use_llvm,
5639 };
5593pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool {
5594 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
5595 const ofmt = zcu.root_mod.resolved_target.result.ofmt;
5596 const use_llvm = zcu.comp.config.use_llvm;
5597 return target_util.backendSupportsFeature(cpu_arch, ofmt, use_llvm, feature);
56405598}
56415599
56425600/// Shortcut for calling `intern_pool.get`.
src/Package.zig+12-2
......@@ -88,10 +88,10 @@ pub const Path = struct {
8888 p: Path,
8989 sub_path: []const u8,
9090 options: fs.Dir.AtomicFileOptions,
91 buf: *[fs.MAX_PATH_BYTES]u8,
9192 ) !fs.AtomicFile {
92 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
9393 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
94 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
94 break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
9595 p.sub_path, sub_path,
9696 }) catch return error.NameTooLong;
9797 };
......@@ -108,6 +108,16 @@ pub const Path = struct {
108108 return p.root_dir.handle.access(joined_path, flags);
109109 }
110110
111 pub fn makePath(p: Path, sub_path: []const u8) !void {
112 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
113 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
114 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
115 p.sub_path, sub_path,
116 }) catch return error.NameTooLong;
117 };
118 return p.root_dir.handle.makePath(joined_path);
119 }
120
111121 pub fn format(
112122 self: Path,
113123 comptime fmt_string: []const u8,
src/Package/Module.zig+460-6
......@@ -1,6 +1,6 @@
11//! Corresponds to something that Zig source code can `@import`.
2//! Not to be confused with src/Module.zig which should be renamed
3//! to something else. https://github.com/ziglang/zig/issues/14307
2//! Not to be confused with src/Module.zig which will be renamed
3//! to Zcu. https://github.com/ziglang/zig/issues/14307
44
55/// Only files inside this directory can be imported.
66root: Package.Path,
......@@ -14,17 +14,465 @@ fully_qualified_name: []const u8,
1414/// responsible for detecting these names and using the correct package.
1515deps: Deps = .{},
1616
17resolved_target: ResolvedTarget,
18optimize_mode: std.builtin.OptimizeMode,
19code_model: std.builtin.CodeModel,
20single_threaded: bool,
21error_tracing: bool,
22valgrind: bool,
23pic: bool,
24strip: bool,
25omit_frame_pointer: bool,
26stack_check: bool,
27stack_protector: u32,
28red_zone: bool,
29sanitize_c: bool,
30sanitize_thread: bool,
31unwind_tables: bool,
32cc_argv: []const []const u8,
33/// (SPIR-V) whether to generate a structured control flow graph or not
34structured_cfg: bool,
35
36/// If the module is an `@import("builtin")` module, this is the `File` that
37/// is preallocated for it. Otherwise this field is null.
38builtin_file: ?*File,
39
1740pub const Deps = std.StringArrayHashMapUnmanaged(*Module);
1841
42pub fn isBuiltin(m: Module) bool {
43 return m.builtin_file != null;
44}
45
1946pub const Tree = struct {
2047 /// Each `Package` exposes a `Module` with build.zig as its root source file.
2148 build_module_table: std.AutoArrayHashMapUnmanaged(MultiHashHexDigest, *Module),
2249};
2350
24pub fn create(allocator: Allocator, m: Module) Allocator.Error!*Module {
25 const new = try allocator.create(Module);
26 new.* = m;
27 return new;
51pub const CreateOptions = struct {
52 /// Where to store builtin.zig. The global cache directory is used because
53 /// it is a pure function based on CLI flags.
54 global_cache_directory: Cache.Directory,
55 paths: Paths,
56 fully_qualified_name: []const u8,
57
58 cc_argv: []const []const u8,
59 inherited: Inherited,
60 global: Compilation.Config,
61 /// If this is null then `resolved_target` must be non-null.
62 parent: ?*Package.Module,
63
64 builtin_mod: ?*Package.Module,
65
66 pub const Paths = struct {
67 root: Package.Path,
68 /// Relative to `root`. May contain path separators.
69 root_src_path: []const u8,
70 };
71
72 pub const Inherited = struct {
73 /// If this is null then `parent` must be non-null.
74 resolved_target: ?ResolvedTarget = null,
75 optimize_mode: ?std.builtin.OptimizeMode = null,
76 code_model: ?std.builtin.CodeModel = null,
77 single_threaded: ?bool = null,
78 error_tracing: ?bool = null,
79 valgrind: ?bool = null,
80 pic: ?bool = null,
81 strip: ?bool = null,
82 omit_frame_pointer: ?bool = null,
83 stack_check: ?bool = null,
84 /// null means default.
85 /// 0 means no stack protector.
86 /// other number means stack protection with that buffer size.
87 stack_protector: ?u32 = null,
88 red_zone: ?bool = null,
89 unwind_tables: ?bool = null,
90 sanitize_c: ?bool = null,
91 sanitize_thread: ?bool = null,
92 structured_cfg: ?bool = null,
93 };
94};
95
96pub const ResolvedTarget = struct {
97 result: std.Target,
98 is_native_os: bool,
99 is_native_abi: bool,
100 llvm_cpu_features: ?[*:0]const u8 = null,
101};
102
103/// At least one of `parent` and `resolved_target` must be non-null.
104pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
105 if (options.inherited.sanitize_thread == true) assert(options.global.any_sanitize_thread);
106 if (options.inherited.single_threaded == false) assert(options.global.any_non_single_threaded);
107 if (options.inherited.unwind_tables == true) assert(options.global.any_unwind_tables);
108 if (options.inherited.error_tracing == true) assert(options.global.any_error_tracing);
109
110 const resolved_target = options.inherited.resolved_target orelse options.parent.?.resolved_target;
111 const target = resolved_target.result;
112
113 const optimize_mode = options.inherited.optimize_mode orelse
114 if (options.parent) |p| p.optimize_mode else .Debug;
115
116 const unwind_tables = options.inherited.unwind_tables orelse
117 if (options.parent) |p| p.unwind_tables else options.global.any_unwind_tables;
118
119 const strip = b: {
120 if (options.inherited.strip) |x| break :b x;
121 if (options.parent) |p| break :b p.strip;
122 break :b options.global.root_strip;
123 };
124
125 const valgrind = b: {
126 if (!target_util.hasValgrindSupport(target)) {
127 if (options.inherited.valgrind == true)
128 return error.ValgrindUnsupportedOnTarget;
129 break :b false;
130 }
131 if (options.inherited.valgrind) |x| break :b x;
132 if (options.parent) |p| break :b p.valgrind;
133 if (strip) break :b false;
134 break :b optimize_mode == .Debug;
135 };
136
137 const zig_backend = target_util.zigBackend(target, options.global.use_llvm);
138
139 const single_threaded = b: {
140 if (target_util.alwaysSingleThreaded(target)) {
141 if (options.inherited.single_threaded == false)
142 return error.TargetRequiresSingleThreaded;
143 break :b true;
144 }
145
146 if (options.global.have_zcu) {
147 if (!target_util.supportsThreads(target, zig_backend)) {
148 if (options.inherited.single_threaded == false)
149 return error.BackendRequiresSingleThreaded;
150 break :b true;
151 }
152 }
153
154 if (options.inherited.single_threaded) |x| break :b x;
155 if (options.parent) |p| break :b p.single_threaded;
156 break :b target_util.defaultSingleThreaded(target);
157 };
158
159 const error_tracing = b: {
160 if (options.inherited.error_tracing) |x| break :b x;
161 if (options.parent) |p| break :b p.error_tracing;
162 break :b options.global.root_error_tracing;
163 };
164
165 const pic = b: {
166 if (target_util.requiresPIC(target, options.global.link_libc)) {
167 if (options.inherited.pic == false)
168 return error.TargetRequiresPic;
169 break :b true;
170 }
171 if (options.global.pie) {
172 if (options.inherited.pic == false)
173 return error.PieRequiresPic;
174 break :b true;
175 }
176 if (options.global.link_mode == .Dynamic) {
177 if (options.inherited.pic == false)
178 return error.DynamicLinkingRequiresPic;
179 break :b true;
180 }
181 if (options.inherited.pic) |x| break :b x;
182 if (options.parent) |p| break :b p.pic;
183 break :b false;
184 };
185
186 const red_zone = b: {
187 if (!target_util.hasRedZone(target)) {
188 if (options.inherited.red_zone == true)
189 return error.TargetHasNoRedZone;
190 break :b false;
191 }
192 if (options.inherited.red_zone) |x| break :b x;
193 if (options.parent) |p| break :b p.red_zone;
194 break :b true;
195 };
196
197 const omit_frame_pointer = b: {
198 if (options.inherited.omit_frame_pointer) |x| break :b x;
199 if (options.parent) |p| break :b p.omit_frame_pointer;
200 if (optimize_mode == .Debug) break :b false;
201 break :b true;
202 };
203
204 const sanitize_thread = b: {
205 if (options.inherited.sanitize_thread) |x| break :b x;
206 if (options.parent) |p| break :b p.sanitize_thread;
207 break :b false;
208 };
209
210 const code_model = b: {
211 if (options.inherited.code_model) |x| break :b x;
212 if (options.parent) |p| break :b p.code_model;
213 break :b .default;
214 };
215
216 const is_safe_mode = switch (optimize_mode) {
217 .Debug, .ReleaseSafe => true,
218 .ReleaseFast, .ReleaseSmall => false,
219 };
220
221 const sanitize_c = b: {
222 if (options.inherited.sanitize_c) |x| break :b x;
223 if (options.parent) |p| break :b p.sanitize_c;
224 break :b is_safe_mode;
225 };
226
227 const stack_check = b: {
228 if (!target_util.supportsStackProbing(target)) {
229 if (options.inherited.stack_check == true)
230 return error.StackCheckUnsupportedByTarget;
231 break :b false;
232 }
233 if (options.inherited.stack_check) |x| break :b x;
234 if (options.parent) |p| break :b p.stack_check;
235 break :b is_safe_mode;
236 };
237
238 const stack_protector: u32 = sp: {
239 const use_zig_backend = options.global.have_zcu or
240 (options.global.any_c_source_files and options.global.c_frontend == .aro);
241 if (use_zig_backend and !target_util.supportsStackProtector(target, zig_backend)) {
242 if (options.inherited.stack_protector) |x| {
243 if (x > 0) return error.StackProtectorUnsupportedByTarget;
244 }
245 break :sp 0;
246 }
247
248 if (options.global.any_c_source_files and options.global.c_frontend == .clang and
249 !target_util.clangSupportsStackProtector(target))
250 {
251 if (options.inherited.stack_protector) |x| {
252 if (x > 0) return error.StackProtectorUnsupportedByTarget;
253 }
254 break :sp 0;
255 }
256
257 // This logic is checking for linking libc because otherwise our start code
258 // which is trying to set up TLS (i.e. the fs/gs registers) but the stack
259 // protection code depends on fs/gs registers being already set up.
260 // If we were able to annotate start code, or perhaps the entire std lib,
261 // as being exempt from stack protection checks, we could change this logic
262 // to supporting stack protection even when not linking libc.
263 // TODO file issue about this
264 if (!options.global.link_libc) {
265 if (options.inherited.stack_protector) |x| {
266 if (x > 0) return error.StackProtectorUnavailableWithoutLibC;
267 }
268 break :sp 0;
269 }
270
271 if (options.inherited.stack_protector) |x| break :sp x;
272 if (options.parent) |p| break :sp p.stack_protector;
273 if (!is_safe_mode) break :sp 0;
274
275 break :sp target_util.default_stack_protector_buffer_size;
276 };
277
278 const structured_cfg = b: {
279 if (options.inherited.structured_cfg) |x| break :b x;
280 if (options.parent) |p| break :b p.structured_cfg;
281 // We always want a structured control flow in shaders. This option is
282 // only relevant for OpenCL kernels.
283 break :b switch (target.os.tag) {
284 .opencl => false,
285 else => true,
286 };
287 };
288
289 const llvm_cpu_features: ?[*:0]const u8 = b: {
290 if (resolved_target.llvm_cpu_features) |x| break :b x;
291 if (!options.global.use_llvm) break :b null;
292
293 var buf = std.ArrayList(u8).init(arena);
294 for (target.cpu.arch.allFeaturesList(), 0..) |feature, index_usize| {
295 const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
296 const is_enabled = target.cpu.features.isEnabled(index);
297
298 if (feature.llvm_name) |llvm_name| {
299 const plus_or_minus = "-+"[@intFromBool(is_enabled)];
300 try buf.ensureUnusedCapacity(2 + llvm_name.len);
301 buf.appendAssumeCapacity(plus_or_minus);
302 buf.appendSliceAssumeCapacity(llvm_name);
303 buf.appendSliceAssumeCapacity(",");
304 }
305 }
306 if (buf.items.len == 0) break :b "";
307 assert(std.mem.endsWith(u8, buf.items, ","));
308 buf.items[buf.items.len - 1] = 0;
309 buf.shrinkAndFree(buf.items.len);
310 break :b buf.items[0 .. buf.items.len - 1 :0].ptr;
311 };
312
313 const mod = try arena.create(Module);
314 mod.* = .{
315 .root = options.paths.root,
316 .root_src_path = options.paths.root_src_path,
317 .fully_qualified_name = options.fully_qualified_name,
318 .resolved_target = .{
319 .result = target,
320 .is_native_os = resolved_target.is_native_os,
321 .is_native_abi = resolved_target.is_native_abi,
322 .llvm_cpu_features = llvm_cpu_features,
323 },
324 .optimize_mode = optimize_mode,
325 .single_threaded = single_threaded,
326 .error_tracing = error_tracing,
327 .valgrind = valgrind,
328 .pic = pic,
329 .strip = strip,
330 .omit_frame_pointer = omit_frame_pointer,
331 .stack_check = stack_check,
332 .stack_protector = stack_protector,
333 .code_model = code_model,
334 .red_zone = red_zone,
335 .sanitize_c = sanitize_c,
336 .sanitize_thread = sanitize_thread,
337 .unwind_tables = unwind_tables,
338 .cc_argv = options.cc_argv,
339 .structured_cfg = structured_cfg,
340 .builtin_file = null,
341 };
342
343 const opt_builtin_mod = options.builtin_mod orelse b: {
344 if (!options.global.have_zcu) break :b null;
345
346 const generated_builtin_source = try Builtin.generate(.{
347 .target = target,
348 .zig_backend = zig_backend,
349 .output_mode = options.global.output_mode,
350 .link_mode = options.global.link_mode,
351 .is_test = options.global.is_test,
352 .test_evented_io = options.global.test_evented_io,
353 .single_threaded = single_threaded,
354 .link_libc = options.global.link_libc,
355 .link_libcpp = options.global.link_libcpp,
356 .optimize_mode = optimize_mode,
357 .error_tracing = error_tracing,
358 .valgrind = valgrind,
359 .sanitize_thread = sanitize_thread,
360 .pic = pic,
361 .pie = options.global.pie,
362 .strip = strip,
363 .code_model = code_model,
364 .omit_frame_pointer = omit_frame_pointer,
365 .wasi_exec_model = options.global.wasi_exec_model,
366 }, arena);
367
368 const new_file = try arena.create(File);
369
370 const digest = Cache.HashHelper.oneShot(generated_builtin_source);
371 const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ digest);
372 const new = try arena.create(Module);
373 new.* = .{
374 .root = .{
375 .root_dir = options.global_cache_directory,
376 .sub_path = builtin_sub_path,
377 },
378 .root_src_path = "builtin.zig",
379 .fully_qualified_name = if (options.parent == null)
380 "builtin"
381 else
382 try std.fmt.allocPrint(arena, "{s}.builtin", .{options.fully_qualified_name}),
383 .resolved_target = .{
384 .result = target,
385 .is_native_os = resolved_target.is_native_os,
386 .is_native_abi = resolved_target.is_native_abi,
387 .llvm_cpu_features = llvm_cpu_features,
388 },
389 .optimize_mode = optimize_mode,
390 .single_threaded = single_threaded,
391 .error_tracing = error_tracing,
392 .valgrind = valgrind,
393 .pic = pic,
394 .strip = strip,
395 .omit_frame_pointer = omit_frame_pointer,
396 .stack_check = stack_check,
397 .stack_protector = stack_protector,
398 .code_model = code_model,
399 .red_zone = red_zone,
400 .sanitize_c = sanitize_c,
401 .sanitize_thread = sanitize_thread,
402 .unwind_tables = unwind_tables,
403 .cc_argv = &.{},
404 .structured_cfg = structured_cfg,
405 .builtin_file = new_file,
406 };
407 new_file.* = .{
408 .sub_file_path = "builtin.zig",
409 .source = generated_builtin_source,
410 .source_loaded = true,
411 .tree_loaded = false,
412 .zir_loaded = false,
413 .stat = undefined,
414 .tree = undefined,
415 .zir = undefined,
416 .status = .never_loaded,
417 .mod = new,
418 .root_decl = .none,
419 };
420 break :b new;
421 };
422
423 if (opt_builtin_mod) |builtin_mod| {
424 try mod.deps.ensureUnusedCapacity(arena, 1);
425 mod.deps.putAssumeCapacityNoClobber("builtin", builtin_mod);
426 }
427
428 return mod;
429}
430
431/// All fields correspond to `CreateOptions`.
432pub const LimitedOptions = struct {
433 root: Package.Path,
434 root_src_path: []const u8,
435 fully_qualified_name: []const u8,
436};
437
438/// This one can only be used if the Module will only be used for AstGen and earlier in
439/// the pipeline. Illegal behavior occurs if a limited module touches Sema.
440pub fn createLimited(gpa: Allocator, options: LimitedOptions) Allocator.Error!*Package.Module {
441 const mod = try gpa.create(Module);
442 mod.* = .{
443 .root = options.root,
444 .root_src_path = options.root_src_path,
445 .fully_qualified_name = options.fully_qualified_name,
446
447 .resolved_target = undefined,
448 .optimize_mode = undefined,
449 .code_model = undefined,
450 .single_threaded = undefined,
451 .error_tracing = undefined,
452 .valgrind = undefined,
453 .pic = undefined,
454 .strip = undefined,
455 .omit_frame_pointer = undefined,
456 .stack_check = undefined,
457 .stack_protector = undefined,
458 .red_zone = undefined,
459 .sanitize_c = undefined,
460 .sanitize_thread = undefined,
461 .unwind_tables = undefined,
462 .cc_argv = undefined,
463 .structured_cfg = undefined,
464 .builtin_file = null,
465 };
466 return mod;
467}
468
469/// Asserts that the module has a builtin module, which is not true for non-zig
470/// modules such as ones only used for `@embedFile`, or the root module when
471/// there is no Zig Compilation Unit.
472pub fn getBuiltinDependency(m: Module) *Module {
473 const result = m.deps.values()[0];
474 assert(result.isBuiltin());
475 return result;
28476}
29477
30478const Module = @This();
......@@ -32,3 +480,9 @@ const Package = @import("../Package.zig");
32480const std = @import("std");
33481const Allocator = std.mem.Allocator;
34482const MultiHashHexDigest = Package.Manifest.MultiHashHexDigest;
483const target_util = @import("../target.zig");
484const Cache = std.Build.Cache;
485const Builtin = @import("../Builtin.zig");
486const assert = std.debug.assert;
487const Compilation = @import("../Compilation.zig");
488const File = @import("../Module.zig").File;
src/Sema.zig+88-61
......@@ -784,6 +784,11 @@ pub const Block = struct {
784784 }
785785 }
786786
787 pub fn ownerModule(block: Block) *Package.Module {
788 const zcu = block.sema.mod;
789 return zcu.namespacePtr(block.namespace).file_scope.mod;
790 }
791
787792 pub fn startAnonDecl(block: *Block) !WipAnonDecl {
788793 return WipAnonDecl{
789794 .block = block,
......@@ -1324,13 +1329,13 @@ fn analyzeBodyInner(
13241329 },
13251330 .dbg_block_begin => {
13261331 dbg_block_begins += 1;
1327 try sema.zirDbgBlockBegin(block);
1332 try zirDbgBlockBegin(block);
13281333 i += 1;
13291334 continue;
13301335 },
13311336 .dbg_block_end => {
13321337 dbg_block_begins -= 1;
1333 try sema.zirDbgBlockEnd(block);
1338 try zirDbgBlockEnd(block);
13341339 i += 1;
13351340 continue;
13361341 },
......@@ -1825,17 +1830,17 @@ fn analyzeBodyInner(
18251830 };
18261831
18271832 // balance out dbg_block_begins in case of early noreturn
1828 const noreturn_inst = block.instructions.popOrNull();
1829 while (dbg_block_begins > 0) {
1830 dbg_block_begins -= 1;
1831 if (block.is_comptime or mod.comp.bin_file.options.strip) continue;
1832
1833 _ = try block.addInst(.{
1834 .tag = .dbg_block_end,
1835 .data = undefined,
1836 });
1833 if (!block.is_comptime and !block.ownerModule().strip) {
1834 const noreturn_inst = block.instructions.popOrNull();
1835 while (dbg_block_begins > 0) {
1836 dbg_block_begins -= 1;
1837 _ = try block.addInst(.{
1838 .tag = .dbg_block_end,
1839 .data = undefined,
1840 });
1841 }
1842 if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some);
18371843 }
1838 if (noreturn_inst) |some| try block.instructions.append(sema.gpa, some);
18391844
18401845 // We may have overwritten the capture scope due to a `repeat` instruction where
18411846 // the body had a capture; restore it now.
......@@ -2040,9 +2045,10 @@ fn analyzeAsType(
20402045
20412046pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void {
20422047 const mod = sema.mod;
2048 const comp = mod.comp;
20432049 const gpa = sema.gpa;
20442050 const ip = &mod.intern_pool;
2045 if (!mod.backendSupportsFeature(.error_return_trace)) return;
2051 if (!comp.config.any_error_tracing) return;
20462052
20472053 assert(!block.is_comptime);
20482054 var err_trace_block = block.makeSubBlock();
......@@ -5733,7 +5739,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
57335739 // Ignore the result, all the relevant operations have written to c_import_buf already.
57345740 _ = try sema.analyzeBodyBreak(&child_block, body);
57355741
5736 var c_import_res = comp.cImport(c_import_buf.items) catch |err|
5742 var c_import_res = comp.cImport(c_import_buf.items, parent_block.ownerModule()) catch |err|
57375743 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
57385744 defer c_import_res.deinit(gpa);
57395745
......@@ -5742,7 +5748,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
57425748 const msg = try sema.errMsg(&child_block, src, "C import failed", .{});
57435749 errdefer msg.destroy(gpa);
57445750
5745 if (!comp.bin_file.options.link_libc)
5751 if (!comp.config.link_libc)
57465752 try sema.errNote(&child_block, src, msg, "libc headers not available; compilation does not link against libc", .{});
57475753
57485754 const gop = try mod.cimport_errors.getOrPut(gpa, sema.owner_decl_index);
......@@ -5754,14 +5760,39 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
57545760 };
57555761 return sema.failWithOwnedErrorMsg(&child_block, msg);
57565762 }
5757 const c_import_mod = try Package.Module.create(comp.arena.allocator(), .{
5758 .root = .{
5759 .root_dir = Compilation.Directory.cwd(),
5760 .sub_path = std.fs.path.dirname(c_import_res.out_zig_path) orelse "",
5763 const parent_mod = parent_block.ownerModule();
5764 const c_import_mod = Package.Module.create(comp.arena, .{
5765 .global_cache_directory = comp.global_cache_directory,
5766 .paths = .{
5767 .root = .{
5768 .root_dir = Compilation.Directory.cwd(),
5769 .sub_path = std.fs.path.dirname(c_import_res.out_zig_path) orelse "",
5770 },
5771 .root_src_path = std.fs.path.basename(c_import_res.out_zig_path),
57615772 },
5762 .root_src_path = std.fs.path.basename(c_import_res.out_zig_path),
57635773 .fully_qualified_name = c_import_res.out_zig_path,
5764 });
5774 .cc_argv = parent_mod.cc_argv,
5775 .inherited = .{},
5776 .global = comp.config,
5777 .parent = parent_mod,
5778 .builtin_mod = parent_mod.getBuiltinDependency(),
5779 }) catch |err| switch (err) {
5780 // None of these are possible because we are creating a package with
5781 // the exact same configuration as the parent package, which already
5782 // passed these checks.
5783 error.ValgrindUnsupportedOnTarget => unreachable,
5784 error.TargetRequiresSingleThreaded => unreachable,
5785 error.BackendRequiresSingleThreaded => unreachable,
5786 error.TargetRequiresPic => unreachable,
5787 error.PieRequiresPic => unreachable,
5788 error.DynamicLinkingRequiresPic => unreachable,
5789 error.TargetHasNoRedZone => unreachable,
5790 error.StackCheckUnsupportedByTarget => unreachable,
5791 error.StackProtectorUnsupportedByTarget => unreachable,
5792 error.StackProtectorUnavailableWithoutLibC => unreachable,
5793
5794 else => |e| return e,
5795 };
57655796
57665797 const result = mod.importPkg(c_import_mod) catch |err|
57675798 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
......@@ -6267,7 +6298,7 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
62676298 // ZIR code that possibly will need to generate runtime code. So error messages
62686299 // and other source locations must not rely on sema.src being set from dbg_stmt
62696300 // instructions.
6270 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
6301 if (block.is_comptime or block.ownerModule().strip) return;
62716302
62726303 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
62736304
......@@ -6292,8 +6323,8 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
62926323 });
62936324}
62946325
6295fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void {
6296 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
6326fn zirDbgBlockBegin(block: *Block) CompileError!void {
6327 if (block.is_comptime or block.ownerModule().strip) return;
62976328
62986329 _ = try block.addInst(.{
62996330 .tag = .dbg_block_begin,
......@@ -6301,8 +6332,8 @@ fn zirDbgBlockBegin(sema: *Sema, block: *Block) CompileError!void {
63016332 });
63026333}
63036334
6304fn zirDbgBlockEnd(sema: *Sema, block: *Block) CompileError!void {
6305 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
6335fn zirDbgBlockEnd(block: *Block) CompileError!void {
6336 if (block.is_comptime or block.ownerModule().strip) return;
63066337
63076338 _ = try block.addInst(.{
63086339 .tag = .dbg_block_end,
......@@ -6316,7 +6347,7 @@ fn zirDbgVar(
63166347 inst: Zir.Inst.Index,
63176348 air_tag: Air.Inst.Tag,
63186349) CompileError!void {
6319 if (block.is_comptime or sema.mod.comp.bin_file.options.strip) return;
6350 if (block.is_comptime or block.ownerModule().strip) return;
63206351
63216352 const str_op = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_op;
63226353 const operand = try sema.resolveInst(str_op.operand);
......@@ -6513,8 +6544,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
65136544 const gpa = sema.gpa;
65146545 const src = sema.src;
65156546
6516 if (!mod.backendSupportsFeature(.error_return_trace)) return .none;
6517 if (!mod.comp.bin_file.options.error_return_tracing) return .none;
6547 if (!block.ownerModule().error_tracing) return .none;
65186548
65196549 if (block.is_comptime)
65206550 return .none;
......@@ -6698,7 +6728,7 @@ fn zirCall(
66986728 input_is_error = false;
66996729 }
67006730
6701 if (mod.backendSupportsFeature(.error_return_trace) and mod.comp.bin_file.options.error_return_tracing and
6731 if (block.ownerModule().error_tracing and
67026732 !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace))
67036733 {
67046734 const return_ty = sema.typeOf(call_inst);
......@@ -7451,7 +7481,7 @@ fn analyzeCall(
74517481 new_fn_info.return_type = sema.fn_ret_ty.toIntern();
74527482 const new_func_resolved_ty = try mod.funcType(new_fn_info);
74537483 if (!is_comptime_call and !block.is_typeof) {
7454 try sema.emitDbgInline(block, prev_fn_index, module_fn_index, new_func_resolved_ty, .dbg_inline_begin);
7484 try emitDbgInline(block, prev_fn_index, module_fn_index, new_func_resolved_ty, .dbg_inline_begin);
74557485
74567486 const zir_tags = sema.code.instructions.items(.tag);
74577487 for (fn_info.param_body) |param| switch (zir_tags[@intFromEnum(param)]) {
......@@ -7489,7 +7519,7 @@ fn analyzeCall(
74897519 if (!is_comptime_call and !block.is_typeof and
74907520 sema.typeOf(result).zigTypeTag(mod) != .NoReturn)
74917521 {
7492 try sema.emitDbgInline(
7522 try emitDbgInline(
74937523 block,
74947524 module_fn_index,
74957525 prev_fn_index,
......@@ -8062,15 +8092,13 @@ fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type)
80628092}
80638093
80648094fn emitDbgInline(
8065 sema: *Sema,
80668095 block: *Block,
80678096 old_func: InternPool.Index,
80688097 new_func: InternPool.Index,
80698098 new_func_ty: Type,
80708099 tag: Air.Inst.Tag,
80718100) CompileError!void {
8072 const mod = sema.mod;
8073 if (mod.comp.bin_file.options.strip) return;
8101 if (block.ownerModule().strip) return;
80748102
80758103 // Recursive inline call; no dbg_inline needed.
80768104 if (old_func == new_func) return;
......@@ -9058,7 +9086,7 @@ fn resolveGenericBody(
90589086
90599087/// Given a library name, examines if the library name should end up in
90609088/// `link.File.Options.system_libs` table (for example, libc is always
9061/// specified via dedicated flag `link.File.Options.link_libc` instead),
9089/// specified via dedicated flag `link_libc` instead),
90629090/// and puts it there if it doesn't exist.
90639091/// It also dupes the library name which can then be saved as part of the
90649092/// respective `Decl` (either `ExternFn` or `Var`).
......@@ -9075,8 +9103,8 @@ fn handleExternLibName(
90759103 const comp = mod.comp;
90769104 const target = mod.getTarget();
90779105 log.debug("extern fn symbol expected in lib '{s}'", .{lib_name});
9078 if (target_util.is_libc_lib_name(target, lib_name)) {
9079 if (!comp.bin_file.options.link_libc) {
9106 if (target.is_libc_lib_name(lib_name)) {
9107 if (!comp.config.link_libc) {
90809108 return sema.fail(
90819109 block,
90829110 src_loc,
......@@ -9086,22 +9114,25 @@ fn handleExternLibName(
90869114 }
90879115 break :blk;
90889116 }
9089 if (target_util.is_libcpp_lib_name(target, lib_name)) {
9090 if (!comp.bin_file.options.link_libcpp) {
9091 return sema.fail(
9092 block,
9093 src_loc,
9094 "dependency on libc++ must be explicitly specified in the build command",
9095 .{},
9096 );
9097 }
9117 if (target.is_libcpp_lib_name(lib_name)) {
9118 if (!comp.config.link_libcpp) return sema.fail(
9119 block,
9120 src_loc,
9121 "dependency on libc++ must be explicitly specified in the build command",
9122 .{},
9123 );
90989124 break :blk;
90999125 }
91009126 if (mem.eql(u8, lib_name, "unwind")) {
9101 comp.bin_file.options.link_libunwind = true;
9127 if (!comp.config.link_libunwind) return sema.fail(
9128 block,
9129 src_loc,
9130 "dependency on libunwind must be explicitly specified in the build command",
9131 .{},
9132 );
91029133 break :blk;
91039134 }
9104 if (!target.isWasm() and !comp.bin_file.options.pic) {
9135 if (!target.isWasm() and !block.ownerModule().pic) {
91059136 return sema.fail(
91069137 block,
91079138 src_loc,
......@@ -18728,18 +18759,14 @@ fn retWithErrTracing(
1872818759
1872918760fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
1873018761 const mod = sema.mod;
18731 if (!mod.backendSupportsFeature(.error_return_trace)) return false;
18732
18733 return fn_ret_ty.isError(mod) and
18734 mod.comp.bin_file.options.error_return_tracing;
18762 return fn_ret_ty.isError(mod) and mod.comp.config.any_error_tracing;
1873518763}
1873618764
1873718765fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
1873818766 const mod = sema.mod;
1873918767 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].save_err_ret_index;
1874018768
18741 if (!mod.backendSupportsFeature(.error_return_trace)) return;
18742 if (!mod.comp.bin_file.options.error_return_tracing) return;
18769 if (!block.ownerModule().error_tracing) return;
1874318770
1874418771 // This is only relevant at runtime.
1874518772 if (block.is_comptime or block.is_typeof) return;
......@@ -18764,9 +18791,8 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index)
1876418791 const mod = sema.mod;
1876518792 const ip = &mod.intern_pool;
1876618793
18767 if (!mod.backendSupportsFeature(.error_return_trace)) return;
1876818794 if (!ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn) return;
18769 if (!mod.comp.bin_file.options.error_return_tracing) return;
18795 if (!start_block.ownerModule().error_tracing) return;
1877018796
1877118797 const tracy = trace(@src());
1877218798 defer tracy.end();
......@@ -20037,8 +20063,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2003720063
2003820064 if (sema.owner_func_index != .none and
2003920065 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn and
20040 mod.comp.bin_file.options.error_return_tracing and
20041 mod.backendSupportsFeature(.error_return_trace))
20066 block.ownerModule().error_tracing)
2004220067 {
2004320068 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
2004420069 }
......@@ -34520,7 +34545,9 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
3452034545
3452134546 try sema.resolveTypeFully(Type.fromInterned(fn_ty_info.return_type));
3452234547
34523 if (mod.comp.bin_file.options.error_return_tracing and Type.fromInterned(fn_ty_info.return_type).isError(mod)) {
34548 if (mod.comp.config.any_error_tracing and
34549 Type.fromInterned(fn_ty_info.return_type).isError(mod))
34550 {
3452434551 // Ensure the type exists so that backends can assume that.
3452534552 _ = try sema.getBuiltinType("StackTrace");
3452634553 }
......@@ -36692,7 +36719,7 @@ fn getBuiltinDecl(sema: *Sema, block: *Block, name: []const u8) CompileError!Int
3669236719
3669336720 const mod = sema.mod;
3669436721 const ip = &mod.intern_pool;
36695 const std_mod = mod.main_mod.deps.get("std").?;
36722 const std_mod = mod.std_mod;
3669636723 const std_file = (mod.importPkg(std_mod) catch unreachable).file;
3669736724 const opt_builtin_inst = (try sema.namespaceLookupRef(
3669836725 block,
src/arch/aarch64/CodeGen.zig+92-93
......@@ -329,7 +329,7 @@ const BigTomb = struct {
329329const Self = @This();
330330
331331pub fn generate(
332 bin_file: *link.File,
332 lf: *link.File,
333333 src_loc: Module.SrcLoc,
334334 func_index: InternPool.Index,
335335 air: Air,
......@@ -337,31 +337,30 @@ pub fn generate(
337337 code: *std.ArrayList(u8),
338338 debug_output: DebugInfoOutput,
339339) CodeGenError!Result {
340 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {
341 @panic("Attempted to compile for architecture that was disabled by build configuration");
342 }
343
344 const mod = bin_file.options.module.?;
345 const func = mod.funcInfo(func_index);
346 const fn_owner_decl = mod.declPtr(func.owner_decl);
340 const gpa = lf.comp.gpa;
341 const zcu = lf.comp.module.?;
342 const func = zcu.funcInfo(func_index);
343 const fn_owner_decl = zcu.declPtr(func.owner_decl);
347344 assert(fn_owner_decl.has_tv);
348345 const fn_type = fn_owner_decl.ty;
346 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
347 const target = &namespace.file_scope.mod.resolved_target.result;
349348
350 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
349 var branch_stack = std.ArrayList(Branch).init(gpa);
351350 defer {
352351 assert(branch_stack.items.len == 1);
353 branch_stack.items[0].deinit(bin_file.allocator);
352 branch_stack.items[0].deinit(gpa);
354353 branch_stack.deinit();
355354 }
356355 try branch_stack.append(.{});
357356
358357 var function = Self{
359 .gpa = bin_file.allocator,
358 .gpa = gpa,
360359 .air = air,
361360 .liveness = liveness,
362361 .debug_output = debug_output,
363 .target = &bin_file.options.target,
364 .bin_file = bin_file,
362 .target = target,
363 .bin_file = lf,
365364 .func_index = func_index,
366365 .owner_decl = func.owner_decl,
367366 .err_msg = null,
......@@ -375,15 +374,15 @@ pub fn generate(
375374 .end_di_line = func.rbrace_line,
376375 .end_di_column = func.rbrace_column,
377376 };
378 defer function.stack.deinit(bin_file.allocator);
379 defer function.blocks.deinit(bin_file.allocator);
380 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
381 defer function.dbg_info_relocs.deinit(bin_file.allocator);
377 defer function.stack.deinit(gpa);
378 defer function.blocks.deinit(gpa);
379 defer function.exitlude_jump_relocs.deinit(gpa);
380 defer function.dbg_info_relocs.deinit(gpa);
382381
383382 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
384383 error.CodegenFail => return Result{ .fail = function.err_msg.? },
385384 error.OutOfRegisters => return Result{
386 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
385 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
387386 },
388387 else => |e| return e,
389388 };
......@@ -397,7 +396,7 @@ pub fn generate(
397396 function.gen() catch |err| switch (err) {
398397 error.CodegenFail => return Result{ .fail = function.err_msg.? },
399398 error.OutOfRegisters => return Result{
400 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
399 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
401400 },
402401 else => |e| return e,
403402 };
......@@ -408,15 +407,15 @@ pub fn generate(
408407
409408 var mir = Mir{
410409 .instructions = function.mir_instructions.toOwnedSlice(),
411 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
410 .extra = try function.mir_extra.toOwnedSlice(gpa),
412411 };
413 defer mir.deinit(bin_file.allocator);
412 defer mir.deinit(gpa);
414413
415414 var emit = Emit{
416415 .mir = mir,
417 .bin_file = bin_file,
416 .bin_file = lf,
418417 .debug_output = debug_output,
419 .target = &bin_file.options.target,
418 .target = target,
420419 .src_loc = src_loc,
421420 .code = code,
422421 .prev_di_pc = 0,
......@@ -476,7 +475,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
476475}
477476
478477fn gen(self: *Self) !void {
479 const mod = self.bin_file.options.module.?;
478 const mod = self.bin_file.comp.module.?;
480479 const cc = self.fn_type.fnCallingConvention(mod);
481480 if (cc != .Naked) {
482481 // stp fp, lr, [sp, #-16]!
......@@ -656,7 +655,7 @@ fn gen(self: *Self) !void {
656655}
657656
658657fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
659 const mod = self.bin_file.options.module.?;
658 const mod = self.bin_file.comp.module.?;
660659 const ip = &mod.intern_pool;
661660 const air_tags = self.air.instructions.items(.tag);
662661
......@@ -1028,7 +1027,7 @@ fn allocMem(
10281027
10291028/// Use a pointer instruction as the basis for allocating stack memory.
10301029fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1031 const mod = self.bin_file.options.module.?;
1030 const mod = self.bin_file.comp.module.?;
10321031 const elem_ty = self.typeOfIndex(inst).childType(mod);
10331032
10341033 if (!elem_ty.hasRuntimeBits(mod)) {
......@@ -1048,7 +1047,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10481047}
10491048
10501049fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
1051 const mod = self.bin_file.options.module.?;
1050 const mod = self.bin_file.comp.module.?;
10521051 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
10531052 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
10541053 };
......@@ -1139,7 +1138,7 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
11391138}
11401139
11411140fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
1142 const mod = self.bin_file.options.module.?;
1141 const mod = self.bin_file.comp.module.?;
11431142 const result: MCValue = switch (self.ret_mcv) {
11441143 .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },
11451144 .stack_offset => blk: {
......@@ -1176,7 +1175,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
11761175 if (self.liveness.isUnused(inst))
11771176 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
11781177
1179 const mod = self.bin_file.options.module.?;
1178 const mod = self.bin_file.comp.module.?;
11801179 const operand = ty_op.operand;
11811180 const operand_mcv = try self.resolveInst(operand);
11821181 const operand_ty = self.typeOf(operand);
......@@ -1257,7 +1256,7 @@ fn trunc(
12571256 operand_ty: Type,
12581257 dest_ty: Type,
12591258) !MCValue {
1260 const mod = self.bin_file.options.module.?;
1259 const mod = self.bin_file.comp.module.?;
12611260 const info_a = operand_ty.intInfo(mod);
12621261 const info_b = dest_ty.intInfo(mod);
12631262
......@@ -1320,7 +1319,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
13201319
13211320fn airNot(self: *Self, inst: Air.Inst.Index) !void {
13221321 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1323 const mod = self.bin_file.options.module.?;
1322 const mod = self.bin_file.comp.module.?;
13241323 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
13251324 const operand = try self.resolveInst(ty_op.operand);
13261325 const operand_ty = self.typeOf(ty_op.operand);
......@@ -1415,7 +1414,7 @@ fn minMax(
14151414 rhs_ty: Type,
14161415 maybe_inst: ?Air.Inst.Index,
14171416) !MCValue {
1418 const mod = self.bin_file.options.module.?;
1417 const mod = self.bin_file.comp.module.?;
14191418 switch (lhs_ty.zigTypeTag(mod)) {
14201419 .Float => return self.fail("TODO ARM min/max on floats", .{}),
14211420 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
......@@ -1905,7 +1904,7 @@ fn addSub(
19051904 rhs_ty: Type,
19061905 maybe_inst: ?Air.Inst.Index,
19071906) InnerError!MCValue {
1908 const mod = self.bin_file.options.module.?;
1907 const mod = self.bin_file.comp.module.?;
19091908 switch (lhs_ty.zigTypeTag(mod)) {
19101909 .Float => return self.fail("TODO binary operations on floats", .{}),
19111910 .Vector => return self.fail("TODO binary operations on vectors", .{}),
......@@ -1966,7 +1965,7 @@ fn mul(
19661965 rhs_ty: Type,
19671966 maybe_inst: ?Air.Inst.Index,
19681967) InnerError!MCValue {
1969 const mod = self.bin_file.options.module.?;
1968 const mod = self.bin_file.comp.module.?;
19701969 switch (lhs_ty.zigTypeTag(mod)) {
19711970 .Vector => return self.fail("TODO binary operations on vectors", .{}),
19721971 .Int => {
......@@ -1998,7 +1997,7 @@ fn divFloat(
19981997 _ = rhs_ty;
19991998 _ = maybe_inst;
20001999
2001 const mod = self.bin_file.options.module.?;
2000 const mod = self.bin_file.comp.module.?;
20022001 switch (lhs_ty.zigTypeTag(mod)) {
20032002 .Float => return self.fail("TODO div_float", .{}),
20042003 .Vector => return self.fail("TODO div_float on vectors", .{}),
......@@ -2014,7 +2013,7 @@ fn divTrunc(
20142013 rhs_ty: Type,
20152014 maybe_inst: ?Air.Inst.Index,
20162015) InnerError!MCValue {
2017 const mod = self.bin_file.options.module.?;
2016 const mod = self.bin_file.comp.module.?;
20182017 switch (lhs_ty.zigTypeTag(mod)) {
20192018 .Float => return self.fail("TODO div on floats", .{}),
20202019 .Vector => return self.fail("TODO div on vectors", .{}),
......@@ -2048,7 +2047,7 @@ fn divFloor(
20482047 rhs_ty: Type,
20492048 maybe_inst: ?Air.Inst.Index,
20502049) InnerError!MCValue {
2051 const mod = self.bin_file.options.module.?;
2050 const mod = self.bin_file.comp.module.?;
20522051 switch (lhs_ty.zigTypeTag(mod)) {
20532052 .Float => return self.fail("TODO div on floats", .{}),
20542053 .Vector => return self.fail("TODO div on vectors", .{}),
......@@ -2081,7 +2080,7 @@ fn divExact(
20812080 rhs_ty: Type,
20822081 maybe_inst: ?Air.Inst.Index,
20832082) InnerError!MCValue {
2084 const mod = self.bin_file.options.module.?;
2083 const mod = self.bin_file.comp.module.?;
20852084 switch (lhs_ty.zigTypeTag(mod)) {
20862085 .Float => return self.fail("TODO div on floats", .{}),
20872086 .Vector => return self.fail("TODO div on vectors", .{}),
......@@ -2117,7 +2116,7 @@ fn rem(
21172116) InnerError!MCValue {
21182117 _ = maybe_inst;
21192118
2120 const mod = self.bin_file.options.module.?;
2119 const mod = self.bin_file.comp.module.?;
21212120 switch (lhs_ty.zigTypeTag(mod)) {
21222121 .Float => return self.fail("TODO rem/mod on floats", .{}),
21232122 .Vector => return self.fail("TODO rem/mod on vectors", .{}),
......@@ -2188,7 +2187,7 @@ fn modulo(
21882187 _ = rhs_ty;
21892188 _ = maybe_inst;
21902189
2191 const mod = self.bin_file.options.module.?;
2190 const mod = self.bin_file.comp.module.?;
21922191 switch (lhs_ty.zigTypeTag(mod)) {
21932192 .Float => return self.fail("TODO mod on floats", .{}),
21942193 .Vector => return self.fail("TODO mod on vectors", .{}),
......@@ -2206,7 +2205,7 @@ fn wrappingArithmetic(
22062205 rhs_ty: Type,
22072206 maybe_inst: ?Air.Inst.Index,
22082207) InnerError!MCValue {
2209 const mod = self.bin_file.options.module.?;
2208 const mod = self.bin_file.comp.module.?;
22102209 switch (lhs_ty.zigTypeTag(mod)) {
22112210 .Vector => return self.fail("TODO binary operations on vectors", .{}),
22122211 .Int => {
......@@ -2241,7 +2240,7 @@ fn bitwise(
22412240 rhs_ty: Type,
22422241 maybe_inst: ?Air.Inst.Index,
22432242) InnerError!MCValue {
2244 const mod = self.bin_file.options.module.?;
2243 const mod = self.bin_file.comp.module.?;
22452244 switch (lhs_ty.zigTypeTag(mod)) {
22462245 .Vector => return self.fail("TODO binary operations on vectors", .{}),
22472246 .Int => {
......@@ -2276,7 +2275,7 @@ fn shiftExact(
22762275) InnerError!MCValue {
22772276 _ = rhs_ty;
22782277
2279 const mod = self.bin_file.options.module.?;
2278 const mod = self.bin_file.comp.module.?;
22802279 switch (lhs_ty.zigTypeTag(mod)) {
22812280 .Vector => return self.fail("TODO binary operations on vectors", .{}),
22822281 .Int => {
......@@ -2326,7 +2325,7 @@ fn shiftNormal(
23262325 rhs_ty: Type,
23272326 maybe_inst: ?Air.Inst.Index,
23282327) InnerError!MCValue {
2329 const mod = self.bin_file.options.module.?;
2328 const mod = self.bin_file.comp.module.?;
23302329 switch (lhs_ty.zigTypeTag(mod)) {
23312330 .Vector => return self.fail("TODO binary operations on vectors", .{}),
23322331 .Int => {
......@@ -2366,7 +2365,7 @@ fn booleanOp(
23662365 rhs_ty: Type,
23672366 maybe_inst: ?Air.Inst.Index,
23682367) InnerError!MCValue {
2369 const mod = self.bin_file.options.module.?;
2368 const mod = self.bin_file.comp.module.?;
23702369 switch (lhs_ty.zigTypeTag(mod)) {
23712370 .Bool => {
23722371 assert((try lhs_bind.resolveToImmediate(self)) == null); // should have been handled by Sema
......@@ -2393,7 +2392,7 @@ fn ptrArithmetic(
23932392 rhs_ty: Type,
23942393 maybe_inst: ?Air.Inst.Index,
23952394) InnerError!MCValue {
2396 const mod = self.bin_file.options.module.?;
2395 const mod = self.bin_file.comp.module.?;
23972396 switch (lhs_ty.zigTypeTag(mod)) {
23982397 .Pointer => {
23992398 assert(rhs_ty.eql(Type.usize, mod));
......@@ -2516,7 +2515,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
25162515 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
25172516 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
25182517 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2519 const mod = self.bin_file.options.module.?;
2518 const mod = self.bin_file.comp.module.?;
25202519 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
25212520 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
25222521 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -2644,7 +2643,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
26442643 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
26452644 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
26462645 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2647 const mod = self.bin_file.options.module.?;
2646 const mod = self.bin_file.comp.module.?;
26482647 const result: MCValue = result: {
26492648 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
26502649 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -2868,7 +2867,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
28682867 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
28692868 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
28702869 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
2871 const mod = self.bin_file.options.module.?;
2870 const mod = self.bin_file.comp.module.?;
28722871 const result: MCValue = result: {
28732872 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
28742873 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -3016,7 +3015,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
30163015}
30173016
30183017fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue {
3019 const mod = self.bin_file.options.module.?;
3018 const mod = self.bin_file.comp.module.?;
30203019 const payload_ty = optional_ty.optionalChild(mod);
30213020 if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none;
30223021 if (optional_ty.isPtrLikeOptional(mod)) {
......@@ -3060,7 +3059,7 @@ fn errUnionErr(
30603059 error_union_ty: Type,
30613060 maybe_inst: ?Air.Inst.Index,
30623061) !MCValue {
3063 const mod = self.bin_file.options.module.?;
3062 const mod = self.bin_file.comp.module.?;
30643063 const err_ty = error_union_ty.errorUnionSet(mod);
30653064 const payload_ty = error_union_ty.errorUnionPayload(mod);
30663065 if (err_ty.errorSetIsEmpty(mod)) {
......@@ -3140,7 +3139,7 @@ fn errUnionPayload(
31403139 error_union_ty: Type,
31413140 maybe_inst: ?Air.Inst.Index,
31423141) !MCValue {
3143 const mod = self.bin_file.options.module.?;
3142 const mod = self.bin_file.comp.module.?;
31443143 const err_ty = error_union_ty.errorUnionSet(mod);
31453144 const payload_ty = error_union_ty.errorUnionPayload(mod);
31463145 if (err_ty.errorSetIsEmpty(mod)) {
......@@ -3252,7 +3251,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
32523251}
32533252
32543253fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
3255 const mod = self.bin_file.options.module.?;
3254 const mod = self.bin_file.comp.module.?;
32563255 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
32573256
32583257 if (self.liveness.isUnused(inst)) {
......@@ -3297,7 +3296,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
32973296
32983297/// T to E!T
32993298fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
3300 const mod = self.bin_file.options.module.?;
3299 const mod = self.bin_file.comp.module.?;
33013300 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
33023301 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
33033302 const error_union_ty = ty_op.ty.toType();
......@@ -3323,7 +3322,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
33233322fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
33243323 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
33253324 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3326 const mod = self.bin_file.options.module.?;
3325 const mod = self.bin_file.comp.module.?;
33273326 const error_union_ty = ty_op.ty.toType();
33283327 const error_ty = error_union_ty.errorUnionSet(mod);
33293328 const payload_ty = error_union_ty.errorUnionPayload(mod);
......@@ -3426,7 +3425,7 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void {
34263425}
34273426
34283427fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
3429 const mod = self.bin_file.options.module.?;
3428 const mod = self.bin_file.comp.module.?;
34303429 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34313430 const slice_ty = self.typeOf(bin_op.lhs);
34323431 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
......@@ -3450,7 +3449,7 @@ fn ptrElemVal(
34503449 ptr_ty: Type,
34513450 maybe_inst: ?Air.Inst.Index,
34523451) !MCValue {
3453 const mod = self.bin_file.options.module.?;
3452 const mod = self.bin_file.comp.module.?;
34543453 const elem_ty = ptr_ty.childType(mod);
34553454 const elem_size = @as(u32, @intCast(elem_ty.abiSize(mod)));
34563455
......@@ -3492,7 +3491,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
34923491}
34933492
34943493fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
3495 const mod = self.bin_file.options.module.?;
3494 const mod = self.bin_file.comp.module.?;
34963495 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34973496 const ptr_ty = self.typeOf(bin_op.lhs);
34983497 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
......@@ -3615,7 +3614,7 @@ fn reuseOperand(
36153614}
36163615
36173616fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
3618 const mod = self.bin_file.options.module.?;
3617 const mod = self.bin_file.comp.module.?;
36193618 const elem_ty = ptr_ty.childType(mod);
36203619 const elem_size = elem_ty.abiSize(mod);
36213620
......@@ -3863,7 +3862,7 @@ fn genInlineMemsetCode(
38633862}
38643863
38653864fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
3866 const mod = self.bin_file.options.module.?;
3865 const mod = self.bin_file.comp.module.?;
38673866 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
38683867 const elem_ty = self.typeOfIndex(inst);
38693868 const elem_size = elem_ty.abiSize(mod);
......@@ -3894,7 +3893,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
38943893}
38953894
38963895fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {
3897 const mod = self.bin_file.options.module.?;
3896 const mod = self.bin_file.comp.module.?;
38983897 const abi_size = ty.abiSize(mod);
38993898
39003899 const tag: Mir.Inst.Tag = switch (abi_size) {
......@@ -3917,7 +3916,7 @@ fn genLdrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
39173916}
39183917
39193918fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type) !void {
3920 const mod = self.bin_file.options.module.?;
3919 const mod = self.bin_file.comp.module.?;
39213920 const abi_size = ty.abiSize(mod);
39223921
39233922 const tag: Mir.Inst.Tag = switch (abi_size) {
......@@ -3939,7 +3938,7 @@ fn genStrRegister(self: *Self, value_reg: Register, addr_reg: Register, ty: Type
39393938}
39403939
39413940fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
3942 const mod = self.bin_file.options.module.?;
3941 const mod = self.bin_file.comp.module.?;
39433942 log.debug("store: storing {} to {}", .{ value, ptr });
39443943 const abi_size = value_ty.abiSize(mod);
39453944
......@@ -4092,7 +4091,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
40924091
40934092fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
40944093 return if (self.liveness.isUnused(inst)) .dead else result: {
4095 const mod = self.bin_file.options.module.?;
4094 const mod = self.bin_file.comp.module.?;
40964095 const mcv = try self.resolveInst(operand);
40974096 const ptr_ty = self.typeOf(operand);
40984097 const struct_ty = ptr_ty.childType(mod);
......@@ -4117,7 +4116,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
41174116 const operand = extra.struct_operand;
41184117 const index = extra.field_index;
41194118 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4120 const mod = self.bin_file.options.module.?;
4119 const mod = self.bin_file.comp.module.?;
41214120 const mcv = try self.resolveInst(operand);
41224121 const struct_ty = self.typeOf(operand);
41234122 const struct_field_ty = struct_ty.structFieldType(index, mod);
......@@ -4167,7 +4166,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
41674166}
41684167
41694168fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
4170 const mod = self.bin_file.options.module.?;
4169 const mod = self.bin_file.comp.module.?;
41714170 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
41724171 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
41734172 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
......@@ -4195,7 +4194,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
41954194 while (self.args[arg_index] == .none) arg_index += 1;
41964195 self.arg_index = arg_index + 1;
41974196
4198 const mod = self.bin_file.options.module.?;
4197 const mod = self.bin_file.comp.module.?;
41994198 const ty = self.typeOfIndex(inst);
42004199 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
42014200 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
......@@ -4250,7 +4249,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42504249 const extra = self.air.extraData(Air.Call, pl_op.payload);
42514250 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]));
42524251 const ty = self.typeOf(callee);
4253 const mod = self.bin_file.options.module.?;
4252 const mod = self.bin_file.comp.module.?;
42544253
42554254 const fn_ty = switch (ty.zigTypeTag(mod)) {
42564255 .Fn => ty,
......@@ -4422,7 +4421,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
44224421}
44234422
44244423fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4425 const mod = self.bin_file.options.module.?;
4424 const mod = self.bin_file.comp.module.?;
44264425 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
44274426 const operand = try self.resolveInst(un_op);
44284427 const ret_ty = self.fn_type.fnReturnType(mod);
......@@ -4454,7 +4453,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
44544453}
44554454
44564455fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4457 const mod = self.bin_file.options.module.?;
4456 const mod = self.bin_file.comp.module.?;
44584457 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
44594458 const ptr = try self.resolveInst(un_op);
44604459 const ptr_ty = self.typeOf(un_op);
......@@ -4514,7 +4513,7 @@ fn cmp(
45144513 lhs_ty: Type,
45154514 op: math.CompareOperator,
45164515) !MCValue {
4517 const mod = self.bin_file.options.module.?;
4516 const mod = self.bin_file.comp.module.?;
45184517 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
45194518 .Optional => blk: {
45204519 const payload_ty = lhs_ty.optionalChild(mod);
......@@ -4622,7 +4621,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
46224621
46234622fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
46244623 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
4625 const mod = self.bin_file.options.module.?;
4624 const mod = self.bin_file.comp.module.?;
46264625 const func = mod.funcInfo(ty_fn.func);
46274626 // TODO emit debug info for function change
46284627 _ = func;
......@@ -4830,7 +4829,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
48304829}
48314830
48324831fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue {
4833 const mod = self.bin_file.options.module.?;
4832 const mod = self.bin_file.comp.module.?;
48344833 const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: {
48354834 const payload_ty = operand_ty.optionalChild(mod);
48364835 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod))
......@@ -4886,7 +4885,7 @@ fn isErr(
48864885 error_union_bind: ReadArg.Bind,
48874886 error_union_ty: Type,
48884887) !MCValue {
4889 const mod = self.bin_file.options.module.?;
4888 const mod = self.bin_file.comp.module.?;
48904889 const error_type = error_union_ty.errorUnionSet(mod);
48914890
48924891 if (error_type.errorSetIsEmpty(mod)) {
......@@ -4928,7 +4927,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
49284927}
49294928
49304929fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4931 const mod = self.bin_file.options.module.?;
4930 const mod = self.bin_file.comp.module.?;
49324931 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
49334932 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
49344933 const operand_ptr = try self.resolveInst(un_op);
......@@ -4955,7 +4954,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
49554954}
49564955
49574956fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4958 const mod = self.bin_file.options.module.?;
4957 const mod = self.bin_file.comp.module.?;
49594958 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
49604959 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
49614960 const operand_ptr = try self.resolveInst(un_op);
......@@ -4982,7 +4981,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
49824981}
49834982
49844983fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4985 const mod = self.bin_file.options.module.?;
4984 const mod = self.bin_file.comp.module.?;
49864985 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
49874986 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
49884987 const operand_ptr = try self.resolveInst(un_op);
......@@ -5009,7 +5008,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
50095008}
50105009
50115010fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
5012 const mod = self.bin_file.options.module.?;
5011 const mod = self.bin_file.comp.module.?;
50135012 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
50145013 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
50155014 const operand_ptr = try self.resolveInst(un_op);
......@@ -5226,7 +5225,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
52265225}
52275226
52285227fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5229 const mod = self.bin_file.options.module.?;
5228 const mod = self.bin_file.comp.module.?;
52305229 const block_data = self.blocks.getPtr(block).?;
52315230
52325231 if (self.typeOf(operand).hasRuntimeBits(mod)) {
......@@ -5403,7 +5402,7 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
54035402}
54045403
54055404fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5406 const mod = self.bin_file.options.module.?;
5405 const mod = self.bin_file.comp.module.?;
54075406 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
54085407 switch (mcv) {
54095408 .dead => unreachable,
......@@ -5573,7 +5572,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
55735572}
55745573
55755574fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5576 const mod = self.bin_file.options.module.?;
5575 const mod = self.bin_file.comp.module.?;
55775576 switch (mcv) {
55785577 .dead => unreachable,
55795578 .unreach, .none => return, // Nothing to do.
......@@ -5735,7 +5734,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
57355734}
57365735
57375736fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5738 const mod = self.bin_file.options.module.?;
5737 const mod = self.bin_file.comp.module.?;
57395738 const abi_size = @as(u32, @intCast(ty.abiSize(mod)));
57405739 switch (mcv) {
57415740 .dead => unreachable,
......@@ -5934,7 +5933,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
59345933}
59355934
59365935fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
5937 const mod = self.bin_file.options.module.?;
5936 const mod = self.bin_file.comp.module.?;
59385937 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59395938 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
59405939 const ptr_ty = self.typeOf(ty_op.operand);
......@@ -6054,7 +6053,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
60546053}
60556054
60566055fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
6057 const mod = self.bin_file.options.module.?;
6056 const mod = self.bin_file.comp.module.?;
60586057 const vector_ty = self.typeOfIndex(inst);
60596058 const len = vector_ty.vectorLen(mod);
60606059 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -6098,7 +6097,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
60986097}
60996098
61006099fn airTry(self: *Self, inst: Air.Inst.Index) !void {
6101 const mod = self.bin_file.options.module.?;
6100 const mod = self.bin_file.comp.module.?;
61026101 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
61036102 const extra = self.air.extraData(Air.Try, pl_op.payload);
61046103 const body: []const Air.Inst.Index = @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]);
......@@ -6135,7 +6134,7 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
61356134}
61366135
61376136fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6138 const mod = self.bin_file.options.module.?;
6137 const mod = self.bin_file.comp.module.?;
61396138
61406139 // If the type has no codegen bits, no need to store it.
61416140 const inst_ty = self.typeOf(inst);
......@@ -6200,7 +6199,7 @@ const CallMCValues = struct {
62006199
62016200/// Caller must call `CallMCValues.deinit`.
62026201fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6203 const mod = self.bin_file.options.module.?;
6202 const mod = self.bin_file.comp.module.?;
62046203 const ip = &mod.intern_pool;
62056204 const fn_info = mod.typeToFunc(fn_ty).?;
62066205 const cc = fn_info.cc;
......@@ -6333,7 +6332,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
63336332
63346333/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.
63356334fn wantSafety(self: *Self) bool {
6336 return switch (self.bin_file.options.optimize_mode) {
6335 return switch (self.bin_file.comp.root_mod.optimize_mode) {
63376336 .Debug => true,
63386337 .ReleaseSafe => true,
63396338 .ReleaseFast => false,
......@@ -6344,14 +6343,14 @@ fn wantSafety(self: *Self) bool {
63446343fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
63456344 @setCold(true);
63466345 assert(self.err_msg == null);
6347 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
6346 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
63486347 return error.CodegenFail;
63496348}
63506349
63516350fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
63526351 @setCold(true);
63536352 assert(self.err_msg == null);
6354 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
6353 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
63556354 return error.CodegenFail;
63566355}
63576356
......@@ -6363,7 +6362,7 @@ fn parseRegName(name: []const u8) ?Register {
63636362}
63646363
63656364fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
6366 const mod = self.bin_file.options.module.?;
6365 const mod = self.bin_file.comp.module.?;
63676366 const abi_size = ty.abiSize(mod);
63686367
63696368 switch (reg.class()) {
......@@ -6392,11 +6391,11 @@ fn registerAlias(self: *Self, reg: Register, ty: Type) Register {
63926391}
63936392
63946393fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
6395 const mod = self.bin_file.options.module.?;
6394 const mod = self.bin_file.comp.module.?;
63966395 return self.air.typeOf(inst, &mod.intern_pool);
63976396}
63986397
63996398fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
6400 const mod = self.bin_file.options.module.?;
6399 const mod = self.bin_file.comp.module.?;
64016400 return self.air.typeOfIndex(inst, &mod.intern_pool);
64026401}
src/arch/aarch64/Emit.zig+17-12
......@@ -218,14 +218,16 @@ pub fn emitMir(
218218}
219219
220220pub fn deinit(emit: *Emit) void {
221 const comp = emit.bin_file.comp;
222 const gpa = comp.gpa;
221223 var iter = emit.branch_forward_origins.valueIterator();
222224 while (iter.next()) |origin_list| {
223 origin_list.deinit(emit.bin_file.allocator);
225 origin_list.deinit(gpa);
224226 }
225227
226 emit.branch_types.deinit(emit.bin_file.allocator);
227 emit.branch_forward_origins.deinit(emit.bin_file.allocator);
228 emit.code_offset_mapping.deinit(emit.bin_file.allocator);
228 emit.branch_types.deinit(gpa);
229 emit.branch_forward_origins.deinit(gpa);
230 emit.code_offset_mapping.deinit(gpa);
229231 emit.* = undefined;
230232}
231233
......@@ -314,8 +316,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index {
314316}
315317
316318fn lowerBranches(emit: *Emit) !void {
319 const comp = emit.bin_file.comp;
320 const gpa = comp.gpa;
317321 const mir_tags = emit.mir.instructions.items(.tag);
318 const allocator = emit.bin_file.allocator;
319322
320323 // First pass: Note down all branches and their target
321324 // instructions, i.e. populate branch_types,
......@@ -329,7 +332,7 @@ fn lowerBranches(emit: *Emit) !void {
329332 const target_inst = emit.branchTarget(inst);
330333
331334 // Remember this branch instruction
332 try emit.branch_types.put(allocator, inst, BranchType.default(tag));
335 try emit.branch_types.put(gpa, inst, BranchType.default(tag));
333336
334337 // Forward branches require some extra stuff: We only
335338 // know their offset once we arrive at the target
......@@ -339,14 +342,14 @@ fn lowerBranches(emit: *Emit) !void {
339342 // etc.
340343 if (target_inst > inst) {
341344 // Remember the branch instruction index
342 try emit.code_offset_mapping.put(allocator, inst, 0);
345 try emit.code_offset_mapping.put(gpa, inst, 0);
343346
344347 if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| {
345 try origin_list.append(allocator, inst);
348 try origin_list.append(gpa, inst);
346349 } else {
347350 var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{};
348 try origin_list.append(allocator, inst);
349 try emit.branch_forward_origins.put(allocator, target_inst, origin_list);
351 try origin_list.append(gpa, inst);
352 try emit.branch_forward_origins.put(gpa, target_inst, origin_list);
350353 }
351354 }
352355
......@@ -356,7 +359,7 @@ fn lowerBranches(emit: *Emit) !void {
356359 // putNoClobber may not be used as the put operation
357360 // may clobber the entry when multiple branches branch
358361 // to the same target instruction
359 try emit.code_offset_mapping.put(allocator, target_inst, 0);
362 try emit.code_offset_mapping.put(gpa, target_inst, 0);
360363 }
361364 }
362365
......@@ -429,7 +432,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
429432fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
430433 @setCold(true);
431434 assert(emit.err_msg == null);
432 emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
435 const comp = emit.bin_file.comp;
436 const gpa = comp.gpa;
437 emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
433438 return error.EmitFail;
434439}
435440
src/arch/arm/CodeGen.zig+97-96
......@@ -260,7 +260,7 @@ const DbgInfoReloc = struct {
260260 }
261261
262262 fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void {
263 const mod = function.bin_file.options.module.?;
263 const mod = function.bin_file.comp.module.?;
264264 switch (function.debug_output) {
265265 .dwarf => |dw| {
266266 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
......@@ -289,7 +289,7 @@ const DbgInfoReloc = struct {
289289 }
290290
291291 fn genVarDbgInfo(reloc: DbgInfoReloc, function: Self) !void {
292 const mod = function.bin_file.options.module.?;
292 const mod = function.bin_file.comp.module.?;
293293 const is_ptr = switch (reloc.tag) {
294294 .dbg_var_ptr => true,
295295 .dbg_var_val => false,
......@@ -336,7 +336,7 @@ const DbgInfoReloc = struct {
336336const Self = @This();
337337
338338pub fn generate(
339 bin_file: *link.File,
339 lf: *link.File,
340340 src_loc: Module.SrcLoc,
341341 func_index: InternPool.Index,
342342 air: Air,
......@@ -344,30 +344,29 @@ pub fn generate(
344344 code: *std.ArrayList(u8),
345345 debug_output: DebugInfoOutput,
346346) CodeGenError!Result {
347 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {
348 @panic("Attempted to compile for architecture that was disabled by build configuration");
349 }
350
351 const mod = bin_file.options.module.?;
352 const func = mod.funcInfo(func_index);
353 const fn_owner_decl = mod.declPtr(func.owner_decl);
347 const gpa = lf.comp.gpa;
348 const zcu = lf.comp.module.?;
349 const func = zcu.funcInfo(func_index);
350 const fn_owner_decl = zcu.declPtr(func.owner_decl);
354351 assert(fn_owner_decl.has_tv);
355352 const fn_type = fn_owner_decl.ty;
353 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
354 const target = &namespace.file_scope.mod.resolved_target.result;
356355
357 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
356 var branch_stack = std.ArrayList(Branch).init(gpa);
358357 defer {
359358 assert(branch_stack.items.len == 1);
360 branch_stack.items[0].deinit(bin_file.allocator);
359 branch_stack.items[0].deinit(gpa);
361360 branch_stack.deinit();
362361 }
363362 try branch_stack.append(.{});
364363
365 var function = Self{
366 .gpa = bin_file.allocator,
364 var function: Self = .{
365 .gpa = gpa,
367366 .air = air,
368367 .liveness = liveness,
369 .target = &bin_file.options.target,
370 .bin_file = bin_file,
368 .target = target,
369 .bin_file = lf,
371370 .debug_output = debug_output,
372371 .func_index = func_index,
373372 .err_msg = null,
......@@ -381,15 +380,15 @@ pub fn generate(
381380 .end_di_line = func.rbrace_line,
382381 .end_di_column = func.rbrace_column,
383382 };
384 defer function.stack.deinit(bin_file.allocator);
385 defer function.blocks.deinit(bin_file.allocator);
386 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
387 defer function.dbg_info_relocs.deinit(bin_file.allocator);
383 defer function.stack.deinit(gpa);
384 defer function.blocks.deinit(gpa);
385 defer function.exitlude_jump_relocs.deinit(gpa);
386 defer function.dbg_info_relocs.deinit(gpa);
388387
389388 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
390389 error.CodegenFail => return Result{ .fail = function.err_msg.? },
391390 error.OutOfRegisters => return Result{
392 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
391 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
393392 },
394393 else => |e| return e,
395394 };
......@@ -403,7 +402,7 @@ pub fn generate(
403402 function.gen() catch |err| switch (err) {
404403 error.CodegenFail => return Result{ .fail = function.err_msg.? },
405404 error.OutOfRegisters => return Result{
406 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
405 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
407406 },
408407 else => |e| return e,
409408 };
......@@ -414,15 +413,15 @@ pub fn generate(
414413
415414 var mir = Mir{
416415 .instructions = function.mir_instructions.toOwnedSlice(),
417 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
416 .extra = try function.mir_extra.toOwnedSlice(gpa),
418417 };
419 defer mir.deinit(bin_file.allocator);
418 defer mir.deinit(gpa);
420419
421420 var emit = Emit{
422421 .mir = mir,
423 .bin_file = bin_file,
422 .bin_file = lf,
424423 .debug_output = debug_output,
425 .target = &bin_file.options.target,
424 .target = target,
426425 .src_loc = src_loc,
427426 .code = code,
428427 .prev_di_pc = 0,
......@@ -482,7 +481,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
482481}
483482
484483fn gen(self: *Self) !void {
485 const mod = self.bin_file.options.module.?;
484 const mod = self.bin_file.comp.module.?;
486485 const cc = self.fn_type.fnCallingConvention(mod);
487486 if (cc != .Naked) {
488487 // push {fp, lr}
......@@ -642,7 +641,7 @@ fn gen(self: *Self) !void {
642641}
643642
644643fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
645 const mod = self.bin_file.options.module.?;
644 const mod = self.bin_file.comp.module.?;
646645 const ip = &mod.intern_pool;
647646 const air_tags = self.air.instructions.items(.tag);
648647
......@@ -1010,7 +1009,7 @@ fn allocMem(
10101009
10111010/// Use a pointer instruction as the basis for allocating stack memory.
10121011fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
1013 const mod = self.bin_file.options.module.?;
1012 const mod = self.bin_file.comp.module.?;
10141013 const elem_ty = self.typeOfIndex(inst).childType(mod);
10151014
10161015 if (!elem_ty.hasRuntimeBits(mod)) {
......@@ -1031,7 +1030,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
10311030}
10321031
10331032fn allocRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool, maybe_inst: ?Air.Inst.Index) !MCValue {
1034 const mod = self.bin_file.options.module.?;
1033 const mod = self.bin_file.comp.module.?;
10351034 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
10361035 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
10371036 };
......@@ -1118,7 +1117,7 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void {
11181117}
11191118
11201119fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void {
1121 const mod = self.bin_file.options.module.?;
1120 const mod = self.bin_file.comp.module.?;
11221121 const result: MCValue = switch (self.ret_mcv) {
11231122 .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) },
11241123 .stack_offset => blk: {
......@@ -1151,7 +1150,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
11511150}
11521151
11531152fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
1154 const mod = self.bin_file.options.module.?;
1153 const mod = self.bin_file.comp.module.?;
11551154 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
11561155 if (self.liveness.isUnused(inst))
11571156 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
......@@ -1217,7 +1216,7 @@ fn trunc(
12171216 operand_ty: Type,
12181217 dest_ty: Type,
12191218) !MCValue {
1220 const mod = self.bin_file.options.module.?;
1219 const mod = self.bin_file.comp.module.?;
12211220 const info_a = operand_ty.intInfo(mod);
12221221 const info_b = dest_ty.intInfo(mod);
12231222
......@@ -1281,7 +1280,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
12811280
12821281fn airNot(self: *Self, inst: Air.Inst.Index) !void {
12831282 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1284 const mod = self.bin_file.options.module.?;
1283 const mod = self.bin_file.comp.module.?;
12851284 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
12861285 const operand_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
12871286 const operand_ty = self.typeOf(ty_op.operand);
......@@ -1377,7 +1376,7 @@ fn minMax(
13771376 rhs_ty: Type,
13781377 maybe_inst: ?Air.Inst.Index,
13791378) !MCValue {
1380 const mod = self.bin_file.options.module.?;
1379 const mod = self.bin_file.comp.module.?;
13811380 switch (lhs_ty.zigTypeTag(mod)) {
13821381 .Float => return self.fail("TODO ARM min/max on floats", .{}),
13831382 .Vector => return self.fail("TODO ARM min/max on vectors", .{}),
......@@ -1586,7 +1585,7 @@ fn airOverflow(self: *Self, inst: Air.Inst.Index) !void {
15861585 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
15871586 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
15881587 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
1589 const mod = self.bin_file.options.module.?;
1588 const mod = self.bin_file.comp.module.?;
15901589 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
15911590 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
15921591 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -1699,7 +1698,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
16991698 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
17001699 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
17011700 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1702 const mod = self.bin_file.options.module.?;
1701 const mod = self.bin_file.comp.module.?;
17031702 const result: MCValue = result: {
17041703 const lhs_bind: ReadArg.Bind = .{ .inst = extra.lhs };
17051704 const rhs_bind: ReadArg.Bind = .{ .inst = extra.rhs };
......@@ -1863,7 +1862,7 @@ fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
18631862 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
18641863 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
18651864 if (self.liveness.isUnused(inst)) return self.finishAir(inst, .dead, .{ extra.lhs, extra.rhs, .none });
1866 const mod = self.bin_file.options.module.?;
1865 const mod = self.bin_file.comp.module.?;
18671866 const result: MCValue = result: {
18681867 const lhs_ty = self.typeOf(extra.lhs);
18691868 const rhs_ty = self.typeOf(extra.rhs);
......@@ -2019,7 +2018,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
20192018}
20202019
20212020fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2022 const mod = self.bin_file.options.module.?;
2021 const mod = self.bin_file.comp.module.?;
20232022 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
20242023 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
20252024 const optional_ty = self.typeOfIndex(inst);
......@@ -2042,7 +2041,7 @@ fn errUnionErr(
20422041 error_union_ty: Type,
20432042 maybe_inst: ?Air.Inst.Index,
20442043) !MCValue {
2045 const mod = self.bin_file.options.module.?;
2044 const mod = self.bin_file.comp.module.?;
20462045 const err_ty = error_union_ty.errorUnionSet(mod);
20472046 const payload_ty = error_union_ty.errorUnionPayload(mod);
20482047 if (err_ty.errorSetIsEmpty(mod)) {
......@@ -2119,7 +2118,7 @@ fn errUnionPayload(
21192118 error_union_ty: Type,
21202119 maybe_inst: ?Air.Inst.Index,
21212120) !MCValue {
2122 const mod = self.bin_file.options.module.?;
2121 const mod = self.bin_file.comp.module.?;
21232122 const err_ty = error_union_ty.errorUnionSet(mod);
21242123 const payload_ty = error_union_ty.errorUnionPayload(mod);
21252124 if (err_ty.errorSetIsEmpty(mod)) {
......@@ -2229,7 +2228,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
22292228
22302229/// T to E!T
22312230fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
2232 const mod = self.bin_file.options.module.?;
2231 const mod = self.bin_file.comp.module.?;
22332232 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
22342233 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
22352234 const error_union_ty = ty_op.ty.toType();
......@@ -2253,7 +2252,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
22532252
22542253/// E to E!T
22552254fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2256 const mod = self.bin_file.options.module.?;
2255 const mod = self.bin_file.comp.module.?;
22572256 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
22582257 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
22592258 const error_union_ty = ty_op.ty.toType();
......@@ -2370,7 +2369,7 @@ fn ptrElemVal(
23702369 ptr_ty: Type,
23712370 maybe_inst: ?Air.Inst.Index,
23722371) !MCValue {
2373 const mod = self.bin_file.options.module.?;
2372 const mod = self.bin_file.comp.module.?;
23742373 const elem_ty = ptr_ty.childType(mod);
23752374 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));
23762375
......@@ -2429,7 +2428,7 @@ fn ptrElemVal(
24292428}
24302429
24312430fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2432 const mod = self.bin_file.options.module.?;
2431 const mod = self.bin_file.comp.module.?;
24332432 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
24342433 const slice_ty = self.typeOf(bin_op.lhs);
24352434 const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
......@@ -2472,7 +2471,7 @@ fn arrayElemVal(
24722471 array_ty: Type,
24732472 maybe_inst: ?Air.Inst.Index,
24742473) InnerError!MCValue {
2475 const mod = self.bin_file.options.module.?;
2474 const mod = self.bin_file.comp.module.?;
24762475 const elem_ty = array_ty.childType(mod);
24772476
24782477 const mcv = try array_bind.resolveToMcv(self);
......@@ -2528,7 +2527,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
25282527}
25292528
25302529fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
2531 const mod = self.bin_file.options.module.?;
2530 const mod = self.bin_file.comp.module.?;
25322531 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
25332532 const ptr_ty = self.typeOf(bin_op.lhs);
25342533 const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
......@@ -2662,7 +2661,7 @@ fn reuseOperand(
26622661}
26632662
26642663fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
2665 const mod = self.bin_file.options.module.?;
2664 const mod = self.bin_file.comp.module.?;
26662665 const elem_ty = ptr_ty.childType(mod);
26672666 const elem_size: u32 = @intCast(elem_ty.abiSize(mod));
26682667
......@@ -2739,7 +2738,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
27392738}
27402739
27412740fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
2742 const mod = self.bin_file.options.module.?;
2741 const mod = self.bin_file.comp.module.?;
27432742 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
27442743 const elem_ty = self.typeOfIndex(inst);
27452744 const result: MCValue = result: {
......@@ -2768,7 +2767,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
27682767}
27692768
27702769fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
2771 const mod = self.bin_file.options.module.?;
2770 const mod = self.bin_file.comp.module.?;
27722771 const elem_size: u32 = @intCast(value_ty.abiSize(mod));
27732772
27742773 switch (ptr) {
......@@ -2888,7 +2887,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
28882887
28892888fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
28902889 return if (self.liveness.isUnused(inst)) .dead else result: {
2891 const mod = self.bin_file.options.module.?;
2890 const mod = self.bin_file.comp.module.?;
28922891 const mcv = try self.resolveInst(operand);
28932892 const ptr_ty = self.typeOf(operand);
28942893 const struct_ty = ptr_ty.childType(mod);
......@@ -2912,7 +2911,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
29122911 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
29132912 const operand = extra.struct_operand;
29142913 const index = extra.field_index;
2915 const mod = self.bin_file.options.module.?;
2914 const mod = self.bin_file.comp.module.?;
29162915 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
29172916 const mcv = try self.resolveInst(operand);
29182917 const struct_ty = self.typeOf(operand);
......@@ -3002,7 +3001,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
30023001}
30033002
30043003fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
3005 const mod = self.bin_file.options.module.?;
3004 const mod = self.bin_file.comp.module.?;
30063005 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
30073006 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
30083007 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
......@@ -3396,7 +3395,7 @@ fn addSub(
33963395 rhs_ty: Type,
33973396 maybe_inst: ?Air.Inst.Index,
33983397) InnerError!MCValue {
3399 const mod = self.bin_file.options.module.?;
3398 const mod = self.bin_file.comp.module.?;
34003399 switch (lhs_ty.zigTypeTag(mod)) {
34013400 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
34023401 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3452,7 +3451,7 @@ fn mul(
34523451 rhs_ty: Type,
34533452 maybe_inst: ?Air.Inst.Index,
34543453) InnerError!MCValue {
3455 const mod = self.bin_file.options.module.?;
3454 const mod = self.bin_file.comp.module.?;
34563455 switch (lhs_ty.zigTypeTag(mod)) {
34573456 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
34583457 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3485,7 +3484,7 @@ fn divFloat(
34853484 _ = rhs_ty;
34863485 _ = maybe_inst;
34873486
3488 const mod = self.bin_file.options.module.?;
3487 const mod = self.bin_file.comp.module.?;
34893488 switch (lhs_ty.zigTypeTag(mod)) {
34903489 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
34913490 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3501,7 +3500,7 @@ fn divTrunc(
35013500 rhs_ty: Type,
35023501 maybe_inst: ?Air.Inst.Index,
35033502) InnerError!MCValue {
3504 const mod = self.bin_file.options.module.?;
3503 const mod = self.bin_file.comp.module.?;
35053504 switch (lhs_ty.zigTypeTag(mod)) {
35063505 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
35073506 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3544,7 +3543,7 @@ fn divFloor(
35443543 rhs_ty: Type,
35453544 maybe_inst: ?Air.Inst.Index,
35463545) InnerError!MCValue {
3547 const mod = self.bin_file.options.module.?;
3546 const mod = self.bin_file.comp.module.?;
35483547 switch (lhs_ty.zigTypeTag(mod)) {
35493548 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
35503549 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3592,7 +3591,7 @@ fn divExact(
35923591 _ = rhs_ty;
35933592 _ = maybe_inst;
35943593
3595 const mod = self.bin_file.options.module.?;
3594 const mod = self.bin_file.comp.module.?;
35963595 switch (lhs_ty.zigTypeTag(mod)) {
35973596 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
35983597 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3609,7 +3608,7 @@ fn rem(
36093608 rhs_ty: Type,
36103609 maybe_inst: ?Air.Inst.Index,
36113610) InnerError!MCValue {
3612 const mod = self.bin_file.options.module.?;
3611 const mod = self.bin_file.comp.module.?;
36133612 switch (lhs_ty.zigTypeTag(mod)) {
36143613 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
36153614 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3678,7 +3677,7 @@ fn modulo(
36783677 _ = rhs_ty;
36793678 _ = maybe_inst;
36803679
3681 const mod = self.bin_file.options.module.?;
3680 const mod = self.bin_file.comp.module.?;
36823681 switch (lhs_ty.zigTypeTag(mod)) {
36833682 .Float => return self.fail("TODO ARM binary operations on floats", .{}),
36843683 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
......@@ -3696,7 +3695,7 @@ fn wrappingArithmetic(
36963695 rhs_ty: Type,
36973696 maybe_inst: ?Air.Inst.Index,
36983697) InnerError!MCValue {
3699 const mod = self.bin_file.options.module.?;
3698 const mod = self.bin_file.comp.module.?;
37003699 switch (lhs_ty.zigTypeTag(mod)) {
37013700 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
37023701 .Int => {
......@@ -3734,7 +3733,7 @@ fn bitwise(
37343733 rhs_ty: Type,
37353734 maybe_inst: ?Air.Inst.Index,
37363735) InnerError!MCValue {
3737 const mod = self.bin_file.options.module.?;
3736 const mod = self.bin_file.comp.module.?;
37383737 switch (lhs_ty.zigTypeTag(mod)) {
37393738 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
37403739 .Int => {
......@@ -3779,7 +3778,7 @@ fn shiftExact(
37793778 rhs_ty: Type,
37803779 maybe_inst: ?Air.Inst.Index,
37813780) InnerError!MCValue {
3782 const mod = self.bin_file.options.module.?;
3781 const mod = self.bin_file.comp.module.?;
37833782 switch (lhs_ty.zigTypeTag(mod)) {
37843783 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
37853784 .Int => {
......@@ -3818,7 +3817,7 @@ fn shiftNormal(
38183817 rhs_ty: Type,
38193818 maybe_inst: ?Air.Inst.Index,
38203819) InnerError!MCValue {
3821 const mod = self.bin_file.options.module.?;
3820 const mod = self.bin_file.comp.module.?;
38223821 switch (lhs_ty.zigTypeTag(mod)) {
38233822 .Vector => return self.fail("TODO ARM binary operations on vectors", .{}),
38243823 .Int => {
......@@ -3861,7 +3860,7 @@ fn booleanOp(
38613860 rhs_ty: Type,
38623861 maybe_inst: ?Air.Inst.Index,
38633862) InnerError!MCValue {
3864 const mod = self.bin_file.options.module.?;
3863 const mod = self.bin_file.comp.module.?;
38653864 switch (lhs_ty.zigTypeTag(mod)) {
38663865 .Bool => {
38673866 const lhs_immediate = try lhs_bind.resolveToImmediate(self);
......@@ -3895,7 +3894,7 @@ fn ptrArithmetic(
38953894 rhs_ty: Type,
38963895 maybe_inst: ?Air.Inst.Index,
38973896) InnerError!MCValue {
3898 const mod = self.bin_file.options.module.?;
3897 const mod = self.bin_file.comp.module.?;
38993898 switch (lhs_ty.zigTypeTag(mod)) {
39003899 .Pointer => {
39013900 assert(rhs_ty.eql(Type.usize, mod));
......@@ -3932,7 +3931,7 @@ fn ptrArithmetic(
39323931}
39333932
39343933fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type) !void {
3935 const mod = self.bin_file.options.module.?;
3934 const mod = self.bin_file.comp.module.?;
39363935 const abi_size = ty.abiSize(mod);
39373936
39383937 const tag: Mir.Inst.Tag = switch (abi_size) {
......@@ -3967,7 +3966,7 @@ fn genLdrRegister(self: *Self, dest_reg: Register, addr_reg: Register, ty: Type)
39673966}
39683967
39693968fn genStrRegister(self: *Self, source_reg: Register, addr_reg: Register, ty: Type) !void {
3970 const mod = self.bin_file.options.module.?;
3969 const mod = self.bin_file.comp.module.?;
39713970 const abi_size = ty.abiSize(mod);
39723971
39733972 const tag: Mir.Inst.Tag = switch (abi_size) {
......@@ -4174,7 +4173,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
41744173 while (self.args[arg_index] == .none) arg_index += 1;
41754174 self.arg_index = arg_index + 1;
41764175
4177 const mod = self.bin_file.options.module.?;
4176 const mod = self.bin_file.comp.module.?;
41784177 const ty = self.typeOfIndex(inst);
41794178 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
41804179 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
......@@ -4229,7 +4228,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
42294228 const extra = self.air.extraData(Air.Call, pl_op.payload);
42304229 const args: []const Air.Inst.Ref = @ptrCast(self.air.extra[extra.end..][0..extra.data.args_len]);
42314230 const ty = self.typeOf(callee);
4232 const mod = self.bin_file.options.module.?;
4231 const mod = self.bin_file.comp.module.?;
42334232
42344233 const fn_ty = switch (ty.zigTypeTag(mod)) {
42354234 .Fn => ty,
......@@ -4380,7 +4379,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
43804379}
43814380
43824381fn airRet(self: *Self, inst: Air.Inst.Index) !void {
4383 const mod = self.bin_file.options.module.?;
4382 const mod = self.bin_file.comp.module.?;
43844383 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
43854384 const operand = try self.resolveInst(un_op);
43864385 const ret_ty = self.fn_type.fnReturnType(mod);
......@@ -4412,7 +4411,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
44124411}
44134412
44144413fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
4415 const mod = self.bin_file.options.module.?;
4414 const mod = self.bin_file.comp.module.?;
44164415 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
44174416 const ptr = try self.resolveInst(un_op);
44184417 const ptr_ty = self.typeOf(un_op);
......@@ -4473,7 +4472,7 @@ fn cmp(
44734472 lhs_ty: Type,
44744473 op: math.CompareOperator,
44754474) !MCValue {
4476 const mod = self.bin_file.options.module.?;
4475 const mod = self.bin_file.comp.module.?;
44774476 const int_ty = switch (lhs_ty.zigTypeTag(mod)) {
44784477 .Optional => blk: {
44794478 const payload_ty = lhs_ty.optionalChild(mod);
......@@ -4580,7 +4579,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
45804579
45814580fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
45824581 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
4583 const mod = self.bin_file.options.module.?;
4582 const mod = self.bin_file.comp.module.?;
45844583 const func = mod.funcInfo(ty_fn.func);
45854584 // TODO emit debug info for function change
45864585 _ = func;
......@@ -4795,7 +4794,7 @@ fn isNull(
47954794 operand_bind: ReadArg.Bind,
47964795 operand_ty: Type,
47974796) !MCValue {
4798 const mod = self.bin_file.options.module.?;
4797 const mod = self.bin_file.comp.module.?;
47994798 if (operand_ty.isPtrLikeOptional(mod)) {
48004799 assert(operand_ty.abiSize(mod) == 4);
48014800
......@@ -4829,7 +4828,7 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void {
48294828}
48304829
48314830fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4832 const mod = self.bin_file.options.module.?;
4831 const mod = self.bin_file.comp.module.?;
48334832 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
48344833 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
48354834 const operand_ptr = try self.resolveInst(un_op);
......@@ -4856,7 +4855,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
48564855}
48574856
48584857fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4859 const mod = self.bin_file.options.module.?;
4858 const mod = self.bin_file.comp.module.?;
48604859 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
48614860 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
48624861 const operand_ptr = try self.resolveInst(un_op);
......@@ -4876,7 +4875,7 @@ fn isErr(
48764875 error_union_bind: ReadArg.Bind,
48774876 error_union_ty: Type,
48784877) !MCValue {
4879 const mod = self.bin_file.options.module.?;
4878 const mod = self.bin_file.comp.module.?;
48804879 const error_type = error_union_ty.errorUnionSet(mod);
48814880
48824881 if (error_type.errorSetIsEmpty(mod)) {
......@@ -4918,7 +4917,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
49184917}
49194918
49204919fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4921 const mod = self.bin_file.options.module.?;
4920 const mod = self.bin_file.comp.module.?;
49224921 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
49234922 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
49244923 const operand_ptr = try self.resolveInst(un_op);
......@@ -4945,7 +4944,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
49454944}
49464945
49474946fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4948 const mod = self.bin_file.options.module.?;
4947 const mod = self.bin_file.comp.module.?;
49494948 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
49504949 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
49514950 const operand_ptr = try self.resolveInst(un_op);
......@@ -5160,7 +5159,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
51605159}
51615160
51625161fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
5163 const mod = self.bin_file.options.module.?;
5162 const mod = self.bin_file.comp.module.?;
51645163 const block_data = self.blocks.getPtr(block).?;
51655164
51665165 if (self.typeOf(operand).hasRuntimeBits(mod)) {
......@@ -5331,7 +5330,7 @@ fn setRegOrMem(self: *Self, ty: Type, loc: MCValue, val: MCValue) !void {
53315330}
53325331
53335332fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5334 const mod = self.bin_file.options.module.?;
5333 const mod = self.bin_file.comp.module.?;
53355334 const abi_size: u32 = @intCast(ty.abiSize(mod));
53365335 switch (mcv) {
53375336 .dead => unreachable,
......@@ -5493,7 +5492,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
54935492}
54945493
54955494fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
5496 const mod = self.bin_file.options.module.?;
5495 const mod = self.bin_file.comp.module.?;
54975496 switch (mcv) {
54985497 .dead => unreachable,
54995498 .unreach, .none => return, // Nothing to do.
......@@ -5740,7 +5739,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
57405739}
57415740
57425741fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
5743 const mod = self.bin_file.options.module.?;
5742 const mod = self.bin_file.comp.module.?;
57445743 const abi_size: u32 = @intCast(ty.abiSize(mod));
57455744 switch (mcv) {
57465745 .dead => unreachable,
......@@ -5896,7 +5895,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
58965895}
58975896
58985897fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
5899 const mod = self.bin_file.options.module.?;
5898 const mod = self.bin_file.comp.module.?;
59005899 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59015900 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
59025901 const ptr_ty = self.typeOf(ty_op.operand);
......@@ -6015,7 +6014,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
60156014}
60166015
60176016fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
6018 const mod = self.bin_file.options.module.?;
6017 const mod = self.bin_file.comp.module.?;
60196018 const vector_ty = self.typeOfIndex(inst);
60206019 const len = vector_ty.vectorLen(mod);
60216020 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -6066,7 +6065,7 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
60666065 const result: MCValue = result: {
60676066 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
60686067 const error_union_ty = self.typeOf(pl_op.operand);
6069 const mod = self.bin_file.options.module.?;
6068 const mod = self.bin_file.comp.module.?;
60706069 const error_union_size: u32 = @intCast(error_union_ty.abiSize(mod));
60716070 const error_union_align = error_union_ty.abiAlignment(mod);
60726071
......@@ -6097,7 +6096,7 @@ fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void {
60976096}
60986097
60996098fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
6100 const mod = self.bin_file.options.module.?;
6099 const mod = self.bin_file.comp.module.?;
61016100
61026101 // If the type has no codegen bits, no need to store it.
61036102 const inst_ty = self.typeOf(inst);
......@@ -6125,7 +6124,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
61256124}
61266125
61276126fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
6128 const mod = self.bin_file.options.module.?;
6127 const mod = self.bin_file.comp.module.?;
61296128 const mcv: MCValue = switch (try codegen.genTypedValue(
61306129 self.bin_file,
61316130 self.src_loc,
......@@ -6161,7 +6160,7 @@ const CallMCValues = struct {
61616160
61626161/// Caller must call `CallMCValues.deinit`.
61636162fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
6164 const mod = self.bin_file.options.module.?;
6163 const mod = self.bin_file.comp.module.?;
61656164 const ip = &mod.intern_pool;
61666165 const fn_info = mod.typeToFunc(fn_ty).?;
61676166 const cc = fn_info.cc;
......@@ -6282,7 +6281,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
62826281
62836282/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.
62846283fn wantSafety(self: *Self) bool {
6285 return switch (self.bin_file.options.optimize_mode) {
6284 return switch (self.bin_file.comp.root_mod.optimize_mode) {
62866285 .Debug => true,
62876286 .ReleaseSafe => true,
62886287 .ReleaseFast => false,
......@@ -6293,14 +6292,16 @@ fn wantSafety(self: *Self) bool {
62936292fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
62946293 @setCold(true);
62956294 assert(self.err_msg == null);
6296 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
6295 const gpa = self.gpa;
6296 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
62976297 return error.CodegenFail;
62986298}
62996299
63006300fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
63016301 @setCold(true);
63026302 assert(self.err_msg == null);
6303 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
6303 const gpa = self.gpa;
6304 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
63046305 return error.CodegenFail;
63056306}
63066307
......@@ -6312,11 +6313,11 @@ fn parseRegName(name: []const u8) ?Register {
63126313}
63136314
63146315fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
6315 const mod = self.bin_file.options.module.?;
6316 const mod = self.bin_file.comp.module.?;
63166317 return self.air.typeOf(inst, &mod.intern_pool);
63176318}
63186319
63196320fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
6320 const mod = self.bin_file.options.module.?;
6321 const mod = self.bin_file.comp.module.?;
63216322 return self.air.typeOfIndex(inst, &mod.intern_pool);
63226323}
src/arch/arm/Emit.zig+18-12
......@@ -152,14 +152,17 @@ pub fn emitMir(
152152}
153153
154154pub fn deinit(emit: *Emit) void {
155 const comp = emit.bin_file.comp;
156 const gpa = comp.gpa;
157
155158 var iter = emit.branch_forward_origins.valueIterator();
156159 while (iter.next()) |origin_list| {
157 origin_list.deinit(emit.bin_file.allocator);
160 origin_list.deinit(gpa);
158161 }
159162
160 emit.branch_types.deinit(emit.bin_file.allocator);
161 emit.branch_forward_origins.deinit(emit.bin_file.allocator);
162 emit.code_offset_mapping.deinit(emit.bin_file.allocator);
163 emit.branch_types.deinit(gpa);
164 emit.branch_forward_origins.deinit(gpa);
165 emit.code_offset_mapping.deinit(gpa);
163166 emit.* = undefined;
164167}
165168
......@@ -231,8 +234,9 @@ fn branchTarget(emit: *Emit, inst: Mir.Inst.Index) Mir.Inst.Index {
231234}
232235
233236fn lowerBranches(emit: *Emit) !void {
237 const comp = emit.bin_file.comp;
238 const gpa = comp.gpa;
234239 const mir_tags = emit.mir.instructions.items(.tag);
235 const allocator = emit.bin_file.allocator;
236240
237241 // First pass: Note down all branches and their target
238242 // instructions, i.e. populate branch_types,
......@@ -246,7 +250,7 @@ fn lowerBranches(emit: *Emit) !void {
246250 const target_inst = emit.branchTarget(inst);
247251
248252 // Remember this branch instruction
249 try emit.branch_types.put(allocator, inst, BranchType.default(tag));
253 try emit.branch_types.put(gpa, inst, BranchType.default(tag));
250254
251255 // Forward branches require some extra stuff: We only
252256 // know their offset once we arrive at the target
......@@ -256,14 +260,14 @@ fn lowerBranches(emit: *Emit) !void {
256260 // etc.
257261 if (target_inst > inst) {
258262 // Remember the branch instruction index
259 try emit.code_offset_mapping.put(allocator, inst, 0);
263 try emit.code_offset_mapping.put(gpa, inst, 0);
260264
261265 if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| {
262 try origin_list.append(allocator, inst);
266 try origin_list.append(gpa, inst);
263267 } else {
264268 var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{};
265 try origin_list.append(allocator, inst);
266 try emit.branch_forward_origins.put(allocator, target_inst, origin_list);
269 try origin_list.append(gpa, inst);
270 try emit.branch_forward_origins.put(gpa, target_inst, origin_list);
267271 }
268272 }
269273
......@@ -273,7 +277,7 @@ fn lowerBranches(emit: *Emit) !void {
273277 // putNoClobber may not be used as the put operation
274278 // may clobber the entry when multiple branches branch
275279 // to the same target instruction
276 try emit.code_offset_mapping.put(allocator, target_inst, 0);
280 try emit.code_offset_mapping.put(gpa, target_inst, 0);
277281 }
278282 }
279283
......@@ -346,7 +350,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
346350fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
347351 @setCold(true);
348352 assert(emit.err_msg == null);
349 emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
353 const comp = emit.bin_file.comp;
354 const gpa = comp.gpa;
355 emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
350356 return error.EmitFail;
351357}
352358
src/arch/riscv64/CodeGen.zig+45-46
......@@ -217,7 +217,7 @@ const BigTomb = struct {
217217const Self = @This();
218218
219219pub fn generate(
220 bin_file: *link.File,
220 lf: *link.File,
221221 src_loc: Module.SrcLoc,
222222 func_index: InternPool.Index,
223223 air: Air,
......@@ -225,30 +225,29 @@ pub fn generate(
225225 code: *std.ArrayList(u8),
226226 debug_output: DebugInfoOutput,
227227) CodeGenError!Result {
228 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {
229 @panic("Attempted to compile for architecture that was disabled by build configuration");
230 }
231
232 const mod = bin_file.options.module.?;
233 const func = mod.funcInfo(func_index);
234 const fn_owner_decl = mod.declPtr(func.owner_decl);
228 const gpa = lf.comp.gpa;
229 const zcu = lf.comp.module.?;
230 const func = zcu.funcInfo(func_index);
231 const fn_owner_decl = zcu.declPtr(func.owner_decl);
235232 assert(fn_owner_decl.has_tv);
236233 const fn_type = fn_owner_decl.ty;
234 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
235 const target = &namespace.file_scope.mod.resolved_target.result;
237236
238 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
237 var branch_stack = std.ArrayList(Branch).init(gpa);
239238 defer {
240239 assert(branch_stack.items.len == 1);
241 branch_stack.items[0].deinit(bin_file.allocator);
240 branch_stack.items[0].deinit(gpa);
242241 branch_stack.deinit();
243242 }
244243 try branch_stack.append(.{});
245244
246245 var function = Self{
247 .gpa = bin_file.allocator,
246 .gpa = gpa,
248247 .air = air,
249248 .liveness = liveness,
250 .target = &bin_file.options.target,
251 .bin_file = bin_file,
249 .target = target,
250 .bin_file = lf,
252251 .func_index = func_index,
253252 .code = code,
254253 .debug_output = debug_output,
......@@ -263,14 +262,14 @@ pub fn generate(
263262 .end_di_line = func.rbrace_line,
264263 .end_di_column = func.rbrace_column,
265264 };
266 defer function.stack.deinit(bin_file.allocator);
267 defer function.blocks.deinit(bin_file.allocator);
268 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
265 defer function.stack.deinit(gpa);
266 defer function.blocks.deinit(gpa);
267 defer function.exitlude_jump_relocs.deinit(gpa);
269268
270269 var call_info = function.resolveCallingConventionValues(fn_type) catch |err| switch (err) {
271270 error.CodegenFail => return Result{ .fail = function.err_msg.? },
272271 error.OutOfRegisters => return Result{
273 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
272 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
274273 },
275274 else => |e| return e,
276275 };
......@@ -284,22 +283,22 @@ pub fn generate(
284283 function.gen() catch |err| switch (err) {
285284 error.CodegenFail => return Result{ .fail = function.err_msg.? },
286285 error.OutOfRegisters => return Result{
287 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
286 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
288287 },
289288 else => |e| return e,
290289 };
291290
292291 var mir = Mir{
293292 .instructions = function.mir_instructions.toOwnedSlice(),
294 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
293 .extra = try function.mir_extra.toOwnedSlice(gpa),
295294 };
296 defer mir.deinit(bin_file.allocator);
295 defer mir.deinit(gpa);
297296
298297 var emit = Emit{
299298 .mir = mir,
300 .bin_file = bin_file,
299 .bin_file = lf,
301300 .debug_output = debug_output,
302 .target = &bin_file.options.target,
301 .target = target,
303302 .src_loc = src_loc,
304303 .code = code,
305304 .prev_di_pc = 0,
......@@ -350,7 +349,7 @@ pub fn addExtraAssumeCapacity(self: *Self, extra: anytype) u32 {
350349}
351350
352351fn gen(self: *Self) !void {
353 const mod = self.bin_file.options.module.?;
352 const mod = self.bin_file.comp.module.?;
354353 const cc = self.fn_type.fnCallingConvention(mod);
355354 if (cc != .Naked) {
356355 // TODO Finish function prologue and epilogue for riscv64.
......@@ -474,7 +473,7 @@ fn gen(self: *Self) !void {
474473}
475474
476475fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
477 const mod = self.bin_file.options.module.?;
476 const mod = self.bin_file.comp.module.?;
478477 const ip = &mod.intern_pool;
479478 const air_tags = self.air.instructions.items(.tag);
480479
......@@ -805,7 +804,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme
805804
806805/// Use a pointer instruction as the basis for allocating stack memory.
807806fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
808 const mod = self.bin_file.options.module.?;
807 const mod = self.bin_file.comp.module.?;
809808 const elem_ty = self.typeOfIndex(inst).childType(mod);
810809 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
811810 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
......@@ -816,7 +815,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
816815}
817816
818817fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
819 const mod = self.bin_file.options.module.?;
818 const mod = self.bin_file.comp.module.?;
820819 const elem_ty = self.typeOfIndex(inst);
821820 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
822821 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
......@@ -893,7 +892,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
893892 if (self.liveness.isUnused(inst))
894893 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
895894
896 const mod = self.bin_file.options.module.?;
895 const mod = self.bin_file.comp.module.?;
897896 const operand_ty = self.typeOf(ty_op.operand);
898897 const operand = try self.resolveInst(ty_op.operand);
899898 const info_a = operand_ty.intInfo(mod);
......@@ -1069,7 +1068,7 @@ fn binOp(
10691068 lhs_ty: Type,
10701069 rhs_ty: Type,
10711070) InnerError!MCValue {
1072 const mod = self.bin_file.options.module.?;
1071 const mod = self.bin_file.comp.module.?;
10731072 switch (tag) {
10741073 // Arithmetic operations on integers and floats
10751074 .add,
......@@ -1332,7 +1331,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
13321331fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
13331332 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
13341333 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
1335 const mod = self.bin_file.options.module.?;
1334 const mod = self.bin_file.comp.module.?;
13361335 const optional_ty = self.typeOfIndex(inst);
13371336
13381337 // Optional with a zero-bit payload type is just a boolean true
......@@ -1506,7 +1505,7 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind
15061505}
15071506
15081507fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
1509 const mod = self.bin_file.options.module.?;
1508 const mod = self.bin_file.comp.module.?;
15101509 const elem_ty = ptr_ty.childType(mod);
15111510 switch (ptr) {
15121511 .none => unreachable,
......@@ -1532,7 +1531,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!vo
15321531}
15331532
15341533fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1535 const mod = self.bin_file.options.module.?;
1534 const mod = self.bin_file.comp.module.?;
15361535 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
15371536 const elem_ty = self.typeOfIndex(inst);
15381537 const result: MCValue = result: {
......@@ -1633,7 +1632,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
16331632}
16341633
16351634fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
1636 const mod = self.bin_file.options.module.?;
1635 const mod = self.bin_file.comp.module.?;
16371636 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
16381637 const ty = arg.ty.toType();
16391638 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
......@@ -1710,7 +1709,7 @@ fn airFence(self: *Self) !void {
17101709}
17111710
17121711fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
1713 const mod = self.bin_file.options.module.?;
1712 const mod = self.bin_file.comp.module.?;
17141713 if (modifier == .always_tail) return self.fail("TODO implement tail calls for riscv64", .{});
17151714 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
17161715 const fn_ty = self.typeOf(pl_op.operand);
......@@ -1812,7 +1811,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
18121811}
18131812
18141813fn ret(self: *Self, mcv: MCValue) !void {
1815 const mod = self.bin_file.options.module.?;
1814 const mod = self.bin_file.comp.module.?;
18161815 const ret_ty = self.fn_type.fnReturnType(mod);
18171816 try self.setRegOrMem(ret_ty, self.ret_mcv, mcv);
18181817 // Just add space for an instruction, patch this later
......@@ -1843,7 +1842,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
18431842 if (self.liveness.isUnused(inst))
18441843 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
18451844 const ty = self.typeOf(bin_op.lhs);
1846 const mod = self.bin_file.options.module.?;
1845 const mod = self.bin_file.comp.module.?;
18471846 assert(ty.eql(self.typeOf(bin_op.rhs), mod));
18481847 if (ty.zigTypeTag(mod) == .ErrorSet)
18491848 return self.fail("TODO implement cmp for errors", .{});
......@@ -1887,7 +1886,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
18871886
18881887fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
18891888 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
1890 const mod = self.bin_file.options.module.?;
1889 const mod = self.bin_file.comp.module.?;
18911890 const func = mod.funcInfo(ty_fn.func);
18921891 // TODO emit debug info for function change
18931892 _ = func;
......@@ -2125,7 +2124,7 @@ fn airBoolOp(self: *Self, inst: Air.Inst.Index) !void {
21252124fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
21262125 const block_data = self.blocks.getPtr(block).?;
21272126
2128 const mod = self.bin_file.options.module.?;
2127 const mod = self.bin_file.comp.module.?;
21292128 if (self.typeOf(operand).hasRuntimeBits(mod)) {
21302129 const operand_mcv = try self.resolveInst(operand);
21312130 const block_mcv = block_data.mcv;
......@@ -2508,7 +2507,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
25082507}
25092508
25102509fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
2511 const mod = self.bin_file.options.module.?;
2510 const mod = self.bin_file.comp.module.?;
25122511 const vector_ty = self.typeOfIndex(inst);
25132512 const len = vector_ty.vectorLen(mod);
25142513 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -2553,7 +2552,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
25532552}
25542553
25552554fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
2556 const mod = self.bin_file.options.module.?;
2555 const mod = self.bin_file.comp.module.?;
25572556
25582557 // If the type has no codegen bits, no need to store it.
25592558 const inst_ty = self.typeOf(inst);
......@@ -2581,7 +2580,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
25812580}
25822581
25832582fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2584 const mod = self.bin_file.options.module.?;
2583 const mod = self.bin_file.comp.module.?;
25852584 const mcv: MCValue = switch (try codegen.genTypedValue(
25862585 self.bin_file,
25872586 self.src_loc,
......@@ -2617,7 +2616,7 @@ const CallMCValues = struct {
26172616
26182617/// Caller must call `CallMCValues.deinit`.
26192618fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
2620 const mod = self.bin_file.options.module.?;
2619 const mod = self.bin_file.comp.module.?;
26212620 const ip = &mod.intern_pool;
26222621 const fn_info = mod.typeToFunc(fn_ty).?;
26232622 const cc = fn_info.cc;
......@@ -2709,7 +2708,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
27092708
27102709/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.
27112710fn wantSafety(self: *Self) bool {
2712 return switch (self.bin_file.options.optimize_mode) {
2711 return switch (self.bin_file.comp.root_mod.optimize_mode) {
27132712 .Debug => true,
27142713 .ReleaseSafe => true,
27152714 .ReleaseFast => false,
......@@ -2720,14 +2719,14 @@ fn wantSafety(self: *Self) bool {
27202719fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
27212720 @setCold(true);
27222721 assert(self.err_msg == null);
2723 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
2722 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
27242723 return error.CodegenFail;
27252724}
27262725
27272726fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
27282727 @setCold(true);
27292728 assert(self.err_msg == null);
2730 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
2729 self.err_msg = try ErrorMsg.create(self.gpa, self.src_loc, format, args);
27312730 return error.CodegenFail;
27322731}
27332732
......@@ -2739,11 +2738,11 @@ fn parseRegName(name: []const u8) ?Register {
27392738}
27402739
27412740fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
2742 const mod = self.bin_file.options.module.?;
2741 const mod = self.bin_file.comp.module.?;
27432742 return self.air.typeOf(inst, &mod.intern_pool);
27442743}
27452744
27462745fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
2747 const mod = self.bin_file.options.module.?;
2746 const mod = self.bin_file.comp.module.?;
27482747 return self.air.typeOfIndex(inst, &mod.intern_pool);
27492748}
src/arch/riscv64/Emit.zig+3-1
......@@ -80,7 +80,9 @@ fn writeInstruction(emit: *Emit, instruction: Instruction) !void {
8080fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
8181 @setCold(true);
8282 assert(emit.err_msg == null);
83 emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
83 const comp = emit.bin_file.comp;
84 const gpa = comp.gpa;
85 emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
8486 return error.EmitFail;
8587}
8688
src/arch/sparc64/CodeGen.zig+66-66
......@@ -260,7 +260,7 @@ const BigTomb = struct {
260260};
261261
262262pub fn generate(
263 bin_file: *link.File,
263 lf: *link.File,
264264 src_loc: Module.SrcLoc,
265265 func_index: InternPool.Index,
266266 air: Air,
......@@ -268,31 +268,30 @@ pub fn generate(
268268 code: *std.ArrayList(u8),
269269 debug_output: DebugInfoOutput,
270270) CodeGenError!Result {
271 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {
272 @panic("Attempted to compile for architecture that was disabled by build configuration");
273 }
274
275 const mod = bin_file.options.module.?;
276 const func = mod.funcInfo(func_index);
277 const fn_owner_decl = mod.declPtr(func.owner_decl);
271 const gpa = lf.comp.gpa;
272 const zcu = lf.comp.module.?;
273 const func = zcu.funcInfo(func_index);
274 const fn_owner_decl = zcu.declPtr(func.owner_decl);
278275 assert(fn_owner_decl.has_tv);
279276 const fn_type = fn_owner_decl.ty;
277 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
278 const target = &namespace.file_scope.mod.resolved_target.result;
280279
281 var branch_stack = std.ArrayList(Branch).init(bin_file.allocator);
280 var branch_stack = std.ArrayList(Branch).init(gpa);
282281 defer {
283282 assert(branch_stack.items.len == 1);
284 branch_stack.items[0].deinit(bin_file.allocator);
283 branch_stack.items[0].deinit(gpa);
285284 branch_stack.deinit();
286285 }
287286 try branch_stack.append(.{});
288287
289288 var function = Self{
290 .gpa = bin_file.allocator,
289 .gpa = gpa,
291290 .air = air,
292291 .liveness = liveness,
293 .target = &bin_file.options.target,
292 .target = target,
294293 .func_index = func_index,
295 .bin_file = bin_file,
294 .bin_file = lf,
296295 .code = code,
297296 .debug_output = debug_output,
298297 .err_msg = null,
......@@ -306,14 +305,14 @@ pub fn generate(
306305 .end_di_line = func.rbrace_line,
307306 .end_di_column = func.rbrace_column,
308307 };
309 defer function.stack.deinit(bin_file.allocator);
310 defer function.blocks.deinit(bin_file.allocator);
311 defer function.exitlude_jump_relocs.deinit(bin_file.allocator);
308 defer function.stack.deinit(gpa);
309 defer function.blocks.deinit(gpa);
310 defer function.exitlude_jump_relocs.deinit(gpa);
312311
313312 var call_info = function.resolveCallingConventionValues(fn_type, .callee) catch |err| switch (err) {
314313 error.CodegenFail => return Result{ .fail = function.err_msg.? },
315314 error.OutOfRegisters => return Result{
316 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
315 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
317316 },
318317 else => |e| return e,
319318 };
......@@ -327,22 +326,22 @@ pub fn generate(
327326 function.gen() catch |err| switch (err) {
328327 error.CodegenFail => return Result{ .fail = function.err_msg.? },
329328 error.OutOfRegisters => return Result{
330 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
329 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
331330 },
332331 else => |e| return e,
333332 };
334333
335334 var mir = Mir{
336335 .instructions = function.mir_instructions.toOwnedSlice(),
337 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
336 .extra = try function.mir_extra.toOwnedSlice(gpa),
338337 };
339 defer mir.deinit(bin_file.allocator);
338 defer mir.deinit(gpa);
340339
341340 var emit = Emit{
342341 .mir = mir,
343 .bin_file = bin_file,
342 .bin_file = lf,
344343 .debug_output = debug_output,
345 .target = &bin_file.options.target,
344 .target = target,
346345 .src_loc = src_loc,
347346 .code = code,
348347 .prev_di_pc = 0,
......@@ -364,7 +363,7 @@ pub fn generate(
364363}
365364
366365fn gen(self: *Self) !void {
367 const mod = self.bin_file.options.module.?;
366 const mod = self.bin_file.comp.module.?;
368367 const cc = self.fn_type.fnCallingConvention(mod);
369368 if (cc != .Naked) {
370369 // TODO Finish function prologue and epilogue for sparc64.
......@@ -492,7 +491,7 @@ fn gen(self: *Self) !void {
492491}
493492
494493fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
495 const mod = self.bin_file.options.module.?;
494 const mod = self.bin_file.comp.module.?;
496495 const ip = &mod.intern_pool;
497496 const air_tags = self.air.instructions.items(.tag);
498497
......@@ -762,7 +761,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
762761 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
763762 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
764763 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
765 const mod = self.bin_file.options.module.?;
764 const mod = self.bin_file.comp.module.?;
766765 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
767766 const lhs = try self.resolveInst(extra.lhs);
768767 const rhs = try self.resolveInst(extra.rhs);
......@@ -840,7 +839,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
840839}
841840
842841fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
843 const mod = self.bin_file.options.module.?;
842 const mod = self.bin_file.comp.module.?;
844843 const vector_ty = self.typeOfIndex(inst);
845844 const len = vector_ty.vectorLen(mod);
846845 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -874,7 +873,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
874873}
875874
876875fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
877 const mod = self.bin_file.options.module.?;
876 const mod = self.bin_file.comp.module.?;
878877 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
879878 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
880879 const ptr_ty = self.typeOf(ty_op.operand);
......@@ -1011,7 +1010,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
10111010}
10121011
10131012fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1014 const mod = self.bin_file.options.module.?;
1013 const mod = self.bin_file.comp.module.?;
10151014 const arg_index = self.arg_index;
10161015 self.arg_index += 1;
10171016
......@@ -1206,7 +1205,7 @@ fn airBreakpoint(self: *Self) !void {
12061205}
12071206
12081207fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
1209 const mod = self.bin_file.options.module.?;
1208 const mod = self.bin_file.comp.module.?;
12101209 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
12111210
12121211 // We have hardware byteswapper in SPARCv9, don't let mainstream compilers mislead you.
......@@ -1298,7 +1297,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
12981297 const extra = self.air.extraData(Air.Call, pl_op.payload);
12991298 const args = @as([]const Air.Inst.Ref, @ptrCast(self.air.extra[extra.end .. extra.end + extra.data.args_len]));
13001299 const ty = self.typeOf(callee);
1301 const mod = self.bin_file.options.module.?;
1300 const mod = self.bin_file.comp.module.?;
13021301 const fn_ty = switch (ty.zigTypeTag(mod)) {
13031302 .Fn => ty,
13041303 .Pointer => ty.childType(mod),
......@@ -1430,7 +1429,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
14301429
14311430fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
14321431 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1433 const mod = self.bin_file.options.module.?;
1432 const mod = self.bin_file.comp.module.?;
14341433 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
14351434 const lhs = try self.resolveInst(bin_op.lhs);
14361435 const rhs = try self.resolveInst(bin_op.rhs);
......@@ -1662,7 +1661,7 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
16621661
16631662fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
16641663 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
1665 const mod = self.bin_file.options.module.?;
1664 const mod = self.bin_file.comp.module.?;
16661665 const func = mod.funcInfo(ty_fn.func);
16671666 // TODO emit debug info for function change
16681667 _ = func;
......@@ -1758,7 +1757,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
17581757 if (self.liveness.isUnused(inst))
17591758 return self.finishAir(inst, .dead, .{ ty_op.operand, .none, .none });
17601759
1761 const mod = self.bin_file.options.module.?;
1760 const mod = self.bin_file.comp.module.?;
17621761 const operand_ty = self.typeOf(ty_op.operand);
17631762 const operand = try self.resolveInst(ty_op.operand);
17641763 const info_a = operand_ty.intInfo(mod);
......@@ -1819,7 +1818,7 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void {
18191818}
18201819
18211820fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
1822 const mod = self.bin_file.options.module.?;
1821 const mod = self.bin_file.comp.module.?;
18231822 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
18241823 const elem_ty = self.typeOfIndex(inst);
18251824 const elem_size = elem_ty.abiSize(mod);
......@@ -1903,7 +1902,7 @@ fn airMod(self: *Self, inst: Air.Inst.Index) !void {
19031902 const rhs = try self.resolveInst(bin_op.rhs);
19041903 const lhs_ty = self.typeOf(bin_op.lhs);
19051904 const rhs_ty = self.typeOf(bin_op.rhs);
1906 assert(lhs_ty.eql(rhs_ty, self.bin_file.options.module.?));
1905 assert(lhs_ty.eql(rhs_ty, self.bin_file.comp.module.?));
19071906
19081907 if (self.liveness.isUnused(inst))
19091908 return self.finishAir(inst, .dead, .{ bin_op.lhs, bin_op.rhs, .none });
......@@ -2045,7 +2044,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
20452044 //const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
20462045 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
20472046 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2048 const mod = self.bin_file.options.module.?;
2047 const mod = self.bin_file.comp.module.?;
20492048 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
20502049 const lhs = try self.resolveInst(extra.lhs);
20512050 const rhs = try self.resolveInst(extra.rhs);
......@@ -2109,7 +2108,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
21092108
21102109fn airNot(self: *Self, inst: Air.Inst.Index) !void {
21112110 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
2112 const mod = self.bin_file.options.module.?;
2111 const mod = self.bin_file.comp.module.?;
21132112 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
21142113 const operand = try self.resolveInst(ty_op.operand);
21152114 const operand_ty = self.typeOf(ty_op.operand);
......@@ -2341,7 +2340,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
23412340fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
23422341 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
23432342 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
2344 const mod = self.bin_file.options.module.?;
2343 const mod = self.bin_file.comp.module.?;
23452344 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
23462345 const lhs = try self.resolveInst(extra.lhs);
23472346 const rhs = try self.resolveInst(extra.rhs);
......@@ -2446,7 +2445,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
24462445}
24472446
24482447fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
2449 const mod = self.bin_file.options.module.?;
2448 const mod = self.bin_file.comp.module.?;
24502449 const is_volatile = false; // TODO
24512450 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
24522451
......@@ -2571,7 +2570,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
25712570 const operand = extra.struct_operand;
25722571 const index = extra.field_index;
25732572 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
2574 const mod = self.bin_file.options.module.?;
2573 const mod = self.bin_file.comp.module.?;
25752574 const mcv = try self.resolveInst(operand);
25762575 const struct_ty = self.typeOf(operand);
25772576 const struct_field_offset = @as(u32, @intCast(struct_ty.structFieldOffset(index, mod)));
......@@ -2704,7 +2703,7 @@ fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
27042703}
27052704
27062705fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
2707 const mod = self.bin_file.options.module.?;
2706 const mod = self.bin_file.comp.module.?;
27082707 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
27092708 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27102709 const error_union_ty = self.typeOf(ty_op.operand);
......@@ -2718,7 +2717,7 @@ fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
27182717}
27192718
27202719fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
2721 const mod = self.bin_file.options.module.?;
2720 const mod = self.bin_file.comp.module.?;
27222721 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
27232722 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27242723 const error_union_ty = self.typeOf(ty_op.operand);
......@@ -2732,7 +2731,7 @@ fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
27322731
27332732/// E to E!T
27342733fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
2735 const mod = self.bin_file.options.module.?;
2734 const mod = self.bin_file.comp.module.?;
27362735 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
27372736 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27382737 const error_union_ty = ty_op.ty.toType();
......@@ -2753,7 +2752,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
27532752}
27542753
27552754fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
2756 const mod = self.bin_file.options.module.?;
2755 const mod = self.bin_file.comp.module.?;
27572756 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
27582757 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
27592758 const optional_ty = self.typeOfIndex(inst);
......@@ -2793,7 +2792,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: Alignme
27932792
27942793/// Use a pointer instruction as the basis for allocating stack memory.
27952794fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
2796 const mod = self.bin_file.options.module.?;
2795 const mod = self.bin_file.comp.module.?;
27972796 const elem_ty = self.typeOfIndex(inst).childType(mod);
27982797
27992798 if (!elem_ty.hasRuntimeBits(mod)) {
......@@ -2813,7 +2812,7 @@ fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 {
28132812}
28142813
28152814fn allocRegOrMem(self: *Self, inst: Air.Inst.Index, reg_ok: bool) !MCValue {
2816 const mod = self.bin_file.options.module.?;
2815 const mod = self.bin_file.comp.module.?;
28172816 const elem_ty = self.typeOfIndex(inst);
28182817 const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse {
28192818 return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)});
......@@ -2860,7 +2859,7 @@ fn binOp(
28602859 rhs_ty: Type,
28612860 metadata: ?BinOpMetadata,
28622861) InnerError!MCValue {
2863 const mod = self.bin_file.options.module.?;
2862 const mod = self.bin_file.comp.module.?;
28642863 switch (tag) {
28652864 .add,
28662865 .sub,
......@@ -3401,7 +3400,7 @@ fn binOpRegister(
34013400fn br(self: *Self, block: Air.Inst.Index, operand: Air.Inst.Ref) !void {
34023401 const block_data = self.blocks.getPtr(block).?;
34033402
3404 const mod = self.bin_file.options.module.?;
3403 const mod = self.bin_file.comp.module.?;
34053404 if (self.typeOf(operand).hasRuntimeBits(mod)) {
34063405 const operand_mcv = try self.resolveInst(operand);
34073406 const block_mcv = block_data.mcv;
......@@ -3521,7 +3520,7 @@ fn ensureProcessDeathCapacity(self: *Self, additional_count: usize) !void {
35213520
35223521/// Given an error union, returns the payload
35233522fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {
3524 const mod = self.bin_file.options.module.?;
3523 const mod = self.bin_file.comp.module.?;
35253524 const err_ty = error_union_ty.errorUnionSet(mod);
35263525 const payload_ty = error_union_ty.errorUnionPayload(mod);
35273526 if (err_ty.errorSetIsEmpty(mod)) {
......@@ -3547,7 +3546,8 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
35473546fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
35483547 @setCold(true);
35493548 assert(self.err_msg == null);
3550 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
3549 const gpa = self.gpa;
3550 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
35513551 return error.CodegenFail;
35523552}
35533553
......@@ -3591,7 +3591,7 @@ fn finishAir(self: *Self, inst: Air.Inst.Index, result: MCValue, operands: [Live
35913591}
35923592
35933593fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3594 const mod = self.bin_file.options.module.?;
3594 const mod = self.bin_file.comp.module.?;
35953595 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
35963596 const ty = arg.ty.toType();
35973597 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
......@@ -3740,7 +3740,7 @@ fn genLoadASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Reg
37403740}
37413741
37423742fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void {
3743 const mod = self.bin_file.options.module.?;
3743 const mod = self.bin_file.comp.module.?;
37443744 switch (mcv) {
37453745 .dead => unreachable,
37463746 .unreach, .none => return, // Nothing to do.
......@@ -3951,7 +3951,7 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
39513951}
39523952
39533953fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerError!void {
3954 const mod = self.bin_file.options.module.?;
3954 const mod = self.bin_file.comp.module.?;
39553955 const abi_size = ty.abiSize(mod);
39563956 switch (mcv) {
39573957 .dead => unreachable,
......@@ -4125,7 +4125,7 @@ fn genStoreASI(self: *Self, value_reg: Register, addr_reg: Register, off_reg: Re
41254125}
41264126
41274127fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
4128 const mod = self.bin_file.options.module.?;
4128 const mod = self.bin_file.comp.module.?;
41294129 const mcv: MCValue = switch (try codegen.genTypedValue(
41304130 self.bin_file,
41314131 self.src_loc,
......@@ -4161,7 +4161,7 @@ fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) MCValue {
41614161}
41624162
41634163fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
4164 const mod = self.bin_file.options.module.?;
4164 const mod = self.bin_file.comp.module.?;
41654165 const error_type = ty.errorUnionSet(mod);
41664166 const payload_type = ty.errorUnionPayload(mod);
41674167
......@@ -4259,7 +4259,7 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void {
42594259}
42604260
42614261fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void {
4262 const mod = self.bin_file.options.module.?;
4262 const mod = self.bin_file.comp.module.?;
42634263 const elem_ty = ptr_ty.childType(mod);
42644264 const elem_size = elem_ty.abiSize(mod);
42654265
......@@ -4330,7 +4330,7 @@ fn minMax(
43304330 lhs_ty: Type,
43314331 rhs_ty: Type,
43324332) InnerError!MCValue {
4333 const mod = self.bin_file.options.module.?;
4333 const mod = self.bin_file.comp.module.?;
43344334 assert(lhs_ty.eql(rhs_ty, mod));
43354335 switch (lhs_ty.zigTypeTag(mod)) {
43364336 .Float => return self.fail("TODO min/max on floats", .{}),
......@@ -4450,7 +4450,7 @@ fn realStackOffset(off: u32) u32 {
44504450
44514451/// Caller must call `CallMCValues.deinit`.
44524452fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView) !CallMCValues {
4453 const mod = self.bin_file.options.module.?;
4453 const mod = self.bin_file.comp.module.?;
44544454 const ip = &mod.intern_pool;
44554455 const fn_info = mod.typeToFunc(fn_ty).?;
44564456 const cc = fn_info.cc;
......@@ -4542,7 +4542,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type, role: RegisterView)
45424542}
45434543
45444544fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
4545 const mod = self.bin_file.options.module.?;
4545 const mod = self.bin_file.comp.module.?;
45464546 const ty = self.typeOf(ref);
45474547
45484548 // If the type has no codegen bits, no need to store it.
......@@ -4559,7 +4559,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
45594559}
45604560
45614561fn ret(self: *Self, mcv: MCValue) !void {
4562 const mod = self.bin_file.options.module.?;
4562 const mod = self.bin_file.comp.module.?;
45634563 const ret_ty = self.fn_type.fnReturnType(mod);
45644564 try self.setRegOrMem(ret_ty, self.ret_mcv, mcv);
45654565
......@@ -4661,7 +4661,7 @@ pub fn spillInstruction(self: *Self, reg: Register, inst: Air.Inst.Index) !void
46614661}
46624662
46634663fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type) InnerError!void {
4664 const mod = self.bin_file.options.module.?;
4664 const mod = self.bin_file.comp.module.?;
46654665 const abi_size = value_ty.abiSize(mod);
46664666
46674667 switch (ptr) {
......@@ -4703,7 +4703,7 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
47034703
47044704fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
47054705 return if (self.liveness.isUnused(inst)) .dead else result: {
4706 const mod = self.bin_file.options.module.?;
4706 const mod = self.bin_file.comp.module.?;
47074707 const mcv = try self.resolveInst(operand);
47084708 const ptr_ty = self.typeOf(operand);
47094709 const struct_ty = ptr_ty.childType(mod);
......@@ -4745,7 +4745,7 @@ fn trunc(
47454745 operand_ty: Type,
47464746 dest_ty: Type,
47474747) !MCValue {
4748 const mod = self.bin_file.options.module.?;
4748 const mod = self.bin_file.comp.module.?;
47494749 const info_a = operand_ty.intInfo(mod);
47504750 const info_b = dest_ty.intInfo(mod);
47514751
......@@ -4857,7 +4857,7 @@ fn truncRegister(
48574857
48584858/// TODO support scope overrides. Also note this logic is duplicated with `Module.wantSafety`.
48594859fn wantSafety(self: *Self) bool {
4860 return switch (self.bin_file.options.optimize_mode) {
4860 return switch (self.bin_file.comp.root_mod.optimize_mode) {
48614861 .Debug => true,
48624862 .ReleaseSafe => true,
48634863 .ReleaseFast => false,
......@@ -4866,11 +4866,11 @@ fn wantSafety(self: *Self) bool {
48664866}
48674867
48684868fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
4869 const mod = self.bin_file.options.module.?;
4869 const mod = self.bin_file.comp.module.?;
48704870 return self.air.typeOf(inst, &mod.intern_pool);
48714871}
48724872
48734873fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
4874 const mod = self.bin_file.options.module.?;
4874 const mod = self.bin_file.comp.module.?;
48754875 return self.air.typeOfIndex(inst, &mod.intern_pool);
48764876}
src/arch/sparc64/Emit.zig+17-12
......@@ -152,14 +152,16 @@ pub fn emitMir(
152152}
153153
154154pub fn deinit(emit: *Emit) void {
155 const comp = emit.bin_file.comp;
156 const gpa = comp.gpa;
155157 var iter = emit.branch_forward_origins.valueIterator();
156158 while (iter.next()) |origin_list| {
157 origin_list.deinit(emit.bin_file.allocator);
159 origin_list.deinit(gpa);
158160 }
159161
160 emit.branch_types.deinit(emit.bin_file.allocator);
161 emit.branch_forward_origins.deinit(emit.bin_file.allocator);
162 emit.code_offset_mapping.deinit(emit.bin_file.allocator);
162 emit.branch_types.deinit(gpa);
163 emit.branch_forward_origins.deinit(gpa);
164 emit.code_offset_mapping.deinit(gpa);
163165 emit.* = undefined;
164166}
165167
......@@ -511,7 +513,9 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
511513fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
512514 @setCold(true);
513515 assert(emit.err_msg == null);
514 emit.err_msg = try ErrorMsg.create(emit.bin_file.allocator, emit.src_loc, format, args);
516 const comp = emit.bin_file.comp;
517 const gpa = comp.gpa;
518 emit.err_msg = try ErrorMsg.create(gpa, emit.src_loc, format, args);
515519 return error.EmitFail;
516520}
517521
......@@ -537,8 +541,9 @@ fn isBranch(tag: Mir.Inst.Tag) bool {
537541}
538542
539543fn lowerBranches(emit: *Emit) !void {
544 const comp = emit.bin_file.comp;
545 const gpa = comp.gpa;
540546 const mir_tags = emit.mir.instructions.items(.tag);
541 const allocator = emit.bin_file.allocator;
542547
543548 // First pass: Note down all branches and their target
544549 // instructions, i.e. populate branch_types,
......@@ -552,7 +557,7 @@ fn lowerBranches(emit: *Emit) !void {
552557 const target_inst = emit.branchTarget(inst);
553558
554559 // Remember this branch instruction
555 try emit.branch_types.put(allocator, inst, BranchType.default(tag));
560 try emit.branch_types.put(gpa, inst, BranchType.default(tag));
556561
557562 // Forward branches require some extra stuff: We only
558563 // know their offset once we arrive at the target
......@@ -562,14 +567,14 @@ fn lowerBranches(emit: *Emit) !void {
562567 // etc.
563568 if (target_inst > inst) {
564569 // Remember the branch instruction index
565 try emit.code_offset_mapping.put(allocator, inst, 0);
570 try emit.code_offset_mapping.put(gpa, inst, 0);
566571
567572 if (emit.branch_forward_origins.getPtr(target_inst)) |origin_list| {
568 try origin_list.append(allocator, inst);
573 try origin_list.append(gpa, inst);
569574 } else {
570575 var origin_list: std.ArrayListUnmanaged(Mir.Inst.Index) = .{};
571 try origin_list.append(allocator, inst);
572 try emit.branch_forward_origins.put(allocator, target_inst, origin_list);
576 try origin_list.append(gpa, inst);
577 try emit.branch_forward_origins.put(gpa, target_inst, origin_list);
573578 }
574579 }
575580
......@@ -579,7 +584,7 @@ fn lowerBranches(emit: *Emit) !void {
579584 // putNoClobber may not be used as the put operation
580585 // may clobber the entry when multiple branches branch
581586 // to the same target instruction
582 try emit.code_offset_mapping.put(allocator, target_inst, 0);
587 try emit.code_offset_mapping.put(gpa, target_inst, 0);
583588 }
584589 }
585590
src/arch/wasm/CodeGen.zig+131-123
......@@ -766,7 +766,7 @@ pub fn deinit(func: *CodeGen) void {
766766
767767/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
768768fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
769 const mod = func.bin_file.base.options.module.?;
769 const mod = func.bin_file.base.comp.module.?;
770770 const src = LazySrcLoc.nodeOffset(0);
771771 const src_loc = src.toSrcLoc(func.decl, mod);
772772 func.err_msg = try Module.ErrorMsg.create(func.gpa, src_loc, fmt, args);
......@@ -791,7 +791,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue {
791791 const gop = try func.branches.items[0].values.getOrPut(func.gpa, ref);
792792 assert(!gop.found_existing);
793793
794 const mod = func.bin_file.base.options.module.?;
794 const mod = func.bin_file.base.comp.module.?;
795795 const val = (try func.air.value(ref, mod)).?;
796796 const ty = func.typeOf(ref);
797797 if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) {
......@@ -1101,7 +1101,7 @@ fn getResolvedInst(func: *CodeGen, ref: Air.Inst.Ref) *WValue {
11011101/// Creates one locals for a given `Type`.
11021102/// Returns a corresponding `Wvalue` with `local` as active tag
11031103fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1104 const mod = func.bin_file.base.options.module.?;
1104 const mod = func.bin_file.base.comp.module.?;
11051105 const valtype = typeToValtype(ty, mod);
11061106 switch (valtype) {
11071107 .i32 => if (func.free_locals_i32.popOrNull()) |index| {
......@@ -1133,7 +1133,7 @@ fn allocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
11331133/// Ensures a new local will be created. This is useful when it's useful
11341134/// to use a zero-initialized local.
11351135fn ensureAllocLocal(func: *CodeGen, ty: Type) InnerError!WValue {
1136 const mod = func.bin_file.base.options.module.?;
1136 const mod = func.bin_file.base.comp.module.?;
11371137 try func.locals.append(func.gpa, genValtype(ty, mod));
11381138 const initial_index = func.local_index;
11391139 func.local_index += 1;
......@@ -1210,18 +1210,23 @@ pub fn generate(
12101210 debug_output: codegen.DebugInfoOutput,
12111211) codegen.CodeGenError!codegen.Result {
12121212 _ = src_loc;
1213 const mod = bin_file.options.module.?;
1213 const comp = bin_file.comp;
1214 const gpa = comp.gpa;
1215 const mod = comp.module.?;
12141216 const func = mod.funcInfo(func_index);
1217 const decl = mod.declPtr(func.owner_decl);
1218 const namespace = mod.namespacePtr(decl.src_namespace);
1219 const target = namespace.file_scope.mod.resolved_target.result;
12151220 var code_gen: CodeGen = .{
1216 .gpa = bin_file.allocator,
1221 .gpa = gpa,
12171222 .air = air,
12181223 .liveness = liveness,
12191224 .code = code,
12201225 .decl_index = func.owner_decl,
1221 .decl = mod.declPtr(func.owner_decl),
1226 .decl = decl,
12221227 .err_msg = undefined,
12231228 .locals = .{},
1224 .target = bin_file.options.target,
1229 .target = target,
12251230 .bin_file = bin_file.cast(link.File.Wasm).?,
12261231 .debug_output = debug_output,
12271232 .func_index = func_index,
......@@ -1237,7 +1242,7 @@ pub fn generate(
12371242}
12381243
12391244fn genFunc(func: *CodeGen) InnerError!void {
1240 const mod = func.bin_file.base.options.module.?;
1245 const mod = func.bin_file.base.comp.module.?;
12411246 const ip = &mod.intern_pool;
12421247 const fn_info = mod.typeToFunc(func.decl.ty).?;
12431248 var func_type = try genFunctype(func.gpa, fn_info.cc, fn_info.param_types.get(ip), Type.fromInterned(fn_info.return_type), mod);
......@@ -1348,7 +1353,7 @@ const CallWValues = struct {
13481353};
13491354
13501355fn resolveCallingConventionValues(func: *CodeGen, fn_ty: Type) InnerError!CallWValues {
1351 const mod = func.bin_file.base.options.module.?;
1356 const mod = func.bin_file.base.comp.module.?;
13521357 const ip = &mod.intern_pool;
13531358 const fn_info = mod.typeToFunc(fn_ty).?;
13541359 const cc = fn_info.cc;
......@@ -1417,7 +1422,7 @@ fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value:
14171422 return func.lowerToStack(value);
14181423 }
14191424
1420 const mod = func.bin_file.base.options.module.?;
1425 const mod = func.bin_file.base.comp.module.?;
14211426 const ty_classes = abi.classifyType(ty, mod);
14221427 assert(ty_classes[0] != .none);
14231428 switch (ty.zigTypeTag(mod)) {
......@@ -1516,7 +1521,7 @@ fn restoreStackPointer(func: *CodeGen) !void {
15161521///
15171522/// Asserts Type has codegenbits
15181523fn allocStack(func: *CodeGen, ty: Type) !WValue {
1519 const mod = func.bin_file.base.options.module.?;
1524 const mod = func.bin_file.base.comp.module.?;
15201525 assert(ty.hasRuntimeBitsIgnoreComptime(mod));
15211526 if (func.initial_stack_value == .none) {
15221527 try func.initializeStack();
......@@ -1542,7 +1547,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue {
15421547/// This is different from allocStack where this will use the pointer's alignment
15431548/// if it is set, to ensure the stack alignment will be set correctly.
15441549fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue {
1545 const mod = func.bin_file.base.options.module.?;
1550 const mod = func.bin_file.base.comp.module.?;
15461551 const ptr_ty = func.typeOfIndex(inst);
15471552 const pointee_ty = ptr_ty.childType(mod);
15481553
......@@ -2072,7 +2077,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
20722077}
20732078
20742079fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
2075 const mod = func.bin_file.base.options.module.?;
2080 const mod = func.bin_file.base.comp.module.?;
20762081 const ip = &mod.intern_pool;
20772082
20782083 for (body) |inst| {
......@@ -2093,7 +2098,7 @@ fn genBody(func: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
20932098}
20942099
20952100fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2096 const mod = func.bin_file.base.options.module.?;
2101 const mod = func.bin_file.base.comp.module.?;
20972102 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
20982103 const operand = try func.resolveInst(un_op);
20992104 const fn_info = mod.typeToFunc(func.decl.ty).?;
......@@ -2136,7 +2141,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21362141}
21372142
21382143fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2139 const mod = func.bin_file.base.options.module.?;
2144 const mod = func.bin_file.base.comp.module.?;
21402145 const child_type = func.typeOfIndex(inst).childType(mod);
21412146
21422147 const result = result: {
......@@ -2156,7 +2161,7 @@ fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
21562161}
21572162
21582163fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2159 const mod = func.bin_file.base.options.module.?;
2164 const mod = func.bin_file.base.comp.module.?;
21602165 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
21612166 const operand = try func.resolveInst(un_op);
21622167 const ret_ty = func.typeOf(un_op).childType(mod);
......@@ -2183,7 +2188,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif
21832188 const args = @as([]const Air.Inst.Ref, @ptrCast(func.air.extra[extra.end..][0..extra.data.args_len]));
21842189 const ty = func.typeOf(pl_op.operand);
21852190
2186 const mod = func.bin_file.base.options.module.?;
2191 const mod = func.bin_file.base.comp.module.?;
21872192 const ip = &mod.intern_pool;
21882193 const fn_ty = switch (ty.zigTypeTag(mod)) {
21892194 .Fn => ty,
......@@ -2295,7 +2300,7 @@ fn airAlloc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
22952300}
22962301
22972302fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
2298 const mod = func.bin_file.base.options.module.?;
2303 const mod = func.bin_file.base.comp.module.?;
22992304 if (safety) {
23002305 // TODO if the value is undef, write 0xaa bytes to dest
23012306 } else {
......@@ -2349,7 +2354,7 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
23492354
23502355fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerError!void {
23512356 assert(!(lhs != .stack and rhs == .stack));
2352 const mod = func.bin_file.base.options.module.?;
2357 const mod = func.bin_file.base.comp.module.?;
23532358 const abi_size = ty.abiSize(mod);
23542359 switch (ty.zigTypeTag(mod)) {
23552360 .ErrorUnion => {
......@@ -2428,7 +2433,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24282433 },
24292434 else => if (abi_size > 8) {
24302435 return func.fail("TODO: `store` for type `{}` with abisize `{d}`", .{
2431 ty.fmt(func.bin_file.base.options.module.?),
2436 ty.fmt(func.bin_file.base.comp.module.?),
24322437 abi_size,
24332438 });
24342439 },
......@@ -2456,7 +2461,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE
24562461}
24572462
24582463fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2459 const mod = func.bin_file.base.options.module.?;
2464 const mod = func.bin_file.base.comp.module.?;
24602465 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
24612466 const operand = try func.resolveInst(ty_op.operand);
24622467 const ty = ty_op.ty.toType();
......@@ -2499,7 +2504,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
24992504/// Loads an operand from the linear memory section.
25002505/// NOTE: Leaves the value on the stack.
25012506fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
2502 const mod = func.bin_file.base.options.module.?;
2507 const mod = func.bin_file.base.comp.module.?;
25032508 // load local's value from memory by its stack position
25042509 try func.emitWValue(operand);
25052510
......@@ -2536,7 +2541,7 @@ fn load(func: *CodeGen, operand: WValue, ty: Type, offset: u32) InnerError!WValu
25362541}
25372542
25382543fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2539 const mod = func.bin_file.base.options.module.?;
2544 const mod = func.bin_file.base.comp.module.?;
25402545 const arg_index = func.arg_index;
25412546 const arg = func.args[arg_index];
25422547 const cc = mod.typeToFunc(func.decl.ty).?.cc;
......@@ -2555,7 +2560,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25552560 if (arg_ty.zigTypeTag(mod) != .Int and arg_ty.zigTypeTag(mod) != .Float) {
25562561 return func.fail(
25572562 "TODO: Implement C-ABI argument for type '{}'",
2558 .{arg_ty.fmt(func.bin_file.base.options.module.?)},
2563 .{arg_ty.fmt(func.bin_file.base.comp.module.?)},
25592564 );
25602565 }
25612566 const result = try func.allocStack(arg_ty);
......@@ -2582,7 +2587,7 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25822587}
25832588
25842589fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2585 const mod = func.bin_file.base.options.module.?;
2590 const mod = func.bin_file.base.comp.module.?;
25862591 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
25872592 const lhs = try func.resolveInst(bin_op.lhs);
25882593 const rhs = try func.resolveInst(bin_op.rhs);
......@@ -2619,7 +2624,7 @@ fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
26192624/// Performs a binary operation on the given `WValue`'s
26202625/// NOTE: THis leaves the value on top of the stack.
26212626fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2622 const mod = func.bin_file.base.options.module.?;
2627 const mod = func.bin_file.base.comp.module.?;
26232628 assert(!(lhs != .stack and rhs == .stack));
26242629
26252630 if (ty.isAnyFloat()) {
......@@ -2633,7 +2638,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26332638 } else {
26342639 return func.fail(
26352640 "TODO: Implement binary operation for type: {}",
2636 .{ty.fmt(func.bin_file.base.options.module.?)},
2641 .{ty.fmt(func.bin_file.base.comp.module.?)},
26372642 );
26382643 }
26392644 }
......@@ -2652,7 +2657,7 @@ fn binOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!
26522657}
26532658
26542659fn binOpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerError!WValue {
2655 const mod = func.bin_file.base.options.module.?;
2660 const mod = func.bin_file.base.comp.module.?;
26562661 const int_info = ty.intInfo(mod);
26572662 if (int_info.bits > 128) {
26582663 return func.fail("TODO: Implement binary operation for big integers larger than 128 bits", .{});
......@@ -2788,7 +2793,7 @@ const FloatOp = enum {
27882793};
27892794
27902795fn airAbs(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2791 const mod = func.bin_file.base.options.module.?;
2796 const mod = func.bin_file.base.comp.module.?;
27922797 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
27932798 const operand = try func.resolveInst(ty_op.operand);
27942799 const ty = func.typeOf(ty_op.operand);
......@@ -2873,7 +2878,7 @@ fn airUnaryFloatOp(func: *CodeGen, inst: Air.Inst.Index, op: FloatOp) InnerError
28732878}
28742879
28752880fn floatOp(func: *CodeGen, float_op: FloatOp, ty: Type, args: []const WValue) InnerError!WValue {
2876 const mod = func.bin_file.base.options.module.?;
2881 const mod = func.bin_file.base.comp.module.?;
28772882 if (ty.zigTypeTag(mod) == .Vector) {
28782883 return func.fail("TODO: Implement floatOps for vectors", .{});
28792884 }
......@@ -2979,7 +2984,7 @@ fn floatNeg(func: *CodeGen, ty: Type, arg: WValue) InnerError!WValue {
29792984}
29802985
29812986fn airWrapBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
2982 const mod = func.bin_file.base.options.module.?;
2987 const mod = func.bin_file.base.comp.module.?;
29832988 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
29842989
29852990 const lhs = try func.resolveInst(bin_op.lhs);
......@@ -3030,7 +3035,7 @@ fn wrapBinOp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: Op) InnerEr
30303035/// Asserts `Type` is <= 128 bits.
30313036/// NOTE: When the Type is <= 64 bits, leaves the value on top of the stack.
30323037fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
3033 const mod = func.bin_file.base.options.module.?;
3038 const mod = func.bin_file.base.comp.module.?;
30343039 assert(ty.abiSize(mod) <= 16);
30353040 const bitsize = @as(u16, @intCast(ty.bitSize(mod)));
30363041 const wasm_bits = toWasmBits(bitsize) orelse {
......@@ -3069,7 +3074,7 @@ fn wrapOperand(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
30693074}
30703075
30713076fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue {
3072 const mod = func.bin_file.base.options.module.?;
3077 const mod = func.bin_file.base.comp.module.?;
30733078 const ptr = mod.intern_pool.indexToKey(ptr_val.ip_index).ptr;
30743079 switch (ptr.addr) {
30753080 .decl => |decl_index| {
......@@ -3132,7 +3137,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue
31323137}
31333138
31343139fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3135 const mod = func.bin_file.base.options.module.?;
3140 const mod = func.bin_file.base.comp.module.?;
31363141 const decl = mod.declPtr(decl_index);
31373142 try mod.markDeclAlive(decl);
31383143 const ptr_ty = try mod.singleMutPtrType(decl.ty);
......@@ -3144,7 +3149,7 @@ fn lowerAnonDeclRef(
31443149 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
31453150 offset: u32,
31463151) InnerError!WValue {
3147 const mod = func.bin_file.base.options.module.?;
3152 const mod = func.bin_file.base.comp.module.?;
31483153 const decl_val = anon_decl.val;
31493154 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
31503155
......@@ -3172,7 +3177,7 @@ fn lowerAnonDeclRef(
31723177}
31733178
31743179fn lowerDeclRefValue(func: *CodeGen, tv: TypedValue, decl_index: InternPool.DeclIndex, offset: u32) InnerError!WValue {
3175 const mod = func.bin_file.base.options.module.?;
3180 const mod = func.bin_file.base.comp.module.?;
31763181 if (tv.ty.isSlice(mod)) {
31773182 return WValue{ .memory = try func.bin_file.lowerUnnamedConst(tv, decl_index) };
31783183 }
......@@ -3225,7 +3230,7 @@ fn toTwosComplement(value: anytype, bits: u7) std.meta.Int(.unsigned, @typeInfo(
32253230/// This function is intended to assert that `isByRef` returns `false` for `ty`.
32263231/// However such an assertion fails on the behavior tests currently.
32273232fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3228 const mod = func.bin_file.base.options.module.?;
3233 const mod = func.bin_file.base.comp.module.?;
32293234 // TODO: enable this assertion
32303235 //assert(!isByRef(ty, mod));
32313236 const ip = &mod.intern_pool;
......@@ -3394,7 +3399,7 @@ fn storeSimdImmd(func: *CodeGen, value: [16]u8) !WValue {
33943399}
33953400
33963401fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3397 const mod = func.bin_file.base.options.module.?;
3402 const mod = func.bin_file.base.comp.module.?;
33983403 const ip = &mod.intern_pool;
33993404 switch (ty.zigTypeTag(mod)) {
34003405 .Bool, .ErrorSet => return WValue{ .imm32 = 0xaaaaaaaa },
......@@ -3436,7 +3441,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
34363441/// It's illegal to provide a value with a type that cannot be represented
34373442/// as an integer value.
34383443fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {
3439 const mod = func.bin_file.base.options.module.?;
3444 const mod = func.bin_file.base.comp.module.?;
34403445
34413446 switch (val.ip_index) {
34423447 .none => {},
......@@ -3472,7 +3477,7 @@ fn intStorageAsI32(storage: InternPool.Key.Int.Storage, mod: *Module) i32 {
34723477}
34733478
34743479fn airBlock(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3475 const mod = func.bin_file.base.options.module.?;
3480 const mod = func.bin_file.base.comp.module.?;
34763481 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
34773482 const block_ty = ty_pl.ty.toType();
34783483 const wasm_block_ty = genBlockType(block_ty, mod);
......@@ -3593,7 +3598,7 @@ fn airCmp(func: *CodeGen, inst: Air.Inst.Index, op: std.math.CompareOperator) In
35933598/// NOTE: This leaves the result on top of the stack, rather than a new local.
35943599fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareOperator) InnerError!WValue {
35953600 assert(!(lhs != .stack and rhs == .stack));
3596 const mod = func.bin_file.base.options.module.?;
3601 const mod = func.bin_file.base.comp.module.?;
35973602 if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) {
35983603 const payload_ty = ty.optionalChild(mod);
35993604 if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -3711,7 +3716,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37113716 const errors_len = WValue{ .memory = sym_index };
37123717
37133718 try func.emitWValue(operand);
3714 const mod = func.bin_file.base.options.module.?;
3719 const mod = func.bin_file.base.comp.module.?;
37153720 const err_int_ty = try mod.errorIntType();
37163721 const errors_len_val = try func.load(errors_len, err_int_ty, 0);
37173722 const result = try func.cmp(.stack, errors_len_val, err_int_ty, .lt);
......@@ -3720,7 +3725,7 @@ fn airCmpLtErrorsLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37203725}
37213726
37223727fn airBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3723 const mod = func.bin_file.base.options.module.?;
3728 const mod = func.bin_file.base.comp.module.?;
37243729 const br = func.air.instructions.items(.data)[@intFromEnum(inst)].br;
37253730 const block = func.blocks.get(br.block_inst).?;
37263731
......@@ -3747,7 +3752,7 @@ fn airNot(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
37473752
37483753 const operand = try func.resolveInst(ty_op.operand);
37493754 const operand_ty = func.typeOf(ty_op.operand);
3750 const mod = func.bin_file.base.options.module.?;
3755 const mod = func.bin_file.base.comp.module.?;
37513756
37523757 const result = result: {
37533758 if (operand_ty.zigTypeTag(mod) == .Bool) {
......@@ -3818,7 +3823,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38183823 const bitcast_result = try func.bitcast(wanted_ty, given_ty, operand);
38193824 break :result try bitcast_result.toLocal(func, wanted_ty);
38203825 }
3821 const mod = func.bin_file.base.options.module.?;
3826 const mod = func.bin_file.base.comp.module.?;
38223827 if (isByRef(given_ty, mod) and !isByRef(wanted_ty, mod)) {
38233828 const loaded_memory = try func.load(operand, wanted_ty, 0);
38243829 break :result try loaded_memory.toLocal(func, wanted_ty);
......@@ -3834,7 +3839,7 @@ fn airBitcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38343839}
38353840
38363841fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) InnerError!WValue {
3837 const mod = func.bin_file.base.options.module.?;
3842 const mod = func.bin_file.base.comp.module.?;
38383843 // if we bitcast a float to or from an integer we must use the 'reinterpret' instruction
38393844 if (!(wanted_ty.isAnyFloat() or given_ty.isAnyFloat())) return operand;
38403845 if (wanted_ty.ip_index == .f16_type or given_ty.ip_index == .f16_type) return operand;
......@@ -3852,7 +3857,7 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn
38523857}
38533858
38543859fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3855 const mod = func.bin_file.base.options.module.?;
3860 const mod = func.bin_file.base.comp.module.?;
38563861 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
38573862 const extra = func.air.extraData(Air.StructField, ty_pl.payload);
38583863
......@@ -3864,7 +3869,7 @@ fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
38643869}
38653870
38663871fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void {
3867 const mod = func.bin_file.base.options.module.?;
3872 const mod = func.bin_file.base.comp.module.?;
38683873 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
38693874 const struct_ptr = try func.resolveInst(ty_op.operand);
38703875 const struct_ptr_ty = func.typeOf(ty_op.operand);
......@@ -3883,7 +3888,7 @@ fn structFieldPtr(
38833888 struct_ty: Type,
38843889 index: u32,
38853890) InnerError!WValue {
3886 const mod = func.bin_file.base.options.module.?;
3891 const mod = func.bin_file.base.comp.module.?;
38873892 const result_ty = func.typeOfIndex(inst);
38883893 const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod);
38893894
......@@ -3914,7 +3919,7 @@ fn structFieldPtr(
39143919}
39153920
39163921fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
3917 const mod = func.bin_file.base.options.module.?;
3922 const mod = func.bin_file.base.comp.module.?;
39183923 const ip = &mod.intern_pool;
39193924 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
39203925 const struct_field = func.air.extraData(Air.StructField, ty_pl.payload).data;
......@@ -4013,7 +4018,7 @@ fn airStructFieldVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40134018}
40144019
40154020fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4016 const mod = func.bin_file.base.options.module.?;
4021 const mod = func.bin_file.base.comp.module.?;
40174022 // result type is always 'noreturn'
40184023 const blocktype = wasm.block_empty;
40194024 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
......@@ -4193,7 +4198,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
41934198}
41944199
41954200fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerError!void {
4196 const mod = func.bin_file.base.options.module.?;
4201 const mod = func.bin_file.base.comp.module.?;
41974202 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
41984203 const operand = try func.resolveInst(un_op);
41994204 const err_union_ty = func.typeOf(un_op);
......@@ -4228,7 +4233,7 @@ fn airIsErr(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode) InnerErro
42284233}
42294234
42304235fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4231 const mod = func.bin_file.base.options.module.?;
4236 const mod = func.bin_file.base.comp.module.?;
42324237 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42334238
42344239 const operand = try func.resolveInst(ty_op.operand);
......@@ -4256,7 +4261,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo
42564261}
42574262
42584263fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void {
4259 const mod = func.bin_file.base.options.module.?;
4264 const mod = func.bin_file.base.comp.module.?;
42604265 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42614266
42624267 const operand = try func.resolveInst(ty_op.operand);
......@@ -4280,7 +4285,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool)
42804285}
42814286
42824287fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4283 const mod = func.bin_file.base.options.module.?;
4288 const mod = func.bin_file.base.comp.module.?;
42844289 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
42854290
42864291 const operand = try func.resolveInst(ty_op.operand);
......@@ -4310,7 +4315,7 @@ fn airWrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void
43104315}
43114316
43124317fn airWrapErrUnionErr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4313 const mod = func.bin_file.base.options.module.?;
4318 const mod = func.bin_file.base.comp.module.?;
43144319 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
43154320
43164321 const operand = try func.resolveInst(ty_op.operand);
......@@ -4342,7 +4347,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43424347 const ty = ty_op.ty.toType();
43434348 const operand = try func.resolveInst(ty_op.operand);
43444349 const operand_ty = func.typeOf(ty_op.operand);
4345 const mod = func.bin_file.base.options.module.?;
4350 const mod = func.bin_file.base.comp.module.?;
43464351 if (ty.zigTypeTag(mod) == .Vector or operand_ty.zigTypeTag(mod) == .Vector) {
43474352 return func.fail("todo Wasm intcast for vectors", .{});
43484353 }
......@@ -4365,7 +4370,7 @@ fn airIntcast(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
43654370/// Asserts type's bitsize <= 128
43664371/// NOTE: May leave the result on the top of the stack.
43674372fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerError!WValue {
4368 const mod = func.bin_file.base.options.module.?;
4373 const mod = func.bin_file.base.comp.module.?;
43694374 const given_bitsize = @as(u16, @intCast(given.bitSize(mod)));
43704375 const wanted_bitsize = @as(u16, @intCast(wanted.bitSize(mod)));
43714376 assert(given_bitsize <= 128);
......@@ -4433,7 +4438,7 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
44334438}
44344439
44354440fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void {
4436 const mod = func.bin_file.base.options.module.?;
4441 const mod = func.bin_file.base.comp.module.?;
44374442 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
44384443 const operand = try func.resolveInst(un_op);
44394444
......@@ -4447,7 +4452,7 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind:
44474452/// For a given type and operand, checks if it's considered `null`.
44484453/// NOTE: Leaves the result on the stack
44494454fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue {
4450 const mod = func.bin_file.base.options.module.?;
4455 const mod = func.bin_file.base.comp.module.?;
44514456 try func.emitWValue(operand);
44524457 const payload_ty = optional_ty.optionalChild(mod);
44534458 if (!optional_ty.optionalReprIsPayload(mod)) {
......@@ -4475,7 +4480,7 @@ fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcod
44754480}
44764481
44774482fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4478 const mod = func.bin_file.base.options.module.?;
4483 const mod = func.bin_file.base.comp.module.?;
44794484 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
44804485 const opt_ty = func.typeOf(ty_op.operand);
44814486 const payload_ty = func.typeOfIndex(inst);
......@@ -4498,7 +4503,7 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
44984503}
44994504
45004505fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4501 const mod = func.bin_file.base.options.module.?;
4506 const mod = func.bin_file.base.comp.module.?;
45024507 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45034508 const operand = try func.resolveInst(ty_op.operand);
45044509 const opt_ty = func.typeOf(ty_op.operand).childType(mod);
......@@ -4515,7 +4520,7 @@ fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
45154520}
45164521
45174522fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4518 const mod = func.bin_file.base.options.module.?;
4523 const mod = func.bin_file.base.comp.module.?;
45194524 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45204525 const operand = try func.resolveInst(ty_op.operand);
45214526 const opt_ty = func.typeOf(ty_op.operand).childType(mod);
......@@ -4543,7 +4548,7 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
45434548fn airWrapOptional(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
45444549 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45454550 const payload_ty = func.typeOf(ty_op.operand);
4546 const mod = func.bin_file.base.options.module.?;
4551 const mod = func.bin_file.base.comp.module.?;
45474552
45484553 const result = result: {
45494554 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
......@@ -4600,7 +4605,7 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46004605}
46014606
46024607fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4603 const mod = func.bin_file.base.options.module.?;
4608 const mod = func.bin_file.base.comp.module.?;
46044609 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
46054610
46064611 const slice_ty = func.typeOf(bin_op.lhs);
......@@ -4630,7 +4635,7 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46304635}
46314636
46324637fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4633 const mod = func.bin_file.base.options.module.?;
4638 const mod = func.bin_file.base.comp.module.?;
46344639 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
46354640 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
46364641
......@@ -4683,7 +4688,7 @@ fn airTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
46834688/// Truncates a given operand to a given type, discarding any overflown bits.
46844689/// NOTE: Resulting value is left on the stack.
46854690fn trunc(func: *CodeGen, operand: WValue, wanted_ty: Type, given_ty: Type) InnerError!WValue {
4686 const mod = func.bin_file.base.options.module.?;
4691 const mod = func.bin_file.base.comp.module.?;
46874692 const given_bits = @as(u16, @intCast(given_ty.bitSize(mod)));
46884693 if (toWasmBits(given_bits) == null) {
46894694 return func.fail("TODO: Implement wasm integer truncation for integer bitsize: {d}", .{given_bits});
......@@ -4707,7 +4712,7 @@ fn airIntFromBool(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47074712}
47084713
47094714fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4710 const mod = func.bin_file.base.options.module.?;
4715 const mod = func.bin_file.base.comp.module.?;
47114716 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
47124717
47134718 const operand = try func.resolveInst(ty_op.operand);
......@@ -4730,7 +4735,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47304735}
47314736
47324737fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4733 const mod = func.bin_file.base.options.module.?;
4738 const mod = func.bin_file.base.comp.module.?;
47344739 const un_op = func.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
47354740 const operand = try func.resolveInst(un_op);
47364741 const ptr_ty = func.typeOf(un_op);
......@@ -4745,7 +4750,7 @@ fn airIntFromPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47454750}
47464751
47474752fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4748 const mod = func.bin_file.base.options.module.?;
4753 const mod = func.bin_file.base.comp.module.?;
47494754 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
47504755
47514756 const ptr_ty = func.typeOf(bin_op.lhs);
......@@ -4782,7 +4787,7 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
47824787}
47834788
47844789fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4785 const mod = func.bin_file.base.options.module.?;
4790 const mod = func.bin_file.base.comp.module.?;
47864791 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
47874792 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
47884793
......@@ -4812,7 +4817,7 @@ fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
48124817}
48134818
48144819fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
4815 const mod = func.bin_file.base.options.module.?;
4820 const mod = func.bin_file.base.comp.module.?;
48164821 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
48174822 const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data;
48184823
......@@ -4840,7 +4845,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
48404845}
48414846
48424847fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void {
4843 const mod = func.bin_file.base.options.module.?;
4848 const mod = func.bin_file.base.comp.module.?;
48444849 if (safety) {
48454850 // TODO if the value is undef, write 0xaa bytes to dest
48464851 } else {
......@@ -4873,7 +4878,7 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void
48734878/// this to wasm's memset instruction. When the feature is not present,
48744879/// we implement it manually.
48754880fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue) InnerError!void {
4876 const mod = func.bin_file.base.options.module.?;
4881 const mod = func.bin_file.base.comp.module.?;
48774882 const abi_size = @as(u32, @intCast(elem_ty.abiSize(mod)));
48784883
48794884 // When bulk_memory is enabled, we lower it to wasm's memset instruction.
......@@ -4962,7 +4967,7 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue
49624967}
49634968
49644969fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
4965 const mod = func.bin_file.base.options.module.?;
4970 const mod = func.bin_file.base.comp.module.?;
49664971 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
49674972
49684973 const array_ty = func.typeOf(bin_op.lhs);
......@@ -5031,7 +5036,7 @@ fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50315036}
50325037
50335038fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5034 const mod = func.bin_file.base.options.module.?;
5039 const mod = func.bin_file.base.comp.module.?;
50355040 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
50365041
50375042 const operand = try func.resolveInst(ty_op.operand);
......@@ -5076,7 +5081,7 @@ fn airIntFromFloat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
50765081}
50775082
50785083fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5079 const mod = func.bin_file.base.options.module.?;
5084 const mod = func.bin_file.base.comp.module.?;
50805085 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
50815086
50825087 const operand = try func.resolveInst(ty_op.operand);
......@@ -5122,7 +5127,7 @@ fn airFloatFromInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51225127}
51235128
51245129fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5125 const mod = func.bin_file.base.options.module.?;
5130 const mod = func.bin_file.base.comp.module.?;
51265131 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
51275132 const operand = try func.resolveInst(ty_op.operand);
51285133 const ty = func.typeOfIndex(inst);
......@@ -5201,7 +5206,7 @@ fn airSelect(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52015206}
52025207
52035208fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5204 const mod = func.bin_file.base.options.module.?;
5209 const mod = func.bin_file.base.comp.module.?;
52055210 const inst_ty = func.typeOfIndex(inst);
52065211 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
52075212 const extra = func.air.extraData(Air.Shuffle, ty_pl.payload).data;
......@@ -5270,7 +5275,7 @@ fn airReduce(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52705275}
52715276
52725277fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5273 const mod = func.bin_file.base.options.module.?;
5278 const mod = func.bin_file.base.comp.module.?;
52745279 const ip = &mod.intern_pool;
52755280 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
52765281 const result_ty = func.typeOfIndex(inst);
......@@ -5400,7 +5405,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
54005405}
54015406
54025407fn airUnionInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5403 const mod = func.bin_file.base.options.module.?;
5408 const mod = func.bin_file.base.comp.module.?;
54045409 const ip = &mod.intern_pool;
54055410 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
54065411 const extra = func.air.extraData(Air.UnionInit, ty_pl.payload).data;
......@@ -5499,7 +5504,7 @@ fn airWasmMemoryGrow(func: *CodeGen, inst: Air.Inst.Index) !void {
54995504}
55005505
55015506fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5502 const mod = func.bin_file.base.options.module.?;
5507 const mod = func.bin_file.base.comp.module.?;
55035508 assert(operand_ty.hasRuntimeBitsIgnoreComptime(mod));
55045509 assert(op == .eq or op == .neq);
55055510 const payload_ty = operand_ty.optionalChild(mod);
......@@ -5535,7 +5540,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op:
55355540/// NOTE: Leaves the result of the comparison on top of the stack.
55365541/// TODO: Lower this to compiler_rt call when bitsize > 128
55375542fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.math.CompareOperator) InnerError!WValue {
5538 const mod = func.bin_file.base.options.module.?;
5543 const mod = func.bin_file.base.comp.module.?;
55395544 assert(operand_ty.abiSize(mod) >= 16);
55405545 assert(!(lhs != .stack and rhs == .stack));
55415546 if (operand_ty.bitSize(mod) > 128) {
......@@ -5577,7 +5582,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std
55775582}
55785583
55795584fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5580 const mod = func.bin_file.base.options.module.?;
5585 const mod = func.bin_file.base.comp.module.?;
55815586 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
55825587 const un_ty = func.typeOf(bin_op.lhs).childType(mod);
55835588 const tag_ty = func.typeOf(bin_op.rhs);
......@@ -5601,7 +5606,7 @@ fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
56015606}
56025607
56035608fn airGetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5604 const mod = func.bin_file.base.options.module.?;
5609 const mod = func.bin_file.base.comp.module.?;
56055610 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
56065611
56075612 const un_ty = func.typeOf(ty_op.operand);
......@@ -5706,7 +5711,7 @@ fn fptrunc(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro
57065711}
57075712
57085713fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5709 const mod = func.bin_file.base.options.module.?;
5714 const mod = func.bin_file.base.comp.module.?;
57105715 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57115716
57125717 const err_set_ty = func.typeOf(ty_op.operand).childType(mod);
......@@ -5732,7 +5737,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi
57325737}
57335738
57345739fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5735 const mod = func.bin_file.base.options.module.?;
5740 const mod = func.bin_file.base.comp.module.?;
57365741 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
57375742 const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
57385743
......@@ -5753,7 +5758,7 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
57535758}
57545759
57555760fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue {
5756 const mod = func.bin_file.base.options.module.?;
5761 const mod = func.bin_file.base.comp.module.?;
57575762 if (ptr_ty.isSlice(mod)) {
57585763 return func.slicePtr(ptr);
57595764 } else {
......@@ -5762,7 +5767,7 @@ fn sliceOrArrayPtr(func: *CodeGen, ptr: WValue, ptr_ty: Type) InnerError!WValue
57625767}
57635768
57645769fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5765 const mod = func.bin_file.base.options.module.?;
5770 const mod = func.bin_file.base.comp.module.?;
57665771 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
57675772 const dst = try func.resolveInst(bin_op.lhs);
57685773 const dst_ty = func.typeOf(bin_op.lhs);
......@@ -5802,7 +5807,7 @@ fn airRetAddr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
58025807}
58035808
58045809fn airPopcount(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
5805 const mod = func.bin_file.base.options.module.?;
5810 const mod = func.bin_file.base.comp.module.?;
58065811 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
58075812
58085813 const operand = try func.resolveInst(ty_op.operand);
......@@ -5863,7 +5868,7 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
58635868 // to make a copy of the ptr+value but can point towards them directly.
58645869 const error_table_symbol = try func.bin_file.getErrorTableSymbol();
58655870 const name_ty = Type.slice_const_u8_sentinel_0;
5866 const mod = func.bin_file.base.options.module.?;
5871 const mod = func.bin_file.base.comp.module.?;
58675872 const abi_size = name_ty.abiSize(mod);
58685873
58695874 const error_name_value: WValue = .{ .memory = error_table_symbol }; // emitting this will create a relocation
......@@ -5903,7 +5908,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
59035908 const lhs_op = try func.resolveInst(extra.lhs);
59045909 const rhs_op = try func.resolveInst(extra.rhs);
59055910 const lhs_ty = func.typeOf(extra.lhs);
5906 const mod = func.bin_file.base.options.module.?;
5911 const mod = func.bin_file.base.comp.module.?;
59075912
59085913 if (lhs_ty.zigTypeTag(mod) == .Vector) {
59095914 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
......@@ -5975,7 +5980,7 @@ fn airAddSubWithOverflow(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerErro
59755980}
59765981
59775982fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, result_ty: Type, op: Op) InnerError!WValue {
5978 const mod = func.bin_file.base.options.module.?;
5983 const mod = func.bin_file.base.comp.module.?;
59795984 assert(op == .add or op == .sub);
59805985 const int_info = ty.intInfo(mod);
59815986 const is_signed = int_info.signedness == .signed;
......@@ -6040,7 +6045,7 @@ fn addSubWithOverflowBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type,
60406045}
60416046
60426047fn airShlWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6043 const mod = func.bin_file.base.options.module.?;
6048 const mod = func.bin_file.base.comp.module.?;
60446049 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
60456050 const extra = func.air.extraData(Air.Bin, ty_pl.payload).data;
60466051
......@@ -6103,7 +6108,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
61036108 const lhs = try func.resolveInst(extra.lhs);
61046109 const rhs = try func.resolveInst(extra.rhs);
61056110 const lhs_ty = func.typeOf(extra.lhs);
6106 const mod = func.bin_file.base.options.module.?;
6111 const mod = func.bin_file.base.comp.module.?;
61076112
61086113 if (lhs_ty.zigTypeTag(mod) == .Vector) {
61096114 return func.fail("TODO: Implement overflow arithmetic for vectors", .{});
......@@ -6273,7 +6278,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
62736278
62746279fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
62756280 assert(op == .max or op == .min);
6276 const mod = func.bin_file.base.options.module.?;
6281 const mod = func.bin_file.base.comp.module.?;
62776282 const target = mod.getTarget();
62786283 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
62796284
......@@ -6317,7 +6322,7 @@ fn airMaxMin(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
63176322}
63186323
63196324fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6320 const mod = func.bin_file.base.options.module.?;
6325 const mod = func.bin_file.base.comp.module.?;
63216326 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
63226327 const bin_op = func.air.extraData(Air.Bin, pl_op.payload).data;
63236328
......@@ -6351,7 +6356,7 @@ fn airMulAdd(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
63516356}
63526357
63536358fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6354 const mod = func.bin_file.base.options.module.?;
6359 const mod = func.bin_file.base.comp.module.?;
63556360 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63566361
63576362 const ty = func.typeOf(ty_op.operand);
......@@ -6404,7 +6409,7 @@ fn airClz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64046409}
64056410
64066411fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6407 const mod = func.bin_file.base.options.module.?;
6412 const mod = func.bin_file.base.comp.module.?;
64086413 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
64096414
64106415 const ty = func.typeOf(ty_op.operand);
......@@ -6471,7 +6476,7 @@ fn airCtz(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
64716476fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
64726477 if (func.debug_output != .dwarf) return func.finishAir(inst, .none, &.{});
64736478
6474 const mod = func.bin_file.base.options.module.?;
6479 const mod = func.bin_file.base.comp.module.?;
64756480 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
64766481 const ty = func.typeOf(pl_op.operand);
64776482 const operand = try func.resolveInst(pl_op.operand);
......@@ -6517,7 +6522,7 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
65176522}
65186523
65196524fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6520 const mod = func.bin_file.base.options.module.?;
6525 const mod = func.bin_file.base.comp.module.?;
65216526 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
65226527 const extra = func.air.extraData(Air.TryPtr, ty_pl.payload);
65236528 const err_union_ptr = try func.resolveInst(extra.data.ptr);
......@@ -6535,7 +6540,7 @@ fn lowerTry(
65356540 err_union_ty: Type,
65366541 operand_is_ptr: bool,
65376542) InnerError!WValue {
6538 const mod = func.bin_file.base.options.module.?;
6543 const mod = func.bin_file.base.comp.module.?;
65396544 if (operand_is_ptr) {
65406545 return func.fail("TODO: lowerTry for pointers", .{});
65416546 }
......@@ -6584,7 +6589,7 @@ fn lowerTry(
65846589}
65856590
65866591fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6587 const mod = func.bin_file.base.options.module.?;
6592 const mod = func.bin_file.base.comp.module.?;
65886593 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
65896594
65906595 const ty = func.typeOfIndex(inst);
......@@ -6655,7 +6660,7 @@ fn airByteSwap(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66556660}
66566661
66576662fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6658 const mod = func.bin_file.base.options.module.?;
6663 const mod = func.bin_file.base.comp.module.?;
66596664 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
66606665
66616666 const ty = func.typeOfIndex(inst);
......@@ -6670,7 +6675,7 @@ fn airDiv(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66706675}
66716676
66726677fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
6673 const mod = func.bin_file.base.options.module.?;
6678 const mod = func.bin_file.base.comp.module.?;
66746679 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
66756680
66766681 const ty = func.typeOfIndex(inst);
......@@ -6693,7 +6698,7 @@ fn airDivTrunc(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66936698fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
66946699 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
66956700
6696 const mod = func.bin_file.base.options.module.?;
6701 const mod = func.bin_file.base.comp.module.?;
66976702 const ty = func.typeOfIndex(inst);
66986703 const lhs = try func.resolveInst(bin_op.lhs);
66996704 const rhs = try func.resolveInst(bin_op.rhs);
......@@ -6806,7 +6811,7 @@ fn airDivFloor(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68066811}
68076812
68086813fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WValue {
6809 const mod = func.bin_file.base.options.module.?;
6814 const mod = func.bin_file.base.comp.module.?;
68106815 const int_bits = ty.intInfo(mod).bits;
68116816 const wasm_bits = toWasmBits(int_bits) orelse {
68126817 return func.fail("TODO: Implement signed division for integers with bitsize '{d}'", .{int_bits});
......@@ -6836,7 +6841,7 @@ fn divSigned(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type) InnerError!WVal
68366841fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68376842 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
68386843
6839 const mod = func.bin_file.base.options.module.?;
6844 const mod = func.bin_file.base.comp.module.?;
68406845 const ty = func.typeOfIndex(inst);
68416846 const lhs = try func.resolveInst(bin_op.lhs);
68426847 const rhs = try func.resolveInst(bin_op.rhs);
......@@ -6883,7 +6888,7 @@ fn airMod(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
68836888/// The result will be sign extended to 32 bits if N <= 32 or 64 bits if N <= 64.
68846889/// Support for integers wider than 64 bits has not yet been implemented.
68856890fn signExtendInt(func: *CodeGen, operand: WValue, ty: Type) InnerError!WValue {
6886 const mod = func.bin_file.base.options.module.?;
6891 const mod = func.bin_file.base.comp.module.?;
68876892 const int_bits = ty.intInfo(mod).bits;
68886893 const wasm_bits = toWasmBits(int_bits) orelse {
68896894 return func.fail("TODO: signExtendInt for signed integers larger than '{d}' bits", .{int_bits});
......@@ -6919,7 +6924,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
69196924 assert(op == .add or op == .sub);
69206925 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
69216926
6922 const mod = func.bin_file.base.options.module.?;
6927 const mod = func.bin_file.base.comp.module.?;
69236928 const ty = func.typeOfIndex(inst);
69246929 const lhs = try func.resolveInst(bin_op.lhs);
69256930 const rhs = try func.resolveInst(bin_op.rhs);
......@@ -6967,7 +6972,7 @@ fn airSatBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
69676972}
69686973
69696974fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type, op: Op) InnerError!WValue {
6970 const mod = func.bin_file.base.options.module.?;
6975 const mod = func.bin_file.base.comp.module.?;
69716976 const int_info = ty.intInfo(mod);
69726977 const wasm_bits = toWasmBits(int_info.bits).?;
69736978 const is_wasm_bits = wasm_bits == int_info.bits;
......@@ -7034,7 +7039,7 @@ fn signedSat(func: *CodeGen, lhs_operand: WValue, rhs_operand: WValue, ty: Type,
70347039fn airShlSat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
70357040 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
70367041
7037 const mod = func.bin_file.base.options.module.?;
7042 const mod = func.bin_file.base.comp.module.?;
70387043 const ty = func.typeOfIndex(inst);
70397044 const int_info = ty.intInfo(mod);
70407045 const is_signed = int_info.signedness == .signed;
......@@ -7155,7 +7160,7 @@ fn callIntrinsic(
71557160 };
71567161
71577162 // Always pass over C-ABI
7158 const mod = func.bin_file.base.options.module.?;
7163 const mod = func.bin_file.base.comp.module.?;
71597164 var func_type = try genFunctype(func.gpa, .C, param_types, return_type, mod);
71607165 defer func_type.deinit(func.gpa);
71617166 const func_type_index = try func.bin_file.putOrGetFuncType(func_type);
......@@ -7208,7 +7213,7 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
72087213}
72097214
72107215fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7211 const mod = func.bin_file.base.options.module.?;
7216 const mod = func.bin_file.base.comp.module.?;
72127217 const enum_decl_index = enum_ty.getOwnerDecl(mod);
72137218
72147219 var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
......@@ -7364,7 +7369,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
73647369}
73657370
73667371fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7367 const mod = func.bin_file.base.options.module.?;
7372 const mod = func.bin_file.base.comp.module.?;
73687373 const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
73697374
73707375 const operand = try func.resolveInst(ty_op.operand);
......@@ -7449,7 +7454,7 @@ inline fn useAtomicFeature(func: *const CodeGen) bool {
74497454}
74507455
74517456fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7452 const mod = func.bin_file.base.options.module.?;
7457 const mod = func.bin_file.base.comp.module.?;
74537458 const ty_pl = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
74547459 const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
74557460
......@@ -7522,7 +7527,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
75227527}
75237528
75247529fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7525 const mod = func.bin_file.base.options.module.?;
7530 const mod = func.bin_file.base.comp.module.?;
75267531 const atomic_load = func.air.instructions.items(.data)[@intFromEnum(inst)].atomic_load;
75277532 const ptr = try func.resolveInst(atomic_load.ptr);
75287533 const ty = func.typeOfIndex(inst);
......@@ -7549,7 +7554,7 @@ fn airAtomicLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
75497554}
75507555
75517556fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7552 const mod = func.bin_file.base.options.module.?;
7557 const mod = func.bin_file.base.comp.module.?;
75537558 const pl_op = func.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
75547559 const extra = func.air.extraData(Air.AtomicRmw, pl_op.payload).data;
75557560
......@@ -7724,10 +7729,13 @@ fn airAtomicRmw(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
77247729}
77257730
77267731fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7732 const zcu = func.bin_file.base.comp.module.?;
77277733 // Only when the atomic feature is enabled, and we're not building
77287734 // for a single-threaded build, can we emit the `fence` instruction.
77297735 // In all other cases, we emit no instructions for a fence.
7730 if (func.useAtomicFeature() and !func.bin_file.base.options.single_threaded) {
7736 const func_namespace = zcu.namespacePtr(func.decl.src_namespace);
7737 const single_threaded = func_namespace.file_scope.mod.single_threaded;
7738 if (func.useAtomicFeature() and !single_threaded) {
77317739 try func.addAtomicTag(.atomic_fence);
77327740 }
77337741
......@@ -7735,7 +7743,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
77357743}
77367744
77377745fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7738 const mod = func.bin_file.base.options.module.?;
7746 const mod = func.bin_file.base.comp.module.?;
77397747 const bin_op = func.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
77407748
77417749 const ptr = try func.resolveInst(bin_op.lhs);
......@@ -7774,11 +7782,11 @@ fn airFrameAddress(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
77747782}
77757783
77767784fn typeOf(func: *CodeGen, inst: Air.Inst.Ref) Type {
7777 const mod = func.bin_file.base.options.module.?;
7785 const mod = func.bin_file.base.comp.module.?;
77787786 return func.air.typeOf(inst, &mod.intern_pool);
77797787}
77807788
77817789fn typeOfIndex(func: *CodeGen, inst: Air.Inst.Index) Type {
7782 const mod = func.bin_file.base.options.module.?;
7790 const mod = func.bin_file.base.comp.module.?;
77837791 return func.air.typeOfIndex(inst, &mod.intern_pool);
77847792}
src/arch/wasm/Emit.zig+18-7
......@@ -254,8 +254,10 @@ fn offset(self: Emit) u32 {
254254fn fail(emit: *Emit, comptime format: []const u8, args: anytype) InnerError {
255255 @setCold(true);
256256 std.debug.assert(emit.error_msg == null);
257 const mod = emit.bin_file.base.options.module.?;
258 emit.error_msg = try Module.ErrorMsg.create(emit.bin_file.base.allocator, mod.declPtr(emit.decl_index).srcLoc(mod), format, args);
257 const comp = emit.bin_file.base.comp;
258 const zcu = comp.module.?;
259 const gpa = comp.gpa;
260 emit.error_msg = try Module.ErrorMsg.create(gpa, zcu.declPtr(emit.decl_index).srcLoc(zcu), format, args);
259261 return error.EmitFail;
260262}
261263
......@@ -299,6 +301,8 @@ fn emitLabel(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
299301}
300302
301303fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
304 const comp = emit.bin_file.base.comp;
305 const gpa = comp.gpa;
302306 const label = emit.mir.instructions.items(.data)[inst].label;
303307 try emit.code.append(@intFromEnum(tag));
304308 var buf: [5]u8 = undefined;
......@@ -308,7 +312,7 @@ fn emitGlobal(emit: *Emit, tag: Mir.Inst.Tag, inst: Mir.Inst.Index) !void {
308312
309313 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
310314 const atom = emit.bin_file.getAtomPtr(atom_index);
311 try atom.relocs.append(emit.bin_file.base.allocator, .{
315 try atom.relocs.append(gpa, .{
312316 .index = label,
313317 .offset = global_offset,
314318 .relocation_type = .R_WASM_GLOBAL_INDEX_LEB,
......@@ -356,6 +360,8 @@ fn encodeMemArg(mem_arg: Mir.MemArg, writer: anytype) !void {
356360}
357361
358362fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
363 const comp = emit.bin_file.base.comp;
364 const gpa = comp.gpa;
359365 const label = emit.mir.instructions.items(.data)[inst].label;
360366 try emit.code.append(std.wasm.opcode(.call));
361367 const call_offset = emit.offset();
......@@ -366,7 +372,7 @@ fn emitCall(emit: *Emit, inst: Mir.Inst.Index) !void {
366372 if (label != 0) {
367373 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
368374 const atom = emit.bin_file.getAtomPtr(atom_index);
369 try atom.relocs.append(emit.bin_file.base.allocator, .{
375 try atom.relocs.append(gpa, .{
370376 .offset = call_offset,
371377 .index = label,
372378 .relocation_type = .R_WASM_FUNCTION_INDEX_LEB,
......@@ -384,6 +390,8 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
384390}
385391
386392fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
393 const comp = emit.bin_file.base.comp;
394 const gpa = comp.gpa;
387395 const symbol_index = emit.mir.instructions.items(.data)[inst].label;
388396 try emit.code.append(std.wasm.opcode(.i32_const));
389397 const index_offset = emit.offset();
......@@ -394,7 +402,7 @@ fn emitFunctionIndex(emit: *Emit, inst: Mir.Inst.Index) !void {
394402 if (symbol_index != 0) {
395403 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
396404 const atom = emit.bin_file.getAtomPtr(atom_index);
397 try atom.relocs.append(emit.bin_file.base.allocator, .{
405 try atom.relocs.append(gpa, .{
398406 .offset = index_offset,
399407 .index = symbol_index,
400408 .relocation_type = .R_WASM_TABLE_INDEX_SLEB,
......@@ -406,7 +414,10 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
406414 const extra_index = emit.mir.instructions.items(.data)[inst].payload;
407415 const mem = emit.mir.extraData(Mir.Memory, extra_index).data;
408416 const mem_offset = emit.offset() + 1;
409 const is_wasm32 = emit.bin_file.base.options.target.cpu.arch == .wasm32;
417 const comp = emit.bin_file.base.comp;
418 const gpa = comp.gpa;
419 const target = comp.root_mod.resolved_target.result;
420 const is_wasm32 = target.cpu.arch == .wasm32;
410421 if (is_wasm32) {
411422 try emit.code.append(std.wasm.opcode(.i32_const));
412423 var buf: [5]u8 = undefined;
......@@ -422,7 +433,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
422433 if (mem.pointer != 0) {
423434 const atom_index = emit.bin_file.decls.get(emit.decl_index).?;
424435 const atom = emit.bin_file.getAtomPtr(atom_index);
425 try atom.relocs.append(emit.bin_file.base.allocator, .{
436 try atom.relocs.append(gpa, .{
426437 .offset = mem_offset,
427438 .index = mem.pointer,
428439 .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64,
src/arch/x86_64/CodeGen.zig+172-152
......@@ -25,7 +25,9 @@ const Emit = @import("Emit.zig");
2525const Liveness = @import("../../Liveness.zig");
2626const Lower = @import("Lower.zig");
2727const Mir = @import("Mir.zig");
28const Package = @import("../../Package.zig");
2829const Module = @import("../../Module.zig");
30const Zcu = Module;
2931const InternPool = @import("../../InternPool.zig");
3032const Alignment = InternPool.Alignment;
3133const Target = std.Target;
......@@ -56,6 +58,7 @@ bin_file: *link.File,
5658debug_output: DebugInfoOutput,
5759target: *const std.Target,
5860owner: Owner,
61mod: *Package.Module,
5962err_msg: ?*ErrorMsg,
6063args: []MCValue,
6164va_info: union {
......@@ -131,7 +134,7 @@ const Owner = union(enum) {
131134 fn getSymbolIndex(owner: Owner, ctx: *Self) !u32 {
132135 switch (owner) {
133136 .func_index => |func_index| {
134 const mod = ctx.bin_file.options.module.?;
137 const mod = ctx.bin_file.comp.module.?;
135138 const decl_index = mod.funcOwnerDeclIndex(func_index);
136139 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
137140 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
......@@ -795,22 +798,22 @@ pub fn generate(
795798 code: *std.ArrayList(u8),
796799 debug_output: DebugInfoOutput,
797800) CodeGenError!Result {
798 if (build_options.skip_non_native and builtin.cpu.arch != bin_file.options.target.cpu.arch) {
799 @panic("Attempted to compile for architecture that was disabled by build configuration");
800 }
801
802 const mod = bin_file.options.module.?;
803 const func = mod.funcInfo(func_index);
804 const fn_owner_decl = mod.declPtr(func.owner_decl);
801 const comp = bin_file.comp;
802 const gpa = comp.gpa;
803 const zcu = comp.module.?;
804 const func = zcu.funcInfo(func_index);
805 const fn_owner_decl = zcu.declPtr(func.owner_decl);
805806 assert(fn_owner_decl.has_tv);
806807 const fn_type = fn_owner_decl.ty;
808 const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace);
809 const mod = namespace.file_scope.mod;
807810
808 const gpa = bin_file.allocator;
809811 var function = Self{
810812 .gpa = gpa,
811813 .air = air,
812814 .liveness = liveness,
813 .target = &bin_file.options.target,
815 .target = &mod.resolved_target.result,
816 .mod = mod,
814817 .bin_file = bin_file,
815818 .debug_output = debug_output,
816819 .owner = .{ .func_index = func_index },
......@@ -841,7 +844,7 @@ pub fn generate(
841844
842845 wip_mir_log.debug("{}:", .{function.fmtDecl(func.owner_decl)});
843846
844 const ip = &mod.intern_pool;
847 const ip = &zcu.intern_pool;
845848
846849 try function.frame_allocs.resize(gpa, FrameIndex.named_count);
847850 function.frame_allocs.set(
......@@ -856,13 +859,13 @@ pub fn generate(
856859 FrameAlloc.init(.{ .size = 0, .alignment = .@"1" }),
857860 );
858861
859 const fn_info = mod.typeToFunc(fn_type).?;
862 const fn_info = zcu.typeToFunc(fn_type).?;
860863 const cc = abi.resolveCallingConvention(fn_info.cc, function.target.*);
861864 var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) {
862865 error.CodegenFail => return Result{ .fail = function.err_msg.? },
863866 error.OutOfRegisters => return Result{
864867 .fail = try ErrorMsg.create(
865 bin_file.allocator,
868 gpa,
866869 src_loc,
867870 "CodeGen ran out of registers. This is a bug in the Zig compiler.",
868871 .{},
......@@ -875,14 +878,14 @@ pub fn generate(
875878 function.args = call_info.args;
876879 function.ret_mcv = call_info.return_value;
877880 function.frame_allocs.set(@intFromEnum(FrameIndex.ret_addr), FrameAlloc.init(.{
878 .size = Type.usize.abiSize(mod),
879 .alignment = Type.usize.abiAlignment(mod).min(call_info.stack_align),
881 .size = Type.usize.abiSize(zcu),
882 .alignment = Type.usize.abiAlignment(zcu).min(call_info.stack_align),
880883 }));
881884 function.frame_allocs.set(@intFromEnum(FrameIndex.base_ptr), FrameAlloc.init(.{
882 .size = Type.usize.abiSize(mod),
885 .size = Type.usize.abiSize(zcu),
883886 .alignment = Alignment.min(
884887 call_info.stack_align,
885 Alignment.fromNonzeroByteUnits(bin_file.options.target.stackAlignment()),
888 Alignment.fromNonzeroByteUnits(function.target.stackAlignment()),
886889 ),
887890 }));
888891 function.frame_allocs.set(
......@@ -906,25 +909,28 @@ pub fn generate(
906909 function.gen() catch |err| switch (err) {
907910 error.CodegenFail => return Result{ .fail = function.err_msg.? },
908911 error.OutOfRegisters => return Result{
909 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
912 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
910913 },
911914 else => |e| return e,
912915 };
913916
914917 var mir = Mir{
915918 .instructions = function.mir_instructions.toOwnedSlice(),
916 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
919 .extra = try function.mir_extra.toOwnedSlice(gpa),
917920 .frame_locs = function.frame_locs.toOwnedSlice(),
918921 };
919 defer mir.deinit(bin_file.allocator);
922 defer mir.deinit(gpa);
920923
921924 var emit = Emit{
922925 .lower = .{
923926 .bin_file = bin_file,
924 .allocator = bin_file.allocator,
927 .allocator = gpa,
925928 .mir = mir,
926929 .cc = cc,
927930 .src_loc = src_loc,
931 .output_mode = comp.config.output_mode,
932 .link_mode = comp.config.link_mode,
933 .pic = mod.pic,
928934 },
929935 .debug_output = debug_output,
930936 .code = code,
......@@ -942,7 +948,7 @@ pub fn generate(
942948 };
943949 return Result{
944950 .fail = try ErrorMsg.create(
945 bin_file.allocator,
951 gpa,
946952 src_loc,
947953 "{s} This is a bug in the Zig compiler.",
948954 .{msg},
......@@ -966,12 +972,16 @@ pub fn generateLazy(
966972 code: *std.ArrayList(u8),
967973 debug_output: DebugInfoOutput,
968974) CodeGenError!Result {
969 const gpa = bin_file.allocator;
975 const comp = bin_file.comp;
976 const gpa = comp.gpa;
977 // This function is for generating global code, so we use the root module.
978 const mod = comp.root_mod;
970979 var function = Self{
971980 .gpa = gpa,
972981 .air = undefined,
973982 .liveness = undefined,
974 .target = &bin_file.options.target,
983 .target = &mod.resolved_target.result,
984 .mod = mod,
975985 .bin_file = bin_file,
976986 .debug_output = debug_output,
977987 .owner = .{ .lazy_sym = lazy_sym },
......@@ -993,25 +1003,28 @@ pub fn generateLazy(
9931003 function.genLazy(lazy_sym) catch |err| switch (err) {
9941004 error.CodegenFail => return Result{ .fail = function.err_msg.? },
9951005 error.OutOfRegisters => return Result{
996 .fail = try ErrorMsg.create(bin_file.allocator, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
1006 .fail = try ErrorMsg.create(gpa, src_loc, "CodeGen ran out of registers. This is a bug in the Zig compiler.", .{}),
9971007 },
9981008 else => |e| return e,
9991009 };
10001010
10011011 var mir = Mir{
10021012 .instructions = function.mir_instructions.toOwnedSlice(),
1003 .extra = try function.mir_extra.toOwnedSlice(bin_file.allocator),
1013 .extra = try function.mir_extra.toOwnedSlice(gpa),
10041014 .frame_locs = function.frame_locs.toOwnedSlice(),
10051015 };
1006 defer mir.deinit(bin_file.allocator);
1016 defer mir.deinit(gpa);
10071017
10081018 var emit = Emit{
10091019 .lower = .{
10101020 .bin_file = bin_file,
1011 .allocator = bin_file.allocator,
1021 .allocator = gpa,
10121022 .mir = mir,
10131023 .cc = abi.resolveCallingConvention(.Unspecified, function.target.*),
10141024 .src_loc = src_loc,
1025 .output_mode = comp.config.output_mode,
1026 .link_mode = comp.config.link_mode,
1027 .pic = mod.pic,
10151028 },
10161029 .debug_output = debug_output,
10171030 .code = code,
......@@ -1029,7 +1042,7 @@ pub fn generateLazy(
10291042 };
10301043 return Result{
10311044 .fail = try ErrorMsg.create(
1032 bin_file.allocator,
1045 gpa,
10331046 src_loc,
10341047 "{s} This is a bug in the Zig compiler.",
10351048 .{msg},
......@@ -1060,7 +1073,7 @@ fn formatDecl(
10601073}
10611074fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
10621075 return .{ .data = .{
1063 .mod = self.bin_file.options.module.?,
1076 .mod = self.bin_file.comp.module.?,
10641077 .decl_index = decl_index,
10651078 } };
10661079}
......@@ -1077,7 +1090,7 @@ fn formatAir(
10771090) @TypeOf(writer).Error!void {
10781091 @import("../../print_air.zig").dumpInst(
10791092 data.inst,
1080 data.self.bin_file.options.module.?,
1093 data.self.bin_file.comp.module.?,
10811094 data.self.air,
10821095 data.self.liveness,
10831096 );
......@@ -1096,6 +1109,8 @@ fn formatWipMir(
10961109 _: std.fmt.FormatOptions,
10971110 writer: anytype,
10981111) @TypeOf(writer).Error!void {
1112 const comp = data.self.bin_file.comp;
1113 const mod = comp.root_mod;
10991114 var lower = Lower{
11001115 .bin_file = data.self.bin_file,
11011116 .allocator = data.self.gpa,
......@@ -1106,6 +1121,9 @@ fn formatWipMir(
11061121 },
11071122 .cc = .Unspecified,
11081123 .src_loc = data.self.src_loc,
1124 .output_mode = comp.config.output_mode,
1125 .link_mode = comp.config.link_mode,
1126 .pic = mod.pic,
11091127 };
11101128 var first = true;
11111129 for ((lower.lowerMir(data.inst) catch |err| switch (err) {
......@@ -1683,7 +1701,7 @@ fn asmMemoryRegisterImmediate(
16831701}
16841702
16851703fn gen(self: *Self) InnerError!void {
1686 const mod = self.bin_file.options.module.?;
1704 const mod = self.bin_file.comp.module.?;
16871705 const fn_info = mod.typeToFunc(self.fn_type).?;
16881706 const cc = abi.resolveCallingConvention(fn_info.cc, self.target.*);
16891707 if (cc != .Naked) {
......@@ -1885,7 +1903,7 @@ fn gen(self: *Self) InnerError!void {
18851903}
18861904
18871905fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
1888 const mod = self.bin_file.options.module.?;
1906 const mod = self.bin_file.comp.module.?;
18891907 const ip = &mod.intern_pool;
18901908 const air_tags = self.air.instructions.items(.tag);
18911909
......@@ -2167,7 +2185,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
21672185}
21682186
21692187fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
2170 const mod = self.bin_file.options.module.?;
2188 const mod = self.bin_file.comp.module.?;
21712189 switch (lazy_sym.ty.zigTypeTag(mod)) {
21722190 .Enum => {
21732191 const enum_ty = lazy_sym.ty;
......@@ -2418,7 +2436,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex {
24182436
24192437/// Use a pointer instruction as the basis for allocating stack memory.
24202438fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex {
2421 const mod = self.bin_file.options.module.?;
2439 const mod = self.bin_file.comp.module.?;
24222440 const ptr_ty = self.typeOfIndex(inst);
24232441 const val_ty = ptr_ty.childType(mod);
24242442 return self.allocFrameIndex(FrameAlloc.init(.{
......@@ -2438,7 +2456,7 @@ fn allocTempRegOrMem(self: *Self, elem_ty: Type, reg_ok: bool) !MCValue {
24382456}
24392457
24402458fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: bool) !MCValue {
2441 const mod = self.bin_file.options.module.?;
2459 const mod = self.bin_file.comp.module.?;
24422460 const abi_size = math.cast(u32, ty.abiSize(mod)) orelse {
24432461 return self.fail("type '{}' too big to fit into stack frame", .{ty.fmt(mod)});
24442462 };
......@@ -2471,7 +2489,7 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b
24712489}
24722490
24732491fn regClassForType(self: *Self, ty: Type) RegisterManager.RegisterBitSet {
2474 const mod = self.bin_file.options.module.?;
2492 const mod = self.bin_file.comp.module.?;
24752493 return switch (ty.zigTypeTag(mod)) {
24762494 .Float => switch (ty.floatBits(self.target.*)) {
24772495 80 => abi.RegisterClass.x87,
......@@ -2884,7 +2902,7 @@ fn airFpext(self: *Self, inst: Air.Inst.Index) !void {
28842902}
28852903
28862904fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
2887 const mod = self.bin_file.options.module.?;
2905 const mod = self.bin_file.comp.module.?;
28882906 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
28892907 const result: MCValue = result: {
28902908 const src_ty = self.typeOf(ty_op.operand);
......@@ -2975,7 +2993,7 @@ fn airIntCast(self: *Self, inst: Air.Inst.Index) !void {
29752993}
29762994
29772995fn airTrunc(self: *Self, inst: Air.Inst.Index) !void {
2978 const mod = self.bin_file.options.module.?;
2996 const mod = self.bin_file.comp.module.?;
29792997 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
29802998
29812999 const dst_ty = self.typeOfIndex(inst);
......@@ -3102,7 +3120,7 @@ fn airIntFromBool(self: *Self, inst: Air.Inst.Index) !void {
31023120}
31033121
31043122fn airSlice(self: *Self, inst: Air.Inst.Index) !void {
3105 const mod = self.bin_file.options.module.?;
3123 const mod = self.bin_file.comp.module.?;
31063124 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
31073125 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
31083126
......@@ -3131,7 +3149,7 @@ fn airUnOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
31313149}
31323150
31333151fn airBinOp(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void {
3134 const mod = self.bin_file.options.module.?;
3152 const mod = self.bin_file.comp.module.?;
31353153 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
31363154 const dst_mcv = try self.genBinOp(inst, tag, bin_op.lhs, bin_op.rhs);
31373155
......@@ -3172,7 +3190,7 @@ fn airPtrArithmetic(self: *Self, inst: Air.Inst.Index, tag: Air.Inst.Tag) !void
31723190}
31733191
31743192fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
3175 const mod = self.bin_file.options.module.?;
3193 const mod = self.bin_file.comp.module.?;
31763194 const air_tag = self.air.instructions.items(.tag);
31773195 const air_data = self.air.instructions.items(.data);
31783196
......@@ -3206,7 +3224,7 @@ fn activeIntBits(self: *Self, dst_air: Air.Inst.Ref) u16 {
32063224}
32073225
32083226fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
3209 const mod = self.bin_file.options.module.?;
3227 const mod = self.bin_file.comp.module.?;
32103228 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
32113229 const result = result: {
32123230 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
......@@ -3432,7 +3450,7 @@ fn airMulDivBinOp(self: *Self, inst: Air.Inst.Index) !void {
34323450}
34333451
34343452fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
3435 const mod = self.bin_file.options.module.?;
3453 const mod = self.bin_file.comp.module.?;
34363454 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
34373455 const ty = self.typeOf(bin_op.lhs);
34383456 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(
......@@ -3515,7 +3533,7 @@ fn airAddSat(self: *Self, inst: Air.Inst.Index) !void {
35153533}
35163534
35173535fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
3518 const mod = self.bin_file.options.module.?;
3536 const mod = self.bin_file.comp.module.?;
35193537 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
35203538 const ty = self.typeOf(bin_op.lhs);
35213539 if (ty.zigTypeTag(mod) == .Vector or ty.abiSize(mod) > 8) return self.fail(
......@@ -3591,7 +3609,7 @@ fn airSubSat(self: *Self, inst: Air.Inst.Index) !void {
35913609}
35923610
35933611fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
3594 const mod = self.bin_file.options.module.?;
3612 const mod = self.bin_file.comp.module.?;
35953613 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
35963614 const ty = self.typeOf(bin_op.lhs);
35973615
......@@ -3731,7 +3749,7 @@ fn airMulSat(self: *Self, inst: Air.Inst.Index) !void {
37313749}
37323750
37333751fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3734 const mod = self.bin_file.options.module.?;
3752 const mod = self.bin_file.comp.module.?;
37353753 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
37363754 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
37373755 const result: MCValue = result: {
......@@ -3792,7 +3810,7 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
37923810}
37933811
37943812fn airShlWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3795 const mod = self.bin_file.options.module.?;
3813 const mod = self.bin_file.comp.module.?;
37963814 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
37973815 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
37983816 const result: MCValue = result: {
......@@ -3871,7 +3889,7 @@ fn genSetFrameTruncatedOverflowCompare(
38713889 src_mcv: MCValue,
38723890 overflow_cc: ?Condition,
38733891) !void {
3874 const mod = self.bin_file.options.module.?;
3892 const mod = self.bin_file.comp.module.?;
38753893 const src_lock = switch (src_mcv) {
38763894 .register => |reg| self.register_manager.lockReg(reg),
38773895 else => null,
......@@ -3935,7 +3953,7 @@ fn genSetFrameTruncatedOverflowCompare(
39353953}
39363954
39373955fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
3938 const mod = self.bin_file.options.module.?;
3956 const mod = self.bin_file.comp.module.?;
39393957 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
39403958 const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data;
39413959 const tuple_ty = self.typeOfIndex(inst);
......@@ -4169,7 +4187,7 @@ fn airMulWithOverflow(self: *Self, inst: Air.Inst.Index) !void {
41694187/// Clobbers .rax and .rdx registers.
41704188/// Quotient is saved in .rax and remainder in .rdx.
41714189fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue, rhs: MCValue) !void {
4172 const mod = self.bin_file.options.module.?;
4190 const mod = self.bin_file.comp.module.?;
41734191 const abi_size: u32 = @intCast(ty.abiSize(mod));
41744192 const bit_size: u32 = @intCast(self.regBitSize(ty));
41754193 if (abi_size > 8) {
......@@ -4219,7 +4237,7 @@ fn genIntMulDivOpMir(self: *Self, tag: Mir.Inst.FixedTag, ty: Type, lhs: MCValue
42194237/// Always returns a register.
42204238/// Clobbers .rax and .rdx registers.
42214239fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCValue {
4222 const mod = self.bin_file.options.module.?;
4240 const mod = self.bin_file.comp.module.?;
42234241 const abi_size: u32 = @intCast(ty.abiSize(mod));
42244242 const int_info = ty.intInfo(mod);
42254243 const dividend = switch (lhs) {
......@@ -4271,7 +4289,7 @@ fn genInlineIntDivFloor(self: *Self, ty: Type, lhs: MCValue, rhs: MCValue) !MCVa
42714289}
42724290
42734291fn airShlShrBinOp(self: *Self, inst: Air.Inst.Index) !void {
4274 const mod = self.bin_file.options.module.?;
4292 const mod = self.bin_file.comp.module.?;
42754293 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
42764294
42774295 const air_tags = self.air.instructions.items(.tag);
......@@ -4546,7 +4564,7 @@ fn airShlSat(self: *Self, inst: Air.Inst.Index) !void {
45464564}
45474565
45484566fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void {
4549 const mod = self.bin_file.options.module.?;
4567 const mod = self.bin_file.comp.module.?;
45504568 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45514569 const result: MCValue = result: {
45524570 const pl_ty = self.typeOfIndex(inst);
......@@ -4592,7 +4610,7 @@ fn airOptionalPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
45924610}
45934611
45944612fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
4595 const mod = self.bin_file.options.module.?;
4613 const mod = self.bin_file.comp.module.?;
45964614 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
45974615 const result = result: {
45984616 const dst_ty = self.typeOfIndex(inst);
......@@ -4626,7 +4644,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
46264644}
46274645
46284646fn airUnwrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
4629 const mod = self.bin_file.options.module.?;
4647 const mod = self.bin_file.comp.module.?;
46304648 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46314649 const err_union_ty = self.typeOf(ty_op.operand);
46324650 const err_ty = err_union_ty.errorUnionSet(mod);
......@@ -4678,7 +4696,7 @@ fn airUnwrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
46784696
46794697// *(E!T) -> E
46804698fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4681 const mod = self.bin_file.options.module.?;
4699 const mod = self.bin_file.comp.module.?;
46824700 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
46834701
46844702 const src_ty = self.typeOf(ty_op.operand);
......@@ -4725,7 +4743,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void {
47254743}
47264744
47274745fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
4728 const mod = self.bin_file.options.module.?;
4746 const mod = self.bin_file.comp.module.?;
47294747 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
47304748 const result: MCValue = result: {
47314749 const src_ty = self.typeOf(ty_op.operand);
......@@ -4785,7 +4803,7 @@ fn genUnwrapErrUnionPayloadMir(
47854803 err_union_ty: Type,
47864804 err_union: MCValue,
47874805) !MCValue {
4788 const mod = self.bin_file.options.module.?;
4806 const mod = self.bin_file.comp.module.?;
47894807 const payload_ty = err_union_ty.errorUnionPayload(mod);
47904808
47914809 const result: MCValue = result: {
......@@ -4833,7 +4851,7 @@ fn genUnwrapErrUnionPayloadPtrMir(
48334851 ptr_ty: Type,
48344852 ptr_mcv: MCValue,
48354853) !MCValue {
4836 const mod = self.bin_file.options.module.?;
4854 const mod = self.bin_file.comp.module.?;
48374855 const err_union_ty = ptr_ty.childType(mod);
48384856 const payload_ty = err_union_ty.errorUnionPayload(mod);
48394857
......@@ -4867,7 +4885,7 @@ fn airSaveErrReturnTraceIndex(self: *Self, inst: Air.Inst.Index) !void {
48674885}
48684886
48694887fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
4870 const mod = self.bin_file.options.module.?;
4888 const mod = self.bin_file.comp.module.?;
48714889 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
48724890 const result: MCValue = result: {
48734891 const pl_ty = self.typeOf(ty_op.operand);
......@@ -4921,7 +4939,7 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) !void {
49214939
49224940/// T to E!T
49234941fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
4924 const mod = self.bin_file.options.module.?;
4942 const mod = self.bin_file.comp.module.?;
49254943 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
49264944
49274945 const eu_ty = ty_op.ty.toType();
......@@ -4944,7 +4962,7 @@ fn airWrapErrUnionPayload(self: *Self, inst: Air.Inst.Index) !void {
49444962
49454963/// E to E!T
49464964fn airWrapErrUnionErr(self: *Self, inst: Air.Inst.Index) !void {
4947 const mod = self.bin_file.options.module.?;
4965 const mod = self.bin_file.comp.module.?;
49484966 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
49494967
49504968 const eu_ty = ty_op.ty.toType();
......@@ -5003,7 +5021,7 @@ fn airSliceLen(self: *Self, inst: Air.Inst.Index) !void {
50035021}
50045022
50055023fn airPtrSliceLenPtr(self: *Self, inst: Air.Inst.Index) !void {
5006 const mod = self.bin_file.options.module.?;
5024 const mod = self.bin_file.comp.module.?;
50075025 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
50085026
50095027 const src_ty = self.typeOf(ty_op.operand);
......@@ -5071,7 +5089,7 @@ fn elemOffset(self: *Self, index_ty: Type, index: MCValue, elem_size: u64) !Regi
50715089}
50725090
50735091fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
5074 const mod = self.bin_file.options.module.?;
5092 const mod = self.bin_file.comp.module.?;
50755093 const slice_ty = self.typeOf(lhs);
50765094 const slice_mcv = try self.resolveInst(lhs);
50775095 const slice_mcv_lock: ?RegisterLock = switch (slice_mcv) {
......@@ -5107,7 +5125,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
51075125}
51085126
51095127fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
5110 const mod = self.bin_file.options.module.?;
5128 const mod = self.bin_file.comp.module.?;
51115129 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
51125130
51135131 const result: MCValue = result: {
......@@ -5132,7 +5150,7 @@ fn airSliceElemPtr(self: *Self, inst: Air.Inst.Index) !void {
51325150}
51335151
51345152fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
5135 const mod = self.bin_file.options.module.?;
5153 const mod = self.bin_file.comp.module.?;
51365154 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
51375155
51385156 const result: MCValue = result: {
......@@ -5246,7 +5264,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
52465264}
52475265
52485266fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
5249 const mod = self.bin_file.options.module.?;
5267 const mod = self.bin_file.comp.module.?;
52505268 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
52515269 const ptr_ty = self.typeOf(bin_op.lhs);
52525270
......@@ -5296,7 +5314,7 @@ fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
52965314}
52975315
52985316fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
5299 const mod = self.bin_file.options.module.?;
5317 const mod = self.bin_file.comp.module.?;
53005318 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
53015319 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
53025320
......@@ -5341,7 +5359,7 @@ fn airPtrElemPtr(self: *Self, inst: Air.Inst.Index) !void {
53415359}
53425360
53435361fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5344 const mod = self.bin_file.options.module.?;
5362 const mod = self.bin_file.comp.module.?;
53455363 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
53465364 const ptr_union_ty = self.typeOf(bin_op.lhs);
53475365 const union_ty = ptr_union_ty.childType(mod);
......@@ -5385,7 +5403,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
53855403}
53865404
53875405fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
5388 const mod = self.bin_file.options.module.?;
5406 const mod = self.bin_file.comp.module.?;
53895407 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
53905408
53915409 const tag_ty = self.typeOfIndex(inst);
......@@ -5439,7 +5457,7 @@ fn airGetUnionTag(self: *Self, inst: Air.Inst.Index) !void {
54395457}
54405458
54415459fn airClz(self: *Self, inst: Air.Inst.Index) !void {
5442 const mod = self.bin_file.options.module.?;
5460 const mod = self.bin_file.comp.module.?;
54435461 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
54445462 const result = result: {
54455463 const dst_ty = self.typeOfIndex(inst);
......@@ -5598,7 +5616,7 @@ fn airClz(self: *Self, inst: Air.Inst.Index) !void {
55985616}
55995617
56005618fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
5601 const mod = self.bin_file.options.module.?;
5619 const mod = self.bin_file.comp.module.?;
56025620 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
56035621 const result = result: {
56045622 const dst_ty = self.typeOfIndex(inst);
......@@ -5716,7 +5734,7 @@ fn airCtz(self: *Self, inst: Air.Inst.Index) !void {
57165734}
57175735
57185736fn airPopCount(self: *Self, inst: Air.Inst.Index) !void {
5719 const mod = self.bin_file.options.module.?;
5737 const mod = self.bin_file.comp.module.?;
57205738 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
57215739 const result: MCValue = result: {
57225740 try self.spillEflagsIfOccupied();
......@@ -5779,7 +5797,7 @@ fn genPopCount(
57795797 src_mcv: MCValue,
57805798 dst_contains_src: bool,
57815799) !void {
5782 const mod = self.bin_file.options.module.?;
5800 const mod = self.bin_file.comp.module.?;
57835801
57845802 const src_abi_size: u32 = @intCast(src_ty.abiSize(mod));
57855803 if (self.hasFeature(.popcnt)) return self.genBinOpMir(
......@@ -5871,7 +5889,7 @@ fn genByteSwap(
58715889 src_mcv: MCValue,
58725890 mem_ok: bool,
58735891) !MCValue {
5874 const mod = self.bin_file.options.module.?;
5892 const mod = self.bin_file.comp.module.?;
58755893 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
58765894
58775895 if (src_ty.zigTypeTag(mod) == .Vector) return self.fail(
......@@ -5962,7 +5980,7 @@ fn genByteSwap(
59625980}
59635981
59645982fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
5965 const mod = self.bin_file.options.module.?;
5983 const mod = self.bin_file.comp.module.?;
59665984 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59675985
59685986 const src_ty = self.typeOf(ty_op.operand);
......@@ -5984,7 +6002,7 @@ fn airByteSwap(self: *Self, inst: Air.Inst.Index) !void {
59846002}
59856003
59866004fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
5987 const mod = self.bin_file.options.module.?;
6005 const mod = self.bin_file.comp.module.?;
59886006 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
59896007
59906008 const src_ty = self.typeOf(ty_op.operand);
......@@ -6106,7 +6124,7 @@ fn airBitReverse(self: *Self, inst: Air.Inst.Index) !void {
61066124}
61076125
61086126fn floatSign(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, ty: Type) !void {
6109 const mod = self.bin_file.options.module.?;
6127 const mod = self.bin_file.comp.module.?;
61106128 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
61116129
61126130 const result = result: {
......@@ -6282,7 +6300,7 @@ fn airRound(self: *Self, inst: Air.Inst.Index, mode: RoundMode) !void {
62826300}
62836301
62846302fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag {
6285 const mod = self.bin_file.options.module.?;
6303 const mod = self.bin_file.comp.module.?;
62866304 return if (self.hasFeature(.sse4_1)) switch (ty.zigTypeTag(mod)) {
62876305 .Float => switch (ty.floatBits(self.target.*)) {
62886306 32 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round },
......@@ -6314,7 +6332,7 @@ fn getRoundTag(self: *Self, ty: Type) ?Mir.Inst.FixedTag {
63146332}
63156333
63166334fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MCValue {
6317 const mod = self.bin_file.options.module.?;
6335 const mod = self.bin_file.comp.module.?;
63186336 if (self.getRoundTag(ty)) |_| return .none;
63196337
63206338 if (ty.zigTypeTag(mod) != .Float)
......@@ -6338,7 +6356,7 @@ fn genRoundLibcall(self: *Self, ty: Type, src_mcv: MCValue, mode: RoundMode) !MC
63386356}
63396357
63406358fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: RoundMode) !void {
6341 const mod = self.bin_file.options.module.?;
6359 const mod = self.bin_file.comp.module.?;
63426360 const mir_tag = self.getRoundTag(ty) orelse {
63436361 const result = try self.genRoundLibcall(ty, src_mcv, mode);
63446362 return self.genSetReg(dst_reg, ty, result);
......@@ -6380,7 +6398,7 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: Ro
63806398}
63816399
63826400fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
6383 const mod = self.bin_file.options.module.?;
6401 const mod = self.bin_file.comp.module.?;
63846402 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
63856403 const ty = self.typeOf(ty_op.operand);
63866404
......@@ -6520,7 +6538,7 @@ fn airAbs(self: *Self, inst: Air.Inst.Index) !void {
65206538}
65216539
65226540fn airSqrt(self: *Self, inst: Air.Inst.Index) !void {
6523 const mod = self.bin_file.options.module.?;
6541 const mod = self.bin_file.comp.module.?;
65246542 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
65256543 const ty = self.typeOf(un_op);
65266544 const abi_size: u32 = @intCast(ty.abiSize(mod));
......@@ -6765,7 +6783,7 @@ fn reuseOperandAdvanced(
67656783}
67666784
67676785fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {
6768 const mod = self.bin_file.options.module.?;
6786 const mod = self.bin_file.comp.module.?;
67696787
67706788 const ptr_info = ptr_ty.ptrInfo(mod);
67716789 const val_ty = Type.fromInterned(ptr_info.child);
......@@ -6864,7 +6882,7 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn
68646882}
68656883
68666884fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void {
6867 const mod = self.bin_file.options.module.?;
6885 const mod = self.bin_file.comp.module.?;
68686886 const dst_ty = ptr_ty.childType(mod);
68696887 if (!dst_ty.hasRuntimeBitsIgnoreComptime(mod)) return;
68706888 switch (ptr_mcv) {
......@@ -6905,7 +6923,7 @@ fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerErro
69056923}
69066924
69076925fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
6908 const mod = self.bin_file.options.module.?;
6926 const mod = self.bin_file.comp.module.?;
69096927 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
69106928 const elem_ty = self.typeOfIndex(inst);
69116929 const result: MCValue = result: {
......@@ -6962,7 +6980,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void {
69626980}
69636981
69646982fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {
6965 const mod = self.bin_file.options.module.?;
6983 const mod = self.bin_file.comp.module.?;
69666984 const ptr_info = ptr_ty.ptrInfo(mod);
69676985 const src_ty = Type.fromInterned(ptr_info.child);
69686986 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return;
......@@ -7059,7 +7077,7 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In
70597077}
70607078
70617079fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void {
7062 const mod = self.bin_file.options.module.?;
7080 const mod = self.bin_file.comp.module.?;
70637081 const src_ty = ptr_ty.childType(mod);
70647082 if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) return;
70657083 switch (ptr_mcv) {
......@@ -7100,7 +7118,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr
71007118}
71017119
71027120fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
7103 const mod = self.bin_file.options.module.?;
7121 const mod = self.bin_file.comp.module.?;
71047122 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
71057123
71067124 result: {
......@@ -7138,7 +7156,7 @@ fn airStructFieldPtrIndex(self: *Self, inst: Air.Inst.Index, index: u8) !void {
71387156}
71397157
71407158fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32) !MCValue {
7141 const mod = self.bin_file.options.module.?;
7159 const mod = self.bin_file.comp.module.?;
71427160 const ptr_field_ty = self.typeOfIndex(inst);
71437161 const ptr_container_ty = self.typeOf(operand);
71447162 const ptr_container_ty_info = ptr_container_ty.ptrInfo(mod);
......@@ -7163,7 +7181,7 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32
71637181}
71647182
71657183fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
7166 const mod = self.bin_file.options.module.?;
7184 const mod = self.bin_file.comp.module.?;
71677185 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
71687186 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
71697187 const result: MCValue = result: {
......@@ -7451,7 +7469,7 @@ fn airStructFieldVal(self: *Self, inst: Air.Inst.Index) !void {
74517469}
74527470
74537471fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
7454 const mod = self.bin_file.options.module.?;
7472 const mod = self.bin_file.comp.module.?;
74557473 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
74567474 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
74577475
......@@ -7470,7 +7488,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
74707488}
74717489
74727490fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air: Air.Inst.Ref) !MCValue {
7473 const mod = self.bin_file.options.module.?;
7491 const mod = self.bin_file.comp.module.?;
74747492 const src_ty = self.typeOf(src_air);
74757493 if (src_ty.zigTypeTag(mod) == .Vector)
74767494 return self.fail("TODO implement genUnOp for {}", .{src_ty.fmt(mod)});
......@@ -7558,7 +7576,7 @@ fn genUnOp(self: *Self, maybe_inst: ?Air.Inst.Index, tag: Air.Inst.Tag, src_air:
75587576}
75597577
75607578fn genUnOpMir(self: *Self, mir_tag: Mir.Inst.FixedTag, dst_ty: Type, dst_mcv: MCValue) !void {
7561 const mod = self.bin_file.options.module.?;
7579 const mod = self.bin_file.comp.module.?;
75627580 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));
75637581 if (abi_size > 8) return self.fail("TODO implement {} for {}", .{ mir_tag, dst_ty.fmt(mod) });
75647582 switch (dst_mcv) {
......@@ -7605,7 +7623,7 @@ fn genShiftBinOpMir(
76057623 lhs_mcv: MCValue,
76067624 shift_mcv: MCValue,
76077625) !void {
7608 const mod = self.bin_file.options.module.?;
7626 const mod = self.bin_file.comp.module.?;
76097627 const rhs_mcv: MCValue = rhs: {
76107628 switch (shift_mcv) {
76117629 .immediate => |imm| switch (imm) {
......@@ -7975,7 +7993,7 @@ fn genShiftBinOp(
79757993 lhs_ty: Type,
79767994 rhs_ty: Type,
79777995) !MCValue {
7978 const mod = self.bin_file.options.module.?;
7996 const mod = self.bin_file.comp.module.?;
79797997 if (lhs_ty.zigTypeTag(mod) == .Vector) return self.fail("TODO implement genShiftBinOp for {}", .{
79807998 lhs_ty.fmt(mod),
79817999 });
......@@ -8041,7 +8059,7 @@ fn genMulDivBinOp(
80418059 lhs_mcv: MCValue,
80428060 rhs_mcv: MCValue,
80438061) !MCValue {
8044 const mod = self.bin_file.options.module.?;
8062 const mod = self.bin_file.comp.module.?;
80458063 if (dst_ty.zigTypeTag(mod) == .Vector or dst_ty.zigTypeTag(mod) == .Float) return self.fail(
80468064 "TODO implement genMulDivBinOp for {s} from {} to {}",
80478065 .{ @tagName(tag), src_ty.fmt(mod), dst_ty.fmt(mod) },
......@@ -8283,7 +8301,7 @@ fn genBinOp(
82838301 lhs_air: Air.Inst.Ref,
82848302 rhs_air: Air.Inst.Ref,
82858303) !MCValue {
8286 const mod = self.bin_file.options.module.?;
8304 const mod = self.bin_file.comp.module.?;
82878305 const lhs_ty = self.typeOf(lhs_air);
82888306 const rhs_ty = self.typeOf(rhs_air);
82898307 const abi_size: u32 = @intCast(lhs_ty.abiSize(mod));
......@@ -10015,7 +10033,7 @@ fn genBinOpMir(
1001510033 dst_mcv: MCValue,
1001610034 src_mcv: MCValue,
1001710035) !void {
10018 const mod = self.bin_file.options.module.?;
10036 const mod = self.bin_file.comp.module.?;
1001910037 const abi_size: u32 = @intCast(ty.abiSize(mod));
1002010038 try self.spillEflagsIfOccupied();
1002110039 switch (dst_mcv) {
......@@ -10435,7 +10453,7 @@ fn genBinOpMir(
1043510453/// Performs multi-operand integer multiplication between dst_mcv and src_mcv, storing the result in dst_mcv.
1043610454/// Does not support byte-size operands.
1043710455fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
10438 const mod = self.bin_file.options.module.?;
10456 const mod = self.bin_file.comp.module.?;
1043910457 const abi_size: u32 = @intCast(dst_ty.abiSize(mod));
1044010458 try self.spillEflagsIfOccupied();
1044110459 switch (dst_mcv) {
......@@ -10560,7 +10578,7 @@ fn genIntMulComplexOpMir(self: *Self, dst_ty: Type, dst_mcv: MCValue, src_mcv: M
1056010578}
1056110579
1056210580fn airArg(self: *Self, inst: Air.Inst.Index) !void {
10563 const mod = self.bin_file.options.module.?;
10581 const mod = self.bin_file.comp.module.?;
1056410582 // skip zero-bit arguments as they don't have a corresponding arg instruction
1056510583 var arg_index = self.arg_index;
1056610584 while (self.args[arg_index] == .none) arg_index += 1;
......@@ -10593,7 +10611,7 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
1059310611}
1059410612
1059510613fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
10596 const mod = self.bin_file.options.module.?;
10614 const mod = self.bin_file.comp.module.?;
1059710615 switch (self.debug_output) {
1059810616 .dwarf => |dw| {
1059910617 const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
......@@ -10629,7 +10647,7 @@ fn genVarDbgInfo(
1062910647 mcv: MCValue,
1063010648 name: [:0]const u8,
1063110649) !void {
10632 const mod = self.bin_file.options.module.?;
10650 const mod = self.bin_file.comp.module.?;
1063310651 const is_ptr = switch (tag) {
1063410652 .dbg_var_ptr => true,
1063510653 .dbg_var_val => false,
......@@ -10748,7 +10766,7 @@ fn genCall(self: *Self, info: union(enum) {
1074810766 callee: []const u8,
1074910767 },
1075010768}, arg_types: []const Type, args: []const MCValue) !MCValue {
10751 const mod = self.bin_file.options.module.?;
10769 const mod = self.bin_file.comp.module.?;
1075210770
1075310771 const fn_ty = switch (info) {
1075410772 .air => |callee| fn_info: {
......@@ -10901,7 +10919,7 @@ fn genCall(self: *Self, info: union(enum) {
1090110919 if (self.bin_file.cast(link.File.Elf)) |elf_file| {
1090210920 const sym_index = try elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, func.owner_decl);
1090310921 const sym = elf_file.symbol(sym_index);
10904 if (self.bin_file.options.pic) {
10922 if (self.mod.pic) {
1090510923 const callee_reg: Register = switch (resolved_cc) {
1090610924 .SysV => callee: {
1090710925 if (!fn_info.is_var_args) break :callee .rax;
......@@ -10969,7 +10987,7 @@ fn genCall(self: *Self, info: union(enum) {
1096910987}
1097010988
1097110989fn airRet(self: *Self, inst: Air.Inst.Index) !void {
10972 const mod = self.bin_file.options.module.?;
10990 const mod = self.bin_file.comp.module.?;
1097310991 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1097410992
1097510993 const ret_ty = self.fn_type.fnReturnType(mod);
......@@ -11018,7 +11036,7 @@ fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
1101811036}
1101911037
1102011038fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
11021 const mod = self.bin_file.options.module.?;
11039 const mod = self.bin_file.comp.module.?;
1102211040 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1102311041 const ty = self.typeOf(bin_op.lhs);
1102411042
......@@ -11412,7 +11430,7 @@ fn airCmpVector(self: *Self, inst: Air.Inst.Index) !void {
1141211430}
1141311431
1141411432fn airCmpLtErrorsLen(self: *Self, inst: Air.Inst.Index) !void {
11415 const mod = self.bin_file.options.module.?;
11433 const mod = self.bin_file.comp.module.?;
1141611434 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1141711435
1141811436 const addr_reg = try self.register_manager.allocReg(null, abi.RegisterClass.gp);
......@@ -11551,7 +11569,7 @@ fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
1155111569}
1155211570
1155311571fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !Mir.Inst.Index {
11554 const mod = self.bin_file.options.module.?;
11572 const mod = self.bin_file.comp.module.?;
1155511573 const abi_size = ty.abiSize(mod);
1155611574 switch (mcv) {
1155711575 .eflags => |cc| {
......@@ -11624,7 +11642,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
1162411642}
1162511643
1162611644fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
11627 const mod = self.bin_file.options.module.?;
11645 const mod = self.bin_file.comp.module.?;
1162811646 switch (opt_mcv) {
1162911647 .register_overflow => |ro| return .{ .eflags = ro.eflags.negate() },
1163011648 else => {},
......@@ -11732,7 +11750,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
1173211750}
1173311751
1173411752fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {
11735 const mod = self.bin_file.options.module.?;
11753 const mod = self.bin_file.comp.module.?;
1173611754 const opt_ty = ptr_ty.childType(mod);
1173711755 const pl_ty = opt_ty.optionalChild(mod);
1173811756
......@@ -11768,7 +11786,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
1176811786}
1176911787
1177011788fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue) !MCValue {
11771 const mod = self.bin_file.options.module.?;
11789 const mod = self.bin_file.comp.module.?;
1177211790 const err_ty = eu_ty.errorUnionSet(mod);
1177311791 if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false
1177411792
......@@ -11815,7 +11833,7 @@ fn isErr(self: *Self, maybe_inst: ?Air.Inst.Index, eu_ty: Type, eu_mcv: MCValue)
1181511833}
1181611834
1181711835fn isErrPtr(self: *Self, maybe_inst: ?Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) !MCValue {
11818 const mod = self.bin_file.options.module.?;
11836 const mod = self.bin_file.comp.module.?;
1181911837 const eu_ty = ptr_ty.childType(mod);
1182011838 const err_ty = eu_ty.errorUnionSet(mod);
1182111839 if (err_ty.errorSetIsEmpty(mod)) return MCValue{ .immediate = 0 }; // always false
......@@ -12097,7 +12115,7 @@ fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
1209712115}
1209812116
1209912117fn airBr(self: *Self, inst: Air.Inst.Index) !void {
12100 const mod = self.bin_file.options.module.?;
12118 const mod = self.bin_file.comp.module.?;
1210112119 const br = self.air.instructions.items(.data)[@intFromEnum(inst)].br;
1210212120
1210312121 const block_ty = self.typeOfIndex(br.block_inst);
......@@ -12158,7 +12176,7 @@ fn airBr(self: *Self, inst: Air.Inst.Index) !void {
1215812176}
1215912177
1216012178fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
12161 const mod = self.bin_file.options.module.?;
12179 const mod = self.bin_file.comp.module.?;
1216212180 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1216312181 const extra = self.air.extraData(Air.Asm, ty_pl.payload);
1216412182 const clobbers_len: u31 = @truncate(extra.data.flags);
......@@ -12865,7 +12883,7 @@ const MoveStrategy = union(enum) {
1286512883 }
1286612884};
1286712885fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !MoveStrategy {
12868 const mod = self.bin_file.options.module.?;
12886 const mod = self.bin_file.comp.module.?;
1286912887 switch (class) {
1287012888 .general_purpose, .segment => return .{ .move = .{ ._, .mov } },
1287112889 .x87 => return .x87_load_store,
......@@ -13164,7 +13182,7 @@ fn moveStrategy(self: *Self, ty: Type, class: Register.Class, aligned: bool) !Mo
1316413182}
1316513183
1316613184fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError!void {
13167 const mod = self.bin_file.options.module.?;
13185 const mod = self.bin_file.comp.module.?;
1316813186
1316913187 const src_lock = if (src_mcv.getReg()) |reg| self.register_manager.lockReg(reg) else null;
1317013188 defer if (src_lock) |lock| self.register_manager.unlockReg(lock);
......@@ -13262,7 +13280,7 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) InnerError
1326213280}
1326313281
1326413282fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerError!void {
13265 const mod = self.bin_file.options.module.?;
13283 const mod = self.bin_file.comp.module.?;
1326613284 const abi_size: u32 = @intCast(ty.abiSize(mod));
1326713285 if (ty.bitSize(mod) > dst_reg.bitSize())
1326813286 return self.fail("genSetReg called with a value larger than dst_reg", .{});
......@@ -13561,7 +13579,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1356113579}
1356213580
1356313581fn genSetMem(self: *Self, base: Memory.Base, disp: i32, ty: Type, src_mcv: MCValue) InnerError!void {
13564 const mod = self.bin_file.options.module.?;
13582 const mod = self.bin_file.comp.module.?;
1356513583 const abi_size: u32 = @intCast(ty.abiSize(mod));
1356613584 const dst_ptr_mcv: MCValue = switch (base) {
1356713585 .none => .{ .immediate = @bitCast(@as(i64, disp)) },
......@@ -13814,7 +13832,7 @@ fn genLazySymbolRef(
1381413832 const sym_index = elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|
1381513833 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
1381613834 const sym = elf_file.symbol(sym_index);
13817 if (self.bin_file.options.pic) {
13835 if (self.mod.pic) {
1381813836 switch (tag) {
1381913837 .lea, .call => try self.genSetReg(reg, Type.usize, .{
1382013838 .load_symbol = .{ .sym = sym.esym_index },
......@@ -13922,7 +13940,7 @@ fn airIntFromPtr(self: *Self, inst: Air.Inst.Index) !void {
1392213940}
1392313941
1392413942fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
13925 const mod = self.bin_file.options.module.?;
13943 const mod = self.bin_file.comp.module.?;
1392613944 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1392713945 const dst_ty = self.typeOfIndex(inst);
1392813946 const src_ty = self.typeOf(ty_op.operand);
......@@ -13980,7 +13998,7 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void {
1398013998}
1398113999
1398214000fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
13983 const mod = self.bin_file.options.module.?;
14001 const mod = self.bin_file.comp.module.?;
1398414002 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1398514003
1398614004 const slice_ty = self.typeOfIndex(inst);
......@@ -14003,7 +14021,7 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void {
1400314021}
1400414022
1400514023fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
14006 const mod = self.bin_file.options.module.?;
14024 const mod = self.bin_file.comp.module.?;
1400714025 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1400814026
1400914027 const dst_ty = self.typeOfIndex(inst);
......@@ -14082,7 +14100,7 @@ fn airFloatFromInt(self: *Self, inst: Air.Inst.Index) !void {
1408214100}
1408314101
1408414102fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
14085 const mod = self.bin_file.options.module.?;
14103 const mod = self.bin_file.comp.module.?;
1408614104 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1408714105
1408814106 const dst_ty = self.typeOfIndex(inst);
......@@ -14153,7 +14171,7 @@ fn airIntFromFloat(self: *Self, inst: Air.Inst.Index) !void {
1415314171}
1415414172
1415514173fn airCmpxchg(self: *Self, inst: Air.Inst.Index) !void {
14156 const mod = self.bin_file.options.module.?;
14174 const mod = self.bin_file.comp.module.?;
1415714175 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1415814176 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
1415914177
......@@ -14249,7 +14267,7 @@ fn atomicOp(
1424914267 rmw_op: ?std.builtin.AtomicRmwOp,
1425014268 order: std.builtin.AtomicOrder,
1425114269) InnerError!MCValue {
14252 const mod = self.bin_file.options.module.?;
14270 const mod = self.bin_file.comp.module.?;
1425314271 const ptr_lock = switch (ptr_mcv) {
1425414272 .register => |reg| self.register_manager.lockReg(reg),
1425514273 else => null,
......@@ -14653,7 +14671,7 @@ fn airAtomicStore(self: *Self, inst: Air.Inst.Index, order: std.builtin.AtomicOr
1465314671}
1465414672
1465514673fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
14656 const mod = self.bin_file.options.module.?;
14674 const mod = self.bin_file.comp.module.?;
1465714675 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1465814676
1465914677 result: {
......@@ -14781,7 +14799,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
1478114799}
1478214800
1478314801fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
14784 const mod = self.bin_file.options.module.?;
14802 const mod = self.bin_file.comp.module.?;
1478514803 const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op;
1478614804
1478714805 try self.spillRegisters(&.{ .rdi, .rsi, .rcx });
......@@ -14836,7 +14854,7 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void {
1483614854}
1483714855
1483814856fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
14839 const mod = self.bin_file.options.module.?;
14857 const mod = self.bin_file.comp.module.?;
1484014858 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1484114859 const inst_ty = self.typeOfIndex(inst);
1484214860 const enum_ty = self.typeOf(un_op);
......@@ -14878,7 +14896,7 @@ fn airTagName(self: *Self, inst: Air.Inst.Index) !void {
1487814896}
1487914897
1488014898fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
14881 const mod = self.bin_file.options.module.?;
14899 const mod = self.bin_file.comp.module.?;
1488214900 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
1488314901
1488414902 const err_ty = self.typeOf(un_op);
......@@ -14980,7 +14998,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
1498014998}
1498114999
1498215000fn airSplat(self: *Self, inst: Air.Inst.Index) !void {
14983 const mod = self.bin_file.options.module.?;
15001 const mod = self.bin_file.comp.module.?;
1498415002 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1498515003 const vector_ty = self.typeOfIndex(inst);
1498615004 const vector_len = vector_ty.vectorLen(mod);
......@@ -15332,7 +15350,7 @@ fn airShuffle(self: *Self, inst: Air.Inst.Index) !void {
1533215350}
1533315351
1533415352fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
15335 const mod = self.bin_file.options.module.?;
15353 const mod = self.bin_file.comp.module.?;
1533615354 const reduce = self.air.instructions.items(.data)[@intFromEnum(inst)].reduce;
1533715355
1533815356 const result: MCValue = result: {
......@@ -15389,7 +15407,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void {
1538915407}
1539015408
1539115409fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
15392 const mod = self.bin_file.options.module.?;
15410 const mod = self.bin_file.comp.module.?;
1539315411 const result_ty = self.typeOfIndex(inst);
1539415412 const len: usize = @intCast(result_ty.arrayLen(mod));
1539515413 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
......@@ -15562,7 +15580,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void {
1556215580}
1556315581
1556415582fn airUnionInit(self: *Self, inst: Air.Inst.Index) !void {
15565 const mod = self.bin_file.options.module.?;
15583 const mod = self.bin_file.comp.module.?;
1556615584 const ip = &mod.intern_pool;
1556715585 const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
1556815586 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
......@@ -15613,7 +15631,7 @@ fn airPrefetch(self: *Self, inst: Air.Inst.Index) !void {
1561315631}
1561415632
1561515633fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
15616 const mod = self.bin_file.options.module.?;
15634 const mod = self.bin_file.comp.module.?;
1561715635 const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op;
1561815636 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
1561915637 const ty = self.typeOfIndex(inst);
......@@ -15780,7 +15798,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
1578015798}
1578115799
1578215800fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
15783 const mod = self.bin_file.options.module.?;
15801 const mod = self.bin_file.comp.module.?;
1578415802 const va_list_ty = self.air.instructions.items(.data)[@intFromEnum(inst)].ty;
1578515803 const ptr_anyopaque_ty = try mod.singleMutPtrType(Type.anyopaque);
1578615804
......@@ -15833,7 +15851,7 @@ fn airVaStart(self: *Self, inst: Air.Inst.Index) !void {
1583315851}
1583415852
1583515853fn airVaArg(self: *Self, inst: Air.Inst.Index) !void {
15836 const mod = self.bin_file.options.module.?;
15854 const mod = self.bin_file.comp.module.?;
1583715855 const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
1583815856 const ty = self.typeOfIndex(inst);
1583915857 const promote_ty = self.promoteVarArg(ty);
......@@ -16042,7 +16060,7 @@ fn airVaEnd(self: *Self, inst: Air.Inst.Index) !void {
1604216060}
1604316061
1604416062fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
16045 const mod = self.bin_file.options.module.?;
16063 const mod = self.bin_file.comp.module.?;
1604616064 const ty = self.typeOf(ref);
1604716065
1604816066 // If the type has no codegen bits, no need to store it.
......@@ -16057,7 +16075,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
1605716075 const const_mcv = try self.genTypedValue(.{ .ty = ty, .val = Value.fromInterned(ip_index) });
1605816076 switch (const_mcv) {
1605916077 .lea_tlv => |tlv_sym| if (self.bin_file.cast(link.File.Elf)) |_| {
16060 if (self.bin_file.options.pic) {
16078 if (self.mod.pic) {
1606116079 try self.spillRegisters(&.{ .rdi, .rax });
1606216080 } else {
1606316081 try self.spillRegisters(&.{.rax});
......@@ -16116,7 +16134,7 @@ fn limitImmediateType(self: *Self, operand: Air.Inst.Ref, comptime T: type) !MCV
1611616134}
1611716135
1611816136fn genTypedValue(self: *Self, arg_tv: TypedValue) InnerError!MCValue {
16119 const mod = self.bin_file.options.module.?;
16137 const mod = self.bin_file.comp.module.?;
1612016138 return switch (try codegen.genTypedValue(self.bin_file, self.src_loc, arg_tv, self.owner.getDecl(mod))) {
1612116139 .mcv => |mcv| switch (mcv) {
1612216140 .none => .none,
......@@ -16156,7 +16174,7 @@ fn resolveCallingConventionValues(
1615616174 var_args: []const Type,
1615716175 stack_frame_base: FrameIndex,
1615816176) !CallMCValues {
16159 const mod = self.bin_file.options.module.?;
16177 const mod = self.bin_file.comp.module.?;
1616016178 const ip = &mod.intern_pool;
1616116179 const cc = fn_info.cc;
1616216180 const param_types = try self.gpa.alloc(Type, fn_info.param_types.len + var_args.len);
......@@ -16413,14 +16431,16 @@ fn resolveCallingConventionValues(
1641316431fn fail(self: *Self, comptime format: []const u8, args: anytype) InnerError {
1641416432 @setCold(true);
1641516433 assert(self.err_msg == null);
16416 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
16434 const gpa = self.gpa;
16435 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
1641716436 return error.CodegenFail;
1641816437}
1641916438
1642016439fn failSymbol(self: *Self, comptime format: []const u8, args: anytype) InnerError {
1642116440 @setCold(true);
1642216441 assert(self.err_msg == null);
16423 self.err_msg = try ErrorMsg.create(self.bin_file.allocator, self.src_loc, format, args);
16442 const gpa = self.gpa;
16443 self.err_msg = try ErrorMsg.create(gpa, self.src_loc, format, args);
1642416444 return error.CodegenFail;
1642516445}
1642616446
......@@ -16468,7 +16488,7 @@ fn registerAlias(reg: Register, size_bytes: u32) Register {
1646816488}
1646916489
1647016490fn memSize(self: *Self, ty: Type) Memory.Size {
16471 const mod = self.bin_file.options.module.?;
16491 const mod = self.bin_file.comp.module.?;
1647216492 return switch (ty.zigTypeTag(mod)) {
1647316493 .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),
1647416494 else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))),
......@@ -16476,7 +16496,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size {
1647616496}
1647716497
1647816498fn splitType(self: *Self, ty: Type) ![2]Type {
16479 const mod = self.bin_file.options.module.?;
16499 const mod = self.bin_file.comp.module.?;
1648016500 const classes = mem.sliceTo(&abi.classifySystemV(ty, mod, .other), .none);
1648116501 var parts: [2]Type = undefined;
1648216502 if (classes.len == 2) for (&parts, classes, 0..) |*part, class, part_i| {
......@@ -16505,7 +16525,7 @@ fn splitType(self: *Self, ty: Type) ![2]Type {
1650516525/// Truncates the value in the register in place.
1650616526/// Clobbers any remaining bits.
1650716527fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
16508 const mod = self.bin_file.options.module.?;
16528 const mod = self.bin_file.comp.module.?;
1650916529 const int_info = if (ty.isAbiInt(mod)) ty.intInfo(mod) else std.builtin.Type.Int{
1651016530 .signedness = .unsigned,
1651116531 .bits = @intCast(ty.bitSize(mod)),
......@@ -16550,7 +16570,7 @@ fn truncateRegister(self: *Self, ty: Type, reg: Register) !void {
1655016570}
1655116571
1655216572fn regBitSize(self: *Self, ty: Type) u64 {
16553 const mod = self.bin_file.options.module.?;
16573 const mod = self.bin_file.comp.module.?;
1655416574 const abi_size = ty.abiSize(mod);
1655516575 return switch (ty.zigTypeTag(mod)) {
1655616576 else => switch (abi_size) {
......@@ -16569,7 +16589,7 @@ fn regBitSize(self: *Self, ty: Type) u64 {
1656916589}
1657016590
1657116591fn regExtraBits(self: *Self, ty: Type) u64 {
16572 const mod = self.bin_file.options.module.?;
16592 const mod = self.bin_file.comp.module.?;
1657316593 return self.regBitSize(ty) - ty.bitSize(mod);
1657416594}
1657516595
......@@ -16584,12 +16604,12 @@ fn hasAllFeatures(self: *Self, features: anytype) bool {
1658416604}
1658516605
1658616606fn typeOf(self: *Self, inst: Air.Inst.Ref) Type {
16587 const mod = self.bin_file.options.module.?;
16607 const mod = self.bin_file.comp.module.?;
1658816608 return self.air.typeOf(inst, &mod.intern_pool);
1658916609}
1659016610
1659116611fn typeOfIndex(self: *Self, inst: Air.Inst.Index) Type {
16592 const mod = self.bin_file.options.module.?;
16612 const mod = self.bin_file.comp.module.?;
1659316613 return self.air.typeOfIndex(inst, &mod.intern_pool);
1659416614}
1659516615
......@@ -16641,7 +16661,7 @@ fn floatLibcAbiSuffix(ty: Type) []const u8 {
1664116661}
1664216662
1664316663fn promoteInt(self: *Self, ty: Type) Type {
16644 const mod = self.bin_file.options.module.?;
16664 const mod = self.bin_file.comp.module.?;
1664516665 const int_info: InternPool.Key.IntType = switch (ty.toIntern()) {
1664616666 .bool_type => .{ .signedness = .unsigned, .bits = 1 },
1664716667 else => if (ty.isAbiInt(mod)) ty.intInfo(mod) else return ty,
src/arch/x86_64/Emit.zig+3-3
......@@ -103,10 +103,10 @@ pub fn emitMir(emit: *Emit) Error!void {
103103 });
104104 },
105105 .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
106 const is_obj_or_static_lib = switch (emit.lower.bin_file.options.output_mode) {
106 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
107107 .Exe => false,
108108 .Obj => true,
109 .Lib => emit.lower.bin_file.options.link_mode == .Static,
109 .Lib => emit.lower.link_mode == .Static,
110110 };
111111 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
112112 const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
......@@ -114,7 +114,7 @@ pub fn emitMir(emit: *Emit) Error!void {
114114 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
115115 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
116116 }
117 if (emit.lower.bin_file.options.pic) {
117 if (emit.lower.pic) {
118118 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
119119 link.File.Elf.R_X86_64_ZIG_GOTPCREL
120120 else if (sym.flags.needs_got)
src/arch/x86_64/Lower.zig+7-4
......@@ -1,6 +1,9 @@
11//! This file contains the functionality for lowering x86_64 MIR to Instructions
22
33bin_file: *link.File,
4output_mode: std.builtin.OutputMode,
5link_mode: std.builtin.LinkMode,
6pic: bool,
47allocator: Allocator,
58mir: Mir,
69cc: std.builtin.CallingConvention,
......@@ -336,10 +339,10 @@ fn isTls(sym: bits.Symbol, ctx: *link.File) bool {
336339}
337340
338341fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
339 const is_obj_or_static_lib = switch (lower.bin_file.options.output_mode) {
342 const is_obj_or_static_lib = switch (lower.output_mode) {
340343 .Exe => false,
341344 .Obj => true,
342 .Lib => lower.bin_file.options.link_mode == .Static,
345 .Lib => lower.link_mode == .Static,
343346 };
344347
345348 const emit_prefix = prefix;
......@@ -358,7 +361,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
358361
359362 if (isTls(sym, lower.bin_file)) {
360363 // TODO handle extern TLS vars, i.e., emit GD model
361 if (lower.bin_file.options.pic) {
364 if (lower.pic) {
362365 // Here, we currently assume local dynamic TLS vars, and so
363366 // we emit LD model.
364367 _ = lower.reloc(.{ .linker_tlsld = sym });
......@@ -403,7 +406,7 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
403406 }
404407
405408 _ = lower.reloc(.{ .linker_reloc = sym });
406 break :op if (lower.bin_file.options.pic) switch (mnemonic) {
409 break :op if (lower.pic) switch (mnemonic) {
407410 .lea => {
408411 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
409412 },
src/codegen.zig+158-130
......@@ -45,7 +45,7 @@ pub const DebugInfoOutput = union(enum) {
4545};
4646
4747pub fn generateFunction(
48 bin_file: *link.File,
48 lf: *link.File,
4949 src_loc: Module.SrcLoc,
5050 func_index: InternPool.Index,
5151 air: Air,
......@@ -53,33 +53,43 @@ pub fn generateFunction(
5353 code: *std.ArrayList(u8),
5454 debug_output: DebugInfoOutput,
5555) CodeGenError!Result {
56 switch (bin_file.options.target.cpu.arch) {
56 const zcu = lf.comp.module.?;
57 const func = zcu.funcInfo(func_index);
58 const decl = zcu.declPtr(func.owner_decl);
59 const namespace = zcu.namespacePtr(decl.src_namespace);
60 const target = namespace.file_scope.mod.resolved_target.result;
61 switch (target.cpu.arch) {
5762 .arm,
5863 .armeb,
59 => return @import("arch/arm/CodeGen.zig").generate(bin_file, src_loc, func_index, air, liveness, code, debug_output),
64 => return @import("arch/arm/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),
6065 .aarch64,
6166 .aarch64_be,
6267 .aarch64_32,
63 => return @import("arch/aarch64/CodeGen.zig").generate(bin_file, src_loc, func_index, air, liveness, code, debug_output),
64 .riscv64 => return @import("arch/riscv64/CodeGen.zig").generate(bin_file, src_loc, func_index, air, liveness, code, debug_output),
65 .sparc64 => return @import("arch/sparc64/CodeGen.zig").generate(bin_file, src_loc, func_index, air, liveness, code, debug_output),
66 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(bin_file, src_loc, func_index, air, liveness, code, debug_output),
68 => return @import("arch/aarch64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),
69 .riscv64 => return @import("arch/riscv64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),
70 .sparc64 => return @import("arch/sparc64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),
71 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),
6772 .wasm32,
6873 .wasm64,
69 => return @import("arch/wasm/CodeGen.zig").generate(bin_file, src_loc, func_index, air, liveness, code, debug_output),
74 => return @import("arch/wasm/CodeGen.zig").generate(lf, src_loc, func_index, air, liveness, code, debug_output),
7075 else => unreachable,
7176 }
7277}
7378
7479pub fn generateLazyFunction(
75 bin_file: *link.File,
80 lf: *link.File,
7681 src_loc: Module.SrcLoc,
7782 lazy_sym: link.File.LazySymbol,
7883 code: *std.ArrayList(u8),
7984 debug_output: DebugInfoOutput,
8085) CodeGenError!Result {
81 switch (bin_file.options.target.cpu.arch) {
82 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(bin_file, src_loc, lazy_sym, code, debug_output),
86 const zcu = lf.comp.module.?;
87 const decl_index = lazy_sym.ty.getOwnerDecl(zcu);
88 const decl = zcu.declPtr(decl_index);
89 const namespace = zcu.namespacePtr(decl.src_namespace);
90 const target = namespace.file_scope.mod.resolved_target.result;
91 switch (target.cpu.arch) {
92 .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, src_loc, lazy_sym, code, debug_output),
8393 else => unreachable,
8494 }
8595}
......@@ -107,13 +117,15 @@ pub fn generateLazySymbol(
107117 const tracy = trace(@src());
108118 defer tracy.end();
109119
110 const target = bin_file.options.target;
120 const comp = bin_file.comp;
121 const zcu = comp.module.?;
122 const target = comp.root_mod.resolved_target.result;
111123 const endian = target.cpu.arch.endian();
124 const gpa = comp.gpa;
112125
113 const mod = bin_file.options.module.?;
114126 log.debug("generateLazySymbol: kind = {s}, ty = {}", .{
115127 @tagName(lazy_sym.kind),
116 lazy_sym.ty.fmt(mod),
128 lazy_sym.ty.fmt(zcu),
117129 });
118130
119131 if (lazy_sym.kind == .code) {
......@@ -121,14 +133,14 @@ pub fn generateLazySymbol(
121133 return generateLazyFunction(bin_file, src_loc, lazy_sym, code, debug_output);
122134 }
123135
124 if (lazy_sym.ty.isAnyError(mod)) {
136 if (lazy_sym.ty.isAnyError(zcu)) {
125137 alignment.* = .@"4";
126 const err_names = mod.global_error_set.keys();
138 const err_names = zcu.global_error_set.keys();
127139 mem.writeInt(u32, try code.addManyAsArray(4), @as(u32, @intCast(err_names.len)), endian);
128140 var offset = code.items.len;
129141 try code.resize((1 + err_names.len + 1) * 4);
130142 for (err_names) |err_name_nts| {
131 const err_name = mod.intern_pool.stringToSlice(err_name_nts);
143 const err_name = zcu.intern_pool.stringToSlice(err_name_nts);
132144 mem.writeInt(u32, code.items[offset..][0..4], @as(u32, @intCast(code.items.len)), endian);
133145 offset += 4;
134146 try code.ensureUnusedCapacity(err_name.len + 1);
......@@ -137,20 +149,20 @@ pub fn generateLazySymbol(
137149 }
138150 mem.writeInt(u32, code.items[offset..][0..4], @as(u32, @intCast(code.items.len)), endian);
139151 return Result.ok;
140 } else if (lazy_sym.ty.zigTypeTag(mod) == .Enum) {
152 } else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) {
141153 alignment.* = .@"1";
142 for (lazy_sym.ty.enumFields(mod)) |tag_name_ip| {
143 const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
154 for (lazy_sym.ty.enumFields(zcu)) |tag_name_ip| {
155 const tag_name = zcu.intern_pool.stringToSlice(tag_name_ip);
144156 try code.ensureUnusedCapacity(tag_name.len + 1);
145157 code.appendSliceAssumeCapacity(tag_name);
146158 code.appendAssumeCapacity(0);
147159 }
148160 return Result.ok;
149161 } else return .{ .fail = try ErrorMsg.create(
150 bin_file.allocator,
162 gpa,
151163 src_loc,
152164 "TODO implement generateLazySymbol for {s} {}",
153 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(mod) },
165 .{ @tagName(lazy_sym.kind), lazy_sym.ty.fmt(zcu) },
154166 ) };
155167}
156168
......@@ -165,7 +177,7 @@ pub fn generateSymbol(
165177 const tracy = trace(@src());
166178 defer tracy.end();
167179
168 const mod = bin_file.options.module.?;
180 const mod = bin_file.comp.module.?;
169181 const ip = &mod.intern_pool;
170182 const typed_value = arg_tv;
171183
......@@ -662,7 +674,7 @@ fn lowerParentPtr(
662674 debug_output: DebugInfoOutput,
663675 reloc_info: RelocInfo,
664676) CodeGenError!Result {
665 const mod = bin_file.options.module.?;
677 const mod = bin_file.comp.module.?;
666678 const ptr = mod.intern_pool.indexToKey(parent_ptr).ptr;
667679 assert(ptr.len == .none);
668680 return switch (ptr.addr) {
......@@ -757,7 +769,7 @@ const RelocInfo = struct {
757769};
758770
759771fn lowerAnonDeclRef(
760 bin_file: *link.File,
772 lf: *link.File,
761773 src_loc: Module.SrcLoc,
762774 anon_decl: InternPool.Key.Ptr.Addr.AnonDecl,
763775 code: *std.ArrayList(u8),
......@@ -765,27 +777,27 @@ fn lowerAnonDeclRef(
765777 reloc_info: RelocInfo,
766778) CodeGenError!Result {
767779 _ = debug_output;
768 const target = bin_file.options.target;
769 const mod = bin_file.options.module.?;
780 const zcu = lf.comp.module.?;
781 const target = lf.comp.root_mod.resolved_target.result;
770782
771783 const ptr_width_bytes = @divExact(target.ptrBitWidth(), 8);
772784 const decl_val = anon_decl.val;
773 const decl_ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
774 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(mod)});
775 const is_fn_body = decl_ty.zigTypeTag(mod) == .Fn;
776 if (!is_fn_body and !decl_ty.hasRuntimeBits(mod)) {
785 const decl_ty = Type.fromInterned(zcu.intern_pool.typeOf(decl_val));
786 log.debug("lowerAnonDecl: ty = {}", .{decl_ty.fmt(zcu)});
787 const is_fn_body = decl_ty.zigTypeTag(zcu) == .Fn;
788 if (!is_fn_body and !decl_ty.hasRuntimeBits(zcu)) {
777789 try code.appendNTimes(0xaa, ptr_width_bytes);
778790 return Result.ok;
779791 }
780792
781 const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
782 const res = try bin_file.lowerAnonDecl(decl_val, decl_align, src_loc);
793 const decl_align = zcu.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
794 const res = try lf.lowerAnonDecl(decl_val, decl_align, src_loc);
783795 switch (res) {
784796 .ok => {},
785797 .fail => |em| return .{ .fail = em },
786798 }
787799
788 const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{
800 const vaddr = try lf.getAnonDeclVAddr(decl_val, .{
789801 .parent_atom_index = reloc_info.parent_atom_index,
790802 .offset = code.items.len,
791803 .addend = reloc_info.addend orelse 0,
......@@ -802,7 +814,7 @@ fn lowerAnonDeclRef(
802814}
803815
804816fn lowerDeclRef(
805 bin_file: *link.File,
817 lf: *link.File,
806818 src_loc: Module.SrcLoc,
807819 decl_index: InternPool.DeclIndex,
808820 code: *std.ArrayList(u8),
......@@ -811,20 +823,21 @@ fn lowerDeclRef(
811823) CodeGenError!Result {
812824 _ = src_loc;
813825 _ = debug_output;
814 const target = bin_file.options.target;
815 const mod = bin_file.options.module.?;
826 const zcu = lf.comp.module.?;
827 const decl = zcu.declPtr(decl_index);
828 const namespace = zcu.namespacePtr(decl.src_namespace);
829 const target = namespace.file_scope.mod.resolved_target.result;
816830
817831 const ptr_width = target.ptrBitWidth();
818 const decl = mod.declPtr(decl_index);
819 const is_fn_body = decl.ty.zigTypeTag(mod) == .Fn;
820 if (!is_fn_body and !decl.ty.hasRuntimeBits(mod)) {
832 const is_fn_body = decl.ty.zigTypeTag(zcu) == .Fn;
833 if (!is_fn_body and !decl.ty.hasRuntimeBits(zcu)) {
821834 try code.appendNTimes(0xaa, @divExact(ptr_width, 8));
822835 return Result.ok;
823836 }
824837
825 try mod.markDeclAlive(decl);
838 try zcu.markDeclAlive(decl);
826839
827 const vaddr = try bin_file.getDeclVAddr(decl_index, .{
840 const vaddr = try lf.getDeclVAddr(decl_index, .{
828841 .parent_atom_index = reloc_info.parent_atom_index,
829842 .offset = code.items.len,
830843 .addend = reloc_info.addend orelse 0,
......@@ -897,27 +910,29 @@ pub const GenResult = union(enum) {
897910};
898911
899912fn genDeclRef(
900 bin_file: *link.File,
913 lf: *link.File,
901914 src_loc: Module.SrcLoc,
902915 tv: TypedValue,
903916 ptr_decl_index: InternPool.DeclIndex,
904917) CodeGenError!GenResult {
905 const mod = bin_file.options.module.?;
906 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(mod), tv.val.fmtValue(tv.ty, mod) });
918 const zcu = lf.comp.module.?;
919 log.debug("genDeclRef: ty = {}, val = {}", .{ tv.ty.fmt(zcu), tv.val.fmtValue(tv.ty, zcu) });
920
921 const ptr_decl = zcu.declPtr(ptr_decl_index);
922 const namespace = zcu.namespacePtr(ptr_decl.src_namespace);
923 const target = namespace.file_scope.mod.resolved_target.result;
907924
908 const target = bin_file.options.target;
909925 const ptr_bits = target.ptrBitWidth();
910926 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
911927
912 const ptr_decl = mod.declPtr(ptr_decl_index);
913 const decl_index = switch (mod.intern_pool.indexToKey(try ptr_decl.internValue(mod))) {
928 const decl_index = switch (zcu.intern_pool.indexToKey(try ptr_decl.internValue(zcu))) {
914929 .func => |func| func.owner_decl,
915930 .extern_func => |extern_func| extern_func.decl,
916931 else => ptr_decl_index,
917932 };
918 const decl = mod.declPtr(decl_index);
933 const decl = zcu.declPtr(decl_index);
919934
920 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) {
935 if (!decl.ty.isFnOrHasRuntimeBitsIgnoreComptime(zcu)) {
921936 const imm: u64 = switch (ptr_bytes) {
922937 1 => 0xaa,
923938 2 => 0xaaaa,
......@@ -928,29 +943,34 @@ fn genDeclRef(
928943 return GenResult.mcv(.{ .immediate = imm });
929944 }
930945
946 const comp = lf.comp;
947 const gpa = comp.gpa;
948
931949 // TODO this feels clunky. Perhaps we should check for it in `genTypedValue`?
932 if (tv.ty.castPtrToFn(mod)) |fn_ty| {
933 if (mod.typeToFunc(fn_ty).?.is_generic) {
934 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(mod).toByteUnitsOptional().? });
950 if (tv.ty.castPtrToFn(zcu)) |fn_ty| {
951 if (zcu.typeToFunc(fn_ty).?.is_generic) {
952 return GenResult.mcv(.{ .immediate = fn_ty.abiAlignment(zcu).toByteUnitsOptional().? });
935953 }
936 } else if (tv.ty.zigTypeTag(mod) == .Pointer) {
937 const elem_ty = tv.ty.elemType2(mod);
938 if (!elem_ty.hasRuntimeBits(mod)) {
939 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(mod).toByteUnitsOptional().? });
954 } else if (tv.ty.zigTypeTag(zcu) == .Pointer) {
955 const elem_ty = tv.ty.elemType2(zcu);
956 if (!elem_ty.hasRuntimeBits(zcu)) {
957 return GenResult.mcv(.{ .immediate = elem_ty.abiAlignment(zcu).toByteUnitsOptional().? });
940958 }
941959 }
942960
943 try mod.markDeclAlive(decl);
961 try zcu.markDeclAlive(decl);
944962
945 const is_threadlocal = tv.val.isPtrToThreadLocal(mod) and !bin_file.options.single_threaded;
946 const is_extern = decl.isExtern(mod);
963 const decl_namespace = zcu.namespacePtr(decl.src_namespace);
964 const single_threaded = decl_namespace.file_scope.mod.single_threaded;
965 const is_threadlocal = tv.val.isPtrToThreadLocal(zcu) and !single_threaded;
966 const is_extern = decl.isExtern(zcu);
947967
948 if (bin_file.cast(link.File.Elf)) |elf_file| {
968 if (lf.cast(link.File.Elf)) |elf_file| {
949969 if (is_extern) {
950 const name = mod.intern_pool.stringToSlice(decl.name);
970 const name = zcu.intern_pool.stringToSlice(decl.name);
951971 // TODO audit this
952 const lib_name = if (decl.getOwnedVariable(mod)) |ov|
953 mod.intern_pool.stringToSliceUnwrap(ov.lib_name)
972 const lib_name = if (decl.getOwnedVariable(zcu)) |ov|
973 zcu.intern_pool.stringToSliceUnwrap(ov.lib_name)
954974 else
955975 null;
956976 const sym_index = try elf_file.getGlobalSymbol(name, lib_name);
......@@ -963,12 +983,12 @@ fn genDeclRef(
963983 return GenResult.mcv(.{ .load_tlv = sym.esym_index });
964984 }
965985 return GenResult.mcv(.{ .load_symbol = sym.esym_index });
966 } else if (bin_file.cast(link.File.MachO)) |macho_file| {
986 } else if (lf.cast(link.File.MachO)) |macho_file| {
967987 if (is_extern) {
968988 // TODO make this part of getGlobalSymbol
969 const name = mod.intern_pool.stringToSlice(decl.name);
970 const sym_name = try std.fmt.allocPrint(bin_file.allocator, "_{s}", .{name});
971 defer bin_file.allocator.free(sym_name);
989 const name = zcu.intern_pool.stringToSlice(decl.name);
990 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
991 defer gpa.free(sym_name);
972992 const global_index = try macho_file.addUndefined(sym_name, .{ .add_got = true });
973993 return GenResult.mcv(.{ .load_got = link.File.MachO.global_symbol_bit | global_index });
974994 }
......@@ -978,110 +998,118 @@ fn genDeclRef(
978998 return GenResult.mcv(.{ .load_tlv = sym_index });
979999 }
9801000 return GenResult.mcv(.{ .load_got = sym_index });
981 } else if (bin_file.cast(link.File.Coff)) |coff_file| {
1001 } else if (lf.cast(link.File.Coff)) |coff_file| {
9821002 if (is_extern) {
983 const name = mod.intern_pool.stringToSlice(decl.name);
1003 const name = zcu.intern_pool.stringToSlice(decl.name);
9841004 // TODO audit this
985 const lib_name = if (decl.getOwnedVariable(mod)) |ov|
986 mod.intern_pool.stringToSliceUnwrap(ov.lib_name)
1005 const lib_name = if (decl.getOwnedVariable(zcu)) |ov|
1006 zcu.intern_pool.stringToSliceUnwrap(ov.lib_name)
9871007 else
9881008 null;
9891009 const global_index = try coff_file.getGlobalSymbol(name, lib_name);
990 try coff_file.need_got_table.put(bin_file.allocator, global_index, {}); // needs GOT
1010 try coff_file.need_got_table.put(gpa, global_index, {}); // needs GOT
9911011 return GenResult.mcv(.{ .load_got = link.File.Coff.global_symbol_bit | global_index });
9921012 }
9931013 const atom_index = try coff_file.getOrCreateAtomForDecl(decl_index);
9941014 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
9951015 return GenResult.mcv(.{ .load_got = sym_index });
996 } else if (bin_file.cast(link.File.Plan9)) |p9| {
1016 } else if (lf.cast(link.File.Plan9)) |p9| {
9971017 const atom_index = try p9.seeDecl(decl_index);
9981018 const atom = p9.getAtom(atom_index);
9991019 return GenResult.mcv(.{ .memory = atom.getOffsetTableAddress(p9) });
10001020 } else {
1001 return GenResult.fail(bin_file.allocator, src_loc, "TODO genDeclRef for target {}", .{target});
1021 return GenResult.fail(gpa, src_loc, "TODO genDeclRef for target {}", .{target});
10021022 }
10031023}
10041024
10051025fn genUnnamedConst(
1006 bin_file: *link.File,
1026 lf: *link.File,
10071027 src_loc: Module.SrcLoc,
10081028 tv: TypedValue,
10091029 owner_decl_index: InternPool.DeclIndex,
10101030) CodeGenError!GenResult {
1011 const mod = bin_file.options.module.?;
1012 log.debug("genUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmt(mod), tv.val.fmtValue(tv.ty, mod) });
1031 const zcu = lf.comp.module.?;
1032 const gpa = lf.comp.gpa;
1033 log.debug("genUnnamedConst: ty = {}, val = {}", .{ tv.ty.fmt(zcu), tv.val.fmtValue(tv.ty, zcu) });
10131034
1014 const target = bin_file.options.target;
1015 const local_sym_index = bin_file.lowerUnnamedConst(tv, owner_decl_index) catch |err| {
1016 return GenResult.fail(bin_file.allocator, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
1035 const local_sym_index = lf.lowerUnnamedConst(tv, owner_decl_index) catch |err| {
1036 return GenResult.fail(gpa, src_loc, "lowering unnamed constant failed: {s}", .{@errorName(err)});
10171037 };
1018 if (bin_file.cast(link.File.Elf)) |elf_file| {
1019 const local = elf_file.symbol(local_sym_index);
1020 return GenResult.mcv(.{ .load_symbol = local.esym_index });
1021 } else if (bin_file.cast(link.File.MachO)) |_| {
1022 return GenResult.mcv(.{ .load_direct = local_sym_index });
1023 } else if (bin_file.cast(link.File.Coff)) |_| {
1024 return GenResult.mcv(.{ .load_direct = local_sym_index });
1025 } else if (bin_file.cast(link.File.Plan9)) |_| {
1026 const atom_index = local_sym_index; // plan9 returns the atom_index
1027 return GenResult.mcv(.{ .load_direct = atom_index });
1028 } else {
1029 return GenResult.fail(bin_file.allocator, src_loc, "TODO genUnnamedConst for target {}", .{target});
1038 switch (lf.tag) {
1039 .elf => {
1040 const elf_file = lf.cast(link.File.Elf).?;
1041 const local = elf_file.symbol(local_sym_index);
1042 return GenResult.mcv(.{ .load_symbol = local.esym_index });
1043 },
1044 .macho, .coff => {
1045 return GenResult.mcv(.{ .load_direct = local_sym_index });
1046 },
1047 .plan9 => {
1048 const atom_index = local_sym_index; // plan9 returns the atom_index
1049 return GenResult.mcv(.{ .load_direct = atom_index });
1050 },
1051
1052 .c => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for -ofmt=c", .{}),
1053 .wasm => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for wasm", .{}),
1054 .spirv => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for spirv", .{}),
1055 .nvptx => return GenResult.fail(gpa, src_loc, "TODO genUnnamedConst for nvptx", .{}),
10301056 }
10311057}
10321058
10331059pub fn genTypedValue(
1034 bin_file: *link.File,
1060 lf: *link.File,
10351061 src_loc: Module.SrcLoc,
10361062 arg_tv: TypedValue,
10371063 owner_decl_index: InternPool.DeclIndex,
10381064) CodeGenError!GenResult {
1039 const mod = bin_file.options.module.?;
1065 const zcu = lf.comp.module.?;
10401066 const typed_value = arg_tv;
10411067
10421068 log.debug("genTypedValue: ty = {}, val = {}", .{
1043 typed_value.ty.fmt(mod),
1044 typed_value.val.fmtValue(typed_value.ty, mod),
1069 typed_value.ty.fmt(zcu),
1070 typed_value.val.fmtValue(typed_value.ty, zcu),
10451071 });
10461072
1047 if (typed_value.val.isUndef(mod))
1073 if (typed_value.val.isUndef(zcu))
10481074 return GenResult.mcv(.undef);
10491075
1050 const target = bin_file.options.target;
1076 const owner_decl = zcu.declPtr(owner_decl_index);
1077 const namespace = zcu.namespacePtr(owner_decl.src_namespace);
1078 const target = namespace.file_scope.mod.resolved_target.result;
10511079 const ptr_bits = target.ptrBitWidth();
10521080
1053 if (!typed_value.ty.isSlice(mod)) switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
1081 if (!typed_value.ty.isSlice(zcu)) switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) {
10541082 .ptr => |ptr| switch (ptr.addr) {
1055 .decl => |decl| return genDeclRef(bin_file, src_loc, typed_value, decl),
1056 .mut_decl => |mut_decl| return genDeclRef(bin_file, src_loc, typed_value, mut_decl.decl),
1083 .decl => |decl| return genDeclRef(lf, src_loc, typed_value, decl),
1084 .mut_decl => |mut_decl| return genDeclRef(lf, src_loc, typed_value, mut_decl.decl),
10571085 else => {},
10581086 },
10591087 else => {},
10601088 };
10611089
1062 switch (typed_value.ty.zigTypeTag(mod)) {
1090 switch (typed_value.ty.zigTypeTag(zcu)) {
10631091 .Void => return GenResult.mcv(.none),
1064 .Pointer => switch (typed_value.ty.ptrSize(mod)) {
1092 .Pointer => switch (typed_value.ty.ptrSize(zcu)) {
10651093 .Slice => {},
10661094 else => switch (typed_value.val.toIntern()) {
10671095 .null_value => {
10681096 return GenResult.mcv(.{ .immediate = 0 });
10691097 },
10701098 .none => {},
1071 else => switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
1099 else => switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern())) {
10721100 .int => {
1073 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(mod) });
1101 return GenResult.mcv(.{ .immediate = typed_value.val.toUnsignedInt(zcu) });
10741102 },
10751103 else => {},
10761104 },
10771105 },
10781106 },
10791107 .Int => {
1080 const info = typed_value.ty.intInfo(mod);
1108 const info = typed_value.ty.intInfo(zcu);
10811109 if (info.bits <= ptr_bits) {
10821110 const unsigned = switch (info.signedness) {
1083 .signed => @as(u64, @bitCast(typed_value.val.toSignedInt(mod))),
1084 .unsigned => typed_value.val.toUnsignedInt(mod),
1111 .signed => @as(u64, @bitCast(typed_value.val.toSignedInt(zcu))),
1112 .unsigned => typed_value.val.toUnsignedInt(zcu),
10851113 };
10861114 return GenResult.mcv(.{ .immediate = unsigned });
10871115 }
......@@ -1090,45 +1118,45 @@ pub fn genTypedValue(
10901118 return GenResult.mcv(.{ .immediate = @intFromBool(typed_value.val.toBool()) });
10911119 },
10921120 .Optional => {
1093 if (typed_value.ty.isPtrLikeOptional(mod)) {
1094 return genTypedValue(bin_file, src_loc, .{
1095 .ty = typed_value.ty.optionalChild(mod),
1096 .val = typed_value.val.optionalValue(mod) orelse return GenResult.mcv(.{ .immediate = 0 }),
1121 if (typed_value.ty.isPtrLikeOptional(zcu)) {
1122 return genTypedValue(lf, src_loc, .{
1123 .ty = typed_value.ty.optionalChild(zcu),
1124 .val = typed_value.val.optionalValue(zcu) orelse return GenResult.mcv(.{ .immediate = 0 }),
10971125 }, owner_decl_index);
1098 } else if (typed_value.ty.abiSize(mod) == 1) {
1099 return GenResult.mcv(.{ .immediate = @intFromBool(!typed_value.val.isNull(mod)) });
1126 } else if (typed_value.ty.abiSize(zcu) == 1) {
1127 return GenResult.mcv(.{ .immediate = @intFromBool(!typed_value.val.isNull(zcu)) });
11001128 }
11011129 },
11021130 .Enum => {
1103 const enum_tag = mod.intern_pool.indexToKey(typed_value.val.toIntern()).enum_tag;
1104 const int_tag_ty = mod.intern_pool.typeOf(enum_tag.int);
1105 return genTypedValue(bin_file, src_loc, .{
1131 const enum_tag = zcu.intern_pool.indexToKey(typed_value.val.toIntern()).enum_tag;
1132 const int_tag_ty = zcu.intern_pool.typeOf(enum_tag.int);
1133 return genTypedValue(lf, src_loc, .{
11061134 .ty = Type.fromInterned(int_tag_ty),
11071135 .val = Value.fromInterned(enum_tag.int),
11081136 }, owner_decl_index);
11091137 },
11101138 .ErrorSet => {
1111 const err_name = mod.intern_pool.indexToKey(typed_value.val.toIntern()).err.name;
1112 const error_index = mod.global_error_set.getIndex(err_name).?;
1139 const err_name = zcu.intern_pool.indexToKey(typed_value.val.toIntern()).err.name;
1140 const error_index = zcu.global_error_set.getIndex(err_name).?;
11131141 return GenResult.mcv(.{ .immediate = error_index });
11141142 },
11151143 .ErrorUnion => {
1116 const err_type = typed_value.ty.errorUnionSet(mod);
1117 const payload_type = typed_value.ty.errorUnionPayload(mod);
1118 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
1144 const err_type = typed_value.ty.errorUnionSet(zcu);
1145 const payload_type = typed_value.ty.errorUnionPayload(zcu);
1146 if (!payload_type.hasRuntimeBitsIgnoreComptime(zcu)) {
11191147 // We use the error type directly as the type.
1120 const err_int_ty = try mod.errorIntType();
1121 switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) {
1122 .err_name => |err_name| return genTypedValue(bin_file, src_loc, .{
1148 const err_int_ty = try zcu.errorIntType();
1149 switch (zcu.intern_pool.indexToKey(typed_value.val.toIntern()).error_union.val) {
1150 .err_name => |err_name| return genTypedValue(lf, src_loc, .{
11231151 .ty = err_type,
1124 .val = Value.fromInterned((try mod.intern(.{ .err = .{
1152 .val = Value.fromInterned((try zcu.intern(.{ .err = .{
11251153 .ty = err_type.toIntern(),
11261154 .name = err_name,
11271155 } }))),
11281156 }, owner_decl_index),
1129 .payload => return genTypedValue(bin_file, src_loc, .{
1157 .payload => return genTypedValue(lf, src_loc, .{
11301158 .ty = err_int_ty,
1131 .val = try mod.intValue(err_int_ty, 0),
1159 .val = try zcu.intValue(err_int_ty, 0),
11321160 }, owner_decl_index),
11331161 }
11341162 }
......@@ -1146,7 +1174,7 @@ pub fn genTypedValue(
11461174 else => {},
11471175 }
11481176
1149 return genUnnamedConst(bin_file, src_loc, typed_value, owner_decl_index);
1177 return genUnnamedConst(lf, src_loc, typed_value, owner_decl_index);
11501178}
11511179
11521180pub fn errUnionPayloadOffset(payload_ty: Type, mod: *Module) u64 {
src/codegen/llvm.zig+318-309
......@@ -15,6 +15,7 @@ const link = @import("../link.zig");
1515const Compilation = @import("../Compilation.zig");
1616const build_options = @import("build_options");
1717const Module = @import("../Module.zig");
18const Zcu = Module;
1819const InternPool = @import("../InternPool.zig");
1920const Package = @import("../Package.zig");
2021const TypedValue = @import("../TypedValue.zig");
......@@ -821,7 +822,7 @@ pub const Object = struct {
821822 type_map: TypeMap,
822823 di_type_map: DITypeMap,
823824 /// The LLVM global table which holds the names corresponding to Zig errors.
824 /// Note that the values are not added until flushModule, when all errors in
825 /// Note that the values are not added until `emit`, when all errors in
825826 /// the compilation are known.
826827 error_name_table: Builder.Variable.Index,
827828 /// This map is usually very close to empty. It tracks only the cases when a
......@@ -849,27 +850,25 @@ pub const Object = struct {
849850
850851 pub const TypeMap = std.AutoHashMapUnmanaged(InternPool.Index, Builder.Type);
851852
852 /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we
853 /// This is an ArrayHashMap as opposed to a HashMap because in `emit` we
853854 /// want to iterate over it while adding entries to it.
854855 pub const DITypeMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, AnnotatedDITypePtr);
855856
856 pub fn create(gpa: Allocator, options: link.Options) !*Object {
857 const obj = try gpa.create(Object);
858 errdefer gpa.destroy(obj);
859 obj.* = try Object.init(gpa, options);
860 return obj;
861 }
862
863 pub fn init(gpa: Allocator, options: link.Options) !Object {
864 const llvm_target_triple = try targetTriple(gpa, options.target);
865 defer gpa.free(llvm_target_triple);
857 pub fn create(arena: Allocator, comp: *Compilation) !*Object {
858 if (build_options.only_c) unreachable;
859 const gpa = comp.gpa;
860 const target = comp.root_mod.resolved_target.result;
861 const llvm_target_triple = try targetTriple(arena, target);
862 const strip = comp.root_mod.strip;
863 const optimize_mode = comp.root_mod.optimize_mode;
864 const pic = comp.root_mod.pic;
866865
867866 var builder = try Builder.init(.{
868867 .allocator = gpa,
869 .use_lib_llvm = options.use_lib_llvm,
870 .strip = options.strip or !options.use_lib_llvm, // TODO
871 .name = options.root_name,
872 .target = options.target,
868 .use_lib_llvm = comp.config.use_lib_llvm,
869 .strip = strip or !comp.config.use_lib_llvm, // TODO
870 .name = comp.root_name,
871 .target = target,
873872 .triple = llvm_target_triple,
874873 });
875874 errdefer builder.deinit();
......@@ -877,10 +876,11 @@ pub const Object = struct {
877876 var target_machine: if (build_options.have_llvm) *llvm.TargetMachine else void = undefined;
878877 var target_data: if (build_options.have_llvm) *llvm.TargetData else void = undefined;
879878 if (builder.useLibLlvm()) {
880 if (!options.strip) {
881 switch (options.target.ofmt) {
882 .coff => builder.llvm.module.?.addModuleCodeViewFlag(),
883 else => builder.llvm.module.?.addModuleDebugInfoFlag(options.dwarf_format == std.dwarf.Format.@"64"),
879 debug_info: {
880 switch (comp.config.debug_format) {
881 .strip => break :debug_info,
882 .code_view => builder.llvm.module.?.addModuleCodeViewFlag(),
883 .dwarf => |f| builder.llvm.module.?.addModuleDebugInfoFlag(f == .@"64"),
884884 }
885885 builder.llvm.di_builder = builder.llvm.module.?.createDIBuilder(true);
886886
......@@ -898,26 +898,29 @@ pub const Object = struct {
898898 // very location dependent.
899899 // TODO: the only concern I have with this is WASI as either host or target, should
900900 // we leave the paths as relative then?
901 // TODO: This is totally wrong. In dwarf, paths are encoded as relative to
902 // a particular directory, and then the directory path is specified elsewhere.
903 // In the compiler frontend we have it stored correctly in this
904 // way already, but here we throw all that sweet information
905 // into the garbage can by converting into absolute paths. What
906 // a terrible tragedy.
901907 const compile_unit_dir_z = blk: {
902 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
903 if (options.module) |mod| m: {
904 const d = try mod.root_mod.root.joinStringZ(builder.gpa, "");
908 if (comp.module) |zcu| m: {
909 const d = try zcu.root_mod.root.joinStringZ(arena, "");
905910 if (d.len == 0) break :m;
906911 if (std.fs.path.isAbsolute(d)) break :blk d;
907 const abs = std.fs.realpath(d, &buf) catch break :blk d;
908 builder.gpa.free(d);
909 break :blk try builder.gpa.dupeZ(u8, abs);
912 const realpath = std.fs.realpathAlloc(arena, d) catch break :blk d;
913 break :blk try arena.dupeZ(u8, realpath);
910914 }
911 const cwd = try std.process.getCwd(&buf);
912 break :blk try builder.gpa.dupeZ(u8, cwd);
915 const cwd = try std.process.getCwdAlloc(arena);
916 break :blk try arena.dupeZ(u8, cwd);
913917 };
914 defer builder.gpa.free(compile_unit_dir_z);
915918
916919 builder.llvm.di_compile_unit = builder.llvm.di_builder.?.createCompileUnit(
917920 DW.LANG.C99,
918 builder.llvm.di_builder.?.createFile(options.root_name, compile_unit_dir_z),
921 builder.llvm.di_builder.?.createFile(comp.root_name, compile_unit_dir_z),
919922 producer.slice(&builder).?,
920 options.optimize_mode != .Debug,
923 optimize_mode != .Debug,
921924 "", // flags
922925 0, // runtime version
923926 "", // split name
......@@ -926,19 +929,19 @@ pub const Object = struct {
926929 );
927930 }
928931
929 const opt_level: llvm.CodeGenOptLevel = if (options.optimize_mode == .Debug)
932 const opt_level: llvm.CodeGenOptLevel = if (optimize_mode == .Debug)
930933 .None
931934 else
932935 .Aggressive;
933936
934 const reloc_mode: llvm.RelocMode = if (options.pic)
937 const reloc_mode: llvm.RelocMode = if (pic)
935938 .PIC
936 else if (options.link_mode == .Dynamic)
939 else if (comp.config.link_mode == .Dynamic)
937940 llvm.RelocMode.DynamicNoPIC
938941 else
939942 .Static;
940943
941 const code_model: llvm.CodeModel = switch (options.machine_code_model) {
944 const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) {
942945 .default => .Default,
943946 .tiny => .Tiny,
944947 .small => .Small,
......@@ -953,15 +956,15 @@ pub const Object = struct {
953956 target_machine = llvm.TargetMachine.create(
954957 builder.llvm.target.?,
955958 builder.target_triple.slice(&builder).?,
956 if (options.target.cpu.model.llvm_name) |s| s.ptr else null,
957 options.llvm_cpu_features,
959 if (target.cpu.model.llvm_name) |s| s.ptr else null,
960 comp.root_mod.resolved_target.llvm_cpu_features.?,
958961 opt_level,
959962 reloc_mode,
960963 code_model,
961 options.function_sections,
962 options.data_sections,
964 comp.function_sections,
965 comp.data_sections,
963966 float_abi,
964 if (target_util.llvmMachineAbi(options.target)) |s| s.ptr else null,
967 if (target_util.llvmMachineAbi(target)) |s| s.ptr else null,
965968 );
966969 errdefer target_machine.dispose();
967970
......@@ -970,15 +973,15 @@ pub const Object = struct {
970973
971974 builder.llvm.module.?.setModuleDataLayout(target_data);
972975
973 if (options.pic) builder.llvm.module.?.setModulePICLevel();
974 if (options.pie) builder.llvm.module.?.setModulePIELevel();
976 if (pic) builder.llvm.module.?.setModulePICLevel();
977 if (comp.config.pie) builder.llvm.module.?.setModulePIELevel();
975978 if (code_model != .Default) builder.llvm.module.?.setModuleCodeModel(code_model);
976979
977 if (options.opt_bisect_limit >= 0) {
978 builder.llvm.context.setOptBisectLimit(std.math.lossyCast(c_int, options.opt_bisect_limit));
980 if (comp.llvm_opt_bisect_limit >= 0) {
981 builder.llvm.context.setOptBisectLimit(comp.llvm_opt_bisect_limit);
979982 }
980983
981 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = options.target }});
984 builder.data_layout = try builder.fmt("{}", .{DataLayoutBuilder{ .target = target }});
982985 if (std.debug.runtime_safety) {
983986 const rep = target_data.stringRep();
984987 defer llvm.disposeMessage(rep);
......@@ -989,16 +992,17 @@ pub const Object = struct {
989992 }
990993 }
991994
992 return .{
995 const obj = try arena.create(Object);
996 obj.* = .{
993997 .gpa = gpa,
994998 .builder = builder,
995 .module = options.module.?,
999 .module = comp.module.?,
9961000 .di_map = .{},
9971001 .di_builder = if (builder.useLibLlvm()) builder.llvm.di_builder else null, // TODO
9981002 .di_compile_unit = if (builder.useLibLlvm()) builder.llvm.di_compile_unit else null,
9991003 .target_machine = target_machine,
10001004 .target_data = target_data,
1001 .target = options.target,
1005 .target = target,
10021006 .decl_map = .{},
10031007 .anon_decl_map = .{},
10041008 .named_enum_map = .{},
......@@ -1009,9 +1013,11 @@ pub const Object = struct {
10091013 .null_opt_usize = .no_init,
10101014 .struct_field_map = .{},
10111015 };
1016 return obj;
10121017 }
10131018
1014 pub fn deinit(self: *Object, gpa: Allocator) void {
1019 pub fn deinit(self: *Object) void {
1020 const gpa = self.gpa;
10151021 self.di_map.deinit(gpa);
10161022 self.di_type_map.deinit(gpa);
10171023 if (self.builder.useLibLlvm()) {
......@@ -1028,22 +1034,6 @@ pub const Object = struct {
10281034 self.* = undefined;
10291035 }
10301036
1031 pub fn destroy(self: *Object, gpa: Allocator) void {
1032 self.deinit(gpa);
1033 gpa.destroy(self);
1034 }
1035
1036 fn locPath(
1037 arena: Allocator,
1038 opt_loc: ?Compilation.EmitLoc,
1039 cache_directory: Compilation.Directory,
1040 ) !?[*:0]u8 {
1041 const loc = opt_loc orelse return null;
1042 const directory = loc.directory orelse cache_directory;
1043 const slice = try directory.joinZ(arena, &[_][]const u8{loc.basename});
1044 return slice.ptr;
1045 }
1046
10471037 fn genErrorNameTable(o: *Object) Allocator.Error!void {
10481038 // If o.error_name_table is null, then it was not referenced by any instructions.
10491039 if (o.error_name_table == .none) return;
......@@ -1182,12 +1172,22 @@ pub const Object = struct {
11821172 }
11831173 }
11841174
1185 pub fn flushModule(self: *Object, comp: *Compilation, prog_node: *std.Progress.Node) !void {
1186 var sub_prog_node = prog_node.start("LLVM Emit Object", 0);
1187 sub_prog_node.activate();
1188 sub_prog_node.context.refresh();
1189 defer sub_prog_node.end();
1175 pub const EmitOptions = struct {
1176 pre_ir_path: ?[]const u8,
1177 pre_bc_path: ?[]const u8,
1178 bin_path: ?[*:0]const u8,
1179 asm_path: ?[*:0]const u8,
1180 post_ir_path: ?[*:0]const u8,
1181 post_bc_path: ?[*:0]const u8,
1182
1183 is_debug: bool,
1184 is_small: bool,
1185 time_report: bool,
1186 sanitize_thread: bool,
1187 lto: bool,
1188 };
11901189
1190 pub fn emit(self: *Object, options: EmitOptions) !void {
11911191 try self.resolveExportExternCollisions();
11921192 try self.genErrorNameTable();
11931193 try self.genCmpLtErrorsLenFunction();
......@@ -1213,7 +1213,7 @@ pub const Object = struct {
12131213 dib.finalize();
12141214 }
12151215
1216 if (comp.verbose_llvm_ir) |path| {
1216 if (options.pre_ir_path) |path| {
12171217 if (std.mem.eql(u8, path, "-")) {
12181218 self.builder.dump();
12191219 } else {
......@@ -1221,91 +1221,72 @@ pub const Object = struct {
12211221 }
12221222 }
12231223
1224 if (comp.verbose_llvm_bc) |path| _ = try self.builder.writeBitcodeToFile(path);
1225
1226 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
1227 defer arena_allocator.deinit();
1228 const arena = arena_allocator.allocator();
1229
1230 const mod = comp.bin_file.options.module.?;
1231 const cache_dir = mod.zig_cache_artifact_directory;
1224 if (options.pre_bc_path) |path| _ = try self.builder.writeBitcodeToFile(path);
12321225
12331226 if (std.debug.runtime_safety and !try self.builder.verify()) {
1234 if (try locPath(arena, comp.emit_llvm_ir, cache_dir)) |emit_llvm_ir_path|
1235 _ = self.builder.printToFileZ(emit_llvm_ir_path);
12361227 @panic("LLVM module verification failed");
12371228 }
12381229
1239 var emit_bin_path: ?[*:0]const u8 = if (comp.bin_file.options.emit) |emit|
1240 try emit.basenamePath(arena, try arena.dupeZ(u8, comp.bin_file.intermediary_basename.?))
1241 else
1242 null;
1243
1244 const emit_asm_path = try locPath(arena, comp.emit_asm, cache_dir);
1245 var emit_llvm_ir_path = try locPath(arena, comp.emit_llvm_ir, cache_dir);
1246 const emit_llvm_bc_path = try locPath(arena, comp.emit_llvm_bc, cache_dir);
1247
1248 const emit_asm_msg = emit_asm_path orelse "(none)";
1249 const emit_bin_msg = emit_bin_path orelse "(none)";
1250 const emit_llvm_ir_msg = emit_llvm_ir_path orelse "(none)";
1251 const emit_llvm_bc_msg = emit_llvm_bc_path orelse "(none)";
1230 const emit_asm_msg = options.asm_path orelse "(none)";
1231 const emit_bin_msg = options.bin_path orelse "(none)";
1232 const post_llvm_ir_msg = options.post_ir_path orelse "(none)";
1233 const post_llvm_bc_msg = options.post_bc_path orelse "(none)";
12521234 log.debug("emit LLVM object asm={s} bin={s} ir={s} bc={s}", .{
1253 emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg,
1235 emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,
12541236 });
12551237
1256 if (emit_asm_path == null and emit_bin_path == null and
1257 emit_llvm_ir_path == null and emit_llvm_bc_path == null) return;
1238 if (options.asm_path == null and options.bin_path == null and
1239 options.post_ir_path == null and options.post_bc_path == null) return;
12581240
1259 if (!self.builder.useLibLlvm()) {
1260 log.err("emitting without libllvm not implemented", .{});
1261 return error.FailedToEmit;
1262 }
1241 if (!self.builder.useLibLlvm()) unreachable; // caught in Compilation.Config.resolve
12631242
12641243 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly.
12651244 // So we call the entire pipeline multiple times if this is requested.
12661245 var error_message: [*:0]const u8 = undefined;
1267 if (emit_asm_path != null and emit_bin_path != null) {
1246 var emit_bin_path = options.bin_path;
1247 var post_ir_path = options.post_ir_path;
1248 if (options.asm_path != null and options.bin_path != null) {
12681249 if (self.target_machine.emitToFile(
12691250 self.builder.llvm.module.?,
12701251 &error_message,
1271 comp.bin_file.options.optimize_mode == .Debug,
1272 comp.bin_file.options.optimize_mode == .ReleaseSmall,
1273 comp.time_report,
1274 comp.bin_file.options.tsan,
1275 comp.bin_file.options.lto,
1252 options.is_debug,
1253 options.is_small,
1254 options.time_report,
1255 options.sanitize_thread,
1256 options.lto,
12761257 null,
12771258 emit_bin_path,
1278 emit_llvm_ir_path,
1259 post_ir_path,
12791260 null,
12801261 )) {
12811262 defer llvm.disposeMessage(error_message);
12821263
12831264 log.err("LLVM failed to emit bin={s} ir={s}: {s}", .{
1284 emit_bin_msg, emit_llvm_ir_msg, error_message,
1265 emit_bin_msg, post_llvm_ir_msg, error_message,
12851266 });
12861267 return error.FailedToEmit;
12871268 }
12881269 emit_bin_path = null;
1289 emit_llvm_ir_path = null;
1270 post_ir_path = null;
12901271 }
12911272
12921273 if (self.target_machine.emitToFile(
12931274 self.builder.llvm.module.?,
12941275 &error_message,
1295 comp.bin_file.options.optimize_mode == .Debug,
1296 comp.bin_file.options.optimize_mode == .ReleaseSmall,
1297 comp.time_report,
1298 comp.bin_file.options.tsan,
1299 comp.bin_file.options.lto,
1300 emit_asm_path,
1276 options.is_debug,
1277 options.is_small,
1278 options.time_report,
1279 options.sanitize_thread,
1280 options.lto,
1281 options.asm_path,
13011282 emit_bin_path,
1302 emit_llvm_ir_path,
1303 emit_llvm_bc_path,
1283 post_ir_path,
1284 options.post_bc_path,
13041285 )) {
13051286 defer llvm.disposeMessage(error_message);
13061287
13071288 log.err("LLVM failed to emit asm={s} bin={s} ir={s} bc={s}: {s}", .{
1308 emit_asm_msg, emit_bin_msg, emit_llvm_ir_msg, emit_llvm_bc_msg,
1289 emit_asm_msg, emit_bin_msg, post_llvm_ir_msg, post_llvm_bc_msg,
13091290 error_message,
13101291 });
13111292 return error.FailedToEmit;
......@@ -1314,17 +1295,19 @@ pub const Object = struct {
13141295
13151296 pub fn updateFunc(
13161297 o: *Object,
1317 mod: *Module,
1298 zcu: *Module,
13181299 func_index: InternPool.Index,
13191300 air: Air,
13201301 liveness: Liveness,
13211302 ) !void {
1322 const func = mod.funcInfo(func_index);
1303 const func = zcu.funcInfo(func_index);
13231304 const decl_index = func.owner_decl;
1324 const decl = mod.declPtr(decl_index);
1325 const fn_info = mod.typeToFunc(decl.ty).?;
1326 const target = mod.getTarget();
1327 const ip = &mod.intern_pool;
1305 const decl = zcu.declPtr(decl_index);
1306 const namespace = zcu.namespacePtr(decl.src_namespace);
1307 const owner_mod = namespace.file_scope.mod;
1308 const fn_info = zcu.typeToFunc(decl.ty).?;
1309 const target = zcu.getTarget();
1310 const ip = &zcu.intern_pool;
13281311
13291312 var dg: DeclGen = .{
13301313 .object = o,
......@@ -1359,7 +1342,7 @@ pub const Object = struct {
13591342 }
13601343
13611344 // TODO: disable this if safety is off for the function scope
1362 const ssp_buf_size = mod.comp.bin_file.options.stack_protector;
1345 const ssp_buf_size = owner_mod.stack_protector;
13631346 if (ssp_buf_size != 0) {
13641347 try attributes.addFnAttr(.sspstrong, &o.builder);
13651348 try attributes.addFnAttr(.{ .string = .{
......@@ -1369,7 +1352,7 @@ pub const Object = struct {
13691352 }
13701353
13711354 // TODO: disable this if safety is off for the function scope
1372 if (mod.comp.bin_file.options.stack_check) {
1355 if (owner_mod.stack_check) {
13731356 try attributes.addFnAttr(.{ .string = .{
13741357 .kind = try o.builder.string("probe-stack"),
13751358 .value = try o.builder.string("__zig_probe_stack"),
......@@ -1392,20 +1375,22 @@ pub const Object = struct {
13921375 var llvm_arg_i: u32 = 0;
13931376
13941377 // This gets the LLVM values from the function and stores them in `dg.args`.
1395 const sret = firstParamSRet(fn_info, mod);
1378 const sret = firstParamSRet(fn_info, zcu);
13961379 const ret_ptr: Builder.Value = if (sret) param: {
13971380 const param = wip.arg(llvm_arg_i);
13981381 llvm_arg_i += 1;
13991382 break :param param;
14001383 } else .none;
14011384
1402 if (ccAbiPromoteInt(fn_info.cc, mod, Type.fromInterned(fn_info.return_type))) |s| switch (s) {
1385 if (ccAbiPromoteInt(fn_info.cc, zcu, Type.fromInterned(fn_info.return_type))) |s| switch (s) {
14031386 .signed => try attributes.addRetAttr(.signext, &o.builder),
14041387 .unsigned => try attributes.addRetAttr(.zeroext, &o.builder),
14051388 };
14061389
1407 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(mod) and
1408 mod.comp.bin_file.options.error_return_tracing;
1390 const comp = zcu.comp;
1391
1392 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and
1393 comp.config.any_error_tracing;
14091394
14101395 const err_ret_trace: Builder.Value = if (err_return_tracing) param: {
14111396 const param = wip.arg(llvm_arg_i);
......@@ -1433,8 +1418,8 @@ pub const Object = struct {
14331418 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
14341419 const param = wip.arg(llvm_arg_i);
14351420
1436 if (isByRef(param_ty, mod)) {
1437 const alignment = param_ty.abiAlignment(mod).toLlvm();
1421 if (isByRef(param_ty, zcu)) {
1422 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14381423 const param_llvm_ty = param.typeOfWip(&wip);
14391424 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
14401425 _ = try wip.store(.normal, param, arg_ptr, alignment);
......@@ -1450,12 +1435,12 @@ pub const Object = struct {
14501435 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
14511436 const param_llvm_ty = try o.lowerType(param_ty);
14521437 const param = wip.arg(llvm_arg_i);
1453 const alignment = param_ty.abiAlignment(mod).toLlvm();
1438 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14541439
14551440 try o.addByRefParamAttrs(&attributes, llvm_arg_i, alignment, it.byval_attr, param_llvm_ty);
14561441 llvm_arg_i += 1;
14571442
1458 if (isByRef(param_ty, mod)) {
1443 if (isByRef(param_ty, zcu)) {
14591444 args.appendAssumeCapacity(param);
14601445 } else {
14611446 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));
......@@ -1465,12 +1450,12 @@ pub const Object = struct {
14651450 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
14661451 const param_llvm_ty = try o.lowerType(param_ty);
14671452 const param = wip.arg(llvm_arg_i);
1468 const alignment = param_ty.abiAlignment(mod).toLlvm();
1453 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14691454
14701455 try attributes.addParamAttr(llvm_arg_i, .noundef, &o.builder);
14711456 llvm_arg_i += 1;
14721457
1473 if (isByRef(param_ty, mod)) {
1458 if (isByRef(param_ty, zcu)) {
14741459 args.appendAssumeCapacity(param);
14751460 } else {
14761461 args.appendAssumeCapacity(try wip.load(.normal, param_llvm_ty, param, alignment, ""));
......@@ -1483,11 +1468,11 @@ pub const Object = struct {
14831468 llvm_arg_i += 1;
14841469
14851470 const param_llvm_ty = try o.lowerType(param_ty);
1486 const alignment = param_ty.abiAlignment(mod).toLlvm();
1471 const alignment = param_ty.abiAlignment(zcu).toLlvm();
14871472 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
14881473 _ = try wip.store(.normal, param, arg_ptr, alignment);
14891474
1490 args.appendAssumeCapacity(if (isByRef(param_ty, mod))
1475 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
14911476 arg_ptr
14921477 else
14931478 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
......@@ -1495,14 +1480,14 @@ pub const Object = struct {
14951480 .slice => {
14961481 assert(!it.byval_attr);
14971482 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
1498 const ptr_info = param_ty.ptrInfo(mod);
1483 const ptr_info = param_ty.ptrInfo(zcu);
14991484
15001485 if (math.cast(u5, it.zig_index - 1)) |i| {
15011486 if (@as(u1, @truncate(fn_info.noalias_bits >> i)) != 0) {
15021487 try attributes.addParamAttr(llvm_arg_i, .@"noalias", &o.builder);
15031488 }
15041489 }
1505 if (param_ty.zigTypeTag(mod) != .Optional) {
1490 if (param_ty.zigTypeTag(zcu) != .Optional) {
15061491 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
15071492 }
15081493 if (ptr_info.flags.is_const) {
......@@ -1511,7 +1496,7 @@ pub const Object = struct {
15111496 const elem_align = (if (ptr_info.flags.alignment != .none)
15121497 @as(InternPool.Alignment, ptr_info.flags.alignment)
15131498 else
1514 Type.fromInterned(ptr_info.child).abiAlignment(mod).max(.@"1")).toLlvm();
1499 Type.fromInterned(ptr_info.child).abiAlignment(zcu).max(.@"1")).toLlvm();
15151500 try attributes.addParamAttr(llvm_arg_i, .{ .@"align" = elem_align }, &o.builder);
15161501 const ptr_param = wip.arg(llvm_arg_i);
15171502 llvm_arg_i += 1;
......@@ -1528,7 +1513,7 @@ pub const Object = struct {
15281513 const field_types = it.types_buffer[0..it.types_len];
15291514 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
15301515 const param_llvm_ty = try o.lowerType(param_ty);
1531 const param_alignment = param_ty.abiAlignment(mod).toLlvm();
1516 const param_alignment = param_ty.abiAlignment(zcu).toLlvm();
15321517 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, param_alignment, target);
15331518 const llvm_ty = try o.builder.structType(.normal, field_types);
15341519 for (0..field_types.len) |field_i| {
......@@ -1540,7 +1525,7 @@ pub const Object = struct {
15401525 _ = try wip.store(.normal, param, field_ptr, alignment);
15411526 }
15421527
1543 const is_by_ref = isByRef(param_ty, mod);
1528 const is_by_ref = isByRef(param_ty, zcu);
15441529 args.appendAssumeCapacity(if (is_by_ref)
15451530 arg_ptr
15461531 else
......@@ -1558,11 +1543,11 @@ pub const Object = struct {
15581543 const param = wip.arg(llvm_arg_i);
15591544 llvm_arg_i += 1;
15601545
1561 const alignment = param_ty.abiAlignment(mod).toLlvm();
1546 const alignment = param_ty.abiAlignment(zcu).toLlvm();
15621547 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
15631548 _ = try wip.store(.normal, param, arg_ptr, alignment);
15641549
1565 args.appendAssumeCapacity(if (isByRef(param_ty, mod))
1550 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
15661551 arg_ptr
15671552 else
15681553 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
......@@ -1573,11 +1558,11 @@ pub const Object = struct {
15731558 const param = wip.arg(llvm_arg_i);
15741559 llvm_arg_i += 1;
15751560
1576 const alignment = param_ty.abiAlignment(mod).toLlvm();
1561 const alignment = param_ty.abiAlignment(zcu).toLlvm();
15771562 const arg_ptr = try buildAllocaInner(&wip, false, param_llvm_ty, alignment, target);
15781563 _ = try wip.store(.normal, param, arg_ptr, alignment);
15791564
1580 args.appendAssumeCapacity(if (isByRef(param_ty, mod))
1565 args.appendAssumeCapacity(if (isByRef(param_ty, zcu))
15811566 arg_ptr
15821567 else
15831568 try wip.load(.normal, param_llvm_ty, arg_ptr, alignment, ""));
......@@ -1592,11 +1577,11 @@ pub const Object = struct {
15921577 var di_scope: ?if (build_options.have_llvm) *llvm.DIScope else noreturn = null;
15931578
15941579 if (o.di_builder) |dib| {
1595 di_file = try o.getDIFile(gpa, mod.namespacePtr(decl.src_namespace).file_scope);
1580 di_file = try o.getDIFile(gpa, namespace.file_scope);
15961581
15971582 const line_number = decl.src_line + 1;
1598 const is_internal_linkage = decl.val.getExternFunc(mod) == null and
1599 !mod.decl_exports.contains(decl_index);
1583 const is_internal_linkage = decl.val.getExternFunc(zcu) == null and
1584 !zcu.decl_exports.contains(decl_index);
16001585 const noret_bit: c_uint = if (fn_info.return_type == .noreturn_type)
16011586 llvm.DIFlags.NoReturn
16021587 else
......@@ -1613,7 +1598,7 @@ pub const Object = struct {
16131598 true, // is definition
16141599 line_number + func.lbrace_line, // scope line
16151600 llvm.DIFlags.StaticMember | noret_bit,
1616 mod.comp.bin_file.options.optimize_mode != .Debug,
1601 owner_mod.optimize_mode != .Debug,
16171602 null, // decl_subprogram
16181603 );
16191604 try o.di_map.put(gpa, decl, subprogram.toNode());
......@@ -1634,7 +1619,7 @@ pub const Object = struct {
16341619 .arg_index = 0,
16351620 .func_inst_table = .{},
16361621 .blocks = .{},
1637 .sync_scope = if (mod.comp.bin_file.options.single_threaded) .singlethread else .system,
1622 .sync_scope = if (owner_mod.single_threaded) .singlethread else .system,
16381623 .di_scope = di_scope,
16391624 .di_file = di_file,
16401625 .base_line = dg.decl.src_line,
......@@ -1648,7 +1633,7 @@ pub const Object = struct {
16481633 fg.genBody(air.getMainBody()) catch |err| switch (err) {
16491634 error.CodegenFail => {
16501635 decl.analysis = .codegen_failure;
1651 try mod.failed_decls.put(mod.gpa, decl_index, dg.err_msg.?);
1636 try zcu.failed_decls.put(zcu.gpa, decl_index, dg.err_msg.?);
16521637 dg.err_msg = null;
16531638 return;
16541639 },
......@@ -1657,7 +1642,7 @@ pub const Object = struct {
16571642
16581643 try fg.wip.finish();
16591644
1660 try o.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index));
1645 try o.updateExports(zcu, .{ .decl_index = decl_index }, zcu.getDeclExports(decl_index));
16611646 }
16621647
16631648 pub fn updateDecl(self: *Object, module: *Module, decl_index: InternPool.DeclIndex) !void {
......@@ -1695,6 +1680,7 @@ pub const Object = struct {
16951680 // because we call `updateExports` at the end of `updateFunc` and `updateDecl`.
16961681 const global_index = self.decl_map.get(decl_index) orelse return;
16971682 const decl = mod.declPtr(decl_index);
1683 const comp = mod.comp;
16981684 if (decl.isExtern(mod)) {
16991685 const decl_name = decl_name: {
17001686 const decl_name = mod.intern_pool.stringToSlice(decl.name);
......@@ -1719,7 +1705,8 @@ pub const Object = struct {
17191705 try global_index.rename(decl_name, &self.builder);
17201706 global_index.setLinkage(.external, &self.builder);
17211707 global_index.setUnnamedAddr(.default, &self.builder);
1722 if (mod.wantDllExports()) global_index.setDllStorageClass(.default, &self.builder);
1708 if (comp.config.dll_export_fns)
1709 global_index.setDllStorageClass(.default, &self.builder);
17231710 if (self.di_map.get(decl)) |di_node| {
17241711 const decl_name_slice = decl_name.slice(&self.builder).?;
17251712 if (try decl.isFunction(mod)) {
......@@ -1785,11 +1772,14 @@ pub const Object = struct {
17851772 );
17861773 try global_index.rename(fqn, &self.builder);
17871774 global_index.setLinkage(.internal, &self.builder);
1788 if (mod.wantDllExports()) global_index.setDllStorageClass(.default, &self.builder);
1775 if (comp.config.dll_export_fns)
1776 global_index.setDllStorageClass(.default, &self.builder);
17891777 global_index.setUnnamedAddr(.unnamed_addr, &self.builder);
17901778 if (decl.val.getVariable(mod)) |decl_var| {
1779 const decl_namespace = mod.namespacePtr(decl.src_namespace);
1780 const single_threaded = decl_namespace.file_scope.mod.single_threaded;
17911781 global_index.ptrConst(&self.builder).kind.variable.setThreadLocal(
1792 if (decl_var.is_threadlocal and !mod.comp.bin_file.options.single_threaded)
1782 if (decl_var.is_threadlocal and !single_threaded)
17931783 .generaldynamic
17941784 else
17951785 .default,
......@@ -1842,7 +1832,9 @@ pub const Object = struct {
18421832 exports: []const *Module.Export,
18431833 ) link.File.UpdateExportsError!void {
18441834 global_index.setUnnamedAddr(.default, &o.builder);
1845 if (mod.wantDllExports()) global_index.setDllStorageClass(.dllexport, &o.builder);
1835 const comp = mod.comp;
1836 if (comp.config.dll_export_fns)
1837 global_index.setDllStorageClass(.dllexport, &o.builder);
18461838 global_index.setLinkage(switch (exports[0].opts.linkage) {
18471839 .Internal => unreachable,
18481840 .Strong => .external,
......@@ -2821,7 +2813,7 @@ pub const Object = struct {
28212813 }
28222814
28232815 if (Type.fromInterned(fn_info.return_type).isError(mod) and
2824 o.module.comp.bin_file.options.error_return_tracing)
2816 o.module.comp.config.any_error_tracing)
28252817 {
28262818 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
28272819 try param_di_types.append(try o.lowerDebugType(ptr_ty, .full));
......@@ -2899,7 +2891,7 @@ pub const Object = struct {
28992891 fn getStackTraceType(o: *Object) Allocator.Error!Type {
29002892 const mod = o.module;
29012893
2902 const std_mod = mod.main_mod.deps.get("std").?;
2894 const std_mod = mod.std_mod;
29032895 const std_file = (mod.importPkg(std_mod) catch unreachable).file;
29042896
29052897 const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin");
......@@ -2934,22 +2926,24 @@ pub const Object = struct {
29342926 o: *Object,
29352927 decl_index: InternPool.DeclIndex,
29362928 ) Allocator.Error!Builder.Function.Index {
2937 const mod = o.module;
2938 const ip = &mod.intern_pool;
2929 const zcu = o.module;
2930 const ip = &zcu.intern_pool;
29392931 const gpa = o.gpa;
2940 const decl = mod.declPtr(decl_index);
2932 const decl = zcu.declPtr(decl_index);
2933 const namespace = zcu.namespacePtr(decl.src_namespace);
2934 const owner_mod = namespace.file_scope.mod;
29412935 const zig_fn_type = decl.ty;
29422936 const gop = try o.decl_map.getOrPut(gpa, decl_index);
29432937 if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function;
29442938
29452939 assert(decl.has_tv);
2946 const fn_info = mod.typeToFunc(zig_fn_type).?;
2947 const target = mod.getTarget();
2948 const sret = firstParamSRet(fn_info, mod);
2940 const fn_info = zcu.typeToFunc(zig_fn_type).?;
2941 const target = owner_mod.resolved_target.result;
2942 const sret = firstParamSRet(fn_info, zcu);
29492943
29502944 const function_index = try o.builder.addFunction(
29512945 try o.lowerType(zig_fn_type),
2952 try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(mod))),
2946 try o.builder.string(ip.stringToSlice(try decl.getFullyQualifiedName(zcu))),
29532947 toLlvmAddressSpace(decl.@"addrspace", target),
29542948 );
29552949 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
......@@ -2957,7 +2951,7 @@ pub const Object = struct {
29572951 var attributes: Builder.FunctionAttributes.Wip = .{};
29582952 defer attributes.deinit(&o.builder);
29592953
2960 const is_extern = decl.isExtern(mod);
2954 const is_extern = decl.isExtern(zcu);
29612955 if (!is_extern) {
29622956 function_index.setLinkage(.internal, &o.builder);
29632957 function_index.setUnnamedAddr(.unnamed_addr, &o.builder);
......@@ -2967,7 +2961,7 @@ pub const Object = struct {
29672961 .kind = try o.builder.string("wasm-import-name"),
29682962 .value = try o.builder.string(ip.stringToSlice(decl.name)),
29692963 } }, &o.builder);
2970 if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(mod).?.lib_name)) |lib_name| {
2964 if (ip.stringToSliceUnwrap(decl.getOwnedExternFunc(zcu).?.lib_name)) |lib_name| {
29712965 if (!std.mem.eql(u8, lib_name, "c")) try attributes.addFnAttr(.{ .string = .{
29722966 .kind = try o.builder.string("wasm-import-module"),
29732967 .value = try o.builder.string(lib_name),
......@@ -2988,8 +2982,8 @@ pub const Object = struct {
29882982 llvm_arg_i += 1;
29892983 }
29902984
2991 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(mod) and
2992 mod.comp.bin_file.options.error_return_tracing;
2985 const err_return_tracing = Type.fromInterned(fn_info.return_type).isError(zcu) and
2986 zcu.comp.config.any_error_tracing;
29932987
29942988 if (err_return_tracing) {
29952989 try attributes.addParamAttr(llvm_arg_i, .nonnull, &o.builder);
......@@ -3010,7 +3004,7 @@ pub const Object = struct {
30103004 function_index.setAlignment(fn_info.alignment.toLlvm(), &o.builder);
30113005
30123006 // Function attributes that are independent of analysis results of the function body.
3013 try o.addCommonFnAttributes(&attributes);
3007 try o.addCommonFnAttributes(&attributes, owner_mod);
30143008
30153009 if (fn_info.return_type == .noreturn_type) try attributes.addFnAttr(.noreturn, &o.builder);
30163010
......@@ -3023,14 +3017,14 @@ pub const Object = struct {
30233017 .byval => {
30243018 const param_index = it.zig_index - 1;
30253019 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[param_index]);
3026 if (!isByRef(param_ty, mod)) {
3020 if (!isByRef(param_ty, zcu)) {
30273021 try o.addByValParamAttrs(&attributes, param_ty, param_index, fn_info, it.llvm_index - 1);
30283022 }
30293023 },
30303024 .byref => {
30313025 const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[it.zig_index - 1]);
30323026 const param_llvm_ty = try o.lowerType(param_ty);
3033 const alignment = param_ty.abiAlignment(mod);
3027 const alignment = param_ty.abiAlignment(zcu);
30343028 try o.addByRefParamAttrs(&attributes, it.llvm_index - 1, alignment.toLlvm(), it.byval_attr, param_llvm_ty);
30353029 },
30363030 .byref_mut => try attributes.addParamAttr(it.llvm_index - 1, .noundef, &o.builder),
......@@ -3056,13 +3050,14 @@ pub const Object = struct {
30563050 fn addCommonFnAttributes(
30573051 o: *Object,
30583052 attributes: *Builder.FunctionAttributes.Wip,
3053 owner_mod: *Package.Module,
30593054 ) Allocator.Error!void {
30603055 const comp = o.module.comp;
30613056
3062 if (!comp.bin_file.options.red_zone) {
3057 if (!owner_mod.red_zone) {
30633058 try attributes.addFnAttr(.noredzone, &o.builder);
30643059 }
3065 if (comp.bin_file.options.omit_frame_pointer) {
3060 if (owner_mod.omit_frame_pointer) {
30663061 try attributes.addFnAttr(.{ .string = .{
30673062 .kind = try o.builder.string("frame-pointer"),
30683063 .value = try o.builder.string("none"),
......@@ -3074,12 +3069,10 @@ pub const Object = struct {
30743069 } }, &o.builder);
30753070 }
30763071 try attributes.addFnAttr(.nounwind, &o.builder);
3077 if (comp.unwind_tables) {
3072 if (owner_mod.unwind_tables) {
30783073 try attributes.addFnAttr(.{ .uwtable = Builder.Attribute.UwTable.default }, &o.builder);
30793074 }
3080 if (comp.bin_file.options.skip_linker_dependencies or
3081 comp.bin_file.options.no_builtin)
3082 {
3075 if (comp.skip_linker_dependencies or comp.no_builtin) {
30833076 // The intent here is for compiler-rt and libc functions to not generate
30843077 // infinite recursion. For example, if we are compiling the memcpy function,
30853078 // and llvm detects that the body is equivalent to memcpy, it may replace the
......@@ -3087,26 +3080,27 @@ pub const Object = struct {
30873080 // overflow instead of performing memcpy.
30883081 try attributes.addFnAttr(.nobuiltin, &o.builder);
30893082 }
3090 if (comp.bin_file.options.optimize_mode == .ReleaseSmall) {
3083 if (owner_mod.optimize_mode == .ReleaseSmall) {
30913084 try attributes.addFnAttr(.minsize, &o.builder);
30923085 try attributes.addFnAttr(.optsize, &o.builder);
30933086 }
3094 if (comp.bin_file.options.tsan) {
3087 if (owner_mod.sanitize_thread) {
30953088 try attributes.addFnAttr(.sanitize_thread, &o.builder);
30963089 }
3097 if (comp.getTarget().cpu.model.llvm_name) |s| {
3090 const target = owner_mod.resolved_target.result;
3091 if (target.cpu.model.llvm_name) |s| {
30983092 try attributes.addFnAttr(.{ .string = .{
30993093 .kind = try o.builder.string("target-cpu"),
31003094 .value = try o.builder.string(s),
31013095 } }, &o.builder);
31023096 }
3103 if (comp.bin_file.options.llvm_cpu_features) |s| {
3097 if (owner_mod.resolved_target.llvm_cpu_features) |s| {
31043098 try attributes.addFnAttr(.{ .string = .{
31053099 .kind = try o.builder.string("target-features"),
31063100 .value = try o.builder.string(std.mem.span(s)),
31073101 } }, &o.builder);
31083102 }
3109 if (comp.getTarget().cpu.arch.isBpf()) {
3103 if (target.cpu.arch.isBpf()) {
31103104 try attributes.addFnAttr(.{ .string = .{
31113105 .kind = try o.builder.string("no-builtins"),
31123106 .value = .empty,
......@@ -3176,7 +3170,8 @@ pub const Object = struct {
31763170 variable_index.setLinkage(.external, &o.builder);
31773171 variable_index.setUnnamedAddr(.default, &o.builder);
31783172 if (decl.val.getVariable(mod)) |decl_var| {
3179 const single_threaded = mod.comp.bin_file.options.single_threaded;
3173 const decl_namespace = mod.namespacePtr(decl.src_namespace);
3174 const single_threaded = decl_namespace.file_scope.mod.single_threaded;
31803175 variable_index.setThreadLocal(
31813176 if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default,
31823177 &o.builder,
......@@ -3679,7 +3674,7 @@ pub const Object = struct {
36793674 }
36803675
36813676 if (Type.fromInterned(fn_info.return_type).isError(mod) and
3682 mod.comp.bin_file.options.error_return_tracing)
3677 mod.comp.config.any_error_tracing)
36833678 {
36843679 const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType());
36853680 try llvm_params.append(o.gpa, try o.lowerType(ptr_ty));
......@@ -4648,6 +4643,100 @@ pub const Object = struct {
46484643 .field_index = @intCast(field_index),
46494644 });
46504645 }
4646
4647 fn getCmpLtErrorsLenFunction(o: *Object) !Builder.Function.Index {
4648 const name = try o.builder.string(lt_errors_fn_name);
4649 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
4650
4651 const zcu = o.module;
4652 const target = zcu.root_mod.resolved_target.result;
4653 const function_index = try o.builder.addFunction(
4654 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
4655 name,
4656 toLlvmAddressSpace(.generic, target),
4657 );
4658
4659 var attributes: Builder.FunctionAttributes.Wip = .{};
4660 defer attributes.deinit(&o.builder);
4661 try o.addCommonFnAttributes(&attributes, zcu.root_mod);
4662
4663 function_index.setLinkage(.internal, &o.builder);
4664 function_index.setCallConv(.fastcc, &o.builder);
4665 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
4666 return function_index;
4667 }
4668
4669 fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {
4670 const zcu = o.module;
4671 const ip = &zcu.intern_pool;
4672 const enum_type = ip.indexToKey(enum_ty.toIntern()).enum_type;
4673
4674 // TODO: detect when the type changes and re-emit this function.
4675 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
4676 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;
4677 errdefer assert(o.decl_map.remove(enum_type.decl));
4678
4679 const usize_ty = try o.lowerType(Type.usize);
4680 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4681 const fqn = try zcu.declPtr(enum_type.decl).getFullyQualifiedName(zcu);
4682 const target = zcu.root_mod.resolved_target.result;
4683 const function_index = try o.builder.addFunction(
4684 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
4685 try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),
4686 toLlvmAddressSpace(.generic, target),
4687 );
4688
4689 var attributes: Builder.FunctionAttributes.Wip = .{};
4690 defer attributes.deinit(&o.builder);
4691 try o.addCommonFnAttributes(&attributes, zcu.root_mod);
4692
4693 function_index.setLinkage(.internal, &o.builder);
4694 function_index.setCallConv(.fastcc, &o.builder);
4695 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
4696 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
4697
4698 var wip = try Builder.WipFunction.init(&o.builder, function_index);
4699 defer wip.deinit();
4700 wip.cursor = .{ .block = try wip.block(0, "Entry") };
4701
4702 const bad_value_block = try wip.block(1, "BadValue");
4703 const tag_int_value = wip.arg(0);
4704 var wip_switch =
4705 try wip.@"switch"(tag_int_value, bad_value_block, @intCast(enum_type.names.len));
4706 defer wip_switch.finish(&wip);
4707
4708 for (0..enum_type.names.len) |field_index| {
4709 const name = try o.builder.string(ip.stringToSlice(enum_type.names.get(ip)[field_index]));
4710 const name_init = try o.builder.stringNullConst(name);
4711 const name_variable_index =
4712 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
4713 try name_variable_index.setInitializer(name_init, &o.builder);
4714 name_variable_index.setLinkage(.private, &o.builder);
4715 name_variable_index.setMutability(.constant, &o.builder);
4716 name_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
4717 name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);
4718
4719 const name_val = try o.builder.structValue(ret_ty, &.{
4720 name_variable_index.toConst(&o.builder),
4721 try o.builder.intConst(usize_ty, name.slice(&o.builder).?.len),
4722 });
4723
4724 const return_block = try wip.block(1, "Name");
4725 const this_tag_int_value = try o.lowerValue(
4726 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
4727 );
4728 try wip_switch.addCase(this_tag_int_value, return_block, &wip);
4729
4730 wip.cursor = .{ .block = return_block };
4731 _ = try wip.ret(name_val);
4732 }
4733
4734 wip.cursor = .{ .block = bad_value_block };
4735 _ = try wip.@"unreachable"();
4736
4737 try wip.finish();
4738 return function_index;
4739 }
46514740};
46524741
46534742pub const DeclGen = struct {
......@@ -4656,6 +4745,13 @@ pub const DeclGen = struct {
46564745 decl_index: InternPool.DeclIndex,
46574746 err_msg: ?*Module.ErrorMsg,
46584747
4748 fn ownerModule(dg: DeclGen) *Package.Module {
4749 const o = dg.object;
4750 const zcu = o.module;
4751 const namespace = zcu.namespacePtr(dg.decl.src_namespace);
4752 return namespace.file_scope.mod;
4753 }
4754
46594755 fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
46604756 @setCold(true);
46614757 assert(dg.err_msg == null);
......@@ -5144,7 +5240,7 @@ pub const FuncGen = struct {
51445240 };
51455241
51465242 const err_return_tracing = return_type.isError(mod) and
5147 o.module.comp.bin_file.options.error_return_tracing;
5243 o.module.comp.config.any_error_tracing;
51485244 if (err_return_tracing) {
51495245 assert(self.err_ret_trace != .none);
51505246 try llvm_args.append(self.err_ret_trace);
......@@ -5616,7 +5712,7 @@ pub const FuncGen = struct {
56165712 const o = self.dg.object;
56175713 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
56185714 const operand = try self.resolveInst(un_op);
5619 const llvm_fn = try self.getCmpLtErrorsLenFunction();
5715 const llvm_fn = try o.getCmpLtErrorsLenFunction();
56205716 return self.wip.call(
56215717 .normal,
56225718 .fastcc,
......@@ -6549,11 +6645,13 @@ pub const FuncGen = struct {
65496645 const dib = o.di_builder orelse return .none;
65506646 const ty_fn = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_fn;
65516647
6552 const mod = o.module;
6553 const func = mod.funcInfo(ty_fn.func);
6648 const zcu = o.module;
6649 const func = zcu.funcInfo(ty_fn.func);
65546650 const decl_index = func.owner_decl;
6555 const decl = mod.declPtr(decl_index);
6556 const di_file = try o.getDIFile(self.gpa, mod.namespacePtr(decl.src_namespace).file_scope);
6651 const decl = zcu.declPtr(decl_index);
6652 const namespace = zcu.namespacePtr(decl.src_namespace);
6653 const owner_mod = namespace.file_scope.mod;
6654 const di_file = try o.getDIFile(self.gpa, zcu.namespacePtr(decl.src_namespace).file_scope);
65576655 self.di_file = di_file;
65586656 const line_number = decl.src_line + 1;
65596657 const cur_debug_location = self.wip.llvm.builder.getCurrentDebugLocation2();
......@@ -6564,18 +6662,18 @@ pub const FuncGen = struct {
65646662 .base_line = self.base_line,
65656663 });
65666664
6567 const fqn = try decl.getFullyQualifiedName(mod);
6665 const fqn = try decl.getFullyQualifiedName(zcu);
65686666
6569 const is_internal_linkage = !mod.decl_exports.contains(decl_index);
6570 const fn_ty = try mod.funcType(.{
6667 const is_internal_linkage = !zcu.decl_exports.contains(decl_index);
6668 const fn_ty = try zcu.funcType(.{
65716669 .param_types = &.{},
65726670 .return_type = .void_type,
65736671 });
65746672 const fn_di_ty = try o.lowerDebugType(fn_ty, .full);
65756673 const subprogram = dib.createFunction(
65766674 di_file.toScope(),
6577 mod.intern_pool.stringToSlice(decl.name),
6578 mod.intern_pool.stringToSlice(fqn),
6675 zcu.intern_pool.stringToSlice(decl.name),
6676 zcu.intern_pool.stringToSlice(fqn),
65796677 di_file,
65806678 line_number,
65816679 fn_di_ty,
......@@ -6583,7 +6681,7 @@ pub const FuncGen = struct {
65836681 true, // is definition
65846682 line_number + func.lbrace_line, // scope line
65856683 llvm.DIFlags.StaticMember,
6586 mod.comp.bin_file.options.optimize_mode != .Debug,
6684 owner_mod.optimize_mode != .Debug,
65876685 null, // decl_subprogram
65886686 );
65896687
......@@ -6678,11 +6776,12 @@ pub const FuncGen = struct {
66786776 null;
66796777 const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at);
66806778 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
6681 const mod = o.module;
6682 if (isByRef(operand_ty, mod)) {
6779 const zcu = o.module;
6780 const owner_mod = self.dg.ownerModule();
6781 if (isByRef(operand_ty, zcu)) {
66836782 _ = dib.insertDeclareAtEnd(operand.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
6684 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
6685 const alignment = operand_ty.abiAlignment(mod).toLlvm();
6783 } else if (owner_mod.optimize_mode == .Debug) {
6784 const alignment = operand_ty.abiAlignment(zcu).toLlvm();
66866785 const alloca = try self.buildAlloca(operand.typeOfWip(&self.wip), alignment);
66876786 _ = try self.wip.store(.normal, operand, alloca, alignment);
66886787 _ = dib.insertDeclareAtEnd(alloca.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
......@@ -8731,9 +8830,10 @@ pub const FuncGen = struct {
87318830
87328831 const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null);
87338832 const insert_block = self.wip.cursor.block.toLlvm(&self.wip);
8833 const owner_mod = self.dg.ownerModule();
87348834 if (isByRef(inst_ty, mod)) {
87358835 _ = dib.insertDeclareAtEnd(arg_val.toLlvm(&self.wip), di_local_var, debug_loc, insert_block);
8736 } else if (o.module.comp.bin_file.options.optimize_mode == .Debug) {
8836 } else if (owner_mod.optimize_mode == .Debug) {
87378837 const alignment = inst_ty.abiAlignment(mod).toLlvm();
87388838 const alloca = try self.buildAlloca(arg_val.typeOfWip(&self.wip), alignment);
87398839 _ = try self.wip.store(.normal, arg_val, alloca, alignment);
......@@ -8823,7 +8923,8 @@ pub const FuncGen = struct {
88238923 len,
88248924 if (ptr_ty.isVolatilePtr(mod)) .@"volatile" else .normal,
88258925 );
8826 if (safety and mod.comp.bin_file.options.valgrind) {
8926 const owner_mod = self.dg.ownerModule();
8927 if (safety and owner_mod.valgrind) {
88278928 try self.valgrindMarkUndef(dest_ptr, len);
88288929 }
88298930 return .none;
......@@ -9139,7 +9240,8 @@ pub const FuncGen = struct {
91399240 } else {
91409241 _ = try self.wip.callMemSet(dest_ptr, dest_ptr_align, fill_byte, len, access_kind);
91419242 }
9142 if (safety and mod.comp.bin_file.options.valgrind) {
9243 const owner_mod = self.dg.ownerModule();
9244 if (safety and owner_mod.valgrind) {
91439245 try self.valgrindMarkUndef(dest_ptr, len);
91449246 }
91459247 return .none;
......@@ -9490,24 +9592,25 @@ pub const FuncGen = struct {
94909592
94919593 fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
94929594 const o = self.dg.object;
9493 const mod = o.module;
9494 const enum_type = mod.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
9595 const zcu = o.module;
9596 const enum_type = zcu.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
94959597
94969598 // TODO: detect when the type changes and re-emit this function.
94979599 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
94989600 if (gop.found_existing) return gop.value_ptr.*;
94999601 errdefer assert(o.named_enum_map.remove(enum_type.decl));
95009602
9501 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9603 const fqn = try zcu.declPtr(enum_type.decl).getFullyQualifiedName(zcu);
9604 const target = zcu.root_mod.resolved_target.result;
95029605 const function_index = try o.builder.addFunction(
95039606 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9504 try o.builder.fmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&mod.intern_pool)}),
9505 toLlvmAddressSpace(.generic, mod.getTarget()),
9607 try o.builder.fmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}),
9608 toLlvmAddressSpace(.generic, target),
95069609 );
95079610
95089611 var attributes: Builder.FunctionAttributes.Wip = .{};
95099612 defer attributes.deinit(&o.builder);
9510 try o.addCommonFnAttributes(&attributes);
9613 try o.addCommonFnAttributes(&attributes, zcu.root_mod);
95119614
95129615 function_index.setLinkage(.internal, &o.builder);
95139616 function_index.setCallConv(.fastcc, &o.builder);
......@@ -9526,7 +9629,7 @@ pub const FuncGen = struct {
95269629
95279630 for (0..enum_type.names.len) |field_index| {
95289631 const this_tag_int_value = try o.lowerValue(
9529 (try mod.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
9632 (try zcu.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
95309633 );
95319634 try wip_switch.addCase(this_tag_int_value, named_block, &wip);
95329635 }
......@@ -9546,7 +9649,7 @@ pub const FuncGen = struct {
95469649 const operand = try self.resolveInst(un_op);
95479650 const enum_ty = self.typeOf(un_op);
95489651
9549 const llvm_fn = try self.getEnumTagNameFunction(enum_ty);
9652 const llvm_fn = try o.getEnumTagNameFunction(enum_ty);
95509653 return self.wip.call(
95519654 .normal,
95529655 .fastcc,
......@@ -9558,100 +9661,6 @@ pub const FuncGen = struct {
95589661 );
95599662 }
95609663
9561 fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
9562 const o = self.dg.object;
9563 const mod = o.module;
9564 const ip = &mod.intern_pool;
9565 const enum_type = ip.indexToKey(enum_ty.toIntern()).enum_type;
9566
9567 // TODO: detect when the type changes and re-emit this function.
9568 const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
9569 if (gop.found_existing) return gop.value_ptr.ptrConst(&o.builder).kind.function;
9570 errdefer assert(o.decl_map.remove(enum_type.decl));
9571
9572 const usize_ty = try o.lowerType(Type.usize);
9573 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
9574 const fqn = try mod.declPtr(enum_type.decl).getFullyQualifiedName(mod);
9575 const function_index = try o.builder.addFunction(
9576 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9577 try o.builder.fmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),
9578 toLlvmAddressSpace(.generic, mod.getTarget()),
9579 );
9580
9581 var attributes: Builder.FunctionAttributes.Wip = .{};
9582 defer attributes.deinit(&o.builder);
9583 try o.addCommonFnAttributes(&attributes);
9584
9585 function_index.setLinkage(.internal, &o.builder);
9586 function_index.setCallConv(.fastcc, &o.builder);
9587 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9588 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
9589
9590 var wip = try Builder.WipFunction.init(&o.builder, function_index);
9591 defer wip.deinit();
9592 wip.cursor = .{ .block = try wip.block(0, "Entry") };
9593
9594 const bad_value_block = try wip.block(1, "BadValue");
9595 const tag_int_value = wip.arg(0);
9596 var wip_switch =
9597 try wip.@"switch"(tag_int_value, bad_value_block, @intCast(enum_type.names.len));
9598 defer wip_switch.finish(&wip);
9599
9600 for (0..enum_type.names.len) |field_index| {
9601 const name = try o.builder.string(ip.stringToSlice(enum_type.names.get(ip)[field_index]));
9602 const name_init = try o.builder.stringNullConst(name);
9603 const name_variable_index =
9604 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
9605 try name_variable_index.setInitializer(name_init, &o.builder);
9606 name_variable_index.setLinkage(.private, &o.builder);
9607 name_variable_index.setMutability(.constant, &o.builder);
9608 name_variable_index.setUnnamedAddr(.unnamed_addr, &o.builder);
9609 name_variable_index.setAlignment(comptime Builder.Alignment.fromByteUnits(1), &o.builder);
9610
9611 const name_val = try o.builder.structValue(ret_ty, &.{
9612 name_variable_index.toConst(&o.builder),
9613 try o.builder.intConst(usize_ty, name.slice(&o.builder).?.len),
9614 });
9615
9616 const return_block = try wip.block(1, "Name");
9617 const this_tag_int_value = try o.lowerValue(
9618 (try mod.enumValueFieldIndex(enum_ty, @intCast(field_index))).toIntern(),
9619 );
9620 try wip_switch.addCase(this_tag_int_value, return_block, &wip);
9621
9622 wip.cursor = .{ .block = return_block };
9623 _ = try wip.ret(name_val);
9624 }
9625
9626 wip.cursor = .{ .block = bad_value_block };
9627 _ = try wip.@"unreachable"();
9628
9629 try wip.finish();
9630 return function_index;
9631 }
9632
9633 fn getCmpLtErrorsLenFunction(self: *FuncGen) !Builder.Function.Index {
9634 const o = self.dg.object;
9635
9636 const name = try o.builder.string(lt_errors_fn_name);
9637 if (o.builder.getGlobal(name)) |llvm_fn| return llvm_fn.ptrConst(&o.builder).kind.function;
9638
9639 const function_index = try o.builder.addFunction(
9640 try o.builder.fnType(.i1, &.{try o.errorIntType()}, .normal),
9641 name,
9642 toLlvmAddressSpace(.generic, o.module.getTarget()),
9643 );
9644
9645 var attributes: Builder.FunctionAttributes.Wip = .{};
9646 defer attributes.deinit(&o.builder);
9647 try o.addCommonFnAttributes(&attributes);
9648
9649 function_index.setLinkage(.internal, &o.builder);
9650 function_index.setCallConv(.fastcc, &o.builder);
9651 function_index.setAttributes(try attributes.finish(&o.builder), &o.builder);
9652 return function_index;
9653 }
9654
96559664 fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
96569665 const o = self.dg.object;
96579666 const un_op = self.air.instructions.items(.data)[@intFromEnum(inst)].un_op;
src/codegen/spirv.zig+4-8
......@@ -191,13 +191,9 @@ pub const Object = struct {
191191 air: Air,
192192 liveness: Liveness,
193193 ) !void {
194 const target = mod.getTarget();
195 // We always want a structured control flow in shaders. This option is only relevant
196 // for OpenCL kernels.
197 const want_structured_cfg = switch (target.os.tag) {
198 .opencl => mod.comp.bin_file.options.want_structured_cfg orelse false,
199 else => true,
200 };
194 const decl = mod.declPtr(decl_index);
195 const namespace = mod.namespacePtr(decl.src_namespace);
196 const structured_cfg = namespace.file_scope.mod.structured_cfg;
201197
202198 var decl_gen = DeclGen{
203199 .gpa = self.gpa,
......@@ -208,7 +204,7 @@ pub const Object = struct {
208204 .air = air,
209205 .liveness = liveness,
210206 .type_map = &self.type_map,
211 .control_flow = switch (want_structured_cfg) {
207 .control_flow = switch (structured_cfg) {
212208 true => .{ .structured = .{} },
213209 false => .{ .unstructured = .{} },
214210 },
src/glibc.zig+68-32
......@@ -12,7 +12,7 @@ const Compilation = @import("Compilation.zig");
1212const build_options = @import("build_options");
1313const trace = @import("tracy.zig").trace;
1414const Cache = std.Build.Cache;
15const Package = @import("Package.zig");
15const Module = @import("Package/Module.zig");
1616
1717pub const Lib = struct {
1818 name: []const u8,
......@@ -170,7 +170,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
170170 defer arena_allocator.deinit();
171171 const arena = arena_allocator.allocator();
172172
173 const target = comp.getTarget();
173 const target = comp.root_mod.resolved_target.result;
174174 const target_ver = target.os.version_range.linux.glibc;
175175 const start_old_init_fini = target_ver.order(.{ .major = 2, .minor = 33, .patch = 0 }) != .gt;
176176
......@@ -196,12 +196,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
196196 "-DASSEMBLER",
197197 "-Wa,--noexecstack",
198198 });
199 return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &.{
199 var files = [_]Compilation.CSourceFile{
200200 .{
201201 .src_path = try start_asm_path(comp, arena, "crti.S"),
202202 .cache_exempt_flags = args.items,
203 .owner = comp.root_mod,
203204 },
204 });
205 };
206 return comp.build_crt_file("crti", .Obj, .@"glibc crti.o", prog_node, &files);
205207 },
206208 .crtn_o => {
207209 var args = std.ArrayList([]const u8).init(arena);
......@@ -215,12 +217,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
215217 "-DASSEMBLER",
216218 "-Wa,--noexecstack",
217219 });
218 return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &.{
220 var files = [_]Compilation.CSourceFile{
219221 .{
220222 .src_path = try start_asm_path(comp, arena, "crtn.S"),
221223 .cache_exempt_flags = args.items,
224 .owner = undefined,
222225 },
223 });
226 };
227 return comp.build_crt_file("crtn", .Obj, .@"glibc crtn.o", prog_node, &files);
224228 },
225229 .scrt1_o => {
226230 const start_o: Compilation.CSourceFile = blk: {
......@@ -244,6 +248,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
244248 break :blk .{
245249 .src_path = try start_asm_path(comp, arena, src_path),
246250 .cache_exempt_flags = args.items,
251 .owner = undefined,
247252 };
248253 };
249254 const abi_note_o: Compilation.CSourceFile = blk: {
......@@ -263,11 +268,11 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
263268 break :blk .{
264269 .src_path = try lib_path(comp, arena, lib_libc_glibc ++ "csu" ++ path.sep_str ++ "abi-note.S"),
265270 .cache_exempt_flags = args.items,
271 .owner = undefined,
266272 };
267273 };
268 return comp.build_crt_file("Scrt1", .Obj, .@"glibc Scrt1.o", prog_node, &.{
269 start_o, abi_note_o,
270 });
274 var files = [_]Compilation.CSourceFile{ start_o, abi_note_o };
275 return comp.build_crt_file("Scrt1", .Obj, .@"glibc Scrt1.o", prog_node, &files);
271276 },
272277 .libc_nonshared_a => {
273278 const s = path.sep_str;
......@@ -364,6 +369,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
364369 files_buf[files_index] = .{
365370 .src_path = try lib_path(comp, arena, dep.path),
366371 .cache_exempt_flags = args.items,
372 .owner = undefined,
367373 };
368374 files_index += 1;
369375 }
......@@ -1061,40 +1067,70 @@ fn buildSharedLib(
10611067 const version: Version = .{ .major = lib.sover, .minor = 0, .patch = 0 };
10621068 const ld_basename = path.basename(comp.getTarget().standardDynamicLinkerPath().get().?);
10631069 const soname = if (mem.eql(u8, lib.name, "ld")) ld_basename else basename;
1064 const map_file_path = try path.join(arena, &[_][]const u8{ bin_directory.path.?, all_map_basename });
1070 const map_file_path = try path.join(arena, &.{ bin_directory.path.?, all_map_basename });
1071
1072 const optimize_mode = comp.compilerRtOptMode();
1073 const strip = comp.compilerRtStrip();
1074 const config = try Compilation.Config.resolve(.{
1075 .output_mode = .Lib,
1076 .link_mode = .Dynamic,
1077 .resolved_target = comp.root_mod.resolved_target,
1078 .is_test = false,
1079 .have_zcu = false,
1080 .emit_bin = true,
1081 .root_optimize_mode = optimize_mode,
1082 .root_strip = strip,
1083 .link_libc = false,
1084 });
1085
1086 const root_mod = try Module.create(arena, .{
1087 .global_cache_directory = comp.global_cache_directory,
1088 .paths = .{
1089 .root = .{ .root_dir = comp.zig_lib_directory },
1090 .root_src_path = "",
1091 },
1092 .fully_qualified_name = "root",
1093 .inherited = .{
1094 .resolved_target = comp.root_mod.resolved_target,
1095 .strip = strip,
1096 .stack_check = false,
1097 .stack_protector = 0,
1098 .sanitize_c = false,
1099 .sanitize_thread = false,
1100 .red_zone = comp.root_mod.red_zone,
1101 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
1102 .valgrind = false,
1103 .optimize_mode = optimize_mode,
1104 .structured_cfg = comp.root_mod.structured_cfg,
1105 },
1106 .global = config,
1107 .cc_argv = &.{},
1108 .parent = null,
1109 .builtin_mod = null,
1110 });
1111
10651112 const c_source_files = [1]Compilation.CSourceFile{
10661113 .{
1067 .src_path = try path.join(arena, &[_][]const u8{ bin_directory.path.?, asm_file_basename }),
1114 .src_path = try path.join(arena, &.{ bin_directory.path.?, asm_file_basename }),
1115 .owner = root_mod,
10681116 },
10691117 };
1070 const sub_compilation = try Compilation.create(comp.gpa, .{
1118
1119 const sub_compilation = try Compilation.create(comp.gpa, arena, .{
10711120 .local_cache_directory = zig_cache_directory,
10721121 .global_cache_directory = comp.global_cache_directory,
10731122 .zig_lib_directory = comp.zig_lib_directory,
1074 .cache_mode = .whole,
1075 .target = comp.getTarget(),
1076 .root_name = lib.name,
1077 .main_mod = null,
1078 .output_mode = .Lib,
1079 .link_mode = .Dynamic,
10801123 .thread_pool = comp.thread_pool,
1081 .libc_installation = comp.bin_file.options.libc_installation,
1124 .self_exe_path = comp.self_exe_path,
1125 .cache_mode = .incremental,
1126 .config = config,
1127 .root_mod = root_mod,
1128 .root_name = lib.name,
1129 .libc_installation = comp.libc_installation,
10821130 .emit_bin = emit_bin,
1083 .optimize_mode = comp.compilerRtOptMode(),
1084 .want_sanitize_c = false,
1085 .want_stack_check = false,
1086 .want_stack_protector = 0,
1087 .want_red_zone = comp.bin_file.options.red_zone,
1088 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
1089 .want_valgrind = false,
1090 .want_tsan = false,
10911131 .emit_h = null,
1092 .strip = comp.compilerRtStrip(),
1093 .is_native_os = false,
1094 .is_native_abi = false,
1095 .self_exe_path = comp.self_exe_path,
10961132 .verbose_cc = comp.verbose_cc,
1097 .verbose_link = comp.bin_file.options.verbose_link,
1133 .verbose_link = comp.verbose_link,
10981134 .verbose_air = comp.verbose_air,
10991135 .verbose_llvm_ir = comp.verbose_llvm_ir,
11001136 .verbose_llvm_bc = comp.verbose_llvm_bc,
src/libc_installation.zig+6-7
......@@ -41,7 +41,7 @@ pub const LibCInstallation = struct {
4141 pub fn parse(
4242 allocator: Allocator,
4343 libc_file: []const u8,
44 target: std.zig.CrossTarget,
44 target: std.Target,
4545 ) !LibCInstallation {
4646 var self: LibCInstallation = .{};
4747
......@@ -95,24 +95,23 @@ pub const LibCInstallation = struct {
9595 return error.ParseError;
9696 }
9797
98 const os_tag = target.getOsTag();
98 const os_tag = target.os.tag;
9999 if (self.crt_dir == null and !target.isDarwin()) {
100100 log.err("crt_dir may not be empty for {s}\n", .{@tagName(os_tag)});
101101 return error.ParseError;
102102 }
103103
104 const abi = target.getAbi();
105 if (self.msvc_lib_dir == null and target.isWindows() and abi == .msvc) {
104 if (self.msvc_lib_dir == null and os_tag == .windows and target.abi == .msvc) {
106105 log.err("msvc_lib_dir may not be empty for {s}-{s}\n", .{
107106 @tagName(os_tag),
108 @tagName(abi),
107 @tagName(target.abi),
109108 });
110109 return error.ParseError;
111110 }
112 if (self.kernel32_lib_dir == null and target.isWindows() and abi == .msvc) {
111 if (self.kernel32_lib_dir == null and os_tag == .windows and target.abi == .msvc) {
113112 log.err("kernel32_lib_dir may not be empty for {s}-{s}\n", .{
114113 @tagName(os_tag),
115 @tagName(abi),
114 @tagName(target.abi),
116115 });
117116 return error.ParseError;
118117 }
src/libcxx.zig+112-65
......@@ -6,6 +6,7 @@ const target_util = @import("target.zig");
66const Compilation = @import("Compilation.zig");
77const build_options = @import("build_options");
88const trace = @import("tracy.zig").trace;
9const Module = @import("Package/Module.zig");
910
1011pub const AbiVersion = enum(u2) {
1112 @"1" = 1,
......@@ -115,7 +116,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
115116 const root_name = "c++";
116117 const output_mode = .Lib;
117118 const link_mode = .Static;
118 const target = comp.getTarget();
119 const target = comp.root_mod.resolved_target.result;
119120 const basename = try std.zig.binNameAlloc(arena, .{
120121 .root_name = root_name,
121122 .target = target,
......@@ -137,6 +138,50 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
137138 const abi_namespace_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
138139 @intFromEnum(comp.libcxx_abi_version),
139140 });
141
142 const optimize_mode = comp.compilerRtOptMode();
143 const strip = comp.compilerRtStrip();
144
145 const config = try Compilation.Config.resolve(.{
146 .output_mode = output_mode,
147 .link_mode = link_mode,
148 .resolved_target = comp.root_mod.resolved_target,
149 .is_test = false,
150 .have_zcu = false,
151 .emit_bin = true,
152 .root_optimize_mode = optimize_mode,
153 .root_strip = strip,
154 .link_libc = true,
155 .lto = comp.config.lto,
156 });
157
158 const root_mod = try Module.create(arena, .{
159 .global_cache_directory = comp.global_cache_directory,
160 .paths = .{
161 .root = .{ .root_dir = comp.zig_lib_directory },
162 .root_src_path = "",
163 },
164 .fully_qualified_name = "root",
165 .inherited = .{
166 .resolved_target = comp.root_mod.resolved_target,
167 .strip = strip,
168 .stack_check = false,
169 .stack_protector = 0,
170 .sanitize_c = false,
171 .sanitize_thread = comp.config.any_sanitize_thread,
172 .red_zone = comp.root_mod.red_zone,
173 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
174 .valgrind = false,
175 .optimize_mode = optimize_mode,
176 .structured_cfg = comp.root_mod.structured_cfg,
177 .pic = comp.root_mod.pic,
178 },
179 .global = config,
180 .cc_argv = &.{},
181 .parent = null,
182 .builtin_mod = null,
183 });
184
140185 var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxx_files.len);
141186
142187 for (libcxx_files) |cxx_src| {
......@@ -154,7 +199,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
154199 continue;
155200 if (std.mem.startsWith(u8, cxx_src, "src/support/ibm/") and target.os.tag != .zos)
156201 continue;
157 if (comp.bin_file.options.single_threaded) {
202 if (!comp.config.any_non_single_threaded) {
158203 if (std.mem.startsWith(u8, cxx_src, "src/support/win32/thread_win32.cpp")) {
159204 continue;
160205 }
......@@ -223,49 +268,32 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
223268 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxx", cxx_src }),
224269 .extra_flags = cflags.items,
225270 .cache_exempt_flags = cache_exempt_flags.items,
271 .owner = root_mod,
226272 });
227273 }
228274
229 const sub_compilation = try Compilation.create(comp.gpa, .{
275 const sub_compilation = try Compilation.create(comp.gpa, arena, .{
230276 .local_cache_directory = comp.global_cache_directory,
231277 .global_cache_directory = comp.global_cache_directory,
232278 .zig_lib_directory = comp.zig_lib_directory,
279 .self_exe_path = comp.self_exe_path,
233280 .cache_mode = .whole,
234 .target = target,
281 .config = config,
282 .root_mod = root_mod,
235283 .root_name = root_name,
236 .main_mod = null,
237 .output_mode = output_mode,
238284 .thread_pool = comp.thread_pool,
239 .libc_installation = comp.bin_file.options.libc_installation,
285 .libc_installation = comp.libc_installation,
240286 .emit_bin = emit_bin,
241 .optimize_mode = comp.compilerRtOptMode(),
242 .link_mode = link_mode,
243 .want_sanitize_c = false,
244 .want_stack_check = false,
245 .want_stack_protector = 0,
246 .want_red_zone = comp.bin_file.options.red_zone,
247 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
248 .want_valgrind = false,
249 .want_tsan = comp.bin_file.options.tsan,
250 .want_pic = comp.bin_file.options.pic,
251 .want_pie = null,
252 .want_lto = comp.bin_file.options.lto,
253 .function_sections = comp.bin_file.options.function_sections,
254287 .emit_h = null,
255 .strip = comp.compilerRtStrip(),
256 .is_native_os = comp.bin_file.options.is_native_os,
257 .is_native_abi = comp.bin_file.options.is_native_abi,
258 .self_exe_path = comp.self_exe_path,
259288 .c_source_files = c_source_files.items,
260289 .verbose_cc = comp.verbose_cc,
261 .verbose_link = comp.bin_file.options.verbose_link,
290 .verbose_link = comp.verbose_link,
262291 .verbose_air = comp.verbose_air,
263292 .verbose_llvm_ir = comp.verbose_llvm_ir,
264293 .verbose_llvm_bc = comp.verbose_llvm_bc,
265294 .verbose_cimport = comp.verbose_cimport,
266295 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
267296 .clang_passthrough_mode = comp.clang_passthrough_mode,
268 .link_libc = true,
269297 .skip_linker_dependencies = true,
270298 });
271299 defer sub_compilation.destroy();
......@@ -273,12 +301,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
273301 try comp.updateSubCompilation(sub_compilation, .libcxx, prog_node);
274302
275303 assert(comp.libcxx_static_lib == null);
276 comp.libcxx_static_lib = Compilation.CRTFile{
277 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
278 sub_compilation.bin_file.options.emit.?.sub_path,
279 }),
280 .lock = sub_compilation.bin_file.toOwnedLock(),
281 };
304 comp.libcxx_static_lib = try sub_compilation.toCrtFile();
282305}
283306
284307pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
......@@ -296,7 +319,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
296319 const root_name = "c++abi";
297320 const output_mode = .Lib;
298321 const link_mode = .Static;
299 const target = comp.getTarget();
322 const target = comp.root_mod.resolved_target.result;
300323 const basename = try std.zig.binNameAlloc(arena, .{
301324 .root_name = root_name,
302325 .target = target,
......@@ -318,6 +341,53 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
318341 const abi_namespace_arg = try std.fmt.allocPrint(arena, "-D_LIBCPP_ABI_NAMESPACE=__{d}", .{
319342 @intFromEnum(comp.libcxx_abi_version),
320343 });
344
345 const optimize_mode = comp.compilerRtOptMode();
346 const strip = comp.compilerRtStrip();
347 const unwind_tables = true;
348
349 const config = try Compilation.Config.resolve(.{
350 .output_mode = output_mode,
351 .link_mode = link_mode,
352 .resolved_target = comp.root_mod.resolved_target,
353 .is_test = false,
354 .have_zcu = false,
355 .emit_bin = true,
356 .root_optimize_mode = optimize_mode,
357 .root_strip = strip,
358 .link_libc = true,
359 .any_unwind_tables = unwind_tables,
360 .lto = comp.config.lto,
361 });
362
363 const root_mod = try Module.create(arena, .{
364 .global_cache_directory = comp.global_cache_directory,
365 .paths = .{
366 .root = .{ .root_dir = comp.zig_lib_directory },
367 .root_src_path = "",
368 },
369 .fully_qualified_name = "root",
370 .inherited = .{
371 .resolved_target = comp.root_mod.resolved_target,
372 .strip = strip,
373 .stack_check = false,
374 .stack_protector = 0,
375 .sanitize_c = false,
376 .sanitize_thread = comp.config.any_sanitize_thread,
377 .red_zone = comp.root_mod.red_zone,
378 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
379 .valgrind = false,
380 .optimize_mode = optimize_mode,
381 .structured_cfg = comp.root_mod.structured_cfg,
382 .unwind_tables = unwind_tables,
383 .pic = comp.root_mod.pic,
384 },
385 .global = config,
386 .cc_argv = &.{},
387 .parent = null,
388 .builtin_mod = null,
389 });
390
321391 var c_source_files = try std.ArrayList(Compilation.CSourceFile).initCapacity(arena, libcxxabi_files.len);
322392
323393 for (libcxxabi_files) |cxxabi_src| {
......@@ -332,7 +402,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
332402 }
333403
334404 // WASM targets are single threaded.
335 if (comp.bin_file.options.single_threaded) {
405 if (!comp.config.any_non_single_threaded) {
336406 if (std.mem.startsWith(u8, cxxabi_src, "src/cxa_thread_atexit.cpp")) {
337407 continue;
338408 }
......@@ -365,7 +435,6 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
365435 }
366436 try cflags.append("-nostdinc++");
367437 try cflags.append("-fstrict-aliasing");
368 try cflags.append("-funwind-tables");
369438 try cflags.append("-std=c++20");
370439
371440 // These depend on only the zig lib directory file path, which is
......@@ -386,49 +455,32 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
386455 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libcxxabi", cxxabi_src }),
387456 .extra_flags = cflags.items,
388457 .cache_exempt_flags = cache_exempt_flags.items,
458 .owner = root_mod,
389459 });
390460 }
391461
392 const sub_compilation = try Compilation.create(comp.gpa, .{
462 const sub_compilation = try Compilation.create(comp.gpa, arena, .{
393463 .local_cache_directory = comp.global_cache_directory,
394464 .global_cache_directory = comp.global_cache_directory,
395465 .zig_lib_directory = comp.zig_lib_directory,
466 .self_exe_path = comp.self_exe_path,
396467 .cache_mode = .whole,
397 .target = target,
468 .config = config,
469 .root_mod = root_mod,
398470 .root_name = root_name,
399 .main_mod = null,
400 .output_mode = output_mode,
401471 .thread_pool = comp.thread_pool,
402 .libc_installation = comp.bin_file.options.libc_installation,
472 .libc_installation = comp.libc_installation,
403473 .emit_bin = emit_bin,
404 .optimize_mode = comp.compilerRtOptMode(),
405 .link_mode = link_mode,
406 .want_sanitize_c = false,
407 .want_stack_check = false,
408 .want_stack_protector = 0,
409 .want_red_zone = comp.bin_file.options.red_zone,
410 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
411 .want_valgrind = false,
412 .want_tsan = comp.bin_file.options.tsan,
413 .want_pic = comp.bin_file.options.pic,
414 .want_pie = null,
415 .want_lto = comp.bin_file.options.lto,
416 .function_sections = comp.bin_file.options.function_sections,
417474 .emit_h = null,
418 .strip = comp.compilerRtStrip(),
419 .is_native_os = comp.bin_file.options.is_native_os,
420 .is_native_abi = comp.bin_file.options.is_native_abi,
421 .self_exe_path = comp.self_exe_path,
422475 .c_source_files = c_source_files.items,
423476 .verbose_cc = comp.verbose_cc,
424 .verbose_link = comp.bin_file.options.verbose_link,
477 .verbose_link = comp.verbose_link,
425478 .verbose_air = comp.verbose_air,
426479 .verbose_llvm_ir = comp.verbose_llvm_ir,
427480 .verbose_llvm_bc = comp.verbose_llvm_bc,
428481 .verbose_cimport = comp.verbose_cimport,
429482 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
430483 .clang_passthrough_mode = comp.clang_passthrough_mode,
431 .link_libc = true,
432484 .skip_linker_dependencies = true,
433485 });
434486 defer sub_compilation.destroy();
......@@ -436,10 +488,5 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
436488 try comp.updateSubCompilation(sub_compilation, .libcxxabi, prog_node);
437489
438490 assert(comp.libcxxabi_static_lib == null);
439 comp.libcxxabi_static_lib = Compilation.CRTFile{
440 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
441 sub_compilation.bin_file.options.emit.?.sub_path,
442 }),
443 .lock = sub_compilation.bin_file.toOwnedLock(),
444 };
491 comp.libcxxabi_static_lib = try sub_compilation.toCrtFile();
445492}
src/libtsan.zig+64-34
......@@ -4,6 +4,7 @@ const assert = std.debug.assert;
44const Compilation = @import("Compilation.zig");
55const build_options = @import("build_options");
66const trace = @import("tracy.zig").trace;
7const Module = @import("Package/Module.zig");
78
89pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
910 if (!build_options.have_llvm) {
......@@ -33,6 +34,52 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
3334 .basename = basename,
3435 };
3536
37 const optimize_mode = comp.compilerRtOptMode();
38 const strip = comp.compilerRtStrip();
39
40 const config = try Compilation.Config.resolve(.{
41 .output_mode = output_mode,
42 .link_mode = link_mode,
43 .resolved_target = comp.root_mod.resolved_target,
44 .is_test = false,
45 .have_zcu = false,
46 .emit_bin = true,
47 .root_optimize_mode = optimize_mode,
48 .root_strip = strip,
49 .link_libc = true,
50 });
51
52 const common_flags = [_][]const u8{
53 "-DTSAN_CONTAINS_UBSAN=0",
54 };
55
56 const root_mod = try Module.create(arena, .{
57 .global_cache_directory = comp.global_cache_directory,
58 .paths = .{
59 .root = .{ .root_dir = comp.zig_lib_directory },
60 .root_src_path = "",
61 },
62 .fully_qualified_name = "root",
63 .inherited = .{
64 .resolved_target = comp.root_mod.resolved_target,
65 .strip = strip,
66 .stack_check = false,
67 .stack_protector = 0,
68 .sanitize_c = false,
69 .sanitize_thread = false,
70 .red_zone = comp.root_mod.red_zone,
71 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
72 .valgrind = false,
73 .optimize_mode = optimize_mode,
74 .structured_cfg = comp.root_mod.structured_cfg,
75 .pic = true,
76 },
77 .global = config,
78 .cc_argv = &common_flags,
79 .parent = null,
80 .builtin_mod = null,
81 });
82
3683 var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena);
3784 try c_source_files.ensureUnusedCapacity(tsan_sources.len);
3885
......@@ -49,8 +96,9 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
4996 try cflags.append("-fno-rtti");
5097
5198 c_source_files.appendAssumeCapacity(.{
52 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "tsan", tsan_src }),
99 .src_path = try comp.zig_lib_directory.join(arena, &.{ "tsan", tsan_src }),
53100 .extra_flags = cflags.items,
101 .owner = root_mod,
54102 });
55103 }
56104
......@@ -73,6 +121,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
73121 c_source_files.appendAssumeCapacity(.{
74122 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "tsan", tsan_src }),
75123 .extra_flags = cflags.items,
124 .owner = root_mod,
76125 });
77126 }
78127 {
......@@ -93,6 +142,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
93142 c_source_files.appendAssumeCapacity(.{
94143 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "tsan", asm_source }),
95144 .extra_flags = cflags.items,
145 .owner = root_mod,
96146 });
97147 }
98148
......@@ -116,10 +166,11 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
116166 "tsan", "sanitizer_common", common_src,
117167 }),
118168 .extra_flags = cflags.items,
169 .owner = root_mod,
119170 });
120171 }
121172
122 const to_c_or_not_to_c_sources = if (comp.bin_file.options.link_libc)
173 const to_c_or_not_to_c_sources = if (comp.config.link_libc)
123174 &sanitizer_libcdep_sources
124175 else
125176 &sanitizer_nolibc_sources;
......@@ -140,6 +191,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
140191 "tsan", "sanitizer_common", c_src,
141192 }),
142193 .extra_flags = cflags.items,
194 .owner = root_mod,
143195 });
144196 }
145197
......@@ -160,6 +212,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
160212 "tsan", "sanitizer_common", c_src,
161213 }),
162214 .extra_flags = cflags.items,
215 .owner = root_mod,
163216 });
164217 }
165218
......@@ -188,63 +241,40 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
188241 "tsan", "interception", c_src,
189242 }),
190243 .extra_flags = cflags.items,
244 .owner = root_mod,
191245 });
192246 }
193247
194 const common_flags = [_][]const u8{
195 "-DTSAN_CONTAINS_UBSAN=0",
196 };
197
198 const sub_compilation = try Compilation.create(comp.gpa, .{
248 const sub_compilation = try Compilation.create(comp.gpa, arena, .{
199249 .local_cache_directory = comp.global_cache_directory,
200250 .global_cache_directory = comp.global_cache_directory,
201251 .zig_lib_directory = comp.zig_lib_directory,
252 .thread_pool = comp.thread_pool,
253 .self_exe_path = comp.self_exe_path,
202254 .cache_mode = .whole,
203 .target = target,
255 .config = config,
256 .root_mod = root_mod,
204257 .root_name = root_name,
205 .main_mod = null,
206 .output_mode = output_mode,
207 .thread_pool = comp.thread_pool,
208 .libc_installation = comp.bin_file.options.libc_installation,
258 .libc_installation = comp.libc_installation,
209259 .emit_bin = emit_bin,
210 .optimize_mode = comp.compilerRtOptMode(),
211 .link_mode = link_mode,
212 .want_sanitize_c = false,
213 .want_stack_check = false,
214 .want_stack_protector = 0,
215 .want_valgrind = false,
216 .want_tsan = false,
217 .want_pic = true,
218 .want_pie = null,
219260 .emit_h = null,
220 .strip = comp.compilerRtStrip(),
221 .is_native_os = comp.bin_file.options.is_native_os,
222 .is_native_abi = comp.bin_file.options.is_native_abi,
223 .self_exe_path = comp.self_exe_path,
224261 .c_source_files = c_source_files.items,
225262 .verbose_cc = comp.verbose_cc,
226 .verbose_link = comp.bin_file.options.verbose_link,
263 .verbose_link = comp.verbose_link,
227264 .verbose_air = comp.verbose_air,
228265 .verbose_llvm_ir = comp.verbose_llvm_ir,
229266 .verbose_llvm_bc = comp.verbose_llvm_bc,
230267 .verbose_cimport = comp.verbose_cimport,
231268 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
232269 .clang_passthrough_mode = comp.clang_passthrough_mode,
233 .link_libc = true,
234270 .skip_linker_dependencies = true,
235 .clang_argv = &common_flags,
236271 });
237272 defer sub_compilation.destroy();
238273
239274 try comp.updateSubCompilation(sub_compilation, .libtsan, prog_node);
240275
241276 assert(comp.tsan_static_lib == null);
242 comp.tsan_static_lib = Compilation.CRTFile{
243 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
244 sub_compilation.bin_file.options.emit.?.sub_path,
245 }),
246 .lock = sub_compilation.bin_file.toOwnedLock(),
247 };
277 comp.tsan_static_lib = try sub_compilation.toCrtFile();
248278}
249279
250280const tsan_sources = [_][]const u8{
src/libunwind.zig+53-36
......@@ -4,6 +4,7 @@ const assert = std.debug.assert;
44
55const target_util = @import("target.zig");
66const Compilation = @import("Compilation.zig");
7const Module = @import("Package/Module.zig");
78const build_options = @import("build_options");
89const trace = @import("tracy.zig").trace;
910
......@@ -19,10 +20,49 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
1920 defer arena_allocator.deinit();
2021 const arena = arena_allocator.allocator();
2122
22 const root_name = "unwind";
2323 const output_mode = .Lib;
24 const config = try Compilation.Config.resolve(.{
25 .output_mode = .Lib,
26 .resolved_target = comp.root_mod.resolved_target,
27 .is_test = false,
28 .have_zcu = false,
29 .emit_bin = true,
30 .root_optimize_mode = comp.compilerRtOptMode(),
31 .root_strip = comp.compilerRtStrip(),
32 .link_libc = true,
33 // Disable LTO to avoid https://github.com/llvm/llvm-project/issues/56825
34 .lto = false,
35 });
36 const root_mod = try Module.create(arena, .{
37 .global_cache_directory = comp.global_cache_directory,
38 .paths = .{
39 .root = .{ .root_dir = comp.zig_lib_directory },
40 .root_src_path = "",
41 },
42 .fully_qualified_name = "root",
43 .inherited = .{
44 .resolved_target = comp.root_mod.resolved_target,
45 .strip = comp.compilerRtStrip(),
46 .stack_check = false,
47 .stack_protector = 0,
48 .red_zone = comp.root_mod.red_zone,
49 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
50 .valgrind = false,
51 .sanitize_c = false,
52 .sanitize_thread = false,
53 .unwind_tables = false,
54 .pic = comp.root_mod.pic,
55 .optimize_mode = comp.compilerRtOptMode(),
56 },
57 .global = config,
58 .cc_argv = &.{},
59 .parent = null,
60 .builtin_mod = null,
61 });
62
63 const root_name = "unwind";
2464 const link_mode = .Static;
25 const target = comp.getTarget();
65 const target = comp.root_mod.resolved_target.result;
2666 const basename = try std.zig.binNameAlloc(arena, .{
2767 .root_name = root_name,
2868 .target = target,
......@@ -64,10 +104,10 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
64104 // defines will be correct.
65105 try cflags.append("-D_LIBUNWIND_IS_NATIVE_ONLY");
66106
67 if (comp.bin_file.options.optimize_mode == .Debug) {
107 if (comp.root_mod.optimize_mode == .Debug) {
68108 try cflags.append("-D_DEBUG");
69109 }
70 if (comp.bin_file.options.single_threaded) {
110 if (!comp.config.any_non_single_threaded) {
71111 try cflags.append("-D_LIBUNWIND_HAS_NO_THREADS");
72112 }
73113 if (target.cpu.arch.isARM() and target.abi.floatAbi() == .hard) {
......@@ -80,49 +120,32 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
80120 c_source_files[i] = .{
81121 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{unwind_src}),
82122 .extra_flags = cflags.items,
123 .owner = root_mod,
83124 };
84125 }
85 const sub_compilation = try Compilation.create(comp.gpa, .{
126 const sub_compilation = try Compilation.create(comp.gpa, arena, .{
127 .self_exe_path = comp.self_exe_path,
86128 .local_cache_directory = comp.global_cache_directory,
87129 .global_cache_directory = comp.global_cache_directory,
88130 .zig_lib_directory = comp.zig_lib_directory,
131 .config = config,
132 .root_mod = root_mod,
89133 .cache_mode = .whole,
90 .target = target,
91134 .root_name = root_name,
92135 .main_mod = null,
93 .output_mode = output_mode,
94136 .thread_pool = comp.thread_pool,
95 .libc_installation = comp.bin_file.options.libc_installation,
137 .libc_installation = comp.libc_installation,
96138 .emit_bin = emit_bin,
97 .optimize_mode = comp.compilerRtOptMode(),
98 .link_mode = link_mode,
99 .want_sanitize_c = false,
100 .want_stack_check = false,
101 .want_stack_protector = 0,
102 .want_red_zone = comp.bin_file.options.red_zone,
103 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
104 .want_valgrind = false,
105 .want_tsan = false,
106 .want_pic = comp.bin_file.options.pic,
107 .want_pie = null,
108 // Disable LTO to avoid https://github.com/llvm/llvm-project/issues/56825
109 .want_lto = false,
110 .function_sections = comp.bin_file.options.function_sections,
111 .emit_h = null,
112 .strip = comp.compilerRtStrip(),
113 .is_native_os = comp.bin_file.options.is_native_os,
114 .is_native_abi = comp.bin_file.options.is_native_abi,
115 .self_exe_path = comp.self_exe_path,
139 .function_sections = comp.function_sections,
116140 .c_source_files = &c_source_files,
117141 .verbose_cc = comp.verbose_cc,
118 .verbose_link = comp.bin_file.options.verbose_link,
142 .verbose_link = comp.verbose_link,
119143 .verbose_air = comp.verbose_air,
120144 .verbose_llvm_ir = comp.verbose_llvm_ir,
121145 .verbose_llvm_bc = comp.verbose_llvm_bc,
122146 .verbose_cimport = comp.verbose_cimport,
123147 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
124148 .clang_passthrough_mode = comp.clang_passthrough_mode,
125 .link_libc = true,
126149 .skip_linker_dependencies = true,
127150 });
128151 defer sub_compilation.destroy();
......@@ -130,13 +153,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
130153 try comp.updateSubCompilation(sub_compilation, .libunwind, prog_node);
131154
132155 assert(comp.libunwind_static_lib == null);
133
134 comp.libunwind_static_lib = Compilation.CRTFile{
135 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
136 sub_compilation.bin_file.options.emit.?.sub_path,
137 }),
138 .lock = sub_compilation.bin_file.toOwnedLock(),
139 };
156 comp.libunwind_static_lib = try sub_compilation.toCrtFile();
140157}
141158
142159const unwind_src_list = [_][]const u8{
src/link.zig+397-653
......@@ -10,7 +10,6 @@ const wasi_libc = @import("wasi_libc.zig");
1010
1111const Air = @import("Air.zig");
1212const Allocator = std.mem.Allocator;
13const BuildId = std.Build.CompileStep.BuildId;
1413const Cache = std.Build.Cache;
1514const Compilation = @import("Compilation.zig");
1615const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
......@@ -19,6 +18,7 @@ const Module = @import("Module.zig");
1918const InternPool = @import("InternPool.zig");
2019const Type = @import("type.zig").Type;
2120const TypedValue = @import("TypedValue.zig");
21const LlvmObject = @import("codegen/llvm.zig").Object;
2222
2323/// When adding a new field, remember to update `hashAddSystemLibs`.
2424/// These are *always* dynamically linked. Static libraries will be
......@@ -33,17 +33,6 @@ pub const SystemLib = struct {
3333 path: ?[]const u8,
3434};
3535
36/// When adding a new field, remember to update `hashAddFrameworks`.
37pub const Framework = struct {
38 needed: bool = false,
39 weak: bool = false,
40 path: []const u8,
41};
42
43pub const SortSection = enum { name, alignment };
44
45pub const CacheMode = enum { incremental, whole };
46
4736pub fn hashAddSystemLibs(
4837 man: *Cache.Manifest,
4938 hm: std.StringArrayHashMapUnmanaged(SystemLib),
......@@ -57,355 +46,172 @@ pub fn hashAddSystemLibs(
5746 }
5847}
5948
60pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void {
61 for (hm) |value| {
62 man.hash.add(value.needed);
63 man.hash.add(value.weak);
64 _ = try man.addFile(value.path, null);
65 }
66}
67
6849pub const producer_string = if (builtin.is_test) "zig test" else "zig " ++ build_options.version;
6950
70pub const Emit = struct {
71 /// Where the output will go.
72 directory: Compilation.Directory,
73 /// Path to the output file, relative to `directory`.
74 sub_path: []const u8,
75
76 /// Returns the full path to `basename` if it were in the same directory as the
77 /// `Emit` sub_path.
78 pub fn basenamePath(emit: Emit, arena: Allocator, basename: [:0]const u8) ![:0]const u8 {
79 const full_path = if (emit.directory.path) |p|
80 try fs.path.join(arena, &[_][]const u8{ p, emit.sub_path })
81 else
82 emit.sub_path;
83
84 if (fs.path.dirname(full_path)) |dirname| {
85 return try fs.path.joinZ(arena, &.{ dirname, basename });
86 } else {
87 return basename;
88 }
89 }
90};
91
92pub const Options = struct {
93 /// This is `null` when `-fno-emit-bin` is used.
94 emit: ?Emit,
95 /// This is `null` when not building a Windows DLL, or when `-fno-emit-implib` is used.
96 implib_emit: ?Emit,
97 /// This is non-null when `-femit-docs` is provided.
98 docs_emit: ?Emit,
99 target: std.Target,
100 output_mode: std.builtin.OutputMode,
101 link_mode: std.builtin.LinkMode,
102 optimize_mode: std.builtin.OptimizeMode,
103 machine_code_model: std.builtin.CodeModel,
104 root_name: [:0]const u8,
105 /// Not every Compilation compiles .zig code! For example you could do `zig build-exe foo.o`.
106 module: ?*Module,
107 dynamic_linker: ?[]const u8,
108 /// The root path for the dynamic linker and system libraries (as well as frameworks on Darwin)
109 sysroot: ?[]const u8,
110 /// Used for calculating how much space to reserve for symbols in case the binary file
111 /// does not already have a symbol table.
112 symbol_count_hint: u64 = 32,
113 /// Used for calculating how much space to reserve for executable program code in case
114 /// the binary file does not already have such a section.
115 program_code_size_hint: u64 = 256 * 1024,
116 entry_addr: ?u64 = null,
117 entry: ?[]const u8,
118 stack_size_override: ?u64,
119 image_base_override: ?u64,
120 /// 0 means no stack protector
121 /// other value means stack protector with that buffer size.
122 stack_protector: u32,
123 cache_mode: CacheMode,
124 include_compiler_rt: bool,
125 /// Set to `true` to omit debug info.
126 strip: bool,
127 /// If this is true then this link code is responsible for outputting an object
128 /// file and then using LLD to link it together with the link options and other objects.
129 /// Otherwise (depending on `use_llvm`) this link code directly outputs and updates the final binary.
130 use_lld: bool,
131 /// If this is true then this link code is responsible for making an LLVM IR Module,
132 /// outputting it to an object file, and then linking that together with link options and
133 /// other objects.
134 /// Otherwise (depending on `use_lld`) this link code directly outputs and updates the final binary.
135 use_llvm: bool,
136 use_lib_llvm: bool,
137 link_libc: bool,
138 link_libcpp: bool,
139 link_libunwind: bool,
140 darwin_sdk_layout: ?DarwinSdkLayout,
141 function_sections: bool,
142 data_sections: bool,
143 no_builtin: bool,
144 eh_frame_hdr: bool,
145 emit_relocs: bool,
146 rdynamic: bool,
147 z_nodelete: bool,
148 z_notext: bool,
149 z_defs: bool,
150 z_origin: bool,
151 z_nocopyreloc: bool,
152 z_now: bool,
153 z_relro: bool,
154 z_common_page_size: ?u64,
155 z_max_page_size: ?u64,
156 tsaware: bool,
157 nxcompat: bool,
158 dynamicbase: bool,
159 linker_optimization: u8,
160 compress_debug_sections: CompressDebugSections,
161 bind_global_refs_locally: bool,
162 import_memory: bool,
163 export_memory: bool,
164 import_symbols: bool,
165 import_table: bool,
166 export_table: bool,
167 initial_memory: ?u64,
168 max_memory: ?u64,
169 shared_memory: bool,
170 export_symbol_names: []const []const u8,
171 global_base: ?u64,
172 is_native_os: bool,
173 is_native_abi: bool,
174 pic: bool,
175 pie: bool,
176 lto: bool,
177 valgrind: bool,
178 tsan: bool,
179 stack_check: bool,
180 red_zone: bool,
181 omit_frame_pointer: bool,
182 single_threaded: bool,
183 verbose_link: bool,
184 dll_export_fns: bool,
185 error_return_tracing: bool,
186 skip_linker_dependencies: bool,
187 each_lib_rpath: bool,
188 build_id: BuildId,
189 disable_lld_caching: bool,
190 is_test: bool,
191 hash_style: HashStyle,
192 sort_section: ?SortSection,
193 major_subsystem_version: ?u32,
194 minor_subsystem_version: ?u32,
195 gc_sections: ?bool = null,
196 allow_shlib_undefined: ?bool,
197 subsystem: ?std.Target.SubSystem,
198 linker_script: ?[]const u8,
199 version_script: ?[]const u8,
200 soname: ?[]const u8,
201 llvm_cpu_features: ?[*:0]const u8,
202 print_gc_sections: bool,
203 print_icf_sections: bool,
204 print_map: bool,
205 opt_bisect_limit: i32,
206
207 objects: []Compilation.LinkObject,
208 framework_dirs: []const []const u8,
209 frameworks: []const Framework,
210 /// These are *always* dynamically linked. Static libraries will be
211 /// provided as positional arguments.
212 system_libs: std.StringArrayHashMapUnmanaged(SystemLib),
213 wasi_emulated_libs: []const wasi_libc.CRTFile,
214 // TODO: remove this. libraries are resolved by the frontend.
215 lib_dirs: []const []const u8,
216 rpath_list: []const []const u8,
217
218 /// List of symbols forced as undefined in the symbol table
219 /// thus forcing their resolution by the linker.
220 /// Corresponds to `-u <symbol>` for ELF/MachO and `/include:<symbol>` for COFF/PE.
221 force_undefined_symbols: std.StringArrayHashMapUnmanaged(void),
222 /// Use a wrapper function for symbol. Any undefined reference to symbol
223 /// will be resolved to __wrap_symbol. Any undefined reference to
224 /// __real_symbol will be resolved to symbol. This can be used to provide a
225 /// wrapper for a system function. The wrapper function should be called
226 /// __wrap_symbol. If it wishes to call the system function, it should call
227 /// __real_symbol.
228 symbol_wrap_set: std.StringArrayHashMapUnmanaged(void),
229
230 version: ?std.SemanticVersion,
231 compatibility_version: ?std.SemanticVersion,
232 libc_installation: ?*const LibCInstallation,
233
234 dwarf_format: ?std.dwarf.Format,
235
236 /// WASI-only. Type of WASI execution model ("command" or "reactor").
237 wasi_exec_model: std.builtin.WasiExecModel = undefined,
238
239 /// (Zig compiler development) Enable dumping of linker's state as JSON.
240 enable_link_snapshots: bool = false,
241
242 /// (Darwin) Install name for the dylib
243 install_name: ?[]const u8 = null,
244
245 /// (Darwin) Path to entitlements file
246 entitlements: ?[]const u8 = null,
247
248 /// (Darwin) size of the __PAGEZERO segment
249 pagezero_size: ?u64 = null,
250
251 /// (Darwin) set minimum space for future expansion of the load commands
252 headerpad_size: ?u32 = null,
253
254 /// (Darwin) set enough space as if all paths were MATPATHLEN
255 headerpad_max_install_names: bool = false,
256
257 /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
258 dead_strip_dylibs: bool = false,
259
260 /// (Windows) PDB source path prefix to instruct the linker how to resolve relative
261 /// paths when consolidating CodeView streams into a single PDB file.
262 pdb_source_path: ?[]const u8 = null,
263
264 /// (Windows) PDB output path
265 pdb_out_path: ?[]const u8 = null,
266
267 /// (Windows) .def file to specify when linking
268 module_definition_file: ?[]const u8 = null,
269
270 /// (SPIR-V) whether to generate a structured control flow graph or not
271 want_structured_cfg: ?bool = null,
272
273 pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode {
274 return if (options.use_lld) .Obj else options.output_mode;
275 }
276
277 pub fn move(self: *Options) Options {
278 const copied_state = self.*;
279 self.system_libs = .{};
280 self.force_undefined_symbols = .{};
281 return copied_state;
282 }
283};
284
285pub const HashStyle = enum { sysv, gnu, both };
286
287pub const CompressDebugSections = enum { none, zlib, zstd };
288
289/// The filesystem layout of darwin SDK elements.
290pub const DarwinSdkLayout = enum {
291 /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }.
292 sdk,
293 /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }.
294 vendored,
295};
296
29751pub const File = struct {
29852 tag: Tag,
299 options: Options,
53
54 /// The owner of this output File.
55 comp: *Compilation,
56 emit: Compilation.Emit,
57
30058 file: ?fs.File,
301 allocator: Allocator,
30259 /// When linking with LLD, this linker code will output an object file only at
30360 /// this location, and then this path can be placed on the LLD linker line.
304 intermediary_basename: ?[]const u8 = null,
61 zcu_object_sub_path: ?[]const u8 = null,
62 disable_lld_caching: bool,
63 gc_sections: bool,
64 print_gc_sections: bool,
65 build_id: std.zig.BuildId,
66 rpath_list: []const []const u8,
67 allow_shlib_undefined: bool,
68 stack_size: u64,
30569
30670 /// Prevents other processes from clobbering files in the output directory
30771 /// of this linking operation.
30872 lock: ?Cache.Lock = null,
309
31073 child_pid: ?std.ChildProcess.Id = null,
31174
75 pub const OpenOptions = struct {
76 symbol_count_hint: u64 = 32,
77 program_code_size_hint: u64 = 256 * 1024,
78
79 /// This may depend on what symbols are found during the linking process.
80 entry: Entry,
81 /// Virtual address of the entry point procedure relative to image base.
82 entry_addr: ?u64,
83 stack_size: ?u64,
84 image_base: ?u64,
85 emit_relocs: bool,
86 z_nodelete: bool,
87 z_notext: bool,
88 z_defs: bool,
89 z_origin: bool,
90 z_nocopyreloc: bool,
91 z_now: bool,
92 z_relro: bool,
93 z_common_page_size: ?u64,
94 z_max_page_size: ?u64,
95 tsaware: bool,
96 nxcompat: bool,
97 dynamicbase: bool,
98 compress_debug_sections: Elf.CompressDebugSections,
99 bind_global_refs_locally: bool,
100 import_symbols: bool,
101 import_table: bool,
102 export_table: bool,
103 initial_memory: ?u64,
104 max_memory: ?u64,
105 export_symbol_names: []const []const u8,
106 global_base: ?u64,
107 each_lib_rpath: bool,
108 build_id: std.zig.BuildId,
109 disable_lld_caching: bool,
110 hash_style: Elf.HashStyle,
111 sort_section: ?Elf.SortSection,
112 major_subsystem_version: ?u16,
113 minor_subsystem_version: ?u16,
114 gc_sections: ?bool,
115 allow_shlib_undefined: ?bool,
116 subsystem: ?std.Target.SubSystem,
117 linker_script: ?[]const u8,
118 version_script: ?[]const u8,
119 soname: ?[]const u8,
120 print_gc_sections: bool,
121 print_icf_sections: bool,
122 print_map: bool,
123
124 /// Use a wrapper function for symbol. Any undefined reference to symbol
125 /// will be resolved to __wrap_symbol. Any undefined reference to
126 /// __real_symbol will be resolved to symbol. This can be used to provide a
127 /// wrapper for a system function. The wrapper function should be called
128 /// __wrap_symbol. If it wishes to call the system function, it should call
129 /// __real_symbol.
130 symbol_wrap_set: std.StringArrayHashMapUnmanaged(void),
131
132 compatibility_version: ?std.SemanticVersion,
133
134 // TODO: remove this. libraries are resolved by the frontend.
135 lib_dirs: []const []const u8,
136 rpath_list: []const []const u8,
137
138 /// (Zig compiler development) Enable dumping of linker's state as JSON.
139 enable_link_snapshots: bool,
140
141 /// (Darwin) Install name for the dylib
142 install_name: ?[]const u8,
143 /// (Darwin) Path to entitlements file
144 entitlements: ?[]const u8,
145 /// (Darwin) size of the __PAGEZERO segment
146 pagezero_size: ?u64,
147 /// (Darwin) set minimum space for future expansion of the load commands
148 headerpad_size: ?u32,
149 /// (Darwin) set enough space as if all paths were MATPATHLEN
150 headerpad_max_install_names: bool,
151 /// (Darwin) remove dylibs that are unreachable by the entry point or exported symbols
152 dead_strip_dylibs: bool,
153 frameworks: []const MachO.Framework,
154 darwin_sdk_layout: ?MachO.SdkLayout,
155
156 /// (Windows) PDB source path prefix to instruct the linker how to resolve relative
157 /// paths when consolidating CodeView streams into a single PDB file.
158 pdb_source_path: ?[]const u8,
159 /// (Windows) PDB output path
160 pdb_out_path: ?[]const u8,
161 /// (Windows) .def file to specify when linking
162 module_definition_file: ?[]const u8,
163
164 pub const Entry = union(enum) {
165 default,
166 disabled,
167 enabled,
168 named: []const u8,
169 };
170 };
171
312172 /// Attempts incremental linking, if the file already exists. If
313173 /// incremental linking fails, falls back to truncating the file and
314174 /// rewriting it. A malicious file is detected as incremental link failure
315175 /// and does not cause Illegal Behavior. This operation is not atomic.
316 pub fn openPath(allocator: Allocator, options: Options) !*File {
317 const have_macho = !build_options.only_c;
318 if (have_macho and options.target.ofmt == .macho) {
319 return &(try MachO.openPath(allocator, options)).base;
320 }
321
322 if (options.emit == null) {
323 return switch (options.target.ofmt) {
324 .coff => &(try Coff.createEmpty(allocator, options)).base,
325 .elf => &(try Elf.createEmpty(allocator, options)).base,
326 .macho => unreachable,
327 .wasm => &(try Wasm.createEmpty(allocator, options)).base,
328 .plan9 => return &(try Plan9.createEmpty(allocator, options)).base,
329 .c => unreachable, // Reported error earlier.
330 .spirv => &(try SpirV.createEmpty(allocator, options)).base,
331 .nvptx => &(try NvPtx.createEmpty(allocator, options)).base,
332 .hex => return error.HexObjectFormatUnimplemented,
333 .raw => return error.RawObjectFormatUnimplemented,
334 .dxcontainer => return error.DirectXContainerObjectFormatUnimplemented,
335 };
176 /// `arena` is used for allocations with the same lifetime as the created File.
177 pub fn open(
178 arena: Allocator,
179 comp: *Compilation,
180 emit: Compilation.Emit,
181 options: OpenOptions,
182 ) !*File {
183 const tag = Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt);
184 switch (tag) {
185 .c => {
186 const ptr = try C.open(arena, comp, emit, options);
187 return &ptr.base;
188 },
189 inline else => |t| {
190 if (build_options.only_c) unreachable;
191 const ptr = try t.Type().open(arena, comp, emit, options);
192 return &ptr.base;
193 },
336194 }
337 const emit = options.emit.?;
338 const use_lld = build_options.have_llvm and options.use_lld; // comptime-known false when !have_llvm
339 const sub_path = if (use_lld) blk: {
340 if (options.module == null) {
341 // No point in opening a file, we would not write anything to it.
342 // Initialize with empty.
343 return switch (options.target.ofmt) {
344 .coff => &(try Coff.createEmpty(allocator, options)).base,
345 .elf => &(try Elf.createEmpty(allocator, options)).base,
346 .macho => unreachable,
347 .plan9 => &(try Plan9.createEmpty(allocator, options)).base,
348 .wasm => &(try Wasm.createEmpty(allocator, options)).base,
349 .c => unreachable, // Reported error earlier.
350 .spirv => &(try SpirV.createEmpty(allocator, options)).base,
351 .nvptx => &(try NvPtx.createEmpty(allocator, options)).base,
352 .hex => return error.HexObjectFormatUnimplemented,
353 .raw => return error.RawObjectFormatUnimplemented,
354 .dxcontainer => return error.DirectXContainerObjectFormatUnimplemented,
355 };
356 }
357 // Open a temporary object file, not the final output file because we
358 // want to link with LLD.
359 break :blk try std.fmt.allocPrint(allocator, "{s}{s}", .{
360 emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch),
361 });
362 } else emit.sub_path;
363 errdefer if (use_lld) allocator.free(sub_path);
364
365 const file: *File = f: {
366 switch (options.target.ofmt) {
367 .coff => {
368 if (build_options.only_c) unreachable;
369 break :f &(try Coff.openPath(allocator, sub_path, options)).base;
370 },
371 .elf => {
372 if (build_options.only_c) unreachable;
373 break :f &(try Elf.openPath(allocator, sub_path, options)).base;
374 },
375 .macho => unreachable,
376 .plan9 => {
377 if (build_options.only_c) unreachable;
378 break :f &(try Plan9.openPath(allocator, sub_path, options)).base;
379 },
380 .wasm => {
381 if (build_options.only_c) unreachable;
382 break :f &(try Wasm.openPath(allocator, sub_path, options)).base;
383 },
384 .c => {
385 break :f &(try C.openPath(allocator, sub_path, options)).base;
386 },
387 .spirv => {
388 if (build_options.only_c) unreachable;
389 break :f &(try SpirV.openPath(allocator, sub_path, options)).base;
390 },
391 .nvptx => {
392 if (build_options.only_c) unreachable;
393 break :f &(try NvPtx.openPath(allocator, sub_path, options)).base;
394 },
395 .hex => return error.HexObjectFormatUnimplemented,
396 .raw => return error.RawObjectFormatUnimplemented,
397 .dxcontainer => return error.DirectXContainerObjectFormatUnimplemented,
398 }
399 };
195 }
400196
401 if (use_lld) {
402 // TODO this intermediary_basename isn't enough; in the case of `zig build-exe`,
403 // we also want to put the intermediary object file in the cache while the
404 // main emit directory is the cwd.
405 file.intermediary_basename = sub_path;
197 pub fn createEmpty(
198 arena: Allocator,
199 comp: *Compilation,
200 emit: Compilation.Emit,
201 options: OpenOptions,
202 ) !*File {
203 const tag = Tag.fromObjectFormat(comp.root_mod.resolved_target.result.ofmt);
204 switch (tag) {
205 .c => {
206 const ptr = try C.createEmpty(arena, comp, emit, options);
207 return &ptr.base;
208 },
209 inline else => |t| {
210 if (build_options.only_c) unreachable;
211 const ptr = try t.Type().createEmpty(arena, comp, emit, options);
212 return &ptr.base;
213 },
406214 }
407
408 return file;
409215 }
410216
411217 pub fn cast(base: *File, comptime T: type) ?*T {
......@@ -416,11 +222,13 @@ pub const File = struct {
416222 }
417223
418224 pub fn makeWritable(base: *File) !void {
225 const comp = base.comp;
226 const gpa = comp.gpa;
419227 switch (base.tag) {
420228 .coff, .elf, .macho, .plan9, .wasm => {
421229 if (build_options.only_c) unreachable;
422230 if (base.file != null) return;
423 const emit = base.options.emit orelse return;
231 const emit = base.emit;
424232 if (base.child_pid) |pid| {
425233 if (builtin.os.tag == .windows) {
426234 base.cast(Coff).?.ptraceAttach(pid) catch |err| {
......@@ -431,9 +239,10 @@ pub const File = struct {
431239 // it will return ETXTBSY. So instead, we copy the file, atomically rename it
432240 // over top of the exe path, and then proceed normally. This changes the inode,
433241 // avoiding the error.
434 const tmp_sub_path = try std.fmt.allocPrint(base.allocator, "{s}-{x}", .{
242 const tmp_sub_path = try std.fmt.allocPrint(gpa, "{s}-{x}", .{
435243 emit.sub_path, std.crypto.random.int(u32),
436244 });
245 defer gpa.free(tmp_sub_path);
437246 try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, tmp_sub_path, .{});
438247 try emit.directory.handle.rename(tmp_sub_path, emit.sub_path);
439248 switch (builtin.os.tag) {
......@@ -448,10 +257,13 @@ pub const File = struct {
448257 }
449258 }
450259 }
260 const use_lld = build_options.have_llvm and comp.config.use_lld;
261 const output_mode = comp.config.output_mode;
262 const link_mode = comp.config.link_mode;
451263 base.file = try emit.directory.handle.createFile(emit.sub_path, .{
452264 .truncate = false,
453265 .read = true,
454 .mode = determineMode(base.options),
266 .mode = determineMode(use_lld, output_mode, link_mode),
455267 });
456268 },
457269 .c, .spirv, .nvptx => {},
......@@ -459,9 +271,14 @@ pub const File = struct {
459271 }
460272
461273 pub fn makeExecutable(base: *File) !void {
462 switch (base.options.output_mode) {
274 const comp = base.comp;
275 const output_mode = comp.config.output_mode;
276 const link_mode = comp.config.link_mode;
277 const use_lld = build_options.have_llvm and comp.config.use_lld;
278
279 switch (output_mode) {
463280 .Obj => return,
464 .Lib => switch (base.options.link_mode) {
281 .Lib => switch (link_mode) {
465282 .Static => return,
466283 .Dynamic => {},
467284 },
......@@ -470,8 +287,7 @@ pub const File = struct {
470287 switch (base.tag) {
471288 .elf => if (base.file) |f| {
472289 if (build_options.only_c) unreachable;
473 const use_lld = build_options.have_llvm and base.options.use_lld;
474 if (base.intermediary_basename != null and use_lld) {
290 if (base.zcu_object_sub_path != null and use_lld) {
475291 // The file we have open is not the final file that we want to
476292 // make executable, so we don't have to close it.
477293 return;
......@@ -490,7 +306,7 @@ pub const File = struct {
490306 },
491307 .coff, .macho, .plan9, .wasm => if (base.file) |f| {
492308 if (build_options.only_c) unreachable;
493 if (base.intermediary_basename != null) {
309 if (base.zcu_object_sub_path != null) {
494310 // The file we have open is not the final file that we want to
495311 // make executable, so we don't have to close it.
496312 return;
......@@ -555,16 +371,12 @@ pub const File = struct {
555371 pub fn lowerUnnamedConst(base: *File, tv: TypedValue, decl_index: InternPool.DeclIndex) UpdateDeclError!u32 {
556372 if (build_options.only_c) @compileError("unreachable");
557373 switch (base.tag) {
558 // zig fmt: off
559 .coff => return @fieldParentPtr(Coff, "base", base).lowerUnnamedConst(tv, decl_index),
560 .elf => return @fieldParentPtr(Elf, "base", base).lowerUnnamedConst(tv, decl_index),
561 .macho => return @fieldParentPtr(MachO, "base", base).lowerUnnamedConst(tv, decl_index),
562 .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerUnnamedConst(tv, decl_index),
563374 .spirv => unreachable,
564 .c => unreachable,
565 .wasm => return @fieldParentPtr(Wasm, "base", base).lowerUnnamedConst(tv, decl_index),
375 .c => unreachable,
566376 .nvptx => unreachable,
567 // zig fmt: on
377 inline else => |t| {
378 return @fieldParentPtr(t.Type(), "base", base).lowerUnnamedConst(tv, decl_index);
379 },
568380 }
569381 }
570382
......@@ -577,16 +389,13 @@ pub const File = struct {
577389 if (build_options.only_c) @compileError("unreachable");
578390 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });
579391 switch (base.tag) {
580 // zig fmt: off
581 .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name, lib_name),
582 .elf => return @fieldParentPtr(Elf, "base", base).getGlobalSymbol(name, lib_name),
583 .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name, lib_name),
584392 .plan9 => unreachable,
585393 .spirv => unreachable,
586 .c => unreachable,
587 .wasm => return @fieldParentPtr(Wasm, "base", base).getGlobalSymbol(name, lib_name),
394 .c => unreachable,
588395 .nvptx => unreachable,
589 // zig fmt: on
396 inline else => |t| {
397 return @fieldParentPtr(t.Type(), "base", base).getGlobalSymbol(name, lib_name);
398 },
590399 }
591400 }
592401
......@@ -594,59 +403,48 @@ pub const File = struct {
594403 pub fn updateDecl(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
595404 const decl = module.declPtr(decl_index);
596405 assert(decl.has_tv);
597 if (build_options.only_c) {
598 assert(base.tag == .c);
599 return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index);
600 }
601406 switch (base.tag) {
602 // zig fmt: off
603 .coff => return @fieldParentPtr(Coff, "base", base).updateDecl(module, decl_index),
604 .elf => return @fieldParentPtr(Elf, "base", base).updateDecl(module, decl_index),
605 .macho => return @fieldParentPtr(MachO, "base", base).updateDecl(module, decl_index),
606 .c => return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index),
607 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDecl(module, decl_index),
608 .spirv => return @fieldParentPtr(SpirV, "base", base).updateDecl(module, decl_index),
609 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDecl(module, decl_index),
610 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateDecl(module, decl_index),
611 // zig fmt: on
407 .c => {
408 return @fieldParentPtr(C, "base", base).updateDecl(module, decl_index);
409 },
410 inline else => |tag| {
411 if (build_options.only_c) unreachable;
412 return @fieldParentPtr(tag.Type(), "base", base).updateDecl(module, decl_index);
413 },
612414 }
613415 }
614416
615417 /// May be called before or after updateExports for any given Decl.
616 pub fn updateFunc(base: *File, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) UpdateDeclError!void {
617 if (build_options.only_c) {
618 assert(base.tag == .c);
619 return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness);
620 }
418 pub fn updateFunc(
419 base: *File,
420 module: *Module,
421 func_index: InternPool.Index,
422 air: Air,
423 liveness: Liveness,
424 ) UpdateDeclError!void {
621425 switch (base.tag) {
622 // zig fmt: off
623 .coff => return @fieldParentPtr(Coff, "base", base).updateFunc(module, func_index, air, liveness),
624 .elf => return @fieldParentPtr(Elf, "base", base).updateFunc(module, func_index, air, liveness),
625 .macho => return @fieldParentPtr(MachO, "base", base).updateFunc(module, func_index, air, liveness),
626 .c => return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness),
627 .wasm => return @fieldParentPtr(Wasm, "base", base).updateFunc(module, func_index, air, liveness),
628 .spirv => return @fieldParentPtr(SpirV, "base", base).updateFunc(module, func_index, air, liveness),
629 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateFunc(module, func_index, air, liveness),
630 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateFunc(module, func_index, air, liveness),
631 // zig fmt: on
426 .c => {
427 return @fieldParentPtr(C, "base", base).updateFunc(module, func_index, air, liveness);
428 },
429 inline else => |tag| {
430 if (build_options.only_c) unreachable;
431 return @fieldParentPtr(tag.Type(), "base", base).updateFunc(module, func_index, air, liveness);
432 },
632433 }
633434 }
634435
635436 pub fn updateDeclLineNumber(base: *File, module: *Module, decl_index: InternPool.DeclIndex) UpdateDeclError!void {
636437 const decl = module.declPtr(decl_index);
637438 assert(decl.has_tv);
638 if (build_options.only_c) {
639 assert(base.tag == .c);
640 return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index);
641 }
642439 switch (base.tag) {
643 .coff => return @fieldParentPtr(Coff, "base", base).updateDeclLineNumber(module, decl_index),
644 .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl_index),
645 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl_index),
646 .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index),
647 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclLineNumber(module, decl_index),
648 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateDeclLineNumber(module, decl_index),
649440 .spirv, .nvptx => {},
441 .c => {
442 return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl_index);
443 },
444 inline else => |tag| {
445 if (build_options.only_c) unreachable;
446 return @fieldParentPtr(tag.Type(), "base", base).updateDeclLineNumber(module, decl_index);
447 },
650448 }
651449 }
652450
......@@ -666,56 +464,12 @@ pub const File = struct {
666464 pub fn destroy(base: *File) void {
667465 base.releaseLock();
668466 if (base.file) |f| f.close();
669 if (base.intermediary_basename) |sub_path| base.allocator.free(sub_path);
670 base.options.system_libs.deinit(base.allocator);
671 base.options.force_undefined_symbols.deinit(base.allocator);
672467 switch (base.tag) {
673 .coff => {
674 if (build_options.only_c) unreachable;
675 const parent = @fieldParentPtr(Coff, "base", base);
676 parent.deinit();
677 base.allocator.destroy(parent);
678 },
679 .elf => {
680 if (build_options.only_c) unreachable;
681 const parent = @fieldParentPtr(Elf, "base", base);
682 parent.deinit();
683 base.allocator.destroy(parent);
684 },
685 .macho => {
686 if (build_options.only_c) unreachable;
687 const parent = @fieldParentPtr(MachO, "base", base);
688 parent.deinit();
689 base.allocator.destroy(parent);
690 },
691 .c => {
692 const parent = @fieldParentPtr(C, "base", base);
693 parent.deinit();
694 base.allocator.destroy(parent);
695 },
696 .wasm => {
697 if (build_options.only_c) unreachable;
698 const parent = @fieldParentPtr(Wasm, "base", base);
699 parent.deinit();
700 base.allocator.destroy(parent);
701 },
702 .spirv => {
703 if (build_options.only_c) unreachable;
704 const parent = @fieldParentPtr(SpirV, "base", base);
705 parent.deinit();
706 base.allocator.destroy(parent);
707 },
708 .plan9 => {
709 if (build_options.only_c) unreachable;
710 const parent = @fieldParentPtr(Plan9, "base", base);
711 parent.deinit();
712 base.allocator.destroy(parent);
713 },
714 .nvptx => {
468 .c => @fieldParentPtr(C, "base", base).deinit(),
469
470 inline else => |tag| {
715471 if (build_options.only_c) unreachable;
716 const parent = @fieldParentPtr(NvPtx, "base", base);
717 parent.deinit();
718 base.allocator.destroy(parent);
472 @fieldParentPtr(tag.Type(), "base", base).deinit();
719473 },
720474 }
721475 }
......@@ -793,19 +547,22 @@ pub const File = struct {
793547
794548 /// Commit pending changes and write headers. Takes into account final output mode
795549 /// and `use_lld`, not only `effectiveOutputMode`.
796 pub fn flush(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
550 /// `arena` has the lifetime of the call to `Compilation.update`.
551 pub fn flush(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void {
797552 if (build_options.only_c) {
798553 assert(base.tag == .c);
799 return @fieldParentPtr(C, "base", base).flush(comp, prog_node);
554 return @fieldParentPtr(C, "base", base).flush(arena, prog_node);
800555 }
556 const comp = base.comp;
801557 if (comp.clang_preprocessor_mode == .yes) {
802 const emit = base.options.emit orelse return; // -fno-emit-bin
558 const gpa = comp.gpa;
559 const emit = base.emit;
803560 // TODO: avoid extra link step when it's just 1 object file (the `zig cc -c` case)
804561 // Until then, we do `lld -r -o output.o input.o` even though the output is the same
805562 // as the input. For the preprocessing case (`zig cc -E -o foo`) we copy the file
806563 // to the final location. See also the corresponding TODO in Coff linking.
807 const full_out_path = try emit.directory.join(comp.gpa, &[_][]const u8{emit.sub_path});
808 defer comp.gpa.free(full_out_path);
564 const full_out_path = try emit.directory.join(gpa, &[_][]const u8{emit.sub_path});
565 defer gpa.free(full_out_path);
809566 assert(comp.c_object_table.count() == 1);
810567 const the_key = comp.c_object_table.keys()[0];
811568 const cached_pp_file_path = the_key.status.success.object_path;
......@@ -813,75 +570,43 @@ pub const File = struct {
813570 return;
814571 }
815572
816 const use_lld = build_options.have_llvm and base.options.use_lld;
817 if (use_lld and base.options.output_mode == .Lib and base.options.link_mode == .Static) {
818 return base.linkAsArchive(comp, prog_node);
573 const use_lld = build_options.have_llvm and comp.config.use_lld;
574 const output_mode = comp.config.output_mode;
575 const link_mode = comp.config.link_mode;
576 if (use_lld and output_mode == .Lib and link_mode == .Static) {
577 return base.linkAsArchive(arena, prog_node);
819578 }
820579 switch (base.tag) {
821 .coff => return @fieldParentPtr(Coff, "base", base).flush(comp, prog_node),
822 .elf => return @fieldParentPtr(Elf, "base", base).flush(comp, prog_node),
823 .macho => return @fieldParentPtr(MachO, "base", base).flush(comp, prog_node),
824 .c => return @fieldParentPtr(C, "base", base).flush(comp, prog_node),
825 .wasm => return @fieldParentPtr(Wasm, "base", base).flush(comp, prog_node),
826 .spirv => return @fieldParentPtr(SpirV, "base", base).flush(comp, prog_node),
827 .plan9 => return @fieldParentPtr(Plan9, "base", base).flush(comp, prog_node),
828 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flush(comp, prog_node),
580 inline else => |tag| {
581 return @fieldParentPtr(tag.Type(), "base", base).flush(arena, prog_node);
582 },
829583 }
830584 }
831585
832586 /// Commit pending changes and write headers. Works based on `effectiveOutputMode`
833587 /// rather than final output mode.
834 pub fn flushModule(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
835 if (build_options.only_c) {
836 assert(base.tag == .c);
837 return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node);
838 }
588 pub fn flushModule(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void {
839589 switch (base.tag) {
840 .coff => return @fieldParentPtr(Coff, "base", base).flushModule(comp, prog_node),
841 .elf => return @fieldParentPtr(Elf, "base", base).flushModule(comp, prog_node),
842 .macho => return @fieldParentPtr(MachO, "base", base).flushModule(comp, prog_node),
843 .c => return @fieldParentPtr(C, "base", base).flushModule(comp, prog_node),
844 .wasm => return @fieldParentPtr(Wasm, "base", base).flushModule(comp, prog_node),
845 .spirv => return @fieldParentPtr(SpirV, "base", base).flushModule(comp, prog_node),
846 .plan9 => return @fieldParentPtr(Plan9, "base", base).flushModule(comp, prog_node),
847 .nvptx => return @fieldParentPtr(NvPtx, "base", base).flushModule(comp, prog_node),
590 .c => {
591 return @fieldParentPtr(C, "base", base).flushModule(arena, prog_node);
592 },
593 inline else => |tag| {
594 if (build_options.only_c) unreachable;
595 return @fieldParentPtr(tag.Type(), "base", base).flushModule(arena, prog_node);
596 },
848597 }
849598 }
850599
851600 /// Called when a Decl is deleted from the Module.
852601 pub fn freeDecl(base: *File, decl_index: InternPool.DeclIndex) void {
853 if (build_options.only_c) {
854 assert(base.tag == .c);
855 return @fieldParentPtr(C, "base", base).freeDecl(decl_index);
856 }
857 switch (base.tag) {
858 .coff => @fieldParentPtr(Coff, "base", base).freeDecl(decl_index),
859 .elf => @fieldParentPtr(Elf, "base", base).freeDecl(decl_index),
860 .macho => @fieldParentPtr(MachO, "base", base).freeDecl(decl_index),
861 .c => @fieldParentPtr(C, "base", base).freeDecl(decl_index),
862 .wasm => @fieldParentPtr(Wasm, "base", base).freeDecl(decl_index),
863 .spirv => @fieldParentPtr(SpirV, "base", base).freeDecl(decl_index),
864 .plan9 => @fieldParentPtr(Plan9, "base", base).freeDecl(decl_index),
865 .nvptx => @fieldParentPtr(NvPtx, "base", base).freeDecl(decl_index),
866 }
867 }
868
869 pub fn errorFlags(base: *File) ErrorFlags {
870 switch (base.tag) {
871 .coff => return @fieldParentPtr(Coff, "base", base).error_flags,
872 .elf => return @fieldParentPtr(Elf, "base", base).error_flags,
873 .macho => return @fieldParentPtr(MachO, "base", base).error_flags,
874 .plan9 => return @fieldParentPtr(Plan9, "base", base).error_flags,
875 .c => return .{ .no_entry_point_found = false },
876 .wasm, .spirv, .nvptx => return ErrorFlags{},
877 }
878 }
879
880 pub fn miscErrors(base: *File) []const ErrorMsg {
881602 switch (base.tag) {
882 .elf => return @fieldParentPtr(Elf, "base", base).misc_errors.items,
883 .macho => return @fieldParentPtr(MachO, "base", base).misc_errors.items,
884 else => return &.{},
603 .c => {
604 @fieldParentPtr(C, "base", base).freeDecl(decl_index);
605 },
606 inline else => |tag| {
607 if (build_options.only_c) unreachable;
608 @fieldParentPtr(tag.Type(), "base", base).freeDecl(decl_index);
609 },
885610 }
886611 }
887612
......@@ -900,19 +625,14 @@ pub const File = struct {
900625 exported: Module.Exported,
901626 exports: []const *Module.Export,
902627 ) UpdateExportsError!void {
903 if (build_options.only_c) {
904 assert(base.tag == .c);
905 return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports);
906 }
907628 switch (base.tag) {
908 .coff => return @fieldParentPtr(Coff, "base", base).updateExports(module, exported, exports),
909 .elf => return @fieldParentPtr(Elf, "base", base).updateExports(module, exported, exports),
910 .macho => return @fieldParentPtr(MachO, "base", base).updateExports(module, exported, exports),
911 .c => return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports),
912 .wasm => return @fieldParentPtr(Wasm, "base", base).updateExports(module, exported, exports),
913 .spirv => return @fieldParentPtr(SpirV, "base", base).updateExports(module, exported, exports),
914 .plan9 => return @fieldParentPtr(Plan9, "base", base).updateExports(module, exported, exports),
915 .nvptx => return @fieldParentPtr(NvPtx, "base", base).updateExports(module, exported, exports),
629 .c => {
630 return @fieldParentPtr(C, "base", base).updateExports(module, exported, exports);
631 },
632 inline else => |tag| {
633 if (build_options.only_c) unreachable;
634 return @fieldParentPtr(tag.Type(), "base", base).updateExports(module, exported, exports);
635 },
916636 }
917637 }
918638
......@@ -929,150 +649,91 @@ pub const File = struct {
929649 /// May be called before or after updateFunc/updateDecl therefore it is up to the linker to allocate
930650 /// the block/atom.
931651 pub fn getDeclVAddr(base: *File, decl_index: InternPool.DeclIndex, reloc_info: RelocInfo) !u64 {
932 if (build_options.only_c) unreachable;
652 if (build_options.only_c) @compileError("unreachable");
933653 switch (base.tag) {
934 .coff => return @fieldParentPtr(Coff, "base", base).getDeclVAddr(decl_index, reloc_info),
935 .elf => return @fieldParentPtr(Elf, "base", base).getDeclVAddr(decl_index, reloc_info),
936 .macho => return @fieldParentPtr(MachO, "base", base).getDeclVAddr(decl_index, reloc_info),
937 .plan9 => return @fieldParentPtr(Plan9, "base", base).getDeclVAddr(decl_index, reloc_info),
938654 .c => unreachable,
939 .wasm => return @fieldParentPtr(Wasm, "base", base).getDeclVAddr(decl_index, reloc_info),
940655 .spirv => unreachable,
941656 .nvptx => unreachable,
657 inline else => |tag| {
658 return @fieldParentPtr(tag.Type(), "base", base).getDeclVAddr(decl_index, reloc_info);
659 },
942660 }
943661 }
944662
945663 pub const LowerResult = @import("codegen.zig").Result;
946664
947 pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult {
948 if (build_options.only_c) unreachable;
665 pub fn lowerAnonDecl(
666 base: *File,
667 decl_val: InternPool.Index,
668 decl_align: InternPool.Alignment,
669 src_loc: Module.SrcLoc,
670 ) !LowerResult {
671 if (build_options.only_c) @compileError("unreachable");
949672 switch (base.tag) {
950 .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
951 .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
952 .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
953 .plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc),
954673 .c => unreachable,
955 .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
956674 .spirv => unreachable,
957675 .nvptx => unreachable,
676 inline else => |tag| {
677 return @fieldParentPtr(tag.Type(), "base", base).lowerAnonDecl(decl_val, decl_align, src_loc);
678 },
958679 }
959680 }
960681
961682 pub fn getAnonDeclVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {
962 if (build_options.only_c) unreachable;
683 if (build_options.only_c) @compileError("unreachable");
963684 switch (base.tag) {
964 .coff => return @fieldParentPtr(Coff, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
965 .elf => return @fieldParentPtr(Elf, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
966 .macho => return @fieldParentPtr(MachO, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
967 .plan9 => return @fieldParentPtr(Plan9, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
968685 .c => unreachable,
969 .wasm => return @fieldParentPtr(Wasm, "base", base).getAnonDeclVAddr(decl_val, reloc_info),
970686 .spirv => unreachable,
971687 .nvptx => unreachable,
688 inline else => |tag| {
689 return @fieldParentPtr(tag.Type(), "base", base).getAnonDeclVAddr(decl_val, reloc_info);
690 },
972691 }
973692 }
974693
975 pub fn deleteDeclExport(base: *File, decl_index: InternPool.DeclIndex, name: InternPool.NullTerminatedString) !void {
976 if (build_options.only_c) unreachable;
977 switch (base.tag) {
978 .coff => return @fieldParentPtr(Coff, "base", base).deleteDeclExport(decl_index, name),
979 .elf => return @fieldParentPtr(Elf, "base", base).deleteDeclExport(decl_index, name),
980 .macho => return @fieldParentPtr(MachO, "base", base).deleteDeclExport(decl_index, name),
981 .plan9 => {},
982 .c => {},
983 .wasm => return @fieldParentPtr(Wasm, "base", base).deleteDeclExport(decl_index),
984 .spirv => {},
985 .nvptx => {},
986 }
987 }
988
989 /// This function is called by the frontend before flush(). It communicates that
990 /// `options.bin_file.emit` directory needs to be renamed from
991 /// `[zig-cache]/tmp/[random]` to `[zig-cache]/o/[digest]`.
992 /// The frontend would like to simply perform a file system rename, however,
993 /// some linker backends care about the file paths of the objects they are linking.
994 /// So this function call tells linker backends to rename the paths of object files
995 /// to observe the new directory path.
996 /// Linker backends which do not have this requirement can fall back to the simple
997 /// implementation at the bottom of this function.
998 /// This function is only called when CacheMode is `whole`.
999 pub fn renameTmpIntoCache(
694 pub fn deleteDeclExport(
1000695 base: *File,
1001 cache_directory: Compilation.Directory,
1002 tmp_dir_sub_path: []const u8,
1003 o_sub_path: []const u8,
696 decl_index: InternPool.DeclIndex,
697 name: InternPool.NullTerminatedString,
1004698 ) !void {
1005 // So far, none of the linker backends need to respond to this event, however,
1006 // it makes sense that they might want to. So we leave this mechanism here
1007 // for now. Once the linker backends get more mature, if it turns out this
1008 // is not needed we can refactor this into having the frontend do the rename
1009 // directly, and remove this function from link.zig.
1010 _ = base;
1011 while (true) {
1012 if (builtin.os.tag == .windows) {
1013 // Work around windows `renameW` can't fail with `PathAlreadyExists`
1014 // See https://github.com/ziglang/zig/issues/8362
1015 if (cache_directory.handle.access(o_sub_path, .{})) |_| {
1016 try cache_directory.handle.deleteTree(o_sub_path);
1017 continue;
1018 } else |err| switch (err) {
1019 error.FileNotFound => {},
1020 else => |e| return e,
1021 }
1022 std.fs.rename(
1023 cache_directory.handle,
1024 tmp_dir_sub_path,
1025 cache_directory.handle,
1026 o_sub_path,
1027 ) catch |err| {
1028 log.err("unable to rename cache dir {s} to {s}: {s}", .{ tmp_dir_sub_path, o_sub_path, @errorName(err) });
1029 return err;
1030 };
1031 break;
1032 } else {
1033 std.fs.rename(
1034 cache_directory.handle,
1035 tmp_dir_sub_path,
1036 cache_directory.handle,
1037 o_sub_path,
1038 ) catch |err| switch (err) {
1039 error.PathAlreadyExists => {
1040 try cache_directory.handle.deleteTree(o_sub_path);
1041 continue;
1042 },
1043 else => |e| return e,
1044 };
1045 break;
1046 }
699 if (build_options.only_c) @compileError("unreachable");
700 switch (base.tag) {
701 .plan9,
702 .c,
703 .spirv,
704 .nvptx,
705 => {},
706
707 inline else => |tag| {
708 return @fieldParentPtr(tag.Type(), "base", base).deleteDeclExport(decl_index, name);
709 },
1047710 }
1048711 }
1049712
1050 pub fn linkAsArchive(base: *File, comp: *Compilation, prog_node: *std.Progress.Node) FlushError!void {
1051 const emit = base.options.emit orelse return;
1052
713 pub fn linkAsArchive(base: *File, arena: Allocator, prog_node: *std.Progress.Node) FlushError!void {
1053714 const tracy = trace(@src());
1054715 defer tracy.end();
1055716
1056 var arena_allocator = std.heap.ArenaAllocator.init(base.allocator);
1057 defer arena_allocator.deinit();
1058 const arena = arena_allocator.allocator();
717 const comp = base.comp;
718 const gpa = comp.gpa;
1059719
1060 const directory = emit.directory; // Just an alias to make it shorter to type.
1061 const full_out_path = try directory.join(arena, &[_][]const u8{emit.sub_path});
720 const directory = base.emit.directory; // Just an alias to make it shorter to type.
721 const full_out_path = try directory.join(arena, &[_][]const u8{base.emit.sub_path});
1062722 const full_out_path_z = try arena.dupeZ(u8, full_out_path);
723 const opt_zcu = comp.module;
1063724
1064725 // If there is no Zig code to compile, then we should skip flushing the output file
1065726 // because it will not be part of the linker line anyway.
1066 const module_obj_path: ?[]const u8 = if (base.options.module != null) blk: {
1067 try base.flushModule(comp, prog_node);
727 const zcu_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
728 try base.flushModule(arena, prog_node);
1068729
1069730 const dirname = fs.path.dirname(full_out_path_z) orelse ".";
1070 break :blk try fs.path.join(arena, &.{ dirname, base.intermediary_basename.? });
731 break :blk try fs.path.join(arena, &.{ dirname, base.zcu_object_sub_path.? });
1071732 } else null;
1072733
1073 log.debug("module_obj_path={s}", .{if (module_obj_path) |s| s else "(null)"});
734 log.debug("zcu_obj_path={s}", .{if (zcu_obj_path) |s| s else "(null)"});
1074735
1075 const compiler_rt_path: ?[]const u8 = if (base.options.include_compiler_rt)
736 const compiler_rt_path: ?[]const u8 = if (comp.include_compiler_rt)
1076737 comp.compiler_rt_obj.?.full_object_path
1077738 else
1078739 null;
......@@ -1084,17 +745,19 @@ pub const File = struct {
1084745 const id_symlink_basename = "llvm-ar.id";
1085746
1086747 var man: Cache.Manifest = undefined;
1087 defer if (!base.options.disable_lld_caching) man.deinit();
748 defer if (!base.disable_lld_caching) man.deinit();
749
750 const objects = comp.objects;
1088751
1089752 var digest: [Cache.hex_digest_len]u8 = undefined;
1090753
1091 if (!base.options.disable_lld_caching) {
754 if (!base.disable_lld_caching) {
1092755 man = comp.cache_parent.obtain();
1093756
1094757 // We are about to obtain this lock, so here we give other processes a chance first.
1095758 base.releaseLock();
1096759
1097 for (base.options.objects) |obj| {
760 for (objects) |obj| {
1098761 _ = try man.addFile(obj.path, null);
1099762 man.hash.add(obj.must_link);
1100763 man.hash.add(obj.loption);
......@@ -1107,7 +770,7 @@ pub const File = struct {
1107770 _ = try man.addFile(key.status.success.res_path, null);
1108771 }
1109772 }
1110 try man.addOptionalFile(module_obj_path);
773 try man.addOptionalFile(zcu_obj_path);
1111774 try man.addOptionalFile(compiler_rt_path);
1112775
1113776 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
......@@ -1137,11 +800,11 @@ pub const File = struct {
1137800 }
1138801
1139802 const win32_resource_table_len = if (build_options.only_core_functionality) 0 else comp.win32_resource_table.count();
1140 const num_object_files = base.options.objects.len + comp.c_object_table.count() + win32_resource_table_len + 2;
1141 var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files);
803 const num_object_files = objects.len + comp.c_object_table.count() + win32_resource_table_len + 2;
804 var object_files = try std.ArrayList([*:0]const u8).initCapacity(gpa, num_object_files);
1142805 defer object_files.deinit();
1143806
1144 for (base.options.objects) |obj| {
807 for (objects) |obj| {
1145808 object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj.path));
1146809 }
1147810 for (comp.c_object_table.keys()) |key| {
......@@ -1152,14 +815,14 @@ pub const File = struct {
1152815 object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.res_path));
1153816 }
1154817 }
1155 if (module_obj_path) |p| {
818 if (zcu_obj_path) |p| {
1156819 object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
1157820 }
1158821 if (compiler_rt_path) |p| {
1159822 object_files.appendAssumeCapacity(try arena.dupeZ(u8, p));
1160823 }
1161824
1162 if (base.options.verbose_link) {
825 if (comp.verbose_link) {
1163826 std.debug.print("ar rcs {s}", .{full_out_path_z});
1164827 for (object_files.items) |arg| {
1165828 std.debug.print(" {s}", .{arg});
......@@ -1170,12 +833,13 @@ pub const File = struct {
1170833 const llvm_bindings = @import("codegen/llvm/bindings.zig");
1171834 const Builder = @import("codegen/llvm/Builder.zig");
1172835 const llvm = @import("codegen/llvm.zig");
1173 Builder.initializeLLVMTarget(base.options.target.cpu.arch);
1174 const os_tag = llvm.targetOs(base.options.target.os.tag);
836 const target = comp.root_mod.resolved_target.result;
837 Builder.initializeLLVMTarget(target.cpu.arch);
838 const os_tag = llvm.targetOs(target.os.tag);
1175839 const bad = llvm_bindings.WriteArchive(full_out_path_z, object_files.items.ptr, object_files.items.len, os_tag);
1176840 if (bad) return error.UnableToWriteArchive;
1177841
1178 if (!base.options.disable_lld_caching) {
842 if (!base.disable_lld_caching) {
1179843 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
1180844 log.warn("failed to save archive hash digest file: {s}", .{@errorName(err)});
1181845 };
......@@ -1199,6 +863,35 @@ pub const File = struct {
1199863 spirv,
1200864 plan9,
1201865 nvptx,
866
867 pub fn Type(comptime tag: Tag) type {
868 return switch (tag) {
869 .coff => Coff,
870 .elf => Elf,
871 .macho => MachO,
872 .c => C,
873 .wasm => Wasm,
874 .spirv => SpirV,
875 .plan9 => Plan9,
876 .nvptx => NvPtx,
877 };
878 }
879
880 pub fn fromObjectFormat(ofmt: std.Target.ObjectFormat) Tag {
881 return switch (ofmt) {
882 .coff => .coff,
883 .elf => .elf,
884 .macho => .macho,
885 .wasm => .wasm,
886 .plan9 => .plan9,
887 .c => .c,
888 .spirv => .spirv,
889 .nvptx => .nvptx,
890 .hex => @panic("TODO implement hex object format"),
891 .raw => @panic("TODO implement raw object format"),
892 .dxcontainer => @panic("TODO implement dxcontainer object format"),
893 };
894 }
1202895 };
1203896
1204897 pub const ErrorFlags = struct {
......@@ -1237,6 +930,73 @@ pub const File = struct {
1237930 }
1238931 };
1239932
933 pub fn effectiveOutputMode(
934 use_lld: bool,
935 output_mode: std.builtin.OutputMode,
936 ) std.builtin.OutputMode {
937 return if (use_lld) .Obj else output_mode;
938 }
939
940 pub fn determineMode(
941 use_lld: bool,
942 output_mode: std.builtin.OutputMode,
943 link_mode: std.builtin.LinkMode,
944 ) fs.File.Mode {
945 // On common systems with a 0o022 umask, 0o777 will still result in a file created
946 // with 0o755 permissions, but it works appropriately if the system is configured
947 // more leniently. As another data point, C's fopen seems to open files with the
948 // 666 mode.
949 const executable_mode = if (builtin.target.os.tag == .windows) 0 else 0o777;
950 switch (effectiveOutputMode(use_lld, output_mode)) {
951 .Lib => return switch (link_mode) {
952 .Dynamic => executable_mode,
953 .Static => fs.File.default_mode,
954 },
955 .Exe => return executable_mode,
956 .Obj => return fs.File.default_mode,
957 }
958 }
959
960 pub fn isStatic(self: File) bool {
961 return self.comp.config.link_mode == .Static;
962 }
963
964 pub fn isObject(self: File) bool {
965 const output_mode = self.comp.config.output_mode;
966 return output_mode == .Obj;
967 }
968
969 pub fn isExe(self: File) bool {
970 const output_mode = self.comp.config.output_mode;
971 return output_mode == .Exe;
972 }
973
974 pub fn isStaticLib(self: File) bool {
975 const output_mode = self.comp.config.output_mode;
976 return output_mode == .Lib and self.isStatic();
977 }
978
979 pub fn isRelocatable(self: File) bool {
980 return self.isObject() or self.isStaticLib();
981 }
982
983 pub fn isDynLib(self: File) bool {
984 const output_mode = self.comp.config.output_mode;
985 return output_mode == .Lib and !self.isStatic();
986 }
987
988 pub fn emitLlvmObject(
989 base: File,
990 arena: Allocator,
991 llvm_object: *LlvmObject,
992 prog_node: *std.Progress.Node,
993 ) !void {
994 return base.comp.emitLlvmObject(arena, base.emit, .{
995 .directory = null,
996 .basename = base.zcu_object_sub_path.?,
997 }, llvm_object, prog_node);
998 }
999
12401000 pub const C = @import("link/C.zig");
12411001 pub const Coff = @import("link/Coff.zig");
12421002 pub const Plan9 = @import("link/Plan9.zig");
......@@ -1247,19 +1007,3 @@ pub const File = struct {
12471007 pub const NvPtx = @import("link/NvPtx.zig");
12481008 pub const Dwarf = @import("link/Dwarf.zig");
12491009};
1250
1251pub fn determineMode(options: Options) fs.File.Mode {
1252 // On common systems with a 0o022 umask, 0o777 will still result in a file created
1253 // with 0o755 permissions, but it works appropriately if the system is configured
1254 // more leniently. As another data point, C's fopen seems to open files with the
1255 // 666 mode.
1256 const executable_mode = if (builtin.target.os.tag == .windows) 0 else 0o777;
1257 switch (options.effectiveOutputMode()) {
1258 .Lib => return switch (options.link_mode) {
1259 .Dynamic => executable_mode,
1260 .Static => fs.File.default_mode,
1261 },
1262 .Exe => return executable_mode,
1263 .Obj => return fs.File.default_mode,
1264 }
1265}
src/link/C.zig+64-31
......@@ -5,6 +5,7 @@ const Allocator = std.mem.Allocator;
55const fs = std.fs;
66
77const C = @This();
8const build_options = @import("build_options");
89const Module = @import("../Module.zig");
910const InternPool = @import("../InternPool.zig");
1011const Alignment = InternPool.Alignment;
......@@ -83,7 +84,8 @@ pub fn getString(this: C, s: String) []const u8 {
8384}
8485
8586pub fn addString(this: *C, s: []const u8) Allocator.Error!String {
86 const gpa = this.base.allocator;
87 const comp = this.base.comp;
88 const gpa = comp.gpa;
8789 try this.string_bytes.appendSlice(gpa, s);
8890 return .{
8991 .start = @intCast(this.string_bytes.items.len - s.len),
......@@ -91,28 +93,55 @@ pub fn addString(this: *C, s: []const u8) Allocator.Error!String {
9193 };
9294}
9395
94pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C {
95 assert(options.target.ofmt == .c);
96
97 if (options.use_llvm) return error.LLVMHasNoCBackend;
98 if (options.use_lld) return error.LLDHasNoCBackend;
96pub fn open(
97 arena: Allocator,
98 comp: *Compilation,
99 emit: Compilation.Emit,
100 options: link.File.OpenOptions,
101) !*C {
102 return createEmpty(arena, comp, emit, options);
103}
99104
100 const file = try options.emit.?.directory.handle.createFile(sub_path, .{
105pub fn createEmpty(
106 arena: Allocator,
107 comp: *Compilation,
108 emit: Compilation.Emit,
109 options: link.File.OpenOptions,
110) !*C {
111 const target = comp.root_mod.resolved_target.result;
112 assert(target.ofmt == .c);
113 const optimize_mode = comp.root_mod.optimize_mode;
114 const use_lld = build_options.have_llvm and comp.config.use_lld;
115 const use_llvm = comp.config.use_llvm;
116 const output_mode = comp.config.output_mode;
117 const link_mode = comp.config.link_mode;
118
119 // These are caught by `Compilation.Config.resolve`.
120 assert(!use_lld);
121 assert(!use_llvm);
122
123 const file = try emit.directory.handle.createFile(emit.sub_path, .{
101124 // Truncation is done on `flush`.
102125 .truncate = false,
103 .mode = link.determineMode(options),
126 .mode = link.File.determineMode(use_lld, output_mode, link_mode),
104127 });
105128 errdefer file.close();
106129
107 const c_file = try gpa.create(C);
108 errdefer gpa.destroy(c_file);
130 const c_file = try arena.create(C);
109131
110132 c_file.* = .{
111133 .base = .{
112134 .tag = .c,
113 .options = options,
135 .comp = comp,
136 .emit = emit,
137 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
138 .print_gc_sections = options.print_gc_sections,
139 .stack_size = options.stack_size orelse 16777216,
140 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
114141 .file = file,
115 .allocator = gpa,
142 .disable_lld_caching = options.disable_lld_caching,
143 .build_id = options.build_id,
144 .rpath_list = options.rpath_list,
116145 },
117146 };
118147
......@@ -120,7 +149,7 @@ pub fn openPath(gpa: Allocator, sub_path: []const u8, options: link.Options) !*C
120149}
121150
122151pub fn deinit(self: *C) void {
123 const gpa = self.base.allocator;
152 const gpa = self.base.comp.gpa;
124153
125154 for (self.decl_table.values()) |*db| {
126155 db.deinit(gpa);
......@@ -141,7 +170,7 @@ pub fn deinit(self: *C) void {
141170}
142171
143172pub fn freeDecl(self: *C, decl_index: InternPool.DeclIndex) void {
144 const gpa = self.base.allocator;
173 const gpa = self.base.comp.gpa;
145174 if (self.decl_table.fetchSwapRemove(decl_index)) |kv| {
146175 var decl_block = kv.value;
147176 decl_block.deinit(gpa);
......@@ -155,7 +184,7 @@ pub fn updateFunc(
155184 air: Air,
156185 liveness: Liveness,
157186) !void {
158 const gpa = self.base.allocator;
187 const gpa = self.base.comp.gpa;
159188
160189 const func = module.funcInfo(func_index);
161190 const decl_index = func.owner_decl;
......@@ -223,7 +252,7 @@ pub fn updateFunc(
223252}
224253
225254fn updateAnonDecl(self: *C, module: *Module, i: usize) !void {
226 const gpa = self.base.allocator;
255 const gpa = self.base.comp.gpa;
227256 const anon_decl = self.anon_decls.keys()[i];
228257
229258 const fwd_decl = &self.fwd_decl_buf;
......@@ -285,7 +314,7 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: InternPool.DeclIndex) !
285314 const tracy = trace(@src());
286315 defer tracy.end();
287316
288 const gpa = self.base.allocator;
317 const gpa = self.base.comp.gpa;
289318
290319 const gop = try self.decl_table.getOrPut(gpa, decl_index);
291320 if (!gop.found_existing) {
......@@ -347,12 +376,13 @@ pub fn updateDeclLineNumber(self: *C, module: *Module, decl_index: InternPool.De
347376 _ = decl_index;
348377}
349378
350pub fn flush(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) !void {
351 return self.flushModule(comp, prog_node);
379pub fn flush(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void {
380 return self.flushModule(arena, prog_node);
352381}
353382
354383fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
355 var defines = std.ArrayList(u8).init(self.base.allocator);
384 const gpa = self.base.comp.gpa;
385 var defines = std.ArrayList(u8).init(gpa);
356386 errdefer defines.deinit();
357387 const writer = defines.writer();
358388 switch (target.abi) {
......@@ -363,7 +393,9 @@ fn abiDefines(self: *C, target: std.Target) !std.ArrayList(u8) {
363393 return defines;
364394}
365395
366pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !void {
396pub fn flushModule(self: *C, arena: Allocator, prog_node: *std.Progress.Node) !void {
397 _ = arena; // Has the same lifetime as the call to Compilation.update.
398
367399 const tracy = trace(@src());
368400 defer tracy.end();
369401
......@@ -371,8 +403,9 @@ pub fn flushModule(self: *C, _: *Compilation, prog_node: *std.Progress.Node) !vo
371403 sub_prog_node.activate();
372404 defer sub_prog_node.end();
373405
374 const gpa = self.base.allocator;
375 const module = self.base.options.module.?;
406 const comp = self.base.comp;
407 const gpa = comp.gpa;
408 const module = self.base.comp.module.?;
376409
377410 {
378411 var i: usize = 0;
......@@ -520,8 +553,8 @@ fn flushCTypes(
520553 pass: codegen.DeclGen.Pass,
521554 decl_ctypes: codegen.CType.Store,
522555) FlushDeclError!void {
523 const gpa = self.base.allocator;
524 const mod = self.base.options.module.?;
556 const gpa = self.base.comp.gpa;
557 const mod = self.base.comp.module.?;
525558
526559 const decl_ctypes_len = decl_ctypes.count();
527560 f.ctypes_map.clearRetainingCapacity();
......@@ -601,7 +634,7 @@ fn flushCTypes(
601634}
602635
603636fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
604 const gpa = self.base.allocator;
637 const gpa = self.base.comp.gpa;
605638
606639 const fwd_decl = &self.lazy_fwd_decl_buf;
607640 const code = &self.lazy_code_buf;
......@@ -609,7 +642,7 @@ fn flushErrDecls(self: *C, ctypes: *codegen.CType.Store) FlushDeclError!void {
609642 var object = codegen.Object{
610643 .dg = .{
611644 .gpa = gpa,
612 .module = self.base.options.module.?,
645 .module = self.base.comp.module.?,
613646 .error_msg = null,
614647 .pass = .flush,
615648 .is_naked_fn = false,
......@@ -643,7 +676,7 @@ fn flushLazyFn(
643676 ctypes: *codegen.CType.Store,
644677 lazy_fn: codegen.LazyFnMap.Entry,
645678) FlushDeclError!void {
646 const gpa = self.base.allocator;
679 const gpa = self.base.comp.gpa;
647680
648681 const fwd_decl = &self.lazy_fwd_decl_buf;
649682 const code = &self.lazy_code_buf;
......@@ -651,7 +684,7 @@ fn flushLazyFn(
651684 var object = codegen.Object{
652685 .dg = .{
653686 .gpa = gpa,
654 .module = self.base.options.module.?,
687 .module = self.base.comp.module.?,
655688 .error_msg = null,
656689 .pass = .flush,
657690 .is_naked_fn = false,
......@@ -683,7 +716,7 @@ fn flushLazyFn(
683716}
684717
685718fn flushLazyFns(self: *C, f: *Flush, lazy_fns: codegen.LazyFnMap) FlushDeclError!void {
686 const gpa = self.base.allocator;
719 const gpa = self.base.comp.gpa;
687720 try f.lazy_fns.ensureUnusedCapacity(gpa, @intCast(lazy_fns.count()));
688721
689722 var it = lazy_fns.iterator();
......@@ -702,7 +735,7 @@ fn flushDeclBlock(
702735 export_names: std.AutoHashMapUnmanaged(InternPool.NullTerminatedString, void),
703736 extern_symbol_name: InternPool.OptionalNullTerminatedString,
704737) FlushDeclError!void {
705 const gpa = self.base.allocator;
738 const gpa = self.base.comp.gpa;
706739 try self.flushLazyFns(f, decl_block.lazy_fns);
707740 try f.all_buffers.ensureUnusedCapacity(gpa, 1);
708741 fwd_decl: {
src/link/Coff.zig+289-207
......@@ -3,11 +3,24 @@
33//! LLD for traditional linking (linking relocatable object files).
44//! LLD is also the default linker for LLVM.
55
6/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
6/// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path.
77llvm_object: ?*LlvmObject = null,
88
99base: link.File,
10error_flags: link.File.ErrorFlags = .{},
10image_base: u64,
11subsystem: ?std.Target.SubSystem,
12tsaware: bool,
13nxcompat: bool,
14dynamicbase: bool,
15/// TODO this and minor_subsystem_version should be combined into one property and left as
16/// default or populated together. They should not be separate fields.
17major_subsystem_version: u16,
18minor_subsystem_version: u16,
19lib_dirs: []const []const u8,
20entry: link.File.OpenOptions.Entry,
21entry_addr: ?u32,
22module_definition_file: ?[]const u8,
23pdb_out_path: ?[]const u8,
1124
1225ptr_width: PtrWidth,
1326page_size: u32,
......@@ -48,9 +61,6 @@ got_table_count_dirty: bool = true,
4861got_table_contents_dirty: bool = true,
4962imports_count_dirty: bool = true,
5063
51/// Virtual address of the entry point procedure relative to image base.
52entry_addr: ?u32 = null,
53
5464/// Table of tracked LazySymbols.
5565lazy_syms: LazySymbolTable = .{},
5666
......@@ -226,132 +236,112 @@ const ideal_factor = 3;
226236const minimum_text_block_size = 64;
227237pub const min_text_capacity = padToIdeal(minimum_text_block_size);
228238
229pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Coff {
230 assert(options.target.ofmt == .coff);
231
232 if (options.use_llvm) {
233 return createEmpty(allocator, options);
234 }
235
236 const self = try createEmpty(allocator, options);
237 errdefer self.base.destroy();
238
239 const file = try options.emit.?.directory.handle.createFile(sub_path, .{
240 .truncate = false,
241 .read = true,
242 .mode = link.determineMode(options),
243 });
244 self.base.file = file;
245
246 try self.populateMissingMetadata();
247
248 return self;
249}
250
251pub fn createEmpty(gpa: Allocator, options: link.Options) !*Coff {
252 const ptr_width: PtrWidth = switch (options.target.ptrBitWidth()) {
239pub fn createEmpty(
240 arena: Allocator,
241 comp: *Compilation,
242 emit: Compilation.Emit,
243 options: link.File.OpenOptions,
244) !*Coff {
245 const target = comp.root_mod.resolved_target.result;
246 assert(target.ofmt == .coff);
247 const optimize_mode = comp.root_mod.optimize_mode;
248 const output_mode = comp.config.output_mode;
249 const link_mode = comp.config.link_mode;
250 const use_llvm = comp.config.use_llvm;
251 const use_lld = build_options.have_llvm and comp.config.use_lld;
252
253 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
253254 0...32 => .p32,
254255 33...64 => .p64,
255256 else => return error.UnsupportedCOFFArchitecture,
256257 };
257 const page_size: u32 = switch (options.target.cpu.arch) {
258 const page_size: u32 = switch (target.cpu.arch) {
258259 else => 0x1000,
259260 };
260 const self = try gpa.create(Coff);
261 errdefer gpa.destroy(self);
261
262 // If using LLD to link, this code should produce an object file so that it
263 // can be passed to LLD.
264 // If using LLVM to generate the object file for the zig compilation unit,
265 // we need a place to put the object file so that it can be subsequently
266 // handled.
267 const zcu_object_sub_path = if (!use_lld and !use_llvm)
268 null
269 else
270 try std.fmt.allocPrint(arena, "{s}.obj", .{emit.sub_path});
271
272 const self = try arena.create(Coff);
262273 self.* = .{
263274 .base = .{
264275 .tag = .coff,
265 .options = options,
266 .allocator = gpa,
276 .comp = comp,
277 .emit = emit,
278 .zcu_object_sub_path = zcu_object_sub_path,
279 .stack_size = options.stack_size orelse 16777216,
280 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
281 .print_gc_sections = options.print_gc_sections,
282 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
267283 .file = null,
284 .disable_lld_caching = options.disable_lld_caching,
285 .build_id = options.build_id,
286 .rpath_list = options.rpath_list,
268287 },
269288 .ptr_width = ptr_width,
270289 .page_size = page_size,
271 .data_directories = comptime mem.zeroes([coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES]coff.ImageDataDirectory),
272 };
273
274 if (options.use_llvm) {
275 self.llvm_object = try LlvmObject.create(gpa, options);
276 }
277 return self;
278}
279
280pub fn deinit(self: *Coff) void {
281 const gpa = self.base.allocator;
282290
283 if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa);
291 .data_directories = [1]coff.ImageDataDirectory{.{
292 .virtual_address = 0,
293 .size = 0,
294 }} ** coff.IMAGE_NUMBEROF_DIRECTORY_ENTRIES,
284295
285 for (self.objects.items) |*object| {
286 object.deinit(gpa);
287 }
288 self.objects.deinit(gpa);
289
290 for (self.sections.items(.free_list)) |*free_list| {
291 free_list.deinit(gpa);
292 }
293 self.sections.deinit(gpa);
294
295 self.atoms.deinit(gpa);
296 self.locals.deinit(gpa);
297 self.globals.deinit(gpa);
298
299 {
300 var it = self.resolver.keyIterator();
301 while (it.next()) |key_ptr| {
302 gpa.free(key_ptr.*);
303 }
304 self.resolver.deinit(gpa);
305 }
306
307 self.unresolved.deinit(gpa);
308 self.locals_free_list.deinit(gpa);
309 self.globals_free_list.deinit(gpa);
310 self.strtab.deinit(gpa);
311 self.temp_strtab.deinit(gpa);
312 self.got_table.deinit(gpa);
313
314 for (self.import_tables.values()) |*itab| {
315 itab.deinit(gpa);
316 }
317 self.import_tables.deinit(gpa);
318
319 self.lazy_syms.deinit(gpa);
320
321 for (self.decls.values()) |*metadata| {
322 metadata.deinit(gpa);
323 }
324 self.decls.deinit(gpa);
325
326 self.atom_by_index_table.deinit(gpa);
327
328 for (self.unnamed_const_atoms.values()) |*atoms| {
329 atoms.deinit(gpa);
330 }
331 self.unnamed_const_atoms.deinit(gpa);
296 .image_base = options.image_base orelse switch (output_mode) {
297 .Exe => switch (target.cpu.arch) {
298 .aarch64 => 0x140000000,
299 .x86_64, .x86 => 0x400000,
300 else => unreachable,
301 },
302 .Lib => 0x10000000,
303 .Obj => 0,
304 },
332305
333 {
334 var it = self.anon_decls.iterator();
335 while (it.next()) |entry| {
336 entry.value_ptr.exports.deinit(gpa);
337 }
338 self.anon_decls.deinit(gpa);
306 // Subsystem depends on the set of public symbol names from linked objects.
307 // See LinkerDriver::inferSubsystem from the LLD project for the flow chart.
308 .subsystem = options.subsystem,
309
310 .entry = options.entry,
311
312 .tsaware = options.tsaware,
313 .nxcompat = options.nxcompat,
314 .dynamicbase = options.dynamicbase,
315 .major_subsystem_version = options.major_subsystem_version orelse 6,
316 .minor_subsystem_version = options.minor_subsystem_version orelse 0,
317 .lib_dirs = options.lib_dirs,
318 .entry_addr = math.cast(u32, options.entry_addr orelse 0) orelse
319 return error.EntryAddressTooBig,
320 .module_definition_file = options.module_definition_file,
321 .pdb_out_path = options.pdb_out_path,
322 };
323 if (use_llvm and comp.config.have_zcu) {
324 self.llvm_object = try LlvmObject.create(arena, comp);
339325 }
326 errdefer self.base.destroy();
340327
341 for (self.relocs.values()) |*relocs| {
342 relocs.deinit(gpa);
328 if (use_lld and (use_llvm or !comp.config.have_zcu)) {
329 // LLVM emits the object file (if any); LLD links it into the final product.
330 return self;
343331 }
344 self.relocs.deinit(gpa);
345332
346 for (self.base_relocs.values()) |*relocs| {
347 relocs.deinit(gpa);
348 }
349 self.base_relocs.deinit(gpa);
350}
333 // What path should this COFF linker code output to?
334 // If using LLD to link, this code should produce an object file so that it
335 // can be passed to LLD.
336 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
337 self.base.file = try emit.directory.handle.createFile(sub_path, .{
338 .truncate = true,
339 .read = true,
340 .mode = link.File.determineMode(use_lld, output_mode, link_mode),
341 });
351342
352fn populateMissingMetadata(self: *Coff) !void {
353343 assert(self.llvm_object == null);
354 const gpa = self.base.allocator;
344 const gpa = comp.gpa;
355345
356346 try self.strtab.buffer.ensureUnusedCapacity(gpa, @sizeOf(u32));
357347 self.strtab.buffer.appendNTimesAssumeCapacity(0, @sizeOf(u32));
......@@ -369,7 +359,7 @@ fn populateMissingMetadata(self: *Coff) !void {
369359 });
370360
371361 if (self.text_section_index == null) {
372 const file_size = @as(u32, @intCast(self.base.options.program_code_size_hint));
362 const file_size: u32 = @intCast(options.program_code_size_hint);
373363 self.text_section_index = try self.allocateSection(".text", file_size, .{
374364 .CNT_CODE = 1,
375365 .MEM_EXECUTE = 1,
......@@ -378,7 +368,7 @@ fn populateMissingMetadata(self: *Coff) !void {
378368 }
379369
380370 if (self.got_section_index == null) {
381 const file_size = @as(u32, @intCast(self.base.options.symbol_count_hint)) * self.ptr_width.size();
371 const file_size = @as(u32, @intCast(options.symbol_count_hint)) * self.ptr_width.size();
382372 self.got_section_index = try self.allocateSection(".got", file_size, .{
383373 .CNT_INITIALIZED_DATA = 1,
384374 .MEM_READ = 1,
......@@ -403,7 +393,7 @@ fn populateMissingMetadata(self: *Coff) !void {
403393 }
404394
405395 if (self.idata_section_index == null) {
406 const file_size = @as(u32, @intCast(self.base.options.symbol_count_hint)) * self.ptr_width.size();
396 const file_size = @as(u32, @intCast(options.symbol_count_hint)) * self.ptr_width.size();
407397 self.idata_section_index = try self.allocateSection(".idata", file_size, .{
408398 .CNT_INITIALIZED_DATA = 1,
409399 .MEM_READ = 1,
......@@ -411,7 +401,7 @@ fn populateMissingMetadata(self: *Coff) !void {
411401 }
412402
413403 if (self.reloc_section_index == null) {
414 const file_size = @as(u32, @intCast(self.base.options.symbol_count_hint)) * @sizeOf(coff.BaseRelocation);
404 const file_size = @as(u32, @intCast(options.symbol_count_hint)) * @sizeOf(coff.BaseRelocation);
415405 self.reloc_section_index = try self.allocateSection(".reloc", file_size, .{
416406 .CNT_INITIALIZED_DATA = 1,
417407 .MEM_DISCARDABLE = 1,
......@@ -438,6 +428,91 @@ fn populateMissingMetadata(self: *Coff) !void {
438428 }
439429 try self.base.file.?.pwriteAll(&[_]u8{0}, max_file_offset);
440430 }
431
432 return self;
433}
434
435pub fn open(
436 arena: Allocator,
437 comp: *Compilation,
438 emit: Compilation.Emit,
439 options: link.File.OpenOptions,
440) !*Coff {
441 // TODO: restore saved linker state, don't truncate the file, and
442 // participate in incremental compilation.
443 return createEmpty(arena, comp, emit, options);
444}
445
446pub fn deinit(self: *Coff) void {
447 const gpa = self.base.comp.gpa;
448
449 if (self.llvm_object) |llvm_object| llvm_object.deinit();
450
451 for (self.objects.items) |*object| {
452 object.deinit(gpa);
453 }
454 self.objects.deinit(gpa);
455
456 for (self.sections.items(.free_list)) |*free_list| {
457 free_list.deinit(gpa);
458 }
459 self.sections.deinit(gpa);
460
461 self.atoms.deinit(gpa);
462 self.locals.deinit(gpa);
463 self.globals.deinit(gpa);
464
465 {
466 var it = self.resolver.keyIterator();
467 while (it.next()) |key_ptr| {
468 gpa.free(key_ptr.*);
469 }
470 self.resolver.deinit(gpa);
471 }
472
473 self.unresolved.deinit(gpa);
474 self.locals_free_list.deinit(gpa);
475 self.globals_free_list.deinit(gpa);
476 self.strtab.deinit(gpa);
477 self.temp_strtab.deinit(gpa);
478 self.got_table.deinit(gpa);
479
480 for (self.import_tables.values()) |*itab| {
481 itab.deinit(gpa);
482 }
483 self.import_tables.deinit(gpa);
484
485 self.lazy_syms.deinit(gpa);
486
487 for (self.decls.values()) |*metadata| {
488 metadata.deinit(gpa);
489 }
490 self.decls.deinit(gpa);
491
492 self.atom_by_index_table.deinit(gpa);
493
494 for (self.unnamed_const_atoms.values()) |*atoms| {
495 atoms.deinit(gpa);
496 }
497 self.unnamed_const_atoms.deinit(gpa);
498
499 {
500 var it = self.anon_decls.iterator();
501 while (it.next()) |entry| {
502 entry.value_ptr.exports.deinit(gpa);
503 }
504 self.anon_decls.deinit(gpa);
505 }
506
507 for (self.relocs.values()) |*relocs| {
508 relocs.deinit(gpa);
509 }
510 self.relocs.deinit(gpa);
511
512 for (self.base_relocs.values()) |*relocs| {
513 relocs.deinit(gpa);
514 }
515 self.base_relocs.deinit(gpa);
441516}
442517
443518fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.SectionHeaderFlags) !u16 {
......@@ -471,8 +546,9 @@ fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.Section
471546 .number_of_linenumbers = 0,
472547 .flags = flags,
473548 };
549 const gpa = self.base.comp.gpa;
474550 try self.setSectionName(&header, name);
475 try self.sections.append(self.base.allocator, .{ .header = header });
551 try self.sections.append(gpa, .{ .header = header });
476552 return index;
477553}
478554
......@@ -654,7 +730,7 @@ fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignme
654730}
655731
656732pub fn allocateSymbol(self: *Coff) !u32 {
657 const gpa = self.base.allocator;
733 const gpa = self.base.comp.gpa;
658734 try self.locals.ensureUnusedCapacity(gpa, 1);
659735
660736 const index = blk: {
......@@ -682,7 +758,7 @@ pub fn allocateSymbol(self: *Coff) !u32 {
682758}
683759
684760fn allocateGlobal(self: *Coff) !u32 {
685 const gpa = self.base.allocator;
761 const gpa = self.base.comp.gpa;
686762 try self.globals.ensureUnusedCapacity(gpa, 1);
687763
688764 const index = blk: {
......@@ -706,15 +782,16 @@ fn allocateGlobal(self: *Coff) !u32 {
706782}
707783
708784fn addGotEntry(self: *Coff, target: SymbolWithLoc) !void {
785 const gpa = self.base.comp.gpa;
709786 if (self.got_table.lookup.contains(target)) return;
710 const got_index = try self.got_table.allocateEntry(self.base.allocator, target);
787 const got_index = try self.got_table.allocateEntry(gpa, target);
711788 try self.writeOffsetTableEntry(got_index);
712789 self.got_table_count_dirty = true;
713790 self.markRelocsDirtyByTarget(target);
714791}
715792
716793pub fn createAtom(self: *Coff) !Atom.Index {
717 const gpa = self.base.allocator;
794 const gpa = self.base.comp.gpa;
718795 const atom_index = @as(Atom.Index, @intCast(self.atoms.items.len));
719796 const atom = try self.atoms.addOne(gpa);
720797 const sym_index = try self.allocateSymbol();
......@@ -759,7 +836,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
759836 file_offset + code.len,
760837 });
761838
762 const gpa = self.base.allocator;
839 const gpa = self.base.comp.gpa;
763840
764841 // Gather relocs which can be resolved.
765842 // We need to do this as we will be applying different slide values depending
......@@ -807,7 +884,7 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void {
807884 }
808885 }
809886
810 self.resolveRelocs(atom_index, relocs.items, code, self.getImageBase());
887 self.resolveRelocs(atom_index, relocs.items, code, self.image_base);
811888 try self.base.file.?.pwriteAll(code, file_offset);
812889
813890 // Now we can mark the relocs as resolved.
......@@ -853,24 +930,24 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void {
853930 const file_offset = header.pointer_to_raw_data + entry_offset;
854931 const vmaddr = header.virtual_address + entry_offset;
855932
856 log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.getImageBase() });
933 log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.image_base });
857934
858935 switch (self.ptr_width) {
859936 .p32 => {
860937 var buf: [4]u8 = undefined;
861 mem.writeInt(u32, &buf, @as(u32, @intCast(entry_value + self.getImageBase())), .little);
938 mem.writeInt(u32, &buf, @as(u32, @intCast(entry_value + self.image_base)), .little);
862939 try self.base.file.?.pwriteAll(&buf, file_offset);
863940 },
864941 .p64 => {
865942 var buf: [8]u8 = undefined;
866 mem.writeInt(u64, &buf, entry_value + self.getImageBase(), .little);
943 mem.writeInt(u64, &buf, entry_value + self.image_base, .little);
867944 try self.base.file.?.pwriteAll(&buf, file_offset);
868945 },
869946 }
870947
871948 if (is_hot_update_compatible) {
872949 if (self.base.child_pid) |handle| {
873 const gpa = self.base.allocator;
950 const gpa = self.base.comp.gpa;
874951 const slide = @intFromPtr(self.hot_state.loaded_base_address.?);
875952 const actual_vmaddr = vmaddr + slide;
876953 const pvaddr = @as(*anyopaque, @ptrFromInt(actual_vmaddr));
......@@ -974,7 +1051,7 @@ pub fn ptraceDetach(self: *Coff, handle: std.ChildProcess.Id) void {
9741051fn freeAtom(self: *Coff, atom_index: Atom.Index) void {
9751052 log.debug("freeAtom {d}", .{atom_index});
9761053
977 const gpa = self.base.allocator;
1054 const gpa = self.base.comp.gpa;
9781055
9791056 // Remove any relocs and base relocs associated with this Atom
9801057 Atom.freeRelocations(self, atom_index);
......@@ -1061,7 +1138,8 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:
10611138 self.freeUnnamedConsts(decl_index);
10621139 Atom.freeRelocations(self, atom_index);
10631140
1064 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
1141 const gpa = self.base.comp.gpa;
1142 var code_buffer = std.ArrayList(u8).init(gpa);
10651143 defer code_buffer.deinit();
10661144
10671145 const res = try codegen.generateFunction(
......@@ -1090,8 +1168,8 @@ pub fn updateFunc(self: *Coff, mod: *Module, func_index: InternPool.Index, air:
10901168}
10911169
10921170pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
1093 const gpa = self.base.allocator;
1094 const mod = self.base.options.module.?;
1171 const gpa = self.base.comp.gpa;
1172 const mod = self.base.comp.module.?;
10951173 const decl = mod.declPtr(decl_index);
10961174 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
10971175 if (!gop.found_existing) {
......@@ -1121,7 +1199,7 @@ const LowerConstResult = union(enum) {
11211199};
11221200
11231201fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
1124 const gpa = self.base.allocator;
1202 const gpa = self.base.comp.gpa;
11251203
11261204 var code_buffer = std.ArrayList(u8).init(gpa);
11271205 defer code_buffer.deinit();
......@@ -1174,13 +1252,14 @@ pub fn updateDecl(
11741252 return;
11751253 }
11761254
1255 const gpa = self.base.comp.gpa;
11771256 if (decl.isExtern(mod)) {
11781257 // TODO make this part of getGlobalSymbol
11791258 const variable = decl.getOwnedVariable(mod).?;
11801259 const name = mod.intern_pool.stringToSlice(decl.name);
11811260 const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
11821261 const global_index = try self.getGlobalSymbol(name, lib_name);
1183 try self.need_got_table.put(self.base.allocator, global_index, {});
1262 try self.need_got_table.put(gpa, global_index, {});
11841263 return;
11851264 }
11861265
......@@ -1188,7 +1267,7 @@ pub fn updateDecl(
11881267 Atom.freeRelocations(self, atom_index);
11891268 const atom = self.getAtom(atom_index);
11901269
1191 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
1270 var code_buffer = std.ArrayList(u8).init(gpa);
11921271 defer code_buffer.deinit();
11931272
11941273 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
......@@ -1220,8 +1299,8 @@ fn updateLazySymbolAtom(
12201299 atom_index: Atom.Index,
12211300 section_index: u16,
12221301) !void {
1223 const gpa = self.base.allocator;
1224 const mod = self.base.options.module.?;
1302 const gpa = self.base.comp.gpa;
1303 const mod = self.base.comp.module.?;
12251304
12261305 var required_alignment: InternPool.Alignment = .none;
12271306 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1281,8 +1360,9 @@ fn updateLazySymbolAtom(
12811360}
12821361
12831362pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Atom.Index {
1284 const mod = self.base.options.module.?;
1285 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl(mod));
1363 const gpa = self.base.comp.gpa;
1364 const mod = self.base.comp.module.?;
1365 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod));
12861366 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
12871367 if (!gop.found_existing) gop.value_ptr.* = .{};
12881368 const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
......@@ -1305,7 +1385,8 @@ pub fn getOrCreateAtomForLazySymbol(self: *Coff, sym: link.File.LazySymbol) !Ato
13051385}
13061386
13071387pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !Atom.Index {
1308 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
1388 const gpa = self.base.comp.gpa;
1389 const gop = try self.decls.getOrPut(gpa, decl_index);
13091390 if (!gop.found_existing) {
13101391 gop.value_ptr.* = .{
13111392 .atom = try self.createAtom(),
......@@ -1317,9 +1398,9 @@ pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: InternPool.DeclIndex) !At
13171398}
13181399
13191400fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
1320 const decl = self.base.options.module.?.declPtr(decl_index);
1401 const decl = self.base.comp.module.?.declPtr(decl_index);
13211402 const ty = decl.ty;
1322 const mod = self.base.options.module.?;
1403 const mod = self.base.comp.module.?;
13231404 const zig_ty = ty.zigTypeTag(mod);
13241405 const val = decl.val;
13251406 const index: u16 = blk: {
......@@ -1343,7 +1424,7 @@ fn getDeclOutputSection(self: *Coff, decl_index: InternPool.DeclIndex) u16 {
13431424}
13441425
13451426fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, complex_type: coff.ComplexType) !void {
1346 const mod = self.base.options.module.?;
1427 const mod = self.base.comp.module.?;
13471428 const decl = mod.declPtr(decl_index);
13481429
13491430 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
......@@ -1401,7 +1482,7 @@ fn updateDeclCode(self: *Coff, decl_index: InternPool.DeclIndex, code: []u8, com
14011482}
14021483
14031484fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void {
1404 const gpa = self.base.allocator;
1485 const gpa = self.base.comp.gpa;
14051486 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
14061487 for (unnamed_consts.items) |atom_index| {
14071488 self.freeAtom(atom_index);
......@@ -1412,7 +1493,8 @@ fn freeUnnamedConsts(self: *Coff, decl_index: InternPool.DeclIndex) void {
14121493pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void {
14131494 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
14141495
1415 const mod = self.base.options.module.?;
1496 const gpa = self.base.comp.gpa;
1497 const mod = self.base.comp.module.?;
14161498 const decl = mod.declPtr(decl_index);
14171499
14181500 log.debug("freeDecl {*}", .{decl});
......@@ -1421,7 +1503,7 @@ pub fn freeDecl(self: *Coff, decl_index: InternPool.DeclIndex) void {
14211503 var kv = const_kv;
14221504 self.freeAtom(kv.value.atom);
14231505 self.freeUnnamedConsts(decl_index);
1424 kv.value.exports.deinit(self.base.allocator);
1506 kv.value.exports.deinit(gpa);
14251507 }
14261508}
14271509
......@@ -1436,8 +1518,10 @@ pub fn updateExports(
14361518 }
14371519
14381520 const ip = &mod.intern_pool;
1521 const comp = self.base.comp;
1522 const target = comp.root_mod.resolved_target.result;
14391523
1440 if (self.base.options.use_llvm) {
1524 if (comp.config.use_llvm) {
14411525 // Even in the case of LLVM, we need to notice certain exported symbols in order to
14421526 // detect the default subsystem.
14431527 for (exports) |exp| {
......@@ -1447,16 +1531,16 @@ pub fn updateExports(
14471531 };
14481532 const exported_decl = mod.declPtr(exported_decl_index);
14491533 if (exported_decl.getOwnedFunction(mod) == null) continue;
1450 const winapi_cc = switch (self.base.options.target.cpu.arch) {
1534 const winapi_cc = switch (target.cpu.arch) {
14511535 .x86 => std.builtin.CallingConvention.Stdcall,
14521536 else => std.builtin.CallingConvention.C,
14531537 };
14541538 const decl_cc = exported_decl.ty.fnCallingConvention(mod);
14551539 if (decl_cc == .C and ip.stringEqlSlice(exp.opts.name, "main") and
1456 self.base.options.link_libc)
1540 comp.config.link_libc)
14571541 {
14581542 mod.stage1_flags.have_c_main = true;
1459 } else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
1543 } else if (decl_cc == winapi_cc and target.os.tag == .windows) {
14601544 if (ip.stringEqlSlice(exp.opts.name, "WinMain")) {
14611545 mod.stage1_flags.have_winmain = true;
14621546 } else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) {
......@@ -1474,9 +1558,7 @@ pub fn updateExports(
14741558
14751559 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
14761560
1477 if (self.base.options.emit == null) return;
1478
1479 const gpa = self.base.allocator;
1561 const gpa = comp.gpa;
14801562
14811563 const metadata = switch (exported) {
14821564 .decl_index => |decl_index| blk: {
......@@ -1570,11 +1652,11 @@ pub fn deleteDeclExport(
15701652) void {
15711653 if (self.llvm_object) |_| return;
15721654 const metadata = self.decls.getPtr(decl_index) orelse return;
1573 const mod = self.base.options.module.?;
1655 const mod = self.base.comp.module.?;
15741656 const name = mod.intern_pool.stringToSlice(name_ip);
15751657 const sym_index = metadata.getExportPtr(self, name) orelse return;
15761658
1577 const gpa = self.base.allocator;
1659 const gpa = self.base.comp.gpa;
15781660 const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null };
15791661 const sym = self.getSymbolPtr(sym_loc);
15801662 log.debug("deleting export '{s}'", .{name});
......@@ -1602,7 +1684,7 @@ pub fn deleteDeclExport(
16021684}
16031685
16041686fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {
1605 const gpa = self.base.allocator;
1687 const gpa = self.base.comp.gpa;
16061688 const sym = self.getSymbol(current);
16071689 const sym_name = self.getSymbolName(current);
16081690
......@@ -1624,38 +1706,35 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void {
16241706 gop.value_ptr.* = current;
16251707}
16261708
1627pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
1628 if (self.base.options.emit == null) {
1629 if (self.llvm_object) |llvm_object| {
1630 return try llvm_object.flushModule(comp, prog_node);
1631 }
1632 return;
1633 }
1634 const use_lld = build_options.have_llvm and self.base.options.use_lld;
1709pub fn flush(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
1710 const comp = self.base.comp;
1711 const use_lld = build_options.have_llvm and comp.config.use_lld;
16351712 if (use_lld) {
1636 return lld.linkWithLLD(self, comp, prog_node);
1713 return lld.linkWithLLD(self, arena, prog_node);
16371714 }
1638 switch (self.base.options.output_mode) {
1639 .Exe, .Obj => return self.flushModule(comp, prog_node),
1715 switch (comp.config.output_mode) {
1716 .Exe, .Obj => return self.flushModule(arena, prog_node),
16401717 .Lib => return error.TODOImplementWritingLibFiles,
16411718 }
16421719}
16431720
1644pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
1721pub fn flushModule(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
16451722 const tracy = trace(@src());
16461723 defer tracy.end();
16471724
1725 const comp = self.base.comp;
1726 const gpa = comp.gpa;
1727
16481728 if (self.llvm_object) |llvm_object| {
1649 return try llvm_object.flushModule(comp, prog_node);
1729 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
1730 return;
16501731 }
16511732
16521733 var sub_prog_node = prog_node.start("COFF Flush", 0);
16531734 sub_prog_node.activate();
16541735 defer sub_prog_node.end();
16551736
1656 const gpa = self.base.allocator;
1657
1658 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
1737 const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
16591738
16601739 if (self.lazy_syms.getPtr(.none)) |metadata| {
16611740 // Most lazy symbols can be updated on first use, but
......@@ -1756,12 +1835,12 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
17561835 try self.writeDataDirectoriesHeaders();
17571836 try self.writeSectionHeaders();
17581837
1759 if (self.entry_addr == null and self.base.options.output_mode == .Exe) {
1838 if (self.entry_addr == null and comp.config.output_mode == .Exe) {
17601839 log.debug("flushing. no_entry_point_found = true\n", .{});
1761 self.error_flags.no_entry_point_found = true;
1840 comp.link_error_flags.no_entry_point_found = true;
17621841 } else {
17631842 log.debug("flushing. no_entry_point_found = false\n", .{});
1764 self.error_flags.no_entry_point_found = false;
1843 comp.link_error_flags.no_entry_point_found = false;
17651844 try self.writeHeader();
17661845 }
17671846
......@@ -1794,8 +1873,8 @@ pub fn lowerAnonDecl(
17941873 explicit_alignment: InternPool.Alignment,
17951874 src_loc: Module.SrcLoc,
17961875) !codegen.Result {
1797 const gpa = self.base.allocator;
1798 const mod = self.base.options.module.?;
1876 const gpa = self.base.comp.gpa;
1877 const mod = self.base.comp.module.?;
17991878 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
18001879 const decl_alignment = switch (explicit_alignment) {
18011880 .none => ty.abiAlignment(mod),
......@@ -1868,7 +1947,7 @@ pub fn getGlobalSymbol(self: *Coff, name: []const u8, lib_name_name: ?[]const u8
18681947 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null };
18691948 gop.value_ptr.* = sym_loc;
18701949
1871 const gpa = self.base.allocator;
1950 const gpa = self.base.comp.gpa;
18721951 const sym = self.getSymbolPtr(sym_loc);
18731952 try self.setSymbolName(sym, name);
18741953 sym.storage_class = .EXTERNAL;
......@@ -1895,7 +1974,7 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: InternPool
18951974/// TODO: note that .ABSOLUTE is used as padding within each block; we could use this fact to do
18961975/// incremental updates and writes into the table instead of doing it all at once
18971976fn writeBaseRelocations(self: *Coff) !void {
1898 const gpa = self.base.allocator;
1977 const gpa = self.base.comp.gpa;
18991978
19001979 var page_table = std.AutoHashMap(u32, std.ArrayList(coff.BaseRelocation)).init(gpa);
19011980 defer {
......@@ -2006,7 +2085,7 @@ fn writeImportTables(self: *Coff) !void {
20062085 if (self.idata_section_index == null) return;
20072086 if (!self.imports_count_dirty) return;
20082087
2009 const gpa = self.base.allocator;
2088 const gpa = self.base.comp.gpa;
20102089
20112090 const ext = ".dll";
20122091 const header = &self.sections.items(.header)[self.idata_section_index.?];
......@@ -2154,7 +2233,8 @@ fn writeStrtab(self: *Coff) !void {
21542233
21552234 log.debug("writing strtab from 0x{x} to 0x{x}", .{ self.strtab_offset.?, self.strtab_offset.? + needed_size });
21562235
2157 var buffer = std.ArrayList(u8).init(self.base.allocator);
2236 const gpa = self.base.comp.gpa;
2237 var buffer = std.ArrayList(u8).init(gpa);
21582238 defer buffer.deinit();
21592239 try buffer.ensureTotalCapacityPrecise(needed_size);
21602240 buffer.appendSliceAssumeCapacity(self.strtab.buffer.items);
......@@ -2176,7 +2256,8 @@ fn writeDataDirectoriesHeaders(self: *Coff) !void {
21762256}
21772257
21782258fn writeHeader(self: *Coff) !void {
2179 const gpa = self.base.allocator;
2259 const target = self.base.comp.root_mod.resolved_target.result;
2260 const gpa = self.base.comp.gpa;
21802261 var buffer = std.ArrayList(u8).init(gpa);
21812262 defer buffer.deinit();
21822263 const writer = buffer.writer();
......@@ -2194,14 +2275,14 @@ fn writeHeader(self: *Coff) !void {
21942275 .p32 => flags.@"32BIT_MACHINE" = 1,
21952276 .p64 => flags.LARGE_ADDRESS_AWARE = 1,
21962277 }
2197 if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic) {
2278 if (self.base.comp.config.output_mode == .Lib and self.base.comp.config.link_mode == .Dynamic) {
21982279 flags.DLL = 1;
21992280 }
22002281
22012282 const timestamp = std.time.timestamp();
22022283 const size_of_optional_header = @as(u16, @intCast(self.getOptionalHeaderSize() + self.getDataDirectoryHeadersSize()));
22032284 var coff_header = coff.CoffHeader{
2204 .machine = coff.MachineType.fromTargetCpuArch(self.base.options.target.cpu.arch),
2285 .machine = coff.MachineType.fromTargetCpuArch(target.cpu.arch),
22052286 .number_of_sections = @as(u16, @intCast(self.sections.slice().len)), // TODO what if we prune a section
22062287 .time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))),
22072288 .pointer_to_symbol_table = self.strtab_offset orelse 0,
......@@ -2221,8 +2302,6 @@ fn writeHeader(self: *Coff) !void {
22212302 const subsystem: coff.Subsystem = .WINDOWS_CUI;
22222303 const size_of_image: u32 = self.getSizeOfImage();
22232304 const size_of_headers: u32 = mem.alignForward(u32, self.getSizeOfHeaders(), default_file_alignment);
2224 const image_base = self.getImageBase();
2225
22262305 const base_of_code = self.sections.get(self.text_section_index.?).header.virtual_address;
22272306 const base_of_data = self.sections.get(self.data_section_index.?).header.virtual_address;
22282307
......@@ -2253,15 +2332,15 @@ fn writeHeader(self: *Coff) !void {
22532332 .address_of_entry_point = self.entry_addr orelse 0,
22542333 .base_of_code = base_of_code,
22552334 .base_of_data = base_of_data,
2256 .image_base = @as(u32, @intCast(image_base)),
2335 .image_base = @intCast(self.image_base),
22572336 .section_alignment = self.page_size,
22582337 .file_alignment = default_file_alignment,
22592338 .major_operating_system_version = 6,
22602339 .minor_operating_system_version = 0,
22612340 .major_image_version = 0,
22622341 .minor_image_version = 0,
2263 .major_subsystem_version = 6,
2264 .minor_subsystem_version = 0,
2342 .major_subsystem_version = @intCast(self.major_subsystem_version),
2343 .minor_subsystem_version = @intCast(self.minor_subsystem_version),
22652344 .win32_version_value = 0,
22662345 .size_of_image = size_of_image,
22672346 .size_of_headers = size_of_headers,
......@@ -2273,7 +2352,7 @@ fn writeHeader(self: *Coff) !void {
22732352 .size_of_heap_reserve = default_size_of_heap_reserve,
22742353 .size_of_heap_commit = default_size_of_heap_commit,
22752354 .loader_flags = 0,
2276 .number_of_rva_and_sizes = @as(u32, @intCast(self.data_directories.len)),
2355 .number_of_rva_and_sizes = @intCast(self.data_directories.len),
22772356 };
22782357 writer.writeAll(mem.asBytes(&opt_header)) catch unreachable;
22792358 },
......@@ -2287,15 +2366,15 @@ fn writeHeader(self: *Coff) !void {
22872366 .size_of_uninitialized_data = size_of_uninitialized_data,
22882367 .address_of_entry_point = self.entry_addr orelse 0,
22892368 .base_of_code = base_of_code,
2290 .image_base = image_base,
2369 .image_base = self.image_base,
22912370 .section_alignment = self.page_size,
22922371 .file_alignment = default_file_alignment,
22932372 .major_operating_system_version = 6,
22942373 .minor_operating_system_version = 0,
22952374 .major_image_version = 0,
22962375 .minor_image_version = 0,
2297 .major_subsystem_version = 6,
2298 .minor_subsystem_version = 0,
2376 .major_subsystem_version = self.major_subsystem_version,
2377 .minor_subsystem_version = self.minor_subsystem_version,
22992378 .win32_version_value = 0,
23002379 .size_of_image = size_of_image,
23012380 .size_of_headers = size_of_headers,
......@@ -2307,7 +2386,7 @@ fn writeHeader(self: *Coff) !void {
23072386 .size_of_heap_reserve = default_size_of_heap_reserve,
23082387 .size_of_heap_commit = default_size_of_heap_commit,
23092388 .loader_flags = 0,
2310 .number_of_rva_and_sizes = @as(u32, @intCast(self.data_directories.len)),
2389 .number_of_rva_and_sizes = @intCast(self.data_directories.len),
23112390 };
23122391 writer.writeAll(mem.asBytes(&opt_header)) catch unreachable;
23132392 },
......@@ -2421,22 +2500,23 @@ inline fn getSizeOfImage(self: Coff) u32 {
24212500
24222501/// Returns symbol location corresponding to the set entrypoint (if any).
24232502pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {
2424 const entry_name = self.base.options.entry orelse "wWinMainCRTStartup"; // TODO this is incomplete
2425 const global_index = self.resolver.get(entry_name) orelse return null;
2426 return self.globals.items[global_index];
2427}
2428
2429pub fn getImageBase(self: Coff) u64 {
2430 const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.options.output_mode) {
2431 .Exe => switch (self.base.options.target.cpu.arch) {
2432 .aarch64 => @as(u64, 0x140000000),
2433 .x86_64, .x86 => 0x400000,
2434 else => unreachable, // unsupported target architecture
2503 const comp = self.base.comp;
2504
2505 // TODO This is incomplete.
2506 // The entry symbol name depends on the subsystem as well as the set of
2507 // public symbol names from linked objects.
2508 // See LinkerDriver::findDefaultEntry from the LLD project for the flow chart.
2509 const entry_name = switch (self.entry) {
2510 .disabled => return null,
2511 .default => switch (comp.config.output_mode) {
2512 .Exe => "wWinMainCRTStartup",
2513 .Obj, .Lib => return null,
24352514 },
2436 .Lib => 0x10000000,
2437 .Obj => 0,
2515 .enabled => "wWinMainCRTStartup",
2516 .named => |name| name,
24382517 };
2439 return image_base;
2518 const global_index = self.resolver.get(entry_name) orelse return null;
2519 return self.globals.items[global_index];
24402520}
24412521
24422522/// Returns pointer-to-symbol described by `sym_loc` descriptor.
......@@ -2499,7 +2579,7 @@ pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult
24992579 if (self.getGlobalPtr(name)) |ptr| {
25002580 return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr };
25012581 }
2502 const gpa = self.base.allocator;
2582 const gpa = self.base.comp.gpa;
25032583 const global_index = try self.allocateGlobal();
25042584 const global_name = try gpa.dupe(u8, name);
25052585 _ = try self.resolver.put(gpa, global_name, global_index);
......@@ -2530,7 +2610,8 @@ fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !v
25302610 @memset(header.name[name.len..], 0);
25312611 return;
25322612 }
2533 const offset = try self.strtab.insert(self.base.allocator, name);
2613 const gpa = self.base.comp.gpa;
2614 const offset = try self.strtab.insert(gpa, name);
25342615 const name_offset = fmt.bufPrint(&header.name, "/{d}", .{offset}) catch unreachable;
25352616 @memset(header.name[name_offset.len..], 0);
25362617}
......@@ -2549,7 +2630,8 @@ fn setSymbolName(self: *Coff, symbol: *coff.Symbol, name: []const u8) !void {
25492630 @memset(symbol.name[name.len..], 0);
25502631 return;
25512632 }
2552 const offset = try self.strtab.insert(self.base.allocator, name);
2633 const gpa = self.base.comp.gpa;
2634 const offset = try self.strtab.insert(gpa, name);
25532635 @memset(symbol.name[0..4], 0);
25542636 mem.writeInt(u32, symbol.name[4..8], offset, .little);
25552637}
src/link/Coff/Atom.zig+6-3
......@@ -94,7 +94,8 @@ pub fn freeListEligible(self: Atom, coff_file: *const Coff) bool {
9494}
9595
9696pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !void {
97 const gpa = coff_file.base.allocator;
97 const comp = coff_file.base.comp;
98 const gpa = comp.gpa;
9899 log.debug(" (adding reloc of type {s} to target %{d})", .{ @tagName(reloc.type), reloc.target.sym_index });
99100 const gop = try coff_file.relocs.getOrPut(gpa, atom_index);
100101 if (!gop.found_existing) {
......@@ -104,7 +105,8 @@ pub fn addRelocation(coff_file: *Coff, atom_index: Index, reloc: Relocation) !vo
104105}
105106
106107pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void {
107 const gpa = coff_file.base.allocator;
108 const comp = coff_file.base.comp;
109 const gpa = comp.gpa;
108110 log.debug(" (adding base relocation at offset 0x{x} in %{d})", .{
109111 offset,
110112 coff_file.getAtom(atom_index).getSymbolIndex().?,
......@@ -117,7 +119,8 @@ pub fn addBaseRelocation(coff_file: *Coff, atom_index: Index, offset: u32) !void
117119}
118120
119121pub fn freeRelocations(coff_file: *Coff, atom_index: Index) void {
120 const gpa = coff_file.base.allocator;
122 const comp = coff_file.base.comp;
123 const gpa = comp.gpa;
121124 var removed_relocs = coff_file.relocs.fetchOrderedRemove(atom_index);
122125 if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
123126 var removed_base_relocs = coff_file.base_relocs.fetchOrderedRemove(atom_index);
src/link/Coff/Relocation.zig+2-1
......@@ -107,7 +107,8 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base:
107107 .ptr_width = coff_file.ptr_width,
108108 };
109109
110 switch (coff_file.base.options.target.cpu.arch) {
110 const target = coff_file.base.comp.root_mod.resolved_target.result;
111 switch (target.cpu.arch) {
111112 .aarch64 => self.resolveAarch64(ctx),
112113 .x86, .x86_64 => self.resolveX86(ctx),
113114 else => unreachable, // unhandled target architecture
src/link/Coff/lld.zig+94-99
......@@ -17,26 +17,25 @@ const Allocator = mem.Allocator;
1717const Coff = @import("../Coff.zig");
1818const Compilation = @import("../../Compilation.zig");
1919
20pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void {
20pub fn linkWithLLD(self: *Coff, arena: Allocator, prog_node: *std.Progress.Node) !void {
2121 const tracy = trace(@src());
2222 defer tracy.end();
2323
24 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
25 defer arena_allocator.deinit();
26 const arena = arena_allocator.allocator();
24 const comp = self.base.comp;
25 const gpa = comp.gpa;
2726
28 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
29 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
27 const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
28 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
3029
3130 // If there is no Zig code to compile, then we should skip flushing the output file because it
3231 // will not be part of the linker line anyway.
33 const module_obj_path: ?[]const u8 = if (self.base.options.module != null) blk: {
34 try self.flushModule(comp, prog_node);
32 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
33 try self.flushModule(arena, prog_node);
3534
3635 if (fs.path.dirname(full_out_path)) |dirname| {
37 break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
36 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
3837 } else {
39 break :blk self.base.intermediary_basename.?;
38 break :blk self.base.zcu_object_sub_path.?;
4039 }
4140 } else null;
4241
......@@ -45,27 +44,35 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
4544 sub_prog_node.context.refresh();
4645 defer sub_prog_node.end();
4746
48 const is_lib = self.base.options.output_mode == .Lib;
49 const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
50 const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
51 const link_in_crt = self.base.options.link_libc and is_exe_or_dyn_lib;
52 const target = self.base.options.target;
47 const is_lib = comp.config.output_mode == .Lib;
48 const is_dyn_lib = comp.config.link_mode == .Dynamic and is_lib;
49 const is_exe_or_dyn_lib = is_dyn_lib or comp.config.output_mode == .Exe;
50 const link_in_crt = comp.config.link_libc and is_exe_or_dyn_lib;
51 const target = comp.root_mod.resolved_target.result;
52 const optimize_mode = comp.root_mod.optimize_mode;
53 const entry_name: ?[]const u8 = switch (self.entry) {
54 // This logic isn't quite right for disabled or enabled. No point in fixing it
55 // when the goal is to eliminate dependency on LLD anyway.
56 // https://github.com/ziglang/zig/issues/17751
57 .disabled, .default, .enabled => null,
58 .named => |name| name,
59 };
5360
5461 // See link/Elf.zig for comments on how this mechanism works.
5562 const id_symlink_basename = "lld.id";
5663
5764 var man: Cache.Manifest = undefined;
58 defer if (!self.base.options.disable_lld_caching) man.deinit();
65 defer if (!self.base.disable_lld_caching) man.deinit();
5966
6067 var digest: [Cache.hex_digest_len]u8 = undefined;
6168
62 if (!self.base.options.disable_lld_caching) {
69 if (!self.base.disable_lld_caching) {
6370 man = comp.cache_parent.obtain();
6471 self.base.releaseLock();
6572
6673 comptime assert(Compilation.link_hash_implementation_version == 10);
6774
68 for (self.base.options.objects) |obj| {
75 for (comp.objects) |obj| {
6976 _ = try man.addFile(obj.path, null);
7077 man.hash.add(obj.must_link);
7178 }
......@@ -78,14 +85,14 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
7885 }
7986 }
8087 try man.addOptionalFile(module_obj_path);
81 man.hash.addOptionalBytes(self.base.options.entry);
82 man.hash.addOptional(self.base.options.stack_size_override);
83 man.hash.addOptional(self.base.options.image_base_override);
84 man.hash.addListOfBytes(self.base.options.lib_dirs);
85 man.hash.add(self.base.options.skip_linker_dependencies);
86 if (self.base.options.link_libc) {
87 man.hash.add(self.base.options.libc_installation != null);
88 if (self.base.options.libc_installation) |libc_installation| {
88 man.hash.addOptionalBytes(entry_name);
89 man.hash.add(self.base.stack_size);
90 man.hash.add(self.image_base);
91 man.hash.addListOfBytes(self.lib_dirs);
92 man.hash.add(comp.skip_linker_dependencies);
93 if (comp.config.link_libc) {
94 man.hash.add(comp.libc_installation != null);
95 if (comp.libc_installation) |libc_installation| {
8996 man.hash.addBytes(libc_installation.crt_dir.?);
9097 if (target.abi == .msvc) {
9198 man.hash.addBytes(libc_installation.msvc_lib_dir.?);
......@@ -93,19 +100,19 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
93100 }
94101 }
95102 }
96 try link.hashAddSystemLibs(&man, self.base.options.system_libs);
97 man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys());
98 man.hash.addOptional(self.base.options.subsystem);
99 man.hash.add(self.base.options.is_test);
100 man.hash.add(self.base.options.tsaware);
101 man.hash.add(self.base.options.nxcompat);
102 man.hash.add(self.base.options.dynamicbase);
103 man.hash.addOptional(self.base.options.allow_shlib_undefined);
103 try link.hashAddSystemLibs(&man, comp.system_libs);
104 man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
105 man.hash.addOptional(self.subsystem);
106 man.hash.add(comp.config.is_test);
107 man.hash.add(self.tsaware);
108 man.hash.add(self.nxcompat);
109 man.hash.add(self.dynamicbase);
110 man.hash.add(self.base.allow_shlib_undefined);
104111 // strip does not need to go into the linker hash because it is part of the hash namespace
105 man.hash.addOptional(self.base.options.major_subsystem_version);
106 man.hash.addOptional(self.base.options.minor_subsystem_version);
107 man.hash.addOptional(self.base.options.version);
108 try man.addOptionalFile(self.base.options.module_definition_file);
112 man.hash.add(self.major_subsystem_version);
113 man.hash.add(self.minor_subsystem_version);
114 man.hash.addOptional(comp.version);
115 try man.addOptionalFile(self.module_definition_file);
109116
110117 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
111118 _ = try man.hit();
......@@ -135,13 +142,13 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
135142 };
136143 }
137144
138 if (self.base.options.output_mode == .Obj) {
145 if (comp.config.output_mode == .Obj) {
139146 // LLD's COFF driver does not support the equivalent of `-r` so we do a simple file copy
140147 // here. TODO: think carefully about how we can avoid this redundant operation when doing
141148 // build-obj. See also the corresponding TODO in linkAsArchive.
142149 const the_object_path = blk: {
143 if (self.base.options.objects.len != 0)
144 break :blk self.base.options.objects[0].path;
150 if (comp.objects.len != 0)
151 break :blk comp.objects[0].path;
145152
146153 if (comp.c_object_table.count() != 0)
147154 break :blk comp.c_object_table.keys()[0].status.success.object_path;
......@@ -160,7 +167,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
160167 }
161168 } else {
162169 // Create an LLD command line and invoke it.
163 var argv = std.ArrayList([]const u8).init(self.base.allocator);
170 var argv = std.ArrayList([]const u8).init(gpa);
164171 defer argv.deinit();
165172 // We will invoke ourselves as a child process to gain access to LLD.
166173 // This is necessary because LLD does not behave properly as a library -
......@@ -170,34 +177,31 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
170177
171178 try argv.append("-ERRORLIMIT:0");
172179 try argv.append("-NOLOGO");
173 if (!self.base.options.strip) {
180 if (comp.config.debug_format != .strip) {
174181 try argv.append("-DEBUG");
175182
176183 const out_ext = std.fs.path.extension(full_out_path);
177 const out_pdb = self.base.options.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{
184 const out_pdb = self.pdb_out_path orelse try allocPrint(arena, "{s}.pdb", .{
178185 full_out_path[0 .. full_out_path.len - out_ext.len],
179186 });
180187
181188 try argv.append(try allocPrint(arena, "-PDB:{s}", .{out_pdb}));
182189 try argv.append(try allocPrint(arena, "-PDBALTPATH:{s}", .{out_pdb}));
183190 }
184 if (self.base.options.version) |version| {
191 if (comp.version) |version| {
185192 try argv.append(try allocPrint(arena, "-VERSION:{}.{}", .{ version.major, version.minor }));
186193 }
187 if (self.base.options.lto) {
188 switch (self.base.options.optimize_mode) {
194 if (comp.config.lto) {
195 switch (optimize_mode) {
189196 .Debug => {},
190197 .ReleaseSmall => try argv.append("-OPT:lldlto=2"),
191198 .ReleaseFast, .ReleaseSafe => try argv.append("-OPT:lldlto=3"),
192199 }
193200 }
194 if (self.base.options.output_mode == .Exe) {
195 const stack_size = self.base.options.stack_size_override orelse 16777216;
196 try argv.append(try allocPrint(arena, "-STACK:{d}", .{stack_size}));
197 }
198 if (self.base.options.image_base_override) |image_base| {
199 try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{image_base}));
201 if (comp.config.output_mode == .Exe) {
202 try argv.append(try allocPrint(arena, "-STACK:{d}", .{self.base.stack_size}));
200203 }
204 try argv.append(try std.fmt.allocPrint(arena, "-BASE:{d}", .{self.image_base}));
201205
202206 if (target.cpu.arch == .x86) {
203207 try argv.append("-MACHINE:X86");
......@@ -211,7 +215,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
211215 }
212216 }
213217
214 for (self.base.options.force_undefined_symbols.keys()) |symbol| {
218 for (comp.force_undefined_symbols.keys()) |symbol| {
215219 try argv.append(try allocPrint(arena, "-INCLUDE:{s}", .{symbol}));
216220 }
217221
......@@ -219,34 +223,32 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
219223 try argv.append("-DLL");
220224 }
221225
222 if (self.base.options.entry) |entry| {
223 try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{entry}));
226 if (entry_name) |name| {
227 try argv.append(try allocPrint(arena, "-ENTRY:{s}", .{name}));
224228 }
225229
226 if (self.base.options.tsaware) {
230 if (self.tsaware) {
227231 try argv.append("-tsaware");
228232 }
229 if (self.base.options.nxcompat) {
233 if (self.nxcompat) {
230234 try argv.append("-nxcompat");
231235 }
232 if (!self.base.options.dynamicbase) {
236 if (!self.dynamicbase) {
233237 try argv.append("-dynamicbase:NO");
234238 }
235 if (self.base.options.allow_shlib_undefined) |allow_shlib_undefined| {
236 if (allow_shlib_undefined) {
237 try argv.append("-FORCE:UNRESOLVED");
238 }
239 if (self.base.allow_shlib_undefined) {
240 try argv.append("-FORCE:UNRESOLVED");
239241 }
240242
241243 try argv.append(try allocPrint(arena, "-OUT:{s}", .{full_out_path}));
242244
243 if (self.base.options.implib_emit) |emit| {
245 if (comp.implib_emit) |emit| {
244246 const implib_out_path = try emit.directory.join(arena, &[_][]const u8{emit.sub_path});
245247 try argv.append(try allocPrint(arena, "-IMPLIB:{s}", .{implib_out_path}));
246248 }
247249
248 if (self.base.options.link_libc) {
249 if (self.base.options.libc_installation) |libc_installation| {
250 if (comp.config.link_libc) {
251 if (comp.libc_installation) |libc_installation| {
250252 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{libc_installation.crt_dir.?}));
251253
252254 if (target.abi == .msvc) {
......@@ -256,12 +258,12 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
256258 }
257259 }
258260
259 for (self.base.options.lib_dirs) |lib_dir| {
261 for (self.lib_dirs) |lib_dir| {
260262 try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir}));
261263 }
262264
263 try argv.ensureUnusedCapacity(self.base.options.objects.len);
264 for (self.base.options.objects) |obj| {
265 try argv.ensureUnusedCapacity(comp.objects.len);
266 for (comp.objects) |obj| {
265267 if (obj.must_link) {
266268 argv.appendAssumeCapacity(try allocPrint(arena, "-WHOLEARCHIVE:{s}", .{obj.path}));
267269 } else {
......@@ -283,18 +285,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
283285 try argv.append(p);
284286 }
285287
286 if (self.base.options.module_definition_file) |def| {
288 if (self.module_definition_file) |def| {
287289 try argv.append(try allocPrint(arena, "-DEF:{s}", .{def}));
288290 }
289291
290292 const resolved_subsystem: ?std.Target.SubSystem = blk: {
291 if (self.base.options.subsystem) |explicit| break :blk explicit;
293 if (self.subsystem) |explicit| break :blk explicit;
292294 switch (target.os.tag) {
293295 .windows => {
294 if (self.base.options.module) |module| {
296 if (comp.module) |module| {
295297 if (module.stage1_flags.have_dllmain_crt_startup or is_dyn_lib)
296298 break :blk null;
297 if (module.stage1_flags.have_c_main or self.base.options.is_test or
299 if (module.stage1_flags.have_c_main or comp.config.is_test or
298300 module.stage1_flags.have_winmain_crt_startup or
299301 module.stage1_flags.have_wwinmain_crt_startup)
300302 {
......@@ -313,16 +315,9 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
313315 const Mode = enum { uefi, win32 };
314316 const mode: Mode = mode: {
315317 if (resolved_subsystem) |subsystem| {
316 const subsystem_suffix = ss: {
317 if (self.base.options.major_subsystem_version) |major| {
318 if (self.base.options.minor_subsystem_version) |minor| {
319 break :ss try allocPrint(arena, ",{d}.{d}", .{ major, minor });
320 } else {
321 break :ss try allocPrint(arena, ",{d}", .{major});
322 }
323 }
324 break :ss "";
325 };
318 const subsystem_suffix = try allocPrint(arena, ",{d}.{d}", .{
319 self.major_subsystem_version, self.minor_subsystem_version,
320 });
326321
327322 switch (subsystem) {
328323 .Console => {
......@@ -419,21 +414,21 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
419414 try argv.append(try comp.get_libc_crt_file(arena, "uuid.lib"));
420415
421416 for (mingw.always_link_libs) |name| {
422 if (!self.base.options.system_libs.contains(name)) {
417 if (!comp.system_libs.contains(name)) {
423418 const lib_basename = try allocPrint(arena, "{s}.lib", .{name});
424419 try argv.append(try comp.get_libc_crt_file(arena, lib_basename));
425420 }
426421 }
427422 } else {
428 const lib_str = switch (self.base.options.link_mode) {
423 const lib_str = switch (comp.config.link_mode) {
429424 .Dynamic => "",
430425 .Static => "lib",
431426 };
432 const d_str = switch (self.base.options.optimize_mode) {
427 const d_str = switch (optimize_mode) {
433428 .Debug => "d",
434429 else => "",
435430 };
436 switch (self.base.options.link_mode) {
431 switch (comp.config.link_mode) {
437432 .Static => try argv.append(try allocPrint(arena, "libcmt{s}.lib", .{d_str})),
438433 .Dynamic => try argv.append(try allocPrint(arena, "msvcrt{s}.lib", .{d_str})),
439434 }
......@@ -451,8 +446,8 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
451446 }
452447 } else {
453448 try argv.append("-NODEFAULTLIB");
454 if (!is_lib and self.base.options.entry == null) {
455 if (self.base.options.module) |module| {
449 if (!is_lib and entry_name == null) {
450 if (comp.module) |module| {
456451 if (module.stage1_flags.have_winmain_crt_startup) {
457452 try argv.append("-ENTRY:WinMainCRTStartup");
458453 } else {
......@@ -467,18 +462,18 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
467462 }
468463
469464 // libc++ dep
470 if (self.base.options.link_libcpp) {
465 if (comp.config.link_libcpp) {
471466 try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
472467 try argv.append(comp.libcxx_static_lib.?.full_object_path);
473468 }
474469
475470 // libunwind dep
476 if (self.base.options.link_libunwind) {
471 if (comp.config.link_libunwind) {
477472 try argv.append(comp.libunwind_static_lib.?.full_object_path);
478473 }
479474
480 if (is_exe_or_dyn_lib and !self.base.options.skip_linker_dependencies) {
481 if (!self.base.options.link_libc) {
475 if (is_exe_or_dyn_lib and !comp.skip_linker_dependencies) {
476 if (!comp.config.link_libc) {
482477 if (comp.libc_static_lib) |lib| {
483478 try argv.append(lib.full_object_path);
484479 }
......@@ -489,20 +484,20 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
489484 if (comp.compiler_rt_lib) |lib| try argv.append(lib.full_object_path);
490485 }
491486
492 try argv.ensureUnusedCapacity(self.base.options.system_libs.count());
493 for (self.base.options.system_libs.keys()) |key| {
487 try argv.ensureUnusedCapacity(comp.system_libs.count());
488 for (comp.system_libs.keys()) |key| {
494489 const lib_basename = try allocPrint(arena, "{s}.lib", .{key});
495490 if (comp.crt_files.get(lib_basename)) |crt_file| {
496491 argv.appendAssumeCapacity(crt_file.full_object_path);
497492 continue;
498493 }
499 if (try findLib(arena, lib_basename, self.base.options.lib_dirs)) |full_path| {
494 if (try findLib(arena, lib_basename, self.lib_dirs)) |full_path| {
500495 argv.appendAssumeCapacity(full_path);
501496 continue;
502497 }
503498 if (target.abi.isGnu()) {
504499 const fallback_name = try allocPrint(arena, "lib{s}.dll.a", .{key});
505 if (try findLib(arena, fallback_name, self.base.options.lib_dirs)) |full_path| {
500 if (try findLib(arena, fallback_name, self.lib_dirs)) |full_path| {
506501 argv.appendAssumeCapacity(full_path);
507502 continue;
508503 }
......@@ -516,7 +511,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
516511 return error.DllImportLibraryNotFound;
517512 }
518513
519 if (self.base.options.verbose_link) {
514 if (comp.verbose_link) {
520515 // Skip over our own name so that the LLD linker name is the first argv item.
521516 Compilation.dump_argv(argv.items[1..]);
522517 }
......@@ -586,7 +581,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
586581 }
587582 }
588583
589 if (!self.base.options.disable_lld_caching) {
584 if (!self.base.disable_lld_caching) {
590585 // Update the file with the digest. If it fails we can continue; it only
591586 // means that the next invocation will have an unnecessary cache miss.
592587 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
src/link/Dwarf.zig+44-28
......@@ -1022,16 +1022,18 @@ const min_nop_size = 2;
10221022/// actual_capacity + (actual_capacity / ideal_factor)
10231023const ideal_factor = 3;
10241024
1025pub fn init(allocator: Allocator, bin_file: *File, format: Format) Dwarf {
1026 const target = &bin_file.options.target;
1025pub fn init(lf: *File, format: Format) Dwarf {
1026 const comp = lf.comp;
1027 const gpa = comp.gpa;
1028 const target = comp.root_mod.resolved_target.result;
10271029 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
10281030 0...32 => .p32,
10291031 33...64 => .p64,
10301032 else => unreachable,
10311033 };
10321034 return .{
1033 .allocator = allocator,
1034 .bin_file = bin_file,
1035 .allocator = gpa,
1036 .bin_file = lf,
10351037 .format = format,
10361038 .ptr_width = ptr_width,
10371039 .dbg_line_header = switch (target.cpu.arch) {
......@@ -1190,7 +1192,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: InternPool.DeclInde
11901192
11911193pub fn commitDeclState(
11921194 self: *Dwarf,
1193 mod: *Module,
1195 zcu: *Module,
11941196 decl_index: InternPool.DeclIndex,
11951197 sym_addr: u64,
11961198 sym_size: u64,
......@@ -1200,15 +1202,17 @@ pub fn commitDeclState(
12001202 defer tracy.end();
12011203
12021204 const gpa = self.allocator;
1205 const decl = zcu.declPtr(decl_index);
1206 const ip = &zcu.intern_pool;
1207 const namespace = zcu.namespacePtr(decl.src_namespace);
1208 const target = namespace.file_scope.mod.resolved_target.result;
1209 const target_endian = target.cpu.arch.endian();
1210
12031211 var dbg_line_buffer = &decl_state.dbg_line;
12041212 var dbg_info_buffer = &decl_state.dbg_info;
1205 const decl = mod.declPtr(decl_index);
1206 const ip = &mod.intern_pool;
1207
1208 const target_endian = self.bin_file.options.target.cpu.arch.endian();
12091213
12101214 assert(decl.has_tv);
1211 switch (decl.ty.zigTypeTag(mod)) {
1215 switch (decl.ty.zigTypeTag(zcu)) {
12121216 .Fn => {
12131217 try decl_state.setInlineFunc(decl.val.toIntern());
12141218
......@@ -1407,18 +1411,18 @@ pub fn commitDeclState(
14071411 if (ip.isErrorSetType(ty.toIntern())) continue;
14081412
14091413 symbol.offset = @intCast(dbg_info_buffer.items.len);
1410 try decl_state.addDbgInfoType(mod, di_atom_index, ty);
1414 try decl_state.addDbgInfoType(zcu, di_atom_index, ty);
14111415 }
14121416 }
14131417
14141418 try self.updateDeclDebugInfoAllocation(di_atom_index, @intCast(dbg_info_buffer.items.len));
14151419
14161420 while (decl_state.abbrev_relocs.popOrNull()) |reloc| {
1417 if (reloc.target) |target| {
1418 const symbol = decl_state.abbrev_table.items[target];
1421 if (reloc.target) |reloc_target| {
1422 const symbol = decl_state.abbrev_table.items[reloc_target];
14191423 const ty = symbol.type;
14201424 if (ip.isErrorSetType(ty.toIntern())) {
1421 log.debug("resolving %{d} deferred until flush", .{target});
1425 log.debug("resolving %{d} deferred until flush", .{reloc_target});
14221426 try self.global_abbrev_relocs.append(gpa, .{
14231427 .target = null,
14241428 .offset = reloc.offset,
......@@ -1431,8 +1435,8 @@ pub fn commitDeclState(
14311435 log.debug("{x}: [() => {x}] (%{d}, '{}')", .{
14321436 reloc.offset,
14331437 value,
1434 target,
1435 ty.fmt(mod),
1438 reloc_target,
1439 ty.fmt(zcu),
14361440 });
14371441 mem.writeInt(
14381442 u32,
......@@ -1741,6 +1745,7 @@ pub fn freeDecl(self: *Dwarf, decl_index: InternPool.DeclIndex) void {
17411745}
17421746
17431747pub fn writeDbgAbbrev(self: *Dwarf) !void {
1748 const gpa = self.allocator;
17441749 // These are LEB encoded but since the values are all less than 127
17451750 // we can simply append these bytes.
17461751 // zig fmt: off
......@@ -1883,7 +1888,7 @@ pub fn writeDbgAbbrev(self: *Dwarf) !void {
18831888 .wasm => {
18841889 const wasm_file = self.bin_file.cast(File.Wasm).?;
18851890 const debug_abbrev = &wasm_file.getAtomPtr(wasm_file.debug_abbrev_atom.?).code;
1886 try debug_abbrev.resize(wasm_file.base.allocator, needed_size);
1891 try debug_abbrev.resize(gpa, needed_size);
18871892 debug_abbrev.items[0..abbrev_buf.len].* = abbrev_buf;
18881893 },
18891894 else => unreachable,
......@@ -1895,7 +1900,7 @@ fn dbgInfoHeaderBytes(self: *Dwarf) usize {
18951900 return 120;
18961901}
18971902
1898pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u64) !void {
1903pub fn writeDbgInfoHeader(self: *Dwarf, zcu: *Module, low_pc: u64, high_pc: u64) !void {
18991904 // If this value is null it means there is an error in the module;
19001905 // leave debug_info_header_dirty=true.
19011906 const first_dbg_info_off = self.getDebugInfoOff() orelse return;
......@@ -1906,7 +1911,9 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
19061911 var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes);
19071912 defer di_buf.deinit();
19081913
1909 const target_endian = self.bin_file.options.target.cpu.arch.endian();
1914 const comp = self.bin_file.comp;
1915 const target = comp.root_mod.resolved_target.result;
1916 const target_endian = target.cpu.arch.endian();
19101917 const init_len_size: usize = switch (self.format) {
19111918 .dwarf32 => 4,
19121919 .dwarf64 => 12,
......@@ -1929,9 +1936,9 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
19291936 di_buf.appendAssumeCapacity(self.ptrWidthBytes()); // address size
19301937
19311938 // Write the form for the compile unit, which must match the abbrev table above.
1932 const name_strp = try self.strtab.insert(self.allocator, module.root_mod.root_src_path);
1939 const name_strp = try self.strtab.insert(self.allocator, zcu.root_mod.root_src_path);
19331940 var compile_unit_dir_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
1934 const compile_unit_dir = resolveCompilationDir(module, &compile_unit_dir_buffer);
1941 const compile_unit_dir = resolveCompilationDir(zcu, &compile_unit_dir_buffer);
19351942 const comp_dir_strp = try self.strtab.insert(self.allocator, compile_unit_dir);
19361943 const producer_strp = try self.strtab.insert(self.allocator, link.producer_string);
19371944
......@@ -1995,7 +2002,9 @@ fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) []
19952002}
19962003
19972004fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) void {
1998 const target_endian = self.bin_file.options.target.cpu.arch.endian();
2005 const comp = self.bin_file.comp;
2006 const target = comp.root_mod.resolved_target.result;
2007 const target_endian = target.cpu.arch.endian();
19992008 switch (self.ptr_width) {
20002009 .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(addr), target_endian),
20012010 .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian),
......@@ -2003,7 +2012,9 @@ fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) voi
20032012}
20042013
20052014fn writeOffsetAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), off: u64) void {
2006 const target_endian = self.bin_file.options.target.cpu.arch.endian();
2015 const comp = self.bin_file.comp;
2016 const target = comp.root_mod.resolved_target.result;
2017 const target_endian = target.cpu.arch.endian();
20072018 switch (self.format) {
20082019 .dwarf32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @intCast(off), target_endian),
20092020 .dwarf64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), off, target_endian),
......@@ -2225,7 +2236,10 @@ fn writeDbgInfoNopsToArrayList(
22252236}
22262237
22272238pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
2228 const target_endian = self.bin_file.options.target.cpu.arch.endian();
2239 const comp = self.bin_file.comp;
2240 const gpa = comp.gpa;
2241 const target = comp.root_mod.resolved_target.result;
2242 const target_endian = target.cpu.arch.endian();
22292243 const ptr_width_bytes = self.ptrWidthBytes();
22302244
22312245 // Enough for all the data without resizing. When support for more compilation units
......@@ -2289,7 +2303,7 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
22892303 .wasm => {
22902304 const wasm_file = self.bin_file.cast(File.Wasm).?;
22912305 const debug_ranges = &wasm_file.getAtomPtr(wasm_file.debug_ranges_atom.?).code;
2292 try debug_ranges.resize(wasm_file.base.allocator, needed_size);
2306 try debug_ranges.resize(gpa, needed_size);
22932307 @memcpy(debug_ranges.items[0..di_buf.items.len], di_buf.items);
22942308 },
22952309 else => unreachable,
......@@ -2297,9 +2311,10 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
22972311}
22982312
22992313pub fn writeDbgLineHeader(self: *Dwarf) !void {
2314 const comp = self.bin_file.comp;
23002315 const gpa = self.allocator;
2301
2302 const target_endian = self.bin_file.options.target.cpu.arch.endian();
2316 const target = comp.root_mod.resolved_target.result;
2317 const target_endian = target.cpu.arch.endian();
23032318 const init_len_size: usize = switch (self.format) {
23042319 .dwarf32 => 4,
23052320 .dwarf64 => 12,
......@@ -2563,7 +2578,8 @@ fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
25632578}
25642579
25652580pub fn flushModule(self: *Dwarf, module: *Module) !void {
2566 const target = self.bin_file.options.target;
2581 const comp = self.bin_file.comp;
2582 const target = comp.root_mod.resolved_target.result;
25672583
25682584 if (self.global_abbrev_relocs.items.len > 0) {
25692585 const gpa = self.allocator;
src/link/Elf.zig+602-506
......@@ -1,8 +1,34 @@
11base: link.File,
2image_base: u64,
3emit_relocs: bool,
4z_nodelete: bool,
5z_notext: bool,
6z_defs: bool,
7z_origin: bool,
8z_nocopyreloc: bool,
9z_now: bool,
10z_relro: bool,
11/// TODO make this non optional and resolve the default in open()
12z_common_page_size: ?u64,
13/// TODO make this non optional and resolve the default in open()
14z_max_page_size: ?u64,
15lib_dirs: []const []const u8,
16hash_style: HashStyle,
17compress_debug_sections: CompressDebugSections,
18symbol_wrap_set: std.StringArrayHashMapUnmanaged(void),
19each_lib_rpath: bool,
20sort_section: ?SortSection,
21soname: ?[]const u8,
22bind_global_refs_locally: bool,
23linker_script: ?[]const u8,
24version_script: ?[]const u8,
25print_icf_sections: bool,
26print_map: bool,
27entry_name: ?[]const u8,
228
329ptr_width: PtrWidth,
430
5/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
31/// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path.
632llvm_object: ?*LlvmObject = null,
733
834/// A list of all input files.
......@@ -171,9 +197,6 @@ resolver: std.AutoArrayHashMapUnmanaged(u32, Symbol.Index) = .{},
171197has_text_reloc: bool = false,
172198num_ifunc_dynrelocs: usize = 0,
173199
174error_flags: link.File.ErrorFlags = link.File.ErrorFlags{},
175misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{},
176
177200/// List of atoms that are owned directly by the linker.
178201atoms: std.ArrayListUnmanaged(Atom) = .{},
179202
......@@ -199,59 +222,161 @@ const minimum_atom_size = 64;
199222pub const min_text_capacity = padToIdeal(minimum_atom_size);
200223
201224pub const PtrWidth = enum { p32, p64 };
225pub const HashStyle = enum { sysv, gnu, both };
226pub const CompressDebugSections = enum { none, zlib, zstd };
227pub const SortSection = enum { name, alignment };
228
229pub fn createEmpty(
230 arena: Allocator,
231 comp: *Compilation,
232 emit: Compilation.Emit,
233 options: link.File.OpenOptions,
234) !*Elf {
235 const target = comp.root_mod.resolved_target.result;
236 assert(target.ofmt == .elf);
237
238 const use_lld = build_options.have_llvm and comp.config.use_lld;
239 const use_llvm = comp.config.use_llvm;
240 const opt_zcu = comp.module;
241 const output_mode = comp.config.output_mode;
242 const link_mode = comp.config.link_mode;
243 const optimize_mode = comp.root_mod.optimize_mode;
244 const is_native_os = comp.root_mod.resolved_target.is_native_os;
245 const ptr_width: PtrWidth = switch (target.ptrBitWidth()) {
246 0...32 => .p32,
247 33...64 => .p64,
248 else => return error.UnsupportedELFArchitecture,
249 };
202250
203pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Elf {
204 assert(options.target.ofmt == .elf);
251 const page_size: u32 = switch (target.cpu.arch) {
252 .powerpc64le => 0x10000,
253 .sparc64 => 0x2000,
254 else => 0x1000,
255 };
256 const is_dyn_lib = output_mode == .Lib and link_mode == .Dynamic;
257 const default_sym_version: elf.Elf64_Versym = if (is_dyn_lib or comp.config.rdynamic)
258 elf.VER_NDX_GLOBAL
259 else
260 elf.VER_NDX_LOCAL;
205261
206 const self = try createEmpty(allocator, options);
207 errdefer self.base.destroy();
262 // If using LLD to link, this code should produce an object file so that it
263 // can be passed to LLD.
264 // If using LLVM to generate the object file for the zig compilation unit,
265 // we need a place to put the object file so that it can be subsequently
266 // handled.
267 const zcu_object_sub_path = if (!use_lld and !use_llvm)
268 null
269 else
270 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
208271
209 const is_obj = options.output_mode == .Obj;
210 const is_obj_or_ar = is_obj or (options.output_mode == .Lib and options.link_mode == .Static);
272 const self = try arena.create(Elf);
273 self.* = .{
274 .base = .{
275 .tag = .elf,
276 .comp = comp,
277 .emit = emit,
278 .zcu_object_sub_path = zcu_object_sub_path,
279 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
280 .print_gc_sections = options.print_gc_sections,
281 .stack_size = options.stack_size orelse 16777216,
282 .allow_shlib_undefined = options.allow_shlib_undefined orelse !is_native_os,
283 .file = null,
284 .disable_lld_caching = options.disable_lld_caching,
285 .build_id = options.build_id,
286 .rpath_list = options.rpath_list,
287 },
288 .ptr_width = ptr_width,
289 .page_size = page_size,
290 .default_sym_version = default_sym_version,
211291
212 if (options.use_llvm) {
213 const use_lld = build_options.have_llvm and self.base.options.use_lld;
214 if (use_lld) return self;
292 .entry_name = switch (options.entry) {
293 .disabled => null,
294 .default => if (output_mode != .Exe) null else defaultEntrySymbolName(target.cpu.arch),
295 .enabled => defaultEntrySymbolName(target.cpu.arch),
296 .named => |name| name,
297 },
215298
216 if (options.module != null) {
217 self.base.intermediary_basename = try std.fmt.allocPrint(allocator, "{s}{s}", .{
218 sub_path, options.target.ofmt.fileExt(options.target.cpu.arch),
219 });
220 }
299 .image_base = b: {
300 if (is_dyn_lib) break :b 0;
301 if (output_mode == .Exe and comp.config.pie) break :b 0;
302 break :b options.image_base orelse switch (ptr_width) {
303 .p32 => 0x10000,
304 .p64 => 0x1000000,
305 };
306 },
307
308 .emit_relocs = options.emit_relocs,
309 .z_nodelete = options.z_nodelete,
310 .z_notext = options.z_notext,
311 .z_defs = options.z_defs,
312 .z_origin = options.z_origin,
313 .z_nocopyreloc = options.z_nocopyreloc,
314 .z_now = options.z_now,
315 .z_relro = options.z_relro,
316 .z_common_page_size = options.z_common_page_size,
317 .z_max_page_size = options.z_max_page_size,
318 .lib_dirs = options.lib_dirs,
319 .hash_style = options.hash_style,
320 .compress_debug_sections = options.compress_debug_sections,
321 .symbol_wrap_set = options.symbol_wrap_set,
322 .each_lib_rpath = options.each_lib_rpath,
323 .sort_section = options.sort_section,
324 .soname = options.soname,
325 .bind_global_refs_locally = options.bind_global_refs_locally,
326 .linker_script = options.linker_script,
327 .version_script = options.version_script,
328 .print_icf_sections = options.print_icf_sections,
329 .print_map = options.print_map,
330 };
331 if (use_llvm and comp.config.have_zcu) {
332 self.llvm_object = try LlvmObject.create(arena, comp);
333 }
334 errdefer self.base.destroy();
335
336 if (use_lld and (use_llvm or !comp.config.have_zcu)) {
337 // LLVM emits the object file (if any); LLD links it into the final product.
338 return self;
221339 }
222 errdefer if (self.base.intermediary_basename) |path| allocator.free(path);
223340
224 self.base.file = try options.emit.?.directory.handle.createFile(sub_path, .{
225 .truncate = false,
341 const is_obj = output_mode == .Obj;
342 const is_obj_or_ar = is_obj or (output_mode == .Lib and link_mode == .Static);
343
344 // What path should this ELF linker code output to?
345 // If using LLD to link, this code should produce an object file so that it
346 // can be passed to LLD.
347 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
348 self.base.file = try emit.directory.handle.createFile(sub_path, .{
349 .truncate = true,
226350 .read = true,
227 .mode = link.determineMode(options),
351 .mode = link.File.determineMode(use_lld, output_mode, link_mode),
228352 });
229353
354 const gpa = comp.gpa;
355
230356 // Index 0 is always a null symbol.
231 try self.symbols.append(allocator, .{});
357 try self.symbols.append(gpa, .{});
232358 // Index 0 is always a null symbol.
233 try self.symbols_extra.append(allocator, 0);
359 try self.symbols_extra.append(gpa, 0);
234360 // Allocate atom index 0 to null atom
235 try self.atoms.append(allocator, .{});
361 try self.atoms.append(gpa, .{});
236362 // Append null file at index 0
237 try self.files.append(allocator, .null);
363 try self.files.append(gpa, .null);
238364 // Append null byte to string tables
239 try self.shstrtab.append(allocator, 0);
240 try self.strtab.append(allocator, 0);
365 try self.shstrtab.append(gpa, 0);
366 try self.strtab.append(gpa, 0);
241367 // There must always be a null shdr in index 0
242368 _ = try self.addSection(.{ .name = "" });
243369 // Append null symbol in output symtab
244 try self.symtab.append(allocator, null_sym);
370 try self.symtab.append(gpa, null_sym);
245371
246372 if (!is_obj_or_ar) {
247 try self.dynstrtab.append(allocator, 0);
373 try self.dynstrtab.append(gpa, 0);
248374
249375 // Initialize PT_PHDR program header
250376 const p_align: u16 = switch (self.ptr_width) {
251377 .p32 => @alignOf(elf.Elf32_Phdr),
252378 .p64 => @alignOf(elf.Elf64_Phdr),
253379 };
254 const image_base = self.calcImageBase();
255380 const ehsize: u64 = switch (self.ptr_width) {
256381 .p32 => @sizeOf(elf.Elf32_Ehdr),
257382 .p64 => @sizeOf(elf.Elf64_Ehdr),
......@@ -266,7 +391,7 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
266391 .type = elf.PT_PHDR,
267392 .flags = elf.PF_R,
268393 .@"align" = p_align,
269 .addr = image_base + ehsize,
394 .addr = self.image_base + ehsize,
270395 .offset = ehsize,
271396 .filesz = reserved,
272397 .memsz = reserved,
......@@ -275,71 +400,49 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
275400 .type = elf.PT_LOAD,
276401 .flags = elf.PF_R,
277402 .@"align" = self.page_size,
278 .addr = image_base,
403 .addr = self.image_base,
279404 .offset = 0,
280405 .filesz = reserved + ehsize,
281406 .memsz = reserved + ehsize,
282407 });
283408 }
284409
285 if (options.module != null and !options.use_llvm) {
286 const index = @as(File.Index, @intCast(try self.files.addOne(allocator)));
287 self.files.set(index, .{ .zig_object = .{
288 .index = index,
289 .path = try std.fmt.allocPrint(self.base.allocator, "{s}.o", .{std.fs.path.stem(
290 options.module.?.main_mod.root_src_path,
291 )}),
292 } });
293 self.zig_object_index = index;
294 try self.zigObjectPtr().?.init(self);
295 try self.initMetadata();
410 if (opt_zcu) |zcu| {
411 if (!use_llvm) {
412 const index: File.Index = @intCast(try self.files.addOne(gpa));
413 self.files.set(index, .{ .zig_object = .{
414 .index = index,
415 .path = try std.fmt.allocPrint(arena, "{s}.o", .{std.fs.path.stem(
416 zcu.main_mod.root_src_path,
417 )}),
418 } });
419 self.zig_object_index = index;
420 try self.zigObjectPtr().?.init(self);
421 try self.initMetadata(.{
422 .symbol_count_hint = options.symbol_count_hint,
423 .program_code_size_hint = options.program_code_size_hint,
424 });
425 }
296426 }
297427
298428 return self;
299429}
300430
301pub fn createEmpty(gpa: Allocator, options: link.Options) !*Elf {
302 const ptr_width: PtrWidth = switch (options.target.ptrBitWidth()) {
303 0...32 => .p32,
304 33...64 => .p64,
305 else => return error.UnsupportedELFArchitecture,
306 };
307 const self = try gpa.create(Elf);
308 errdefer gpa.destroy(self);
309
310 const page_size: u32 = switch (options.target.cpu.arch) {
311 .powerpc64le => 0x10000,
312 .sparc64 => 0x2000,
313 else => 0x1000,
314 };
315 const is_dyn_lib = options.output_mode == .Lib and options.link_mode == .Dynamic;
316 const default_sym_version: elf.Elf64_Versym = if (is_dyn_lib or options.rdynamic)
317 elf.VER_NDX_GLOBAL
318 else
319 elf.VER_NDX_LOCAL;
320
321 self.* = .{
322 .base = .{
323 .tag = .elf,
324 .options = options,
325 .allocator = gpa,
326 .file = null,
327 },
328 .ptr_width = ptr_width,
329 .page_size = page_size,
330 .default_sym_version = default_sym_version,
331 };
332 if (options.use_llvm and options.module != null) {
333 self.llvm_object = try LlvmObject.create(gpa, options);
334 }
335
336 return self;
431pub fn open(
432 arena: Allocator,
433 comp: *Compilation,
434 emit: Compilation.Emit,
435 options: link.File.OpenOptions,
436) !*Elf {
437 // TODO: restore saved linker state, don't truncate the file, and
438 // participate in incremental compilation.
439 return createEmpty(arena, comp, emit, options);
337440}
338441
339442pub fn deinit(self: *Elf) void {
340 const gpa = self.base.allocator;
443 const gpa = self.base.comp.gpa;
341444
342 if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa);
445 if (self.llvm_object) |llvm_object| llvm_object.deinit();
343446
344447 for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) {
345448 .null => {},
......@@ -378,7 +481,6 @@ pub fn deinit(self: *Elf) void {
378481 }
379482 self.last_atom_and_free_list_table.deinit(gpa);
380483
381 self.misc_errors.deinit(gpa);
382484 self.comdat_groups.deinit(gpa);
383485 self.comdat_groups_owners.deinit(gpa);
384486 self.comdat_groups_table.deinit(gpa);
......@@ -494,17 +596,23 @@ fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) u64 {
494596 return start;
495597}
496598
599pub const InitMetadataOptions = struct {
600 symbol_count_hint: u64,
601 program_code_size_hint: u64,
602};
603
497604/// TODO move to ZigObject
498pub fn initMetadata(self: *Elf) !void {
499 const gpa = self.base.allocator;
605pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
606 const gpa = self.base.comp.gpa;
500607 const ptr_size = self.ptrWidthBytes();
501 const ptr_bit_width = self.base.options.target.ptrBitWidth();
502 const is_linux = self.base.options.target.os.tag == .linux;
608 const target = self.base.comp.root_mod.resolved_target.result;
609 const ptr_bit_width = target.ptrBitWidth();
610 const is_linux = target.os.tag == .linux;
503611 const zig_object = self.zigObjectPtr().?;
504612
505613 const fillSection = struct {
506614 fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) void {
507 if (elf_file.isRelocatable()) {
615 if (elf_file.base.isRelocatable()) {
508616 const off = elf_file.findFreeSpace(size, shdr.sh_addralign);
509617 shdr.sh_offset = off;
510618 shdr.sh_size = size;
......@@ -519,9 +627,9 @@ pub fn initMetadata(self: *Elf) !void {
519627
520628 comptime assert(number_of_zig_segments == 5);
521629
522 if (!self.isRelocatable()) {
630 if (!self.base.isRelocatable()) {
523631 if (self.phdr_zig_load_re_index == null) {
524 const filesz = self.base.options.program_code_size_hint;
632 const filesz = options.program_code_size_hint;
525633 const off = self.findFreeSpace(filesz, self.page_size);
526634 self.phdr_zig_load_re_index = try self.addPhdr(.{
527635 .type = elf.PT_LOAD,
......@@ -538,7 +646,7 @@ pub fn initMetadata(self: *Elf) !void {
538646 // We really only need ptr alignment but since we are using PROGBITS, linux requires
539647 // page align.
540648 const alignment = if (is_linux) self.page_size else @as(u16, ptr_size);
541 const filesz = @as(u64, ptr_size) * self.base.options.symbol_count_hint;
649 const filesz = @as(u64, ptr_size) * options.symbol_count_hint;
542650 const off = self.findFreeSpace(filesz, alignment);
543651 self.phdr_zig_got_index = try self.addPhdr(.{
544652 .type = elf.PT_LOAD,
......@@ -602,8 +710,8 @@ pub fn initMetadata(self: *Elf) !void {
602710 .offset = std.math.maxInt(u64),
603711 });
604712 const shdr = &self.shdrs.items[self.zig_text_section_index.?];
605 fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index);
606 if (self.isRelocatable()) {
713 fillSection(self, shdr, options.program_code_size_hint, self.phdr_zig_load_re_index);
714 if (self.base.isRelocatable()) {
607715 const rela_shndx = try self.addRelaShdr(".rela.text.zig", self.zig_text_section_index.?);
608716 try self.output_rela_sections.putNoClobber(gpa, self.zig_text_section_index.?, .{
609717 .shndx = rela_shndx,
......@@ -619,7 +727,7 @@ pub fn initMetadata(self: *Elf) !void {
619727 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
620728 }
621729
622 if (self.zig_got_section_index == null and !self.isRelocatable()) {
730 if (self.zig_got_section_index == null and !self.base.isRelocatable()) {
623731 self.zig_got_section_index = try self.addSection(.{
624732 .name = ".got.zig",
625733 .type = elf.SHT_PROGBITS,
......@@ -650,7 +758,7 @@ pub fn initMetadata(self: *Elf) !void {
650758 });
651759 const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?];
652760 fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index);
653 if (self.isRelocatable()) {
761 if (self.base.isRelocatable()) {
654762 const rela_shndx = try self.addRelaShdr(
655763 ".rela.data.rel.ro.zig",
656764 self.zig_data_rel_ro_section_index.?,
......@@ -679,7 +787,7 @@ pub fn initMetadata(self: *Elf) !void {
679787 });
680788 const shdr = &self.shdrs.items[self.zig_data_section_index.?];
681789 fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index);
682 if (self.isRelocatable()) {
790 if (self.base.isRelocatable()) {
683791 const rela_shndx = try self.addRelaShdr(
684792 ".rela.data.zig",
685793 self.zig_data_section_index.?,
......@@ -918,56 +1026,47 @@ pub fn markDirty(self: *Elf, shdr_index: u16) void {
9181026 }
9191027}
9201028
921pub fn flush(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
922 if (self.base.options.emit == null) {
923 if (self.llvm_object) |llvm_object| {
924 try llvm_object.flushModule(comp, prog_node);
925 }
926 return;
927 }
928 const use_lld = build_options.have_llvm and self.base.options.use_lld;
1029pub fn flush(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
1030 const use_lld = build_options.have_llvm and self.base.comp.config.use_lld;
9291031 if (use_lld) {
930 return self.linkWithLLD(comp, prog_node);
1032 return self.linkWithLLD(arena, prog_node);
9311033 }
932 try self.flushModule(comp, prog_node);
1034 try self.flushModule(arena, prog_node);
9331035}
9341036
935pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
1037pub fn flushModule(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
9361038 const tracy = trace(@src());
9371039 defer tracy.end();
9381040
939 if (self.llvm_object) |llvm_object| {
940 try llvm_object.flushModule(comp, prog_node);
1041 const comp = self.base.comp;
1042 const gpa = comp.gpa;
9411043
942 const use_lld = build_options.have_llvm and self.base.options.use_lld;
1044 if (self.llvm_object) |llvm_object| {
1045 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
1046 const use_lld = build_options.have_llvm and comp.config.use_lld;
9431047 if (use_lld) return;
9441048 }
9451049
946 const gpa = self.base.allocator;
9471050 var sub_prog_node = prog_node.start("ELF Flush", 0);
9481051 sub_prog_node.activate();
9491052 defer sub_prog_node.end();
9501053
951 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
952 defer arena_allocator.deinit();
953 const arena = arena_allocator.allocator();
954
955 const target = self.base.options.target;
956 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
957 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
958 const module_obj_path: ?[]const u8 = if (self.base.intermediary_basename) |path| blk: {
1054 const target = comp.root_mod.resolved_target.result;
1055 const link_mode = comp.config.link_mode;
1056 const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
1057 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
1058 const module_obj_path: ?[]const u8 = if (self.base.zcu_object_sub_path) |path| blk: {
9591059 if (fs.path.dirname(full_out_path)) |dirname| {
9601060 break :blk try fs.path.join(arena, &.{ dirname, path });
9611061 } else {
9621062 break :blk path;
9631063 }
9641064 } else null;
965 const gc_sections = self.base.options.gc_sections orelse false;
9661065
9671066 // --verbose-link
968 if (self.base.options.verbose_link) try self.dumpArgv(comp);
1067 if (comp.verbose_link) try self.dumpArgv(comp);
9691068
970 const csu = try CsuObjects.init(arena, self.base.options, comp);
1069 const csu = try CsuObjects.init(arena, comp);
9711070 const compiler_rt_path: ?[]const u8 = blk: {
9721071 if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
9731072 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
......@@ -975,8 +1074,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
9751074 };
9761075
9771076 if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self);
978 if (self.isStaticLib()) return self.flushStaticLib(comp, module_obj_path);
979 if (self.isObject()) return self.flushObject(comp, module_obj_path);
1077 if (self.base.isStaticLib()) return self.flushStaticLib(comp, module_obj_path);
1078 if (self.base.isObject()) return self.flushObject(comp, module_obj_path);
9801079
9811080 // Here we will parse input positional and library files (if referenced).
9821081 // This will roughly match in any linker backend we support.
......@@ -987,8 +1086,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
9871086 if (csu.crti) |v| try positionals.append(.{ .path = v });
9881087 if (csu.crtbegin) |v| try positionals.append(.{ .path = v });
9891088
990 try positionals.ensureUnusedCapacity(self.base.options.objects.len);
991 positionals.appendSliceAssumeCapacity(self.base.options.objects);
1089 try positionals.ensureUnusedCapacity(comp.objects.len);
1090 positionals.appendSliceAssumeCapacity(comp.objects);
9921091
9931092 // This is a set of object files emitted by clang in a single `build-exe` invocation.
9941093 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up
......@@ -1000,24 +1099,24 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10001099 if (module_obj_path) |path| try positionals.append(.{ .path = path });
10011100
10021101 // rpaths
1003 var rpath_table = std.StringArrayHashMap(void).init(self.base.allocator);
1102 var rpath_table = std.StringArrayHashMap(void).init(gpa);
10041103 defer rpath_table.deinit();
10051104
1006 for (self.base.options.rpath_list) |rpath| {
1105 for (self.base.rpath_list) |rpath| {
10071106 _ = try rpath_table.put(rpath, {});
10081107 }
10091108
1010 if (self.base.options.each_lib_rpath) {
1011 var test_path = std.ArrayList(u8).init(self.base.allocator);
1109 if (self.each_lib_rpath) {
1110 var test_path = std.ArrayList(u8).init(gpa);
10121111 defer test_path.deinit();
1013 for (self.base.options.lib_dirs) |lib_dir_path| {
1014 for (self.base.options.system_libs.keys()) |link_lib| {
1112 for (self.lib_dirs) |lib_dir_path| {
1113 for (comp.system_libs.keys()) |link_lib| {
10151114 if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))
10161115 continue;
10171116 _ = try rpath_table.put(lib_dir_path, {});
10181117 }
10191118 }
1020 for (self.base.options.objects) |obj| {
1119 for (comp.objects) |obj| {
10211120 if (Compilation.classifyFileExt(obj.path) == .shared_library) {
10221121 const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue;
10231122 if (obj.loption) continue;
......@@ -1027,14 +1126,12 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10271126 }
10281127
10291128 // TSAN
1030 if (self.base.options.tsan) {
1129 if (comp.config.any_sanitize_thread) {
10311130 try positionals.append(.{ .path = comp.tsan_static_lib.?.full_object_path });
10321131 }
10331132
10341133 // libc
1035 if (!self.base.options.skip_linker_dependencies and
1036 !self.base.options.link_libc)
1037 {
1134 if (!comp.skip_linker_dependencies and !comp.config.link_libc) {
10381135 if (comp.libc_static_lib) |lib| {
10391136 try positionals.append(.{ .path = lib.full_object_path });
10401137 }
......@@ -1053,27 +1150,27 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10531150
10541151 var system_libs = std.ArrayList(SystemLib).init(arena);
10551152
1056 try system_libs.ensureUnusedCapacity(self.base.options.system_libs.values().len);
1057 for (self.base.options.system_libs.values()) |lib_info| {
1153 try system_libs.ensureUnusedCapacity(comp.system_libs.values().len);
1154 for (comp.system_libs.values()) |lib_info| {
10581155 system_libs.appendAssumeCapacity(.{ .needed = lib_info.needed, .path = lib_info.path.? });
10591156 }
10601157
10611158 // libc++ dep
1062 if (self.base.options.link_libcpp) {
1159 if (comp.config.link_libcpp) {
10631160 try system_libs.ensureUnusedCapacity(2);
10641161 system_libs.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path });
10651162 system_libs.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path });
10661163 }
10671164
10681165 // libunwind dep
1069 if (self.base.options.link_libunwind) {
1166 if (comp.config.link_libunwind) {
10701167 try system_libs.append(.{ .path = comp.libunwind_static_lib.?.full_object_path });
10711168 }
10721169
10731170 // libc dep
1074 self.error_flags.missing_libc = false;
1075 if (self.base.options.link_libc) {
1076 if (self.base.options.libc_installation) |lc| {
1171 comp.link_error_flags.missing_libc = false;
1172 if (comp.config.link_libc) {
1173 if (comp.libc_installation) |lc| {
10771174 const flags = target_util.libcFullLinkFlags(target);
10781175 try system_libs.ensureUnusedCapacity(flags.len);
10791176
......@@ -1085,7 +1182,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
10851182 const lib_name = flag["-l".len..];
10861183
10871184 success: {
1088 if (!self.isStatic()) {
1185 if (!self.base.isStatic()) {
10891186 if (try self.accessLibPath(&test_path, &checked_paths, lc.crt_dir.?, lib_name, .Dynamic))
10901187 break :success;
10911188 }
......@@ -1116,13 +1213,13 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11161213 .path = try comp.get_libc_crt_file(arena, "libc_nonshared.a"),
11171214 });
11181215 } else if (target.isMusl()) {
1119 const path = try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) {
1216 const path = try comp.get_libc_crt_file(arena, switch (link_mode) {
11201217 .Static => "libc.a",
11211218 .Dynamic => "libc.so",
11221219 });
11231220 try system_libs.append(.{ .path = path });
11241221 } else {
1125 self.error_flags.missing_libc = true;
1222 comp.link_error_flags.missing_libc = true;
11261223 }
11271224 }
11281225
......@@ -1160,7 +1257,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11601257 };
11611258 }
11621259
1163 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1260 if (comp.link_errors.items.len > 0) return error.FlushFailure;
11641261
11651262 // Init all objects
11661263 for (self.objects.items) |index| {
......@@ -1170,7 +1267,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
11701267 try self.file(index).?.shared_object.init(self);
11711268 }
11721269
1173 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1270 if (comp.link_errors.items.len > 0) return error.FlushFailure;
11741271
11751272 // Dedup shared objects
11761273 {
......@@ -1211,18 +1308,15 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12111308
12121309 // Look for entry address in objects if not set by the incremental compiler.
12131310 if (self.entry_index == null) {
1214 const entry: ?[]const u8 = entry: {
1215 if (self.base.options.entry) |entry| break :entry entry;
1216 if (!self.isDynLib()) break :entry "_start";
1217 break :entry null;
1218 };
1219 self.entry_index = if (entry) |name| self.globalByName(name) else null;
1311 if (self.entry_name) |name| {
1312 self.entry_index = self.globalByName(name);
1313 }
12201314 }
12211315
1222 if (gc_sections) {
1316 if (self.base.gc_sections) {
12231317 try gc.gcAtoms(self);
12241318
1225 if (self.base.options.print_gc_sections) {
1319 if (self.base.print_gc_sections) {
12261320 try gc.dumpPrunedAtoms(self);
12271321 }
12281322 }
......@@ -1290,26 +1384,26 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
12901384 try self.writeAtoms();
12911385 try self.writeSyntheticSections();
12921386
1293 if (self.entry_index == null and self.isExe()) {
1387 if (self.entry_index == null and self.base.isExe()) {
12941388 log.debug("flushing. no_entry_point_found = true", .{});
1295 self.error_flags.no_entry_point_found = true;
1389 comp.link_error_flags.no_entry_point_found = true;
12961390 } else {
12971391 log.debug("flushing. no_entry_point_found = false", .{});
1298 self.error_flags.no_entry_point_found = false;
1392 comp.link_error_flags.no_entry_point_found = false;
12991393 try self.writeElfHeader();
13001394 }
13011395
1302 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1396 if (comp.link_errors.items.len > 0) return error.FlushFailure;
13031397}
13041398
13051399pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
1306 const gpa = self.base.allocator;
1400 const gpa = comp.gpa;
13071401
13081402 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
13091403 defer positionals.deinit();
13101404
1311 try positionals.ensureUnusedCapacity(self.base.options.objects.len);
1312 positionals.appendSliceAssumeCapacity(self.base.options.objects);
1405 try positionals.ensureUnusedCapacity(comp.objects.len);
1406 positionals.appendSliceAssumeCapacity(comp.objects);
13131407
13141408 // This is a set of object files emitted by clang in a single `build-exe` invocation.
13151409 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up
......@@ -1331,7 +1425,7 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const
13311425 };
13321426 }
13331427
1334 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1428 if (comp.link_errors.items.len > 0) return error.FlushFailure;
13351429
13361430 // First, we flush relocatable object file generated with our backends.
13371431 if (self.zigObjectPtr()) |zig_object| {
......@@ -1443,16 +1537,16 @@ pub fn flushStaticLib(self: *Elf, comp: *Compilation, module_obj_path: ?[]const
14431537 try self.base.file.?.setEndPos(total_size);
14441538 try self.base.file.?.pwriteAll(buffer.items, 0);
14451539
1446 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1540 if (comp.link_errors.items.len > 0) return error.FlushFailure;
14471541}
14481542
14491543pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) link.File.FlushError!void {
1450 const gpa = self.base.allocator;
1544 const gpa = self.base.comp.gpa;
14511545
14521546 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
14531547 defer positionals.deinit();
1454 try positionals.ensureUnusedCapacity(self.base.options.objects.len);
1455 positionals.appendSliceAssumeCapacity(self.base.options.objects);
1548 try positionals.ensureUnusedCapacity(comp.objects.len);
1549 positionals.appendSliceAssumeCapacity(comp.objects);
14561550
14571551 // This is a set of object files emitted by clang in a single `build-exe` invocation.
14581552 // For instance, the implicit `a.o` as compiled by `zig build-exe a.c` will end up
......@@ -1474,14 +1568,14 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)
14741568 };
14751569 }
14761570
1477 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1571 if (comp.link_errors.items.len > 0) return error.FlushFailure;
14781572
14791573 // Init all objects
14801574 for (self.objects.items) |index| {
14811575 try self.file(index).?.object.init(self);
14821576 }
14831577
1484 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1578 if (comp.link_errors.items.len > 0) return error.FlushFailure;
14851579
14861580 // Now, we are ready to resolve the symbols across all input files.
14871581 // We will first resolve the files in the ZigObject, next in the parsed
......@@ -1515,28 +1609,29 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8)
15151609 try self.writeShdrTable();
15161610 try self.writeElfHeader();
15171611
1518 if (self.misc_errors.items.len > 0) return error.FlushFailure;
1612 if (comp.link_errors.items.len > 0) return error.FlushFailure;
15191613}
15201614
15211615/// --verbose-link output
15221616fn dumpArgv(self: *Elf, comp: *Compilation) !void {
1523 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
1617 const gpa = self.base.comp.gpa;
1618 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
15241619 defer arena_allocator.deinit();
15251620 const arena = arena_allocator.allocator();
15261621
1527 const target = self.base.options.target;
1528 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
1529 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
1530 const module_obj_path: ?[]const u8 = if (self.base.intermediary_basename) |path| blk: {
1622 const target = self.base.comp.root_mod.resolved_target.result;
1623 const link_mode = self.base.comp.config.link_mode;
1624 const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
1625 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
1626 const module_obj_path: ?[]const u8 = if (self.base.zcu_object_sub_path) |path| blk: {
15311627 if (fs.path.dirname(full_out_path)) |dirname| {
15321628 break :blk try fs.path.join(arena, &.{ dirname, path });
15331629 } else {
15341630 break :blk path;
15351631 }
15361632 } else null;
1537 const gc_sections = self.base.options.gc_sections orelse false;
15381633
1539 const csu = try CsuObjects.init(arena, self.base.options, comp);
1634 const csu = try CsuObjects.init(arena, comp);
15401635 const compiler_rt_path: ?[]const u8 = blk: {
15411636 if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
15421637 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
......@@ -1547,21 +1642,21 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
15471642
15481643 try argv.append("zig");
15491644
1550 if (self.isStaticLib()) {
1645 if (self.base.isStaticLib()) {
15511646 try argv.append("ar");
15521647 } else {
15531648 try argv.append("ld");
15541649 }
15551650
1556 if (self.isObject()) {
1651 if (self.base.isObject()) {
15571652 try argv.append("-r");
15581653 }
15591654
15601655 try argv.append("-o");
15611656 try argv.append(full_out_path);
15621657
1563 if (self.isRelocatable()) {
1564 for (self.base.options.objects) |obj| {
1658 if (self.base.isRelocatable()) {
1659 for (comp.objects) |obj| {
15651660 try argv.append(obj.path);
15661661 }
15671662
......@@ -1573,36 +1668,35 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
15731668 try argv.append(p);
15741669 }
15751670 } else {
1576 if (!self.isStatic()) {
1577 if (self.base.options.dynamic_linker) |path| {
1671 if (!self.base.isStatic()) {
1672 if (target.dynamic_linker.get()) |path| {
15781673 try argv.append("-dynamic-linker");
15791674 try argv.append(path);
15801675 }
15811676 }
15821677
1583 if (self.isDynLib()) {
1584 if (self.base.options.soname) |name| {
1678 if (self.base.isDynLib()) {
1679 if (self.soname) |name| {
15851680 try argv.append("-soname");
15861681 try argv.append(name);
15871682 }
15881683 }
15891684
1590 if (self.base.options.entry) |entry| {
1591 try argv.append("--entry");
1592 try argv.append(entry);
1685 if (self.entry_name) |name| {
1686 try argv.appendSlice(&.{ "--entry", name });
15931687 }
15941688
1595 for (self.base.options.rpath_list) |rpath| {
1689 for (self.base.rpath_list) |rpath| {
15961690 try argv.append("-rpath");
15971691 try argv.append(rpath);
15981692 }
15991693
1600 if (self.base.options.each_lib_rpath) {
1601 for (self.base.options.lib_dirs) |lib_dir_path| {
1694 if (self.each_lib_rpath) {
1695 for (self.lib_dirs) |lib_dir_path| {
16021696 try argv.append("-rpath");
16031697 try argv.append(lib_dir_path);
16041698 }
1605 for (self.base.options.objects) |obj| {
1699 for (comp.objects) |obj| {
16061700 if (Compilation.classifyFileExt(obj.path) == .shared_library) {
16071701 const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue;
16081702 if (obj.loption) continue;
......@@ -1613,57 +1707,55 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
16131707 }
16141708 }
16151709
1616 if (self.base.options.stack_size_override) |ss| {
1617 try argv.append("-z");
1618 try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{ss}));
1619 }
1710 try argv.appendSlice(&.{
1711 "-z",
1712 try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}),
1713 });
16201714
1621 if (self.base.options.image_base_override) |image_base| {
1622 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base}));
1623 }
1715 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
16241716
1625 if (gc_sections) {
1717 if (self.base.gc_sections) {
16261718 try argv.append("--gc-sections");
16271719 }
16281720
1629 if (self.base.options.print_gc_sections) {
1721 if (self.base.print_gc_sections) {
16301722 try argv.append("--print-gc-sections");
16311723 }
16321724
1633 if (self.base.options.eh_frame_hdr) {
1725 if (comp.link_eh_frame_hdr) {
16341726 try argv.append("--eh-frame-hdr");
16351727 }
16361728
1637 if (self.base.options.rdynamic) {
1729 if (comp.config.rdynamic) {
16381730 try argv.append("--export-dynamic");
16391731 }
16401732
1641 if (self.base.options.z_notext) {
1733 if (self.z_notext) {
16421734 try argv.append("-z");
16431735 try argv.append("notext");
16441736 }
16451737
1646 if (self.base.options.z_nocopyreloc) {
1738 if (self.z_nocopyreloc) {
16471739 try argv.append("-z");
16481740 try argv.append("nocopyreloc");
16491741 }
16501742
1651 if (self.base.options.z_now) {
1743 if (self.z_now) {
16521744 try argv.append("-z");
16531745 try argv.append("now");
16541746 }
16551747
1656 if (self.isStatic()) {
1748 if (self.base.isStatic()) {
16571749 try argv.append("-static");
1658 } else if (self.isDynLib()) {
1750 } else if (self.base.isDynLib()) {
16591751 try argv.append("-shared");
16601752 }
16611753
1662 if (self.base.options.pie and self.isExe()) {
1754 if (comp.config.pie and self.base.isExe()) {
16631755 try argv.append("-pie");
16641756 }
16651757
1666 if (self.base.options.strip) {
1758 if (comp.config.debug_format == .strip) {
16671759 try argv.append("-s");
16681760 }
16691761
......@@ -1672,20 +1764,20 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
16721764 if (csu.crti) |v| try argv.append(v);
16731765 if (csu.crtbegin) |v| try argv.append(v);
16741766
1675 for (self.base.options.lib_dirs) |lib_dir| {
1767 for (self.lib_dirs) |lib_dir| {
16761768 try argv.append("-L");
16771769 try argv.append(lib_dir);
16781770 }
16791771
1680 if (self.base.options.link_libc) {
1681 if (self.base.options.libc_installation) |libc_installation| {
1772 if (comp.config.link_libc) {
1773 if (self.base.comp.libc_installation) |libc_installation| {
16821774 try argv.append("-L");
16831775 try argv.append(libc_installation.crt_dir.?);
16841776 }
16851777 }
16861778
16871779 var whole_archive = false;
1688 for (self.base.options.objects) |obj| {
1780 for (comp.objects) |obj| {
16891781 if (obj.must_link and !whole_archive) {
16901782 try argv.append("-whole-archive");
16911783 whole_archive = true;
......@@ -1713,15 +1805,12 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
17131805 try argv.append(p);
17141806 }
17151807
1716 // TSAN
1717 if (self.base.options.tsan) {
1808 if (comp.config.any_sanitize_thread) {
17181809 try argv.append(comp.tsan_static_lib.?.full_object_path);
17191810 }
17201811
17211812 // libc
1722 if (!self.base.options.skip_linker_dependencies and
1723 !self.base.options.link_libc)
1724 {
1813 if (!comp.skip_linker_dependencies and !comp.config.link_libc) {
17251814 if (comp.libc_static_lib) |lib| {
17261815 try argv.append(lib.full_object_path);
17271816 }
......@@ -1730,11 +1819,11 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
17301819 // Shared libraries.
17311820 // Worst-case, we need an --as-needed argument for every lib, as well
17321821 // as one before and one after.
1733 try argv.ensureUnusedCapacity(self.base.options.system_libs.keys().len * 2 + 2);
1822 try argv.ensureUnusedCapacity(self.base.comp.system_libs.keys().len * 2 + 2);
17341823 argv.appendAssumeCapacity("--as-needed");
17351824 var as_needed = true;
17361825
1737 for (self.base.options.system_libs.values()) |lib_info| {
1826 for (self.base.comp.system_libs.values()) |lib_info| {
17381827 const lib_as_needed = !lib_info.needed;
17391828 switch ((@as(u2, @intFromBool(lib_as_needed)) << 1) | @intFromBool(as_needed)) {
17401829 0b00, 0b11 => {},
......@@ -1756,20 +1845,20 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
17561845 }
17571846
17581847 // libc++ dep
1759 if (self.base.options.link_libcpp) {
1848 if (comp.config.link_libcpp) {
17601849 try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
17611850 try argv.append(comp.libcxx_static_lib.?.full_object_path);
17621851 }
17631852
17641853 // libunwind dep
1765 if (self.base.options.link_libunwind) {
1854 if (comp.config.link_libunwind) {
17661855 try argv.append(comp.libunwind_static_lib.?.full_object_path);
17671856 }
17681857
17691858 // libc dep
1770 if (self.base.options.link_libc) {
1771 if (self.base.options.libc_installation != null) {
1772 const needs_grouping = self.base.options.link_mode == .Static;
1859 if (comp.config.link_libc) {
1860 if (self.base.comp.libc_installation != null) {
1861 const needs_grouping = link_mode == .Static;
17731862 if (needs_grouping) try argv.append("--start-group");
17741863 try argv.appendSlice(target_util.libcFullLinkFlags(target));
17751864 if (needs_grouping) try argv.append("--end-group");
......@@ -1782,7 +1871,7 @@ fn dumpArgv(self: *Elf, comp: *Compilation) !void {
17821871 }
17831872 try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));
17841873 } else if (target.isMusl()) {
1785 try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) {
1874 try argv.append(try comp.get_libc_crt_file(arena, switch (link_mode) {
17861875 .Static => "libc.a",
17871876 .Dynamic => "libc.so",
17881877 }));
......@@ -1842,7 +1931,7 @@ fn parseObject(self: *Elf, path: []const u8) ParseError!void {
18421931 const tracy = trace(@src());
18431932 defer tracy.end();
18441933
1845 const gpa = self.base.allocator;
1934 const gpa = self.base.comp.gpa;
18461935 const in_file = try std.fs.cwd().openFile(path, .{});
18471936 defer in_file.close();
18481937 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
......@@ -1862,7 +1951,7 @@ fn parseArchive(self: *Elf, path: []const u8, must_link: bool) ParseError!void {
18621951 const tracy = trace(@src());
18631952 defer tracy.end();
18641953
1865 const gpa = self.base.allocator;
1954 const gpa = self.base.comp.gpa;
18661955 const in_file = try std.fs.cwd().openFile(path, .{});
18671956 defer in_file.close();
18681957 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
......@@ -1888,7 +1977,7 @@ fn parseSharedObject(self: *Elf, lib: SystemLib) ParseError!void {
18881977 const tracy = trace(@src());
18891978 defer tracy.end();
18901979
1891 const gpa = self.base.allocator;
1980 const gpa = self.base.comp.gpa;
18921981 const in_file = try std.fs.cwd().openFile(lib.path, .{});
18931982 defer in_file.close();
18941983 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
......@@ -1910,7 +1999,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
19101999 const tracy = trace(@src());
19112000 defer tracy.end();
19122001
1913 const gpa = self.base.allocator;
2002 const gpa = self.base.comp.gpa;
19142003 const in_file = try std.fs.cwd().openFile(lib.path, .{});
19152004 defer in_file.close();
19162005 const data = try in_file.readToEndAlloc(gpa, std.math.maxInt(u32));
......@@ -1920,8 +2009,6 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
19202009 defer script.deinit(gpa);
19212010 try script.parse(data, self);
19222011
1923 const lib_dirs = self.base.options.lib_dirs;
1924
19252012 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
19262013 defer arena_allocator.deinit();
19272014 const arena = arena_allocator.allocator();
......@@ -1938,8 +2025,8 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
19382025
19392026 // TODO I think technically we should re-use the mechanism used by the frontend here.
19402027 // Maybe we should hoist search-strategy all the way here?
1941 for (lib_dirs) |lib_dir| {
1942 if (!self.isStatic()) {
2028 for (self.lib_dirs) |lib_dir| {
2029 if (!self.base.isStatic()) {
19432030 if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, lib_name, .Dynamic))
19442031 break :success;
19452032 }
......@@ -1955,7 +2042,7 @@ fn parseLdScript(self: *Elf, lib: SystemLib) ParseError!void {
19552042 } else |_| {}
19562043
19572044 try checked_paths.append(try gpa.dupe(u8, scr_obj.path));
1958 for (lib_dirs) |lib_dir| {
2045 for (self.lib_dirs) |lib_dir| {
19592046 if (try self.accessLibPath(&test_path, &checked_paths, lib_dir, scr_obj.path, null))
19602047 break :success;
19612048 }
......@@ -1995,8 +2082,9 @@ fn accessLibPath(
19952082 lib_name: []const u8,
19962083 link_mode: ?std.builtin.LinkMode,
19972084) !bool {
2085 const gpa = self.base.comp.gpa;
19982086 const sep = fs.path.sep_str;
1999 const target = self.base.options.target;
2087 const target = self.base.comp.root_mod.resolved_target.result;
20002088 test_path.clearRetainingCapacity();
20012089 const prefix = if (link_mode != null) "lib" else "";
20022090 const suffix = if (link_mode) |mode| switch (mode) {
......@@ -2010,7 +2098,7 @@ fn accessLibPath(
20102098 suffix,
20112099 });
20122100 if (checked_paths) |cpaths| {
2013 try cpaths.append(try self.base.allocator.dupe(u8, test_path.items));
2101 try cpaths.append(try gpa.dupe(u8, test_path.items));
20142102 }
20152103 fs.cwd().access(test_path.items, .{}) catch |err| switch (err) {
20162104 error.FileNotFound => return false,
......@@ -2139,7 +2227,7 @@ fn markImportsExports(self: *Elf) void {
21392227 }
21402228 if (file_ptr.index() == file_index) {
21412229 global.flags.@"export" = true;
2142 if (elf_file.isDynLib() and vis != .PROTECTED) {
2230 if (elf_file.base.isDynLib() and vis != .PROTECTED) {
21432231 global.flags.import = true;
21442232 }
21452233 }
......@@ -2147,7 +2235,7 @@ fn markImportsExports(self: *Elf) void {
21472235 }
21482236 }.mark;
21492237
2150 if (!self.isDynLib()) {
2238 if (!self.base.isDynLib()) {
21512239 for (self.shared_objects.items) |index| {
21522240 for (self.file(index).?.globals()) |global_index| {
21532241 const global = self.symbol(global_index);
......@@ -2190,7 +2278,7 @@ fn claimUnresolvedObject(self: *Elf) void {
21902278/// This is also the point where we will report undefined symbols for any
21912279/// alloc sections.
21922280fn scanRelocs(self: *Elf) !void {
2193 const gpa = self.base.allocator;
2281 const gpa = self.base.comp.gpa;
21942282
21952283 var undefs = std.AutoHashMap(Symbol.Index, std.ArrayList(Atom.Index)).init(gpa);
21962284 defer {
......@@ -2259,26 +2347,25 @@ fn scanRelocs(self: *Elf) !void {
22592347 }
22602348}
22612349
2262fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !void {
2350fn linkWithLLD(self: *Elf, arena: Allocator, prog_node: *std.Progress.Node) !void {
22632351 const tracy = trace(@src());
22642352 defer tracy.end();
22652353
2266 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
2267 defer arena_allocator.deinit();
2268 const arena = arena_allocator.allocator();
2354 const comp = self.base.comp;
2355 const gpa = comp.gpa;
22692356
2270 const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type.
2271 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path});
2357 const directory = self.base.emit.directory; // Just an alias to make it shorter to type.
2358 const full_out_path = try directory.join(arena, &[_][]const u8{self.base.emit.sub_path});
22722359
22732360 // If there is no Zig code to compile, then we should skip flushing the output file because it
22742361 // will not be part of the linker line anyway.
2275 const module_obj_path: ?[]const u8 = if (self.base.options.module != null) blk: {
2276 try self.flushModule(comp, prog_node);
2362 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
2363 try self.flushModule(arena, prog_node);
22772364
22782365 if (fs.path.dirname(full_out_path)) |dirname| {
2279 break :blk try fs.path.join(arena, &.{ dirname, self.base.intermediary_basename.? });
2366 break :blk try fs.path.join(arena, &.{ dirname, self.base.zcu_object_sub_path.? });
22802367 } else {
2281 break :blk self.base.intermediary_basename.?;
2368 break :blk self.base.zcu_object_sub_path.?;
22822369 }
22832370 } else null;
22842371
......@@ -2287,16 +2374,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
22872374 sub_prog_node.context.refresh();
22882375 defer sub_prog_node.end();
22892376
2290 const is_obj = self.base.options.output_mode == .Obj;
2291 const is_lib = self.base.options.output_mode == .Lib;
2292 const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
2293 const is_exe_or_dyn_lib = is_dyn_lib or self.base.options.output_mode == .Exe;
2294 const have_dynamic_linker = self.base.options.link_libc and
2295 self.base.options.link_mode == .Dynamic and is_exe_or_dyn_lib;
2296 const target = self.base.options.target;
2297 const gc_sections = self.base.options.gc_sections orelse !is_obj;
2298 const stack_size = self.base.options.stack_size_override orelse 16777216;
2299 const allow_shlib_undefined = self.base.options.allow_shlib_undefined orelse !self.base.options.is_native_os;
2377 const output_mode = comp.config.output_mode;
2378 const is_obj = output_mode == .Obj;
2379 const is_lib = output_mode == .Lib;
2380 const link_mode = comp.config.link_mode;
2381 const is_dyn_lib = link_mode == .Dynamic and is_lib;
2382 const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe;
2383 const have_dynamic_linker = comp.config.link_libc and
2384 link_mode == .Dynamic and is_exe_or_dyn_lib;
2385 const target = comp.root_mod.resolved_target.result;
23002386 const compiler_rt_path: ?[]const u8 = blk: {
23012387 if (comp.compiler_rt_lib) |x| break :blk x.full_object_path;
23022388 if (comp.compiler_rt_obj) |x| break :blk x.full_object_path;
......@@ -2314,11 +2400,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
23142400 const id_symlink_basename = "lld.id";
23152401
23162402 var man: Cache.Manifest = undefined;
2317 defer if (!self.base.options.disable_lld_caching) man.deinit();
2403 defer if (!self.base.disable_lld_caching) man.deinit();
23182404
23192405 var digest: [Cache.hex_digest_len]u8 = undefined;
23202406
2321 if (!self.base.options.disable_lld_caching) {
2407 if (!self.base.disable_lld_caching) {
23222408 man = comp.cache_parent.obtain();
23232409
23242410 // We are about to obtain this lock, so here we give other processes a chance first.
......@@ -2326,9 +2412,9 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
23262412
23272413 comptime assert(Compilation.link_hash_implementation_version == 10);
23282414
2329 try man.addOptionalFile(self.base.options.linker_script);
2330 try man.addOptionalFile(self.base.options.version_script);
2331 for (self.base.options.objects) |obj| {
2415 try man.addOptionalFile(self.linker_script);
2416 try man.addOptionalFile(self.version_script);
2417 for (comp.objects) |obj| {
23322418 _ = try man.addFile(obj.path, null);
23332419 man.hash.add(obj.must_link);
23342420 man.hash.add(obj.loption);
......@@ -2341,52 +2427,51 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
23412427
23422428 // We can skip hashing libc and libc++ components that we are in charge of building from Zig
23432429 // installation sources because they are always a product of the compiler version + target information.
2344 man.hash.addOptionalBytes(self.base.options.entry);
2345 man.hash.addOptional(self.base.options.image_base_override);
2346 man.hash.add(gc_sections);
2347 man.hash.addOptional(self.base.options.sort_section);
2348 man.hash.add(self.base.options.eh_frame_hdr);
2349 man.hash.add(self.base.options.emit_relocs);
2350 man.hash.add(self.base.options.rdynamic);
2351 man.hash.addListOfBytes(self.base.options.lib_dirs);
2352 man.hash.addListOfBytes(self.base.options.rpath_list);
2353 man.hash.add(self.base.options.each_lib_rpath);
2354 if (self.base.options.output_mode == .Exe) {
2355 man.hash.add(stack_size);
2356 man.hash.add(self.base.options.build_id);
2357 }
2358 man.hash.addListOfBytes(self.base.options.symbol_wrap_set.keys());
2359 man.hash.add(self.base.options.skip_linker_dependencies);
2360 man.hash.add(self.base.options.z_nodelete);
2361 man.hash.add(self.base.options.z_notext);
2362 man.hash.add(self.base.options.z_defs);
2363 man.hash.add(self.base.options.z_origin);
2364 man.hash.add(self.base.options.z_nocopyreloc);
2365 man.hash.add(self.base.options.z_now);
2366 man.hash.add(self.base.options.z_relro);
2367 man.hash.add(self.base.options.z_common_page_size orelse 0);
2368 man.hash.add(self.base.options.z_max_page_size orelse 0);
2369 man.hash.add(self.base.options.hash_style);
2430 man.hash.addOptionalBytes(self.entry_name);
2431 man.hash.add(self.image_base);
2432 man.hash.add(self.base.gc_sections);
2433 man.hash.addOptional(self.sort_section);
2434 man.hash.add(comp.link_eh_frame_hdr);
2435 man.hash.add(self.emit_relocs);
2436 man.hash.add(comp.config.rdynamic);
2437 man.hash.addListOfBytes(self.lib_dirs);
2438 man.hash.addListOfBytes(self.base.rpath_list);
2439 man.hash.add(self.each_lib_rpath);
2440 if (output_mode == .Exe) {
2441 man.hash.add(self.base.stack_size);
2442 man.hash.add(self.base.build_id);
2443 }
2444 man.hash.addListOfBytes(self.symbol_wrap_set.keys());
2445 man.hash.add(comp.skip_linker_dependencies);
2446 man.hash.add(self.z_nodelete);
2447 man.hash.add(self.z_notext);
2448 man.hash.add(self.z_defs);
2449 man.hash.add(self.z_origin);
2450 man.hash.add(self.z_nocopyreloc);
2451 man.hash.add(self.z_now);
2452 man.hash.add(self.z_relro);
2453 man.hash.add(self.z_common_page_size orelse 0);
2454 man.hash.add(self.z_max_page_size orelse 0);
2455 man.hash.add(self.hash_style);
23702456 // strip does not need to go into the linker hash because it is part of the hash namespace
2371 if (self.base.options.link_libc) {
2372 man.hash.add(self.base.options.libc_installation != null);
2373 if (self.base.options.libc_installation) |libc_installation| {
2457 if (comp.config.link_libc) {
2458 man.hash.add(comp.libc_installation != null);
2459 if (comp.libc_installation) |libc_installation| {
23742460 man.hash.addBytes(libc_installation.crt_dir.?);
23752461 }
23762462 if (have_dynamic_linker) {
2377 man.hash.addOptionalBytes(self.base.options.dynamic_linker);
2463 man.hash.addOptionalBytes(target.dynamic_linker.get());
23782464 }
23792465 }
2380 man.hash.addOptionalBytes(self.base.options.soname);
2381 man.hash.addOptional(self.base.options.version);
2382 try link.hashAddSystemLibs(&man, self.base.options.system_libs);
2383 man.hash.addListOfBytes(self.base.options.force_undefined_symbols.keys());
2384 man.hash.add(allow_shlib_undefined);
2385 man.hash.add(self.base.options.bind_global_refs_locally);
2386 man.hash.add(self.base.options.compress_debug_sections);
2387 man.hash.add(self.base.options.tsan);
2388 man.hash.addOptionalBytes(self.base.options.sysroot);
2389 man.hash.add(self.base.options.linker_optimization);
2466 man.hash.addOptionalBytes(self.soname);
2467 man.hash.addOptional(comp.version);
2468 try link.hashAddSystemLibs(&man, comp.system_libs);
2469 man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
2470 man.hash.add(self.base.allow_shlib_undefined);
2471 man.hash.add(self.bind_global_refs_locally);
2472 man.hash.add(self.compress_debug_sections);
2473 man.hash.add(comp.config.any_sanitize_thread);
2474 man.hash.addOptionalBytes(comp.sysroot);
23902475
23912476 // We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
23922477 _ = try man.hit();
......@@ -2421,15 +2506,15 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
24212506 // copy when generating relocatables. Normally, we would expect `lld -r` to work.
24222507 // However, because LLD wants to resolve BPF relocations which it shouldn't, it fails
24232508 // before even generating the relocatable.
2424 if (self.base.options.output_mode == .Obj and
2425 (self.base.options.lto or target.isBpfFreestanding()))
2509 if (output_mode == .Obj and
2510 (comp.config.lto or target.isBpfFreestanding()))
24262511 {
24272512 // In this case we must do a simple file copy
24282513 // here. TODO: think carefully about how we can avoid this redundant operation when doing
24292514 // build-obj. See also the corresponding TODO in linkAsArchive.
24302515 const the_object_path = blk: {
2431 if (self.base.options.objects.len != 0)
2432 break :blk self.base.options.objects[0].path;
2516 if (comp.objects.len != 0)
2517 break :blk comp.objects[0].path;
24332518
24342519 if (comp.c_object_table.count() != 0)
24352520 break :blk comp.c_object_table.keys()[0].status.success.object_path;
......@@ -2448,7 +2533,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
24482533 }
24492534 } else {
24502535 // Create an LLD command line and invoke it.
2451 var argv = std.ArrayList([]const u8).init(self.base.allocator);
2536 var argv = std.ArrayList([]const u8).init(gpa);
24522537 defer argv.deinit();
24532538 // We will invoke ourselves as a child process to gain access to LLD.
24542539 // This is necessary because LLD does not behave properly as a library -
......@@ -2461,46 +2546,49 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
24612546
24622547 try argv.append("--error-limit=0");
24632548
2464 if (self.base.options.sysroot) |sysroot| {
2549 if (comp.sysroot) |sysroot| {
24652550 try argv.append(try std.fmt.allocPrint(arena, "--sysroot={s}", .{sysroot}));
24662551 }
24672552
2468 if (self.base.options.lto) {
2469 switch (self.base.options.optimize_mode) {
2553 if (comp.config.lto) {
2554 switch (comp.root_mod.optimize_mode) {
24702555 .Debug => {},
24712556 .ReleaseSmall => try argv.append("--lto-O2"),
24722557 .ReleaseFast, .ReleaseSafe => try argv.append("--lto-O3"),
24732558 }
24742559 }
2475 try argv.append(try std.fmt.allocPrint(arena, "-O{d}", .{
2476 self.base.options.linker_optimization,
2477 }));
2560 switch (comp.root_mod.optimize_mode) {
2561 .Debug => {},
2562 .ReleaseSmall => try argv.append("-O2"),
2563 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
2564 }
24782565
2479 if (self.base.options.entry) |entry| {
2480 try argv.append("--entry");
2481 try argv.append(entry);
2566 if (self.entry_name) |name| {
2567 try argv.appendSlice(&.{ "--entry", name });
24822568 }
24832569
2484 for (self.base.options.force_undefined_symbols.keys()) |sym| {
2570 for (comp.force_undefined_symbols.keys()) |sym| {
24852571 try argv.append("-u");
24862572 try argv.append(sym);
24872573 }
24882574
2489 switch (self.base.options.hash_style) {
2575 switch (self.hash_style) {
24902576 .gnu => try argv.append("--hash-style=gnu"),
24912577 .sysv => try argv.append("--hash-style=sysv"),
24922578 .both => {}, // this is the default
24932579 }
24942580
2495 if (self.base.options.output_mode == .Exe) {
2496 try argv.append("-z");
2497 try argv.append(try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size}));
2581 if (output_mode == .Exe) {
2582 try argv.appendSlice(&.{
2583 "-z",
2584 try std.fmt.allocPrint(arena, "stack-size={d}", .{self.base.stack_size}),
2585 });
24982586
2499 switch (self.base.options.build_id) {
2587 switch (self.base.build_id) {
25002588 .none => {},
25012589 .fast, .uuid, .sha1, .md5 => {
25022590 try argv.append(try std.fmt.allocPrint(arena, "--build-id={s}", .{
2503 @tagName(self.base.options.build_id),
2591 @tagName(self.base.build_id),
25042592 }));
25052593 },
25062594 .hexstring => |hs| {
......@@ -2511,85 +2599,83 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
25112599 }
25122600 }
25132601
2514 if (self.base.options.image_base_override) |image_base| {
2515 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{image_base}));
2516 }
2602 try argv.append(try std.fmt.allocPrint(arena, "--image-base={d}", .{self.image_base}));
25172603
2518 if (self.base.options.linker_script) |linker_script| {
2604 if (self.linker_script) |linker_script| {
25192605 try argv.append("-T");
25202606 try argv.append(linker_script);
25212607 }
25222608
2523 if (self.base.options.sort_section) |how| {
2609 if (self.sort_section) |how| {
25242610 const arg = try std.fmt.allocPrint(arena, "--sort-section={s}", .{@tagName(how)});
25252611 try argv.append(arg);
25262612 }
25272613
2528 if (gc_sections) {
2614 if (self.base.gc_sections) {
25292615 try argv.append("--gc-sections");
25302616 }
25312617
2532 if (self.base.options.print_gc_sections) {
2618 if (self.base.print_gc_sections) {
25332619 try argv.append("--print-gc-sections");
25342620 }
25352621
2536 if (self.base.options.print_icf_sections) {
2622 if (self.print_icf_sections) {
25372623 try argv.append("--print-icf-sections");
25382624 }
25392625
2540 if (self.base.options.print_map) {
2626 if (self.print_map) {
25412627 try argv.append("--print-map");
25422628 }
25432629
2544 if (self.base.options.eh_frame_hdr) {
2630 if (comp.link_eh_frame_hdr) {
25452631 try argv.append("--eh-frame-hdr");
25462632 }
25472633
2548 if (self.base.options.emit_relocs) {
2634 if (self.emit_relocs) {
25492635 try argv.append("--emit-relocs");
25502636 }
25512637
2552 if (self.base.options.rdynamic) {
2638 if (comp.config.rdynamic) {
25532639 try argv.append("--export-dynamic");
25542640 }
25552641
2556 if (self.base.options.strip) {
2642 if (comp.config.debug_format == .strip) {
25572643 try argv.append("-s");
25582644 }
25592645
2560 if (self.base.options.z_nodelete) {
2646 if (self.z_nodelete) {
25612647 try argv.append("-z");
25622648 try argv.append("nodelete");
25632649 }
2564 if (self.base.options.z_notext) {
2650 if (self.z_notext) {
25652651 try argv.append("-z");
25662652 try argv.append("notext");
25672653 }
2568 if (self.base.options.z_defs) {
2654 if (self.z_defs) {
25692655 try argv.append("-z");
25702656 try argv.append("defs");
25712657 }
2572 if (self.base.options.z_origin) {
2658 if (self.z_origin) {
25732659 try argv.append("-z");
25742660 try argv.append("origin");
25752661 }
2576 if (self.base.options.z_nocopyreloc) {
2662 if (self.z_nocopyreloc) {
25772663 try argv.append("-z");
25782664 try argv.append("nocopyreloc");
25792665 }
2580 if (self.base.options.z_now) {
2666 if (self.z_now) {
25812667 // LLD defaults to -zlazy
25822668 try argv.append("-znow");
25832669 }
2584 if (!self.base.options.z_relro) {
2670 if (!self.z_relro) {
25852671 // LLD defaults to -zrelro
25862672 try argv.append("-znorelro");
25872673 }
2588 if (self.base.options.z_common_page_size) |size| {
2674 if (self.z_common_page_size) |size| {
25892675 try argv.append("-z");
25902676 try argv.append(try std.fmt.allocPrint(arena, "common-page-size={d}", .{size}));
25912677 }
2592 if (self.base.options.z_max_page_size) |size| {
2678 if (self.z_max_page_size) |size| {
25932679 try argv.append("-z");
25942680 try argv.append(try std.fmt.allocPrint(arena, "max-page-size={d}", .{size}));
25952681 }
......@@ -2604,7 +2690,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
26042690 try argv.append(arg);
26052691 }
26062692
2607 if (self.base.options.link_mode == .Static) {
2693 if (link_mode == .Static) {
26082694 if (target.cpu.arch.isArmOrThumb()) {
26092695 try argv.append("-Bstatic");
26102696 } else {
......@@ -2614,7 +2700,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
26142700 try argv.append("-shared");
26152701 }
26162702
2617 if (self.base.options.pie and self.base.options.output_mode == .Exe) {
2703 if (comp.config.pie and output_mode == .Exe) {
26182704 try argv.append("-pie");
26192705 }
26202706
......@@ -2631,29 +2717,29 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
26312717 try argv.append(full_out_path);
26322718
26332719 // csu prelude
2634 const csu = try CsuObjects.init(arena, self.base.options, comp);
2720 const csu = try CsuObjects.init(arena, comp);
26352721 if (csu.crt0) |v| try argv.append(v);
26362722 if (csu.crti) |v| try argv.append(v);
26372723 if (csu.crtbegin) |v| try argv.append(v);
26382724
26392725 // rpaths
2640 var rpath_table = std.StringHashMap(void).init(self.base.allocator);
2726 var rpath_table = std.StringHashMap(void).init(gpa);
26412727 defer rpath_table.deinit();
2642 for (self.base.options.rpath_list) |rpath| {
2728 for (self.base.rpath_list) |rpath| {
26432729 if ((try rpath_table.fetchPut(rpath, {})) == null) {
26442730 try argv.append("-rpath");
26452731 try argv.append(rpath);
26462732 }
26472733 }
26482734
2649 for (self.base.options.symbol_wrap_set.keys()) |symbol_name| {
2735 for (self.symbol_wrap_set.keys()) |symbol_name| {
26502736 try argv.appendSlice(&.{ "-wrap", symbol_name });
26512737 }
26522738
2653 if (self.base.options.each_lib_rpath) {
2739 if (self.each_lib_rpath) {
26542740 var test_path = std.ArrayList(u8).init(arena);
2655 for (self.base.options.lib_dirs) |lib_dir_path| {
2656 for (self.base.options.system_libs.keys()) |link_lib| {
2741 for (self.lib_dirs) |lib_dir_path| {
2742 for (comp.system_libs.keys()) |link_lib| {
26572743 if (!(try self.accessLibPath(&test_path, null, lib_dir_path, link_lib, .Dynamic)))
26582744 continue;
26592745 if ((try rpath_table.fetchPut(lib_dir_path, {})) == null) {
......@@ -2662,7 +2748,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
26622748 }
26632749 }
26642750 }
2665 for (self.base.options.objects) |obj| {
2751 for (comp.objects) |obj| {
26662752 if (Compilation.classifyFileExt(obj.path) == .shared_library) {
26672753 const lib_dir_path = std.fs.path.dirname(obj.path) orelse continue;
26682754 if (obj.loption) continue;
......@@ -2675,19 +2761,19 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
26752761 }
26762762 }
26772763
2678 for (self.base.options.lib_dirs) |lib_dir| {
2764 for (self.lib_dirs) |lib_dir| {
26792765 try argv.append("-L");
26802766 try argv.append(lib_dir);
26812767 }
26822768
2683 if (self.base.options.link_libc) {
2684 if (self.base.options.libc_installation) |libc_installation| {
2769 if (comp.config.link_libc) {
2770 if (comp.libc_installation) |libc_installation| {
26852771 try argv.append("-L");
26862772 try argv.append(libc_installation.crt_dir.?);
26872773 }
26882774
26892775 if (have_dynamic_linker) {
2690 if (self.base.options.dynamic_linker) |dynamic_linker| {
2776 if (target.dynamic_linker.get()) |dynamic_linker| {
26912777 try argv.append("-dynamic-linker");
26922778 try argv.append(dynamic_linker);
26932779 }
......@@ -2695,11 +2781,11 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
26952781 }
26962782
26972783 if (is_dyn_lib) {
2698 if (self.base.options.soname) |soname| {
2784 if (self.soname) |soname| {
26992785 try argv.append("-soname");
27002786 try argv.append(soname);
27012787 }
2702 if (self.base.options.version_script) |version_script| {
2788 if (self.version_script) |version_script| {
27032789 try argv.append("-version-script");
27042790 try argv.append(version_script);
27052791 }
......@@ -2707,7 +2793,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
27072793
27082794 // Positional arguments to the linker such as object files.
27092795 var whole_archive = false;
2710 for (self.base.options.objects) |obj| {
2796 for (comp.objects) |obj| {
27112797 if (obj.must_link and !whole_archive) {
27122798 try argv.append("-whole-archive");
27132799 whole_archive = true;
......@@ -2735,15 +2821,14 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
27352821 try argv.append(p);
27362822 }
27372823
2738 // TSAN
2739 if (self.base.options.tsan) {
2824 if (comp.config.any_sanitize_thread) {
27402825 try argv.append(comp.tsan_static_lib.?.full_object_path);
27412826 }
27422827
27432828 // libc
27442829 if (is_exe_or_dyn_lib and
2745 !self.base.options.skip_linker_dependencies and
2746 !self.base.options.link_libc)
2830 !comp.skip_linker_dependencies and
2831 !comp.config.link_libc)
27472832 {
27482833 if (comp.libc_static_lib) |lib| {
27492834 try argv.append(lib.full_object_path);
......@@ -2752,8 +2837,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
27522837
27532838 // Shared libraries.
27542839 if (is_exe_or_dyn_lib) {
2755 const system_libs = self.base.options.system_libs.keys();
2756 const system_libs_values = self.base.options.system_libs.values();
2840 const system_libs = comp.system_libs.keys();
2841 const system_libs_values = comp.system_libs.values();
27572842
27582843 // Worst-case, we need an --as-needed argument for every lib, as well
27592844 // as one before and one after.
......@@ -2788,21 +2873,21 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
27882873 }
27892874
27902875 // libc++ dep
2791 if (self.base.options.link_libcpp) {
2876 if (comp.config.link_libcpp) {
27922877 try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
27932878 try argv.append(comp.libcxx_static_lib.?.full_object_path);
27942879 }
27952880
27962881 // libunwind dep
2797 if (self.base.options.link_libunwind) {
2882 if (comp.config.link_libunwind) {
27982883 try argv.append(comp.libunwind_static_lib.?.full_object_path);
27992884 }
28002885
28012886 // libc dep
2802 self.error_flags.missing_libc = false;
2803 if (self.base.options.link_libc) {
2804 if (self.base.options.libc_installation != null) {
2805 const needs_grouping = self.base.options.link_mode == .Static;
2887 comp.link_error_flags.missing_libc = false;
2888 if (comp.config.link_libc) {
2889 if (comp.libc_installation != null) {
2890 const needs_grouping = link_mode == .Static;
28062891 if (needs_grouping) try argv.append("--start-group");
28072892 try argv.appendSlice(target_util.libcFullLinkFlags(target));
28082893 if (needs_grouping) try argv.append("--end-group");
......@@ -2815,12 +2900,12 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
28152900 }
28162901 try argv.append(try comp.get_libc_crt_file(arena, "libc_nonshared.a"));
28172902 } else if (target.isMusl()) {
2818 try argv.append(try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) {
2903 try argv.append(try comp.get_libc_crt_file(arena, switch (link_mode) {
28192904 .Static => "libc.a",
28202905 .Dynamic => "libc.so",
28212906 }));
28222907 } else {
2823 self.error_flags.missing_libc = true;
2908 comp.link_error_flags.missing_libc = true;
28242909 }
28252910 }
28262911 }
......@@ -2836,21 +2921,21 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
28362921 if (csu.crtend) |v| try argv.append(v);
28372922 if (csu.crtn) |v| try argv.append(v);
28382923
2839 if (allow_shlib_undefined) {
2924 if (self.base.allow_shlib_undefined) {
28402925 try argv.append("--allow-shlib-undefined");
28412926 }
28422927
2843 switch (self.base.options.compress_debug_sections) {
2928 switch (self.compress_debug_sections) {
28442929 .none => {},
28452930 .zlib => try argv.append("--compress-debug-sections=zlib"),
28462931 .zstd => try argv.append("--compress-debug-sections=zstd"),
28472932 }
28482933
2849 if (self.base.options.bind_global_refs_locally) {
2934 if (self.bind_global_refs_locally) {
28502935 try argv.append("-Bsymbolic");
28512936 }
28522937
2853 if (self.base.options.verbose_link) {
2938 if (comp.verbose_link) {
28542939 // Skip over our own name so that the LLD linker name is the first argv item.
28552940 Compilation.dump_argv(argv.items[1..]);
28562941 }
......@@ -2920,7 +3005,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
29203005 }
29213006 }
29223007
2923 if (!self.base.options.disable_lld_caching) {
3008 if (!self.base.disable_lld_caching) {
29243009 // Update the file with the digest. If it fails we can continue; it only
29253010 // means that the next invocation will have an unnecessary cache miss.
29263011 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
......@@ -2937,7 +3022,8 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v
29373022}
29383023
29393024fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64) void {
2940 const target_endian = self.base.options.target.cpu.arch.endian();
3025 const target = self.base.comp.root_mod.resolved_target.result;
3026 const target_endian = target.cpu.arch.endian();
29413027 switch (self.ptr_width) {
29423028 .p32 => mem.writeInt(u32, buf.addManyAsArrayAssumeCapacity(4), @as(u32, @intCast(addr)), target_endian),
29433029 .p64 => mem.writeInt(u64, buf.addManyAsArrayAssumeCapacity(8), addr, target_endian),
......@@ -2945,8 +3031,9 @@ fn writeDwarfAddrAssumeCapacity(self: *Elf, buf: *std.ArrayList(u8), addr: u64)
29453031}
29463032
29473033fn writeShdrTable(self: *Elf) !void {
2948 const gpa = self.base.allocator;
2949 const target_endian = self.base.options.target.cpu.arch.endian();
3034 const gpa = self.base.comp.gpa;
3035 const target = self.base.comp.root_mod.resolved_target.result;
3036 const target_endian = target.cpu.arch.endian();
29503037 const foreign_endian = target_endian != builtin.cpu.arch.endian();
29513038 const shsize: u64 = switch (self.ptr_width) {
29523039 .p32 => @sizeOf(elf.Elf32_Shdr),
......@@ -3001,8 +3088,9 @@ fn writeShdrTable(self: *Elf) !void {
30013088}
30023089
30033090fn writePhdrTable(self: *Elf) !void {
3004 const gpa = self.base.allocator;
3005 const target_endian = self.base.options.target.cpu.arch.endian();
3091 const gpa = self.base.comp.gpa;
3092 const target = self.base.comp.root_mod.resolved_target.result;
3093 const target_endian = target.cpu.arch.endian();
30063094 const foreign_endian = target_endian != builtin.cpu.arch.endian();
30073095 const phdr_table = &self.phdrs.items[self.phdr_table_index.?];
30083096
......@@ -3040,7 +3128,8 @@ fn writePhdrTable(self: *Elf) !void {
30403128}
30413129
30423130fn writeElfHeader(self: *Elf) !void {
3043 if (self.misc_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable
3131 const comp = self.base.comp;
3132 if (comp.link_errors.items.len > 0) return; // We had errors, so skip flushing to render the output unusable
30443133
30453134 var hdr_buf: [@sizeOf(elf.Elf64_Ehdr)]u8 = undefined;
30463135
......@@ -3054,7 +3143,8 @@ fn writeElfHeader(self: *Elf) !void {
30543143 };
30553144 index += 1;
30563145
3057 const endian = self.base.options.target.cpu.arch.endian();
3146 const target = comp.root_mod.resolved_target.result;
3147 const endian = target.cpu.arch.endian();
30583148 hdr_buf[index] = switch (endian) {
30593149 .little => elf.ELFDATA2LSB,
30603150 .big => elf.ELFDATA2MSB,
......@@ -3072,10 +3162,12 @@ fn writeElfHeader(self: *Elf) !void {
30723162
30733163 assert(index == 16);
30743164
3075 const elf_type: elf.ET = switch (self.base.options.output_mode) {
3076 .Exe => if (self.base.options.pie) .DYN else .EXEC,
3165 const output_mode = comp.config.output_mode;
3166 const link_mode = comp.config.link_mode;
3167 const elf_type: elf.ET = switch (output_mode) {
3168 .Exe => if (comp.config.pie) .DYN else .EXEC,
30773169 .Obj => .REL,
3078 .Lib => switch (self.base.options.link_mode) {
3170 .Lib => switch (link_mode) {
30793171 .Static => @as(elf.ET, .REL),
30803172 .Dynamic => .DYN,
30813173 },
......@@ -3083,7 +3175,7 @@ fn writeElfHeader(self: *Elf) !void {
30833175 mem.writeInt(u16, hdr_buf[index..][0..2], @intFromEnum(elf_type), endian);
30843176 index += 2;
30853177
3086 const machine = self.base.options.target.cpu.arch.toElfMachine();
3178 const machine = target.cpu.arch.toElfMachine();
30873179 mem.writeInt(u16, hdr_buf[index..][0..2], @intFromEnum(machine), endian);
30883180 index += 2;
30893181
......@@ -3201,7 +3293,6 @@ pub fn updateExports(
32013293 @panic("Attempted to compile for object format that was disabled by build configuration");
32023294 }
32033295 if (self.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
3204 if (self.base.options.emit == null) return;
32053296 return self.zigObjectPtr().?.updateExports(self, mod, exported, exports);
32063297}
32073298
......@@ -3220,6 +3311,9 @@ pub fn deleteDeclExport(
32203311}
32213312
32223313fn addLinkerDefinedSymbols(self: *Elf) !void {
3314 const comp = self.base.comp;
3315 const gpa = comp.gpa;
3316
32233317 const linker_defined_index = self.linker_defined_index orelse return;
32243318 const linker_defined = self.file(linker_defined_index).?.linker_defined;
32253319 self.dynamic_index = try linker_defined.addGlobal("_DYNAMIC", self);
......@@ -3234,7 +3328,7 @@ fn addLinkerDefinedSymbols(self: *Elf) !void {
32343328 self.plt_index = try linker_defined.addGlobal("_PROCEDURE_LINKAGE_TABLE_", self);
32353329 self.end_index = try linker_defined.addGlobal("_end", self);
32363330
3237 if (self.base.options.eh_frame_hdr) {
3331 if (comp.link_eh_frame_hdr) {
32383332 self.gnu_eh_frame_hdr_index = try linker_defined.addGlobal("__GNU_EH_FRAME_HDR", self);
32393333 }
32403334
......@@ -3248,7 +3342,6 @@ fn addLinkerDefinedSymbols(self: *Elf) !void {
32483342
32493343 for (self.shdrs.items) |shdr| {
32503344 if (self.getStartStopBasename(shdr)) |name| {
3251 const gpa = self.base.allocator;
32523345 try self.start_stop_indexes.ensureUnusedCapacity(gpa, 2);
32533346
32543347 const start = try std.fmt.allocPrintZ(gpa, "__start_{s}", .{name});
......@@ -3265,6 +3358,9 @@ fn addLinkerDefinedSymbols(self: *Elf) !void {
32653358}
32663359
32673360fn allocateLinkerDefinedSymbols(self: *Elf) void {
3361 const comp = self.base.comp;
3362 const link_mode = comp.config.link_mode;
3363
32683364 // _DYNAMIC
32693365 if (self.dynamic_section_index) |shndx| {
32703366 const shdr = &self.shdrs.items[shndx];
......@@ -3276,7 +3372,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
32763372 // __ehdr_start
32773373 {
32783374 const symbol_ptr = self.symbol(self.ehdr_start_index.?);
3279 symbol_ptr.value = self.calcImageBase();
3375 symbol_ptr.value = self.image_base;
32803376 symbol_ptr.output_section_index = 1;
32813377 }
32823378
......@@ -3347,7 +3443,7 @@ fn allocateLinkerDefinedSymbols(self: *Elf) void {
33473443
33483444 // __rela_iplt_start, __rela_iplt_end
33493445 if (self.rela_dyn_section_index) |shndx| blk: {
3350 if (self.base.options.link_mode != .Static or self.base.options.pie) break :blk;
3446 if (link_mode != .Static or comp.config.pie) break :blk;
33513447 const shdr = &self.shdrs.items[shndx];
33523448 const end_addr = shdr.sh_addr + shdr.sh_size;
33533449 const start_addr = end_addr - self.calcNumIRelativeRelocs() * @sizeOf(elf.Elf64_Rela);
......@@ -3394,6 +3490,8 @@ fn initOutputSections(self: *Elf) !void {
33943490}
33953491
33963492fn initSyntheticSections(self: *Elf) !void {
3493 const comp = self.base.comp;
3494 const target = comp.root_mod.resolved_target.result;
33973495 const ptr_size = self.ptrWidthBytes();
33983496
33993497 const needs_eh_frame = for (self.objects.items) |index| {
......@@ -3408,7 +3506,7 @@ fn initSyntheticSections(self: *Elf) !void {
34083506 .offset = std.math.maxInt(u64),
34093507 });
34103508
3411 if (self.base.options.eh_frame_hdr) {
3509 if (comp.link_eh_frame_hdr) {
34123510 self.eh_frame_hdr_section_index = try self.addSection(.{
34133511 .name = ".eh_frame_hdr",
34143512 .type = elf.SHT_PROGBITS,
......@@ -3502,8 +3600,8 @@ fn initSyntheticSections(self: *Elf) !void {
35023600 // In this case, if we do generate .interp section and segment, we will get
35033601 // a segfault in the dynamic linker trying to load a binary that is static
35043602 // and doesn't contain .dynamic section.
3505 if (self.isStatic() and !self.base.options.pie) break :blk false;
3506 break :blk self.base.options.dynamic_linker != null;
3603 if (self.base.isStatic() and !comp.config.pie) break :blk false;
3604 break :blk target.dynamic_linker.get() != null;
35073605 };
35083606 if (needs_interp) {
35093607 self.interp_section_index = try self.addSection(.{
......@@ -3515,7 +3613,7 @@ fn initSyntheticSections(self: *Elf) !void {
35153613 });
35163614 }
35173615
3518 if (self.isDynLib() or self.shared_objects.items.len > 0 or self.base.options.pie) {
3616 if (self.base.isDynLib() or self.shared_objects.items.len > 0 or comp.config.pie) {
35193617 self.dynstrtab_section_index = try self.addSection(.{
35203618 .name = ".dynstr",
35213619 .flags = elf.SHF_ALLOC,
......@@ -3613,7 +3711,7 @@ fn initSectionsObject(self: *Elf) !void {
36133711}
36143712
36153713fn initComdatGroups(self: *Elf) !void {
3616 const gpa = self.base.allocator;
3714 const gpa = self.base.comp.gpa;
36173715
36183716 for (self.objects.items) |index| {
36193717 const object = self.file(index).?.object;
......@@ -3700,7 +3798,7 @@ fn initSpecialPhdrs(self: *Elf) !void {
37003798 self.phdr_gnu_stack_index = try self.addPhdr(.{
37013799 .type = elf.PT_GNU_STACK,
37023800 .flags = elf.PF_W | elf.PF_R,
3703 .memsz = self.base.options.stack_size_override orelse 0,
3801 .memsz = self.base.stack_size,
37043802 .@"align" = 1,
37053803 });
37063804
......@@ -3732,7 +3830,7 @@ fn initSpecialPhdrs(self: *Elf) !void {
37323830/// Ties are broken by the file prority which corresponds to the inclusion of input sections in this output section
37333831/// we are about to sort.
37343832fn sortInitFini(self: *Elf) !void {
3735 const gpa = self.base.allocator;
3833 const gpa = self.base.comp.gpa;
37363834
37373835 const Entry = struct {
37383836 priority: i32,
......@@ -3806,8 +3904,8 @@ fn setDynamicSection(self: *Elf, rpaths: []const []const u8) !void {
38063904 try self.dynamic.addNeeded(shared_object, self);
38073905 }
38083906
3809 if (self.isDynLib()) {
3810 if (self.base.options.soname) |soname| {
3907 if (self.base.isDynLib()) {
3908 if (self.soname) |soname| {
38113909 try self.dynamic.setSoname(soname, self);
38123910 }
38133911 }
......@@ -3821,8 +3919,9 @@ fn sortDynamicSymtab(self: *Elf) void {
38213919}
38223920
38233921fn setVersionSymtab(self: *Elf) !void {
3922 const gpa = self.base.comp.gpa;
38243923 if (self.versym_section_index == null) return;
3825 try self.versym.resize(self.base.allocator, self.dynsym.count());
3924 try self.versym.resize(gpa, self.dynsym.count());
38263925 self.versym.items[0] = elf.VER_NDX_LOCAL;
38273926 for (self.dynsym.entries.items, 1..) |entry, i| {
38283927 const sym = self.symbol(entry.symbol_index);
......@@ -3872,7 +3971,7 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
38723971 }
38733972 };
38743973
3875 const gpa = self.base.allocator;
3974 const gpa = self.base.comp.gpa;
38763975 var entries = try std.ArrayList(Entry).initCapacity(gpa, self.phdrs.items.len);
38773976 defer entries.deinit();
38783977 for (0..self.phdrs.items.len) |phndx| {
......@@ -3977,7 +4076,7 @@ fn sortShdrs(self: *Elf) !void {
39774076 }
39784077 };
39794078
3980 const gpa = self.base.allocator;
4079 const gpa = self.base.comp.gpa;
39814080 var entries = try std.ArrayList(Entry).initCapacity(gpa, self.shdrs.items.len);
39824081 defer entries.deinit();
39834082 for (0..self.shdrs.items.len) |shndx| {
......@@ -4004,7 +4103,7 @@ fn sortShdrs(self: *Elf) !void {
40044103}
40054104
40064105fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void {
4007 const gpa = self.base.allocator;
4106 const gpa = self.base.comp.gpa;
40084107
40094108 for (&[_]*?u16{
40104109 &self.eh_frame_section_index,
......@@ -4187,6 +4286,7 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u16) !void {
41874286}
41884287
41894288fn updateSectionSizes(self: *Elf) !void {
4289 const target = self.base.comp.root_mod.resolved_target.result;
41904290 for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| {
41914291 const shdr = &self.shdrs.items[shndx];
41924292 for (atom_list.items) |atom_index| {
......@@ -4244,7 +4344,7 @@ fn updateSectionSizes(self: *Elf) !void {
42444344 }
42454345
42464346 if (self.interp_section_index) |index| {
4247 self.shdrs.items[index].sh_size = self.base.options.dynamic_linker.?.len + 1;
4347 self.shdrs.items[index].sh_size = target.dynamic_linker.get().?.len + 1;
42484348 }
42494349
42504350 if (self.hash_section_index) |index| {
......@@ -4453,7 +4553,7 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void {
44534553 // as we are more interested in quick turnaround and compatibility
44544554 // with `findFreeSpace` mechanics than anything else.
44554555 const Cover = std.ArrayList(u16);
4456 const gpa = self.base.allocator;
4556 const gpa = self.base.comp.gpa;
44574557 var covers: [max_number_of_object_segments]Cover = undefined;
44584558 for (&covers) |*cover| {
44594559 cover.* = Cover.init(gpa);
......@@ -4691,7 +4791,7 @@ fn allocateAtoms(self: *Elf) void {
46914791}
46924792
46934793fn writeAtoms(self: *Elf) !void {
4694 const gpa = self.base.allocator;
4794 const gpa = self.base.comp.gpa;
46954795
46964796 var undefs = std.AutoHashMap(Symbol.Index, std.ArrayList(Atom.Index)).init(gpa);
46974797 defer {
......@@ -4779,7 +4879,7 @@ fn writeAtoms(self: *Elf) !void {
47794879}
47804880
47814881fn writeAtomsObject(self: *Elf) !void {
4782 const gpa = self.base.allocator;
4882 const gpa = self.base.comp.gpa;
47834883
47844884 // TODO iterate over `output_sections` directly
47854885 for (self.shdrs.items, 0..) |shdr, shndx| {
......@@ -4852,7 +4952,7 @@ fn updateSymtabSize(self: *Elf) !void {
48524952 var nglobals: u32 = 0;
48534953 var strsize: u32 = 0;
48544954
4855 const gpa = self.base.allocator;
4955 const gpa = self.base.comp.gpa;
48564956 var files = std.ArrayList(File.Index).init(gpa);
48574957 defer files.deinit();
48584958 try files.ensureTotalCapacityPrecise(self.objects.items.len + self.shared_objects.items.len + 2);
......@@ -4935,17 +5035,18 @@ fn updateSymtabSize(self: *Elf) !void {
49355035}
49365036
49375037fn writeSyntheticSections(self: *Elf) !void {
4938 const gpa = self.base.allocator;
5038 const target = self.base.comp.root_mod.resolved_target.result;
5039 const gpa = self.base.comp.gpa;
49395040
49405041 if (self.interp_section_index) |shndx| {
5042 var buffer: [256]u8 = undefined;
5043 const interp = target.dynamic_linker.get().?;
5044 @memcpy(buffer[0..interp.len], interp);
5045 buffer[interp.len] = 0;
5046 const contents = buffer[0 .. interp.len + 1];
49415047 const shdr = self.shdrs.items[shndx];
4942 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
4943 var buffer = try gpa.alloc(u8, sh_size);
4944 defer gpa.free(buffer);
4945 const dylinker = self.base.options.dynamic_linker.?;
4946 @memcpy(buffer[0..dylinker.len], dylinker);
4947 buffer[dylinker.len] = 0;
4948 try self.base.file.?.pwriteAll(buffer, shdr.sh_offset);
5048 assert(shdr.sh_size == contents.len);
5049 try self.base.file.?.pwriteAll(contents, shdr.sh_offset);
49495050 }
49505051
49515052 if (self.hash_section_index) |shndx| {
......@@ -5065,7 +5166,7 @@ fn writeSyntheticSections(self: *Elf) !void {
50655166}
50665167
50675168fn writeSyntheticSectionsObject(self: *Elf) !void {
5068 const gpa = self.base.allocator;
5169 const gpa = self.base.comp.gpa;
50695170
50705171 for (self.output_rela_sections.values()) |sec| {
50715172 if (sec.atom_list.items.len == 0) continue;
......@@ -5135,7 +5236,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void {
51355236}
51365237
51375238fn writeComdatGroups(self: *Elf) !void {
5138 const gpa = self.base.allocator;
5239 const gpa = self.base.comp.gpa;
51395240 for (self.comdat_group_sections.items) |cgs| {
51405241 const shdr = self.shdrs.items[cgs.shndx];
51415242 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
......@@ -5160,7 +5261,8 @@ fn writeShStrtab(self: *Elf) !void {
51605261}
51615262
51625263fn writeSymtab(self: *Elf) !void {
5163 const gpa = self.base.allocator;
5264 const target = self.base.comp.root_mod.resolved_target.result;
5265 const gpa = self.base.comp.gpa;
51645266 const symtab_shdr = self.shdrs.items[self.symtab_section_index.?];
51655267 const strtab_shdr = self.shdrs.items[self.strtab_section_index.?];
51665268 const sym_size: u64 = switch (self.ptr_width) {
......@@ -5220,7 +5322,7 @@ fn writeSymtab(self: *Elf) !void {
52205322 self.plt_got.writeSymtab(self);
52215323 }
52225324
5223 const foreign_endian = self.base.options.target.cpu.arch.endian() != builtin.cpu.arch.endian();
5325 const foreign_endian = target.cpu.arch.endian() != builtin.cpu.arch.endian();
52245326 switch (self.ptr_width) {
52255327 .p32 => {
52265328 const buf = try gpa.alloc(elf.Elf32_Sym, self.symtab.items.len);
......@@ -5299,7 +5401,8 @@ fn ptrWidthBytes(self: Elf) u8 {
52995401/// Does not necessarily match `ptrWidthBytes` for example can be 2 bytes
53005402/// in a 32-bit ELF file.
53015403pub fn archPtrWidthBytes(self: Elf) u8 {
5302 return @as(u8, @intCast(@divExact(self.base.options.target.ptrBitWidth(), 8)));
5404 const target = self.base.comp.root_mod.resolved_target.result;
5405 return @intCast(@divExact(target.ptrBitWidth(), 8));
53035406}
53045407
53055408fn phdrTo32(phdr: elf.Elf64_Phdr) elf.Elf32_Phdr {
......@@ -5393,9 +5496,11 @@ const CsuObjects = struct {
53935496 crtend: ?[]const u8 = null,
53945497 crtn: ?[]const u8 = null,
53955498
5396 fn init(arena: mem.Allocator, link_options: link.Options, comp: *const Compilation) !CsuObjects {
5499 const InitArgs = struct {};
5500
5501 fn init(arena: Allocator, comp: *const Compilation) !CsuObjects {
53975502 // crt objects are only required for libc.
5398 if (!link_options.link_libc) return CsuObjects{};
5503 if (!comp.config.link_libc) return .{};
53995504
54005505 var result: CsuObjects = .{};
54015506
......@@ -5406,19 +5511,21 @@ const CsuObjects = struct {
54065511 dynamic_pie,
54075512 static_exe,
54085513 static_pie,
5409 } = switch (link_options.output_mode) {
5514 } = switch (comp.config.output_mode) {
54105515 .Obj => return CsuObjects{},
5411 .Lib => switch (link_options.link_mode) {
5516 .Lib => switch (comp.config.link_mode) {
54125517 .Dynamic => .dynamic_lib,
54135518 .Static => return CsuObjects{},
54145519 },
5415 .Exe => switch (link_options.link_mode) {
5416 .Dynamic => if (link_options.pie) .dynamic_pie else .dynamic_exe,
5417 .Static => if (link_options.pie) .static_pie else .static_exe,
5520 .Exe => switch (comp.config.link_mode) {
5521 .Dynamic => if (comp.config.pie) .dynamic_pie else .dynamic_exe,
5522 .Static => if (comp.config.pie) .static_pie else .static_exe,
54185523 },
54195524 };
54205525
5421 if (link_options.target.isAndroid()) {
5526 const target = comp.root_mod.resolved_target.result;
5527
5528 if (target.isAndroid()) {
54225529 switch (mode) {
54235530 // zig fmt: off
54245531 .dynamic_lib => result.set( null, null, "crtbegin_so.o", "crtend_so.o", null ),
......@@ -5429,7 +5536,7 @@ const CsuObjects = struct {
54295536 // zig fmt: on
54305537 }
54315538 } else {
5432 switch (link_options.target.os.tag) {
5539 switch (target.os.tag) {
54335540 .linux => {
54345541 switch (mode) {
54355542 // zig fmt: off
......@@ -5440,7 +5547,7 @@ const CsuObjects = struct {
54405547 .static_pie => result.set( "rcrt1.o", "crti.o", "crtbeginS.o", "crtendS.o", "crtn.o" ),
54415548 // zig fmt: on
54425549 }
5443 if (link_options.libc_installation) |_| {
5550 if (comp.libc_installation) |_| {
54445551 // hosted-glibc provides crtbegin/end objects in platform/compiler-specific dirs
54455552 // and they are not known at comptime. For now null-out crtbegin/end objects;
54465553 // there is no feature loss, zig has never linked those objects in before.
......@@ -5448,7 +5555,7 @@ const CsuObjects = struct {
54485555 result.crtend = null;
54495556 } else {
54505557 // Bundled glibc only has Scrt1.o .
5451 if (result.crt0 != null and link_options.target.isGnuLibC()) result.crt0 = "Scrt1.o";
5558 if (result.crt0 != null and target.isGnuLibC()) result.crt0 = "Scrt1.o";
54525559 }
54535560 },
54545561 .dragonfly => switch (mode) {
......@@ -5510,16 +5617,16 @@ const CsuObjects = struct {
55105617 }
55115618
55125619 // Convert each object to a full pathname.
5513 if (link_options.libc_installation) |lci| {
5620 if (comp.libc_installation) |lci| {
55145621 const crt_dir_path = lci.crt_dir orelse return error.LibCInstallationMissingCRTDir;
5515 switch (link_options.target.os.tag) {
5622 switch (target.os.tag) {
55165623 .dragonfly => {
55175624 if (result.crt0) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
55185625 if (result.crti) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
55195626 if (result.crtn) |*obj| obj.* = try fs.path.join(arena, &[_][]const u8{ crt_dir_path, obj.* });
55205627
55215628 var gccv: []const u8 = undefined;
5522 if (link_options.target.os.version_range.semver.isAtLeast(.{ .major = 5, .minor = 4, .patch = 0 }) orelse true) {
5629 if (target.os.version_range.semver.isAtLeast(.{ .major = 5, .minor = 4, .patch = 0 }) orelse true) {
55235630 gccv = "gcc80";
55245631 } else {
55255632 gccv = "gcc54";
......@@ -5576,39 +5683,6 @@ const CsuObjects = struct {
55765683 }
55775684};
55785685
5579pub fn calcImageBase(self: Elf) u64 {
5580 if (self.isDynLib()) return 0;
5581 if (self.isExe() and self.base.options.pie) return 0;
5582 return self.base.options.image_base_override orelse switch (self.ptr_width) {
5583 .p32 => 0x1000,
5584 .p64 => 0x1000000,
5585 };
5586}
5587
5588pub fn isStatic(self: Elf) bool {
5589 return self.base.options.link_mode == .Static;
5590}
5591
5592pub fn isObject(self: Elf) bool {
5593 return self.base.options.output_mode == .Obj;
5594}
5595
5596pub fn isExe(self: Elf) bool {
5597 return self.base.options.output_mode == .Exe;
5598}
5599
5600pub fn isStaticLib(self: Elf) bool {
5601 return self.base.options.output_mode == .Lib and self.isStatic();
5602}
5603
5604pub fn isRelocatable(self: Elf) bool {
5605 return self.isObject() or self.isStaticLib();
5606}
5607
5608pub fn isDynLib(self: Elf) bool {
5609 return self.base.options.output_mode == .Lib and !self.isStatic();
5610}
5611
56125686pub fn isZigSection(self: Elf, shndx: u16) bool {
56135687 inline for (&[_]?u16{
56145688 self.zig_text_section_index,
......@@ -5648,8 +5722,9 @@ fn addPhdr(self: *Elf, opts: struct {
56485722 filesz: u64 = 0,
56495723 memsz: u64 = 0,
56505724}) error{OutOfMemory}!u16 {
5725 const gpa = self.base.comp.gpa;
56515726 const index = @as(u16, @intCast(self.phdrs.items.len));
5652 try self.phdrs.append(self.base.allocator, .{
5727 try self.phdrs.append(gpa, .{
56535728 .p_type = opts.type,
56545729 .p_flags = opts.flags,
56555730 .p_offset = opts.offset,
......@@ -5694,7 +5769,7 @@ pub const AddSectionOpts = struct {
56945769};
56955770
56965771pub fn addSection(self: *Elf, opts: AddSectionOpts) !u16 {
5697 const gpa = self.base.allocator;
5772 const gpa = self.base.comp.gpa;
56985773 const index = @as(u16, @intCast(self.shdrs.items.len));
56995774 const shdr = try self.shdrs.addOne(gpa);
57005775 shdr.* = .{
......@@ -5798,8 +5873,9 @@ pub fn atom(self: *Elf, atom_index: Atom.Index) ?*Atom {
57985873}
57995874
58005875pub fn addAtom(self: *Elf) !Atom.Index {
5876 const gpa = self.base.comp.gpa;
58015877 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
5802 const atom_ptr = try self.atoms.addOne(self.base.allocator);
5878 const atom_ptr = try self.atoms.addOne(gpa);
58035879 atom_ptr.* = .{ .atom_index = index };
58045880 return index;
58055881}
......@@ -5821,14 +5897,15 @@ pub fn symbol(self: *Elf, sym_index: Symbol.Index) *Symbol {
58215897}
58225898
58235899pub fn addSymbol(self: *Elf) !Symbol.Index {
5824 try self.symbols.ensureUnusedCapacity(self.base.allocator, 1);
5900 const gpa = self.base.comp.gpa;
5901 try self.symbols.ensureUnusedCapacity(gpa, 1);
58255902 const index = blk: {
58265903 if (self.symbols_free_list.popOrNull()) |index| {
58275904 log.debug(" (reusing symbol index {d})", .{index});
58285905 break :blk index;
58295906 } else {
58305907 log.debug(" (allocating symbol index {d})", .{self.symbols.items.len});
5831 const index = @as(Symbol.Index, @intCast(self.symbols.items.len));
5908 const index: Symbol.Index = @intCast(self.symbols.items.len);
58325909 _ = self.symbols.addOneAssumeCapacity();
58335910 break :blk index;
58345911 }
......@@ -5838,8 +5915,9 @@ pub fn addSymbol(self: *Elf) !Symbol.Index {
58385915}
58395916
58405917pub fn addSymbolExtra(self: *Elf, extra: Symbol.Extra) !u32 {
5918 const gpa = self.base.comp.gpa;
58415919 const fields = @typeInfo(Symbol.Extra).Struct.fields;
5842 try self.symbols_extra.ensureUnusedCapacity(self.base.allocator, fields.len);
5920 try self.symbols_extra.ensureUnusedCapacity(gpa, fields.len);
58435921 return self.addSymbolExtraAssumeCapacity(extra);
58445922}
58455923
......@@ -5887,11 +5965,12 @@ const GetOrPutGlobalResult = struct {
58875965};
58885966
58895967pub fn getOrPutGlobal(self: *Elf, name: []const u8) !GetOrPutGlobalResult {
5890 const gpa = self.base.allocator;
5968 const gpa = self.base.comp.gpa;
58915969 const name_off = try self.strings.insert(gpa, name);
58925970 const gop = try self.resolver.getOrPut(gpa, name_off);
58935971 if (!gop.found_existing) {
58945972 const index = try self.addSymbol();
5973 log.debug("added symbol '{s}' at index {d}", .{ name, index });
58955974 const global = self.symbol(index);
58965975 global.name_offset = name_off;
58975976 global.flags.global = true;
......@@ -5923,11 +6002,11 @@ const GetOrCreateComdatGroupOwnerResult = struct {
59236002};
59246003
59256004pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateComdatGroupOwnerResult {
5926 const gpa = self.base.allocator;
6005 const gpa = self.base.comp.gpa;
59276006 const off = try self.strings.insert(gpa, name);
59286007 const gop = try self.comdat_groups_table.getOrPut(gpa, off);
59296008 if (!gop.found_existing) {
5930 const index = @as(ComdatGroupOwner.Index, @intCast(self.comdat_groups_owners.items.len));
6009 const index: ComdatGroupOwner.Index = @intCast(self.comdat_groups_owners.items.len);
59316010 const owner = try self.comdat_groups_owners.addOne(gpa);
59326011 owner.* = .{};
59336012 gop.value_ptr.* = index;
......@@ -5939,8 +6018,9 @@ pub fn getOrCreateComdatGroupOwner(self: *Elf, name: [:0]const u8) !GetOrCreateC
59396018}
59406019
59416020pub fn addComdatGroup(self: *Elf) !ComdatGroup.Index {
6021 const gpa = self.base.comp.gpa;
59426022 const index = @as(ComdatGroup.Index, @intCast(self.comdat_groups.items.len));
5943 _ = try self.comdat_groups.addOne(self.base.allocator);
6023 _ = try self.comdat_groups.addOne(gpa);
59446024 return index;
59456025}
59466026
......@@ -5971,7 +6051,7 @@ pub fn tlsAddress(self: *Elf) u64 {
59716051}
59726052
59736053const ErrorWithNotes = struct {
5974 /// Allocated index in misc_errors array.
6054 /// Allocated index in comp.link_errors array.
59756055 index: usize,
59766056
59776057 /// Next available note slot.
......@@ -5983,8 +6063,9 @@ const ErrorWithNotes = struct {
59836063 comptime format: []const u8,
59846064 args: anytype,
59856065 ) error{OutOfMemory}!void {
5986 const gpa = elf_file.base.allocator;
5987 const err_msg = &elf_file.misc_errors.items[err.index];
6066 const comp = elf_file.base.comp;
6067 const gpa = comp.gpa;
6068 const err_msg = &comp.link_errors.items[err.index];
59886069 err_msg.msg = try std.fmt.allocPrint(gpa, format, args);
59896070 }
59906071
......@@ -5994,8 +6075,9 @@ const ErrorWithNotes = struct {
59946075 comptime format: []const u8,
59956076 args: anytype,
59966077 ) error{OutOfMemory}!void {
5997 const gpa = elf_file.base.allocator;
5998 const err_msg = &elf_file.misc_errors.items[err.index];
6078 const comp = elf_file.base.comp;
6079 const gpa = comp.gpa;
6080 const err_msg = &comp.link_errors.items[err.index];
59996081 assert(err.note_slot < err_msg.notes.len);
60006082 err_msg.notes[err.note_slot] = .{ .msg = try std.fmt.allocPrint(gpa, format, args) };
60016083 err.note_slot += 1;
......@@ -6003,14 +6085,18 @@ const ErrorWithNotes = struct {
60036085};
60046086
60056087pub fn addErrorWithNotes(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
6006 try self.misc_errors.ensureUnusedCapacity(self.base.allocator, 1);
6088 const comp = self.base.comp;
6089 const gpa = comp.gpa;
6090 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
60076091 return self.addErrorWithNotesAssumeCapacity(note_count);
60086092}
60096093
60106094fn addErrorWithNotesAssumeCapacity(self: *Elf, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
6011 const index = self.misc_errors.items.len;
6012 const err = self.misc_errors.addOneAssumeCapacity();
6013 err.* = .{ .msg = undefined, .notes = try self.base.allocator.alloc(link.File.ErrorMsg, note_count) };
6095 const comp = self.base.comp;
6096 const gpa = comp.gpa;
6097 const index = comp.link_errors.items.len;
6098 const err = comp.link_errors.addOneAssumeCapacity();
6099 err.* = .{ .msg = undefined, .notes = try gpa.alloc(link.File.ErrorMsg, note_count) };
60146100 return .{ .index = index };
60156101}
60166102
......@@ -6020,9 +6106,10 @@ pub fn getShString(self: Elf, off: u32) [:0]const u8 {
60206106}
60216107
60226108pub fn insertShString(self: *Elf, name: [:0]const u8) error{OutOfMemory}!u32 {
6109 const gpa = self.base.comp.gpa;
60236110 const off = @as(u32, @intCast(self.shstrtab.items.len));
6024 try self.shstrtab.ensureUnusedCapacity(self.base.allocator, name.len + 1);
6025 self.shstrtab.writer(self.base.allocator).print("{s}\x00", .{name}) catch unreachable;
6111 try self.shstrtab.ensureUnusedCapacity(gpa, name.len + 1);
6112 self.shstrtab.writer(gpa).print("{s}\x00", .{name}) catch unreachable;
60266113 return off;
60276114}
60286115
......@@ -6032,17 +6119,19 @@ pub fn getDynString(self: Elf, off: u32) [:0]const u8 {
60326119}
60336120
60346121pub fn insertDynString(self: *Elf, name: []const u8) error{OutOfMemory}!u32 {
6122 const gpa = self.base.comp.gpa;
60356123 const off = @as(u32, @intCast(self.dynstrtab.items.len));
6036 try self.dynstrtab.ensureUnusedCapacity(self.base.allocator, name.len + 1);
6037 self.dynstrtab.writer(self.base.allocator).print("{s}\x00", .{name}) catch unreachable;
6124 try self.dynstrtab.ensureUnusedCapacity(gpa, name.len + 1);
6125 self.dynstrtab.writer(gpa).print("{s}\x00", .{name}) catch unreachable;
60386126 return off;
60396127}
60406128
60416129fn reportUndefinedSymbols(self: *Elf, undefs: anytype) !void {
6042 const gpa = self.base.allocator;
6130 const comp = self.base.comp;
6131 const gpa = comp.gpa;
60436132 const max_notes = 4;
60446133
6045 try self.misc_errors.ensureUnusedCapacity(gpa, undefs.count());
6134 try comp.link_errors.ensureUnusedCapacity(gpa, undefs.count());
60466135
60476136 var it = undefs.iterator();
60486137 while (it.next()) |entry| {
......@@ -6427,6 +6516,13 @@ const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
64276516pub const R_X86_64_ZIG_GOT32 = elf.R_X86_64_NUM + 1;
64286517pub const R_X86_64_ZIG_GOTPCREL = elf.R_X86_64_NUM + 2;
64296518
6519fn defaultEntrySymbolName(cpu_arch: std.Target.Cpu.Arch) []const u8 {
6520 return switch (cpu_arch) {
6521 .mips, .mipsel, .mips64, .mips64el => "__start",
6522 else => "_start",
6523 };
6524}
6525
64306526const std = @import("std");
64316527const build_options = @import("build_options");
64326528const builtin = @import("builtin");
src/link/Elf/Archive.zig+4-2
......@@ -20,7 +20,8 @@ pub fn deinit(self: *Archive, allocator: Allocator) void {
2020}
2121
2222pub fn parse(self: *Archive, elf_file: *Elf) !void {
23 const gpa = elf_file.base.allocator;
23 const comp = elf_file.base.comp;
24 const gpa = comp.gpa;
2425
2526 var stream = std.io.fixedBufferStream(self.data);
2627 const reader = stream.reader();
......@@ -150,7 +151,8 @@ pub const ArSymtab = struct {
150151 const hdr = setArHdr(.{ .name = .symtab, .size = @intCast(ar.size(.p64)) });
151152 try writer.writeAll(mem.asBytes(&hdr));
152153
153 const gpa = elf_file.base.allocator;
154 const comp = elf_file.base.comp;
155 const gpa = comp.gpa;
154156 var offsets = std.AutoHashMap(File.Index, u64).init(gpa);
155157 defer offsets.deinit();
156158 try offsets.ensureUnusedCapacity(@intCast(elf_file.objects.items.len + 1));
src/link/Elf/Atom.zig+21-14
......@@ -227,7 +227,8 @@ pub fn grow(self: *Atom, elf_file: *Elf) !void {
227227pub fn free(self: *Atom, elf_file: *Elf) void {
228228 log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) });
229229
230 const gpa = elf_file.base.allocator;
230 const comp = elf_file.base.comp;
231 const gpa = comp.gpa;
231232 const shndx = self.outputShndx().?;
232233 const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?;
233234 const free_list = &meta.free_list;
......@@ -352,7 +353,8 @@ pub fn markFdesDead(self: Atom, elf_file: *Elf) void {
352353}
353354
354355pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void {
355 const gpa = elf_file.base.allocator;
356 const comp = elf_file.base.comp;
357 const gpa = comp.gpa;
356358 const file_ptr = self.file(elf_file).?;
357359 assert(file_ptr == .zig_object);
358360 const zig_object = file_ptr.zig_object;
......@@ -375,8 +377,8 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool {
375377}
376378
377379pub fn scanRelocs(self: Atom, elf_file: *Elf, code: ?[]const u8, undefs: anytype) !void {
378 const is_static = elf_file.isStatic();
379 const is_dyn_lib = elf_file.isDynLib();
380 const is_static = elf_file.base.isStatic();
381 const is_dyn_lib = elf_file.base.isDynLib();
380382 const file_ptr = self.file(elf_file).?;
381383 const rels = self.relocs(elf_file);
382384 var i: usize = 0;
......@@ -543,7 +545,7 @@ fn scanReloc(
543545 try self.reportPicError(symbol, rel, elf_file),
544546
545547 .copyrel => {
546 if (elf_file.base.options.z_nocopyreloc) {
548 if (elf_file.z_nocopyreloc) {
547549 if (symbol.isAbs(elf_file))
548550 try self.reportNoPicError(symbol, rel, elf_file)
549551 else
......@@ -553,9 +555,9 @@ fn scanReloc(
553555 },
554556
555557 .dyn_copyrel => {
556 if (is_writeable or elf_file.base.options.z_nocopyreloc) {
558 if (is_writeable or elf_file.z_nocopyreloc) {
557559 if (!is_writeable) {
558 if (elf_file.base.options.z_notext) {
560 if (elf_file.z_notext) {
559561 elf_file.has_text_reloc = true;
560562 } else {
561563 try self.reportTextRelocError(symbol, rel, elf_file);
......@@ -587,7 +589,7 @@ fn scanReloc(
587589
588590 .dynrel, .baserel, .ifunc => {
589591 if (!is_writeable) {
590 if (elf_file.base.options.z_notext) {
592 if (elf_file.z_notext) {
591593 elf_file.has_text_reloc = true;
592594 } else {
593595 try self.reportTextRelocError(symbol, rel, elf_file);
......@@ -657,11 +659,12 @@ fn dynAbsRelocAction(symbol: *const Symbol, elf_file: *Elf) RelocAction {
657659}
658660
659661fn outputType(elf_file: *Elf) u2 {
660 assert(!elf_file.isRelocatable());
661 return switch (elf_file.base.options.output_mode) {
662 const comp = elf_file.base.comp;
663 assert(!elf_file.base.isRelocatable());
664 return switch (elf_file.base.comp.config.output_mode) {
662665 .Obj => unreachable,
663666 .Lib => 0,
664 .Exe => if (elf_file.base.options.pie) 1 else 2,
667 .Exe => if (comp.config.pie) 1 else 2,
665668 };
666669}
667670
......@@ -746,6 +749,8 @@ fn reportUndefined(
746749 rel: elf.Elf64_Rela,
747750 undefs: anytype,
748751) !void {
752 const comp = elf_file.base.comp;
753 const gpa = comp.gpa;
749754 const rel_esym = switch (self.file(elf_file).?) {
750755 .zig_object => |x| x.elfSym(rel.r_sym()).*,
751756 .object => |x| x.symtab.items[rel.r_sym()],
......@@ -760,7 +765,7 @@ fn reportUndefined(
760765 {
761766 const gop = try undefs.getOrPut(sym_index);
762767 if (!gop.found_existing) {
763 gop.value_ptr.* = std.ArrayList(Atom.Index).init(elf_file.base.allocator);
768 gop.value_ptr.* = std.ArrayList(Atom.Index).init(gpa);
764769 }
765770 try gop.value_ptr.append(self.atom_index);
766771 }
......@@ -956,6 +961,8 @@ fn resolveDynAbsReloc(
956961 elf_file: *Elf,
957962 writer: anytype,
958963) !void {
964 const comp = elf_file.base.comp;
965 const gpa = comp.gpa;
959966 const P = self.value + rel.r_offset;
960967 const A = rel.r_addend;
961968 const S = @as(i64, @intCast(target.address(.{}, elf_file)));
......@@ -966,7 +973,7 @@ fn resolveDynAbsReloc(
966973 .shared_object => unreachable,
967974 inline else => |x| x.num_dynrelocs,
968975 };
969 try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, num_dynrelocs);
976 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, num_dynrelocs);
970977
971978 switch (action) {
972979 .@"error",
......@@ -979,7 +986,7 @@ fn resolveDynAbsReloc(
979986 => try writer.writeInt(i32, @as(i32, @truncate(S + A)), .little),
980987
981988 .dyn_copyrel => {
982 if (is_writeable or elf_file.base.options.z_nocopyreloc) {
989 if (is_writeable or elf_file.z_nocopyreloc) {
983990 elf_file.addRelaDynAssumeCapacity(.{
984991 .offset = P,
985992 .sym = target.extra(elf_file).?.dynamic,
src/link/Elf/LdScript.zig+2-1
......@@ -14,7 +14,8 @@ pub const Error = error{
1414};
1515
1616pub fn parse(scr: *LdScript, data: []const u8, elf_file: *Elf) Error!void {
17 const gpa = elf_file.base.allocator;
17 const comp = elf_file.base.comp;
18 const gpa = comp.gpa;
1819 var tokenizer = Tokenizer{ .source = data };
1920 var tokens = std.ArrayList(Token).init(gpa);
2021 defer tokens.deinit();
src/link/Elf/LinkerDefined.zig+2-1
......@@ -12,7 +12,8 @@ pub fn deinit(self: *LinkerDefined, allocator: Allocator) void {
1212}
1313
1414pub fn addGlobal(self: *LinkerDefined, name: [:0]const u8, elf_file: *Elf) !u32 {
15 const gpa = elf_file.base.allocator;
15 const comp = elf_file.base.comp;
16 const gpa = comp.gpa;
1617 try self.symtab.ensureUnusedCapacity(gpa, 1);
1718 try self.symbols.ensureUnusedCapacity(gpa, 1);
1819 const name_off = @as(u32, @intCast(self.strtab.items.len));
src/link/Elf/Object.zig+29-16
......@@ -54,7 +54,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
5454
5555 self.header = try reader.readStruct(elf.Elf64_Ehdr);
5656
57 if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
57 const target = elf_file.base.comp.root_mod.resolved_target.result;
58 if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
5859 try elf_file.reportParseError2(
5960 self.index,
6061 "invalid cpu architecture: {s}",
......@@ -65,7 +66,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
6566
6667 if (self.header.?.e_shnum == 0) return;
6768
68 const gpa = elf_file.base.allocator;
69 const comp = elf_file.base.comp;
70 const gpa = comp.gpa;
6971
7072 if (self.data.len < self.header.?.e_shoff or
7173 self.data.len < self.header.?.e_shoff + @as(u64, @intCast(self.header.?.e_shnum)) * @sizeOf(elf.Elf64_Shdr))
......@@ -148,8 +150,10 @@ pub fn init(self: *Object, elf_file: *Elf) !void {
148150}
149151
150152fn initAtoms(self: *Object, elf_file: *Elf) !void {
153 const comp = elf_file.base.comp;
154 const gpa = comp.gpa;
151155 const shdrs = self.shdrs.items;
152 try self.atoms.resize(elf_file.base.allocator, shdrs.len);
156 try self.atoms.resize(gpa, shdrs.len);
153157 @memset(self.atoms.items, 0);
154158
155159 for (shdrs, 0..) |shdr, i| {
......@@ -184,7 +188,6 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void {
184188 continue;
185189 }
186190
187 const gpa = elf_file.base.allocator;
188191 const gop = try elf_file.getOrCreateComdatGroupOwner(group_signature);
189192 const comdat_group_index = try elf_file.addComdatGroup();
190193 const comdat_group = elf_file.comdatGroup(comdat_group_index);
......@@ -247,7 +250,7 @@ fn addAtom(self: *Object, shdr: ElfShdr, shndx: u16, elf_file: *Elf) error{OutOf
247250fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMemory}!u16 {
248251 const name = blk: {
249252 const name = self.getString(shdr.sh_name);
250 if (elf_file.isRelocatable()) break :blk name;
253 if (elf_file.base.isRelocatable()) break :blk name;
251254 if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name;
252255 const sh_name_prefixes: []const [:0]const u8 = &.{
253256 ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss",
......@@ -275,7 +278,7 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMem
275278 };
276279 const flags = blk: {
277280 var flags = shdr.sh_flags;
278 if (!elf_file.isRelocatable()) {
281 if (!elf_file.base.isRelocatable()) {
279282 flags &= ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN);
280283 }
281284 break :blk switch (@"type") {
......@@ -292,13 +295,14 @@ fn initOutputSection(self: Object, elf_file: *Elf, shdr: ElfShdr) error{OutOfMem
292295}
293296
294297fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool {
298 const comp = elf_file.base.comp;
295299 const shdr = self.shdrs.items[index];
296300 const name = self.getString(shdr.sh_name);
297301 const ignore = blk: {
298302 if (mem.startsWith(u8, name, ".note")) break :blk true;
299303 if (mem.startsWith(u8, name, ".comment")) break :blk true;
300304 if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true;
301 if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and
305 if (comp.config.debug_format == .strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and
302306 mem.startsWith(u8, name, ".debug")) break :blk true;
303307 break :blk false;
304308 };
......@@ -306,7 +310,8 @@ fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool {
306310}
307311
308312fn initSymtab(self: *Object, elf_file: *Elf) !void {
309 const gpa = elf_file.base.allocator;
313 const comp = elf_file.base.comp;
314 const gpa = comp.gpa;
310315 const first_global = self.first_global orelse self.symtab.items.len;
311316
312317 try self.symbols.ensureTotalCapacityPrecise(gpa, self.symtab.items.len);
......@@ -338,7 +343,8 @@ fn parseEhFrame(self: *Object, shndx: u16, elf_file: *Elf) !void {
338343 return;
339344 };
340345
341 const gpa = elf_file.base.allocator;
346 const comp = elf_file.base.comp;
347 const gpa = comp.gpa;
342348 const raw = self.shdrContents(shndx);
343349 const relocs = self.getRelocs(relocs_shndx);
344350 const fdes_start = self.fdes.items.len;
......@@ -438,6 +444,8 @@ fn filterRelocs(
438444}
439445
440446pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
447 const comp = elf_file.base.comp;
448 const gpa = comp.gpa;
441449 for (self.atoms.items) |atom_index| {
442450 const atom = elf_file.atom(atom_index) orelse continue;
443451 if (!atom.flags.alive) continue;
......@@ -448,7 +456,7 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void {
448456 // TODO ideally, we don't have to decompress at this stage (should already be done)
449457 // and we just fetch the code slice.
450458 const code = try self.codeDecompressAlloc(elf_file, atom_index);
451 defer elf_file.base.allocator.free(code);
459 defer gpa.free(code);
452460 try atom.scanRelocs(elf_file, code, undefs);
453461 } else try atom.scanRelocs(elf_file, null, undefs);
454462 }
......@@ -512,7 +520,7 @@ pub fn claimUnresolved(self: *Object, elf_file: *Elf) void {
512520 }
513521
514522 const is_import = blk: {
515 if (!elf_file.isDynLib()) break :blk false;
523 if (!elf_file.base.isDynLib()) break :blk false;
516524 const vis = @as(elf.STV, @enumFromInt(esym.st_other));
517525 if (vis == .HIDDEN) break :blk false;
518526 break :blk true;
......@@ -621,7 +629,8 @@ pub fn convertCommonSymbols(self: *Object, elf_file: *Elf) !void {
621629 continue;
622630 }
623631
624 const gpa = elf_file.base.allocator;
632 const comp = elf_file.base.comp;
633 const gpa = comp.gpa;
625634
626635 const atom_index = try elf_file.addAtom();
627636 try self.atoms.append(gpa, atom_index);
......@@ -680,7 +689,8 @@ pub fn addAtomsToOutputSections(self: *Object, elf_file: *Elf) !void {
680689 const shdr = atom.inputShdr(elf_file);
681690 atom.output_section_index = self.initOutputSection(elf_file, shdr) catch unreachable;
682691
683 const gpa = elf_file.base.allocator;
692 const comp = elf_file.base.comp;
693 const gpa = comp.gpa;
684694 const gop = try elf_file.output_sections.getOrPut(gpa, atom.output_section_index);
685695 if (!gop.found_existing) gop.value_ptr.* = .{};
686696 try gop.value_ptr.append(gpa, atom_index);
......@@ -740,7 +750,8 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void {
740750 shdr.sh_info = atom.outputShndx().?;
741751 shdr.sh_link = elf_file.symtab_section_index.?;
742752
743 const gpa = elf_file.base.allocator;
753 const comp = elf_file.base.comp;
754 const gpa = comp.gpa;
744755 const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom.outputShndx().?);
745756 if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx };
746757 try gop.value_ptr.atom_list.append(gpa, atom_index);
......@@ -748,7 +759,8 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void {
748759}
749760
750761pub fn updateArSymtab(self: Object, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) !void {
751 const gpa = elf_file.base.allocator;
762 const comp = elf_file.base.comp;
763 const gpa = comp.gpa;
752764 const start = self.first_global orelse self.symtab.items.len;
753765
754766 try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.symtab.items.len - start);
......@@ -855,7 +867,8 @@ pub fn shdrContents(self: Object, index: u32) []const u8 {
855867/// Returns atom's code and optionally uncompresses data if required (for compressed sections).
856868/// Caller owns the memory.
857869pub fn codeDecompressAlloc(self: Object, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
858 const gpa = elf_file.base.allocator;
870 const comp = elf_file.base.comp;
871 const gpa = comp.gpa;
859872 const atom_ptr = elf_file.atom(atom_index).?;
860873 assert(atom_ptr.file_index == self.index);
861874 const data = self.shdrContents(atom_ptr.input_section_index);
src/link/Elf/SharedObject.zig+10-5
......@@ -47,13 +47,15 @@ pub fn deinit(self: *SharedObject, allocator: Allocator) void {
4747}
4848
4949pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
50 const gpa = elf_file.base.allocator;
50 const comp = elf_file.base.comp;
51 const gpa = comp.gpa;
5152 var stream = std.io.fixedBufferStream(self.data);
5253 const reader = stream.reader();
5354
5455 self.header = try reader.readStruct(elf.Elf64_Ehdr);
5556
56 if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
57 const target = elf_file.base.comp.root_mod.resolved_target.result;
58 if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
5759 try elf_file.reportParseError2(
5860 self.index,
5961 "invalid cpu architecture: {s}",
......@@ -100,7 +102,8 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
100102}
101103
102104fn parseVersions(self: *SharedObject, elf_file: *Elf) !void {
103 const gpa = elf_file.base.allocator;
105 const comp = elf_file.base.comp;
106 const gpa = comp.gpa;
104107 const symtab = self.getSymtabRaw();
105108
106109 try self.verstrings.resize(gpa, 2);
......@@ -145,7 +148,8 @@ fn parseVersions(self: *SharedObject, elf_file: *Elf) !void {
145148}
146149
147150pub fn init(self: *SharedObject, elf_file: *Elf) !void {
148 const gpa = elf_file.base.allocator;
151 const comp = elf_file.base.comp;
152 const gpa = comp.gpa;
149153 const symtab = self.getSymtabRaw();
150154 const strtab = self.getStrtabRaw();
151155
......@@ -294,7 +298,8 @@ pub fn initSymbolAliases(self: *SharedObject, elf_file: *Elf) !void {
294298 }
295299 };
296300
297 const gpa = elf_file.base.allocator;
301 const comp = elf_file.base.comp;
302 const gpa = comp.gpa;
298303 var aliases = std.ArrayList(Symbol.Index).init(gpa);
299304 defer aliases.deinit();
300305 try aliases.ensureTotalCapacityPrecise(self.globals().len);
src/link/Elf/Symbol.zig+3-3
......@@ -43,7 +43,7 @@ pub fn outputShndx(symbol: Symbol) ?u16 {
4343}
4444
4545pub fn isLocal(symbol: Symbol, elf_file: *Elf) bool {
46 if (elf_file.isRelocatable()) return symbol.elfSym(elf_file).st_bind() == elf.STB_LOCAL;
46 if (elf_file.base.isRelocatable()) return symbol.elfSym(elf_file).st_bind() == elf.STB_LOCAL;
4747 return !(symbol.flags.import or symbol.flags.@"export");
4848}
4949
......@@ -186,7 +186,7 @@ const GetOrCreateZigGotEntryResult = struct {
186186};
187187
188188pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult {
189 assert(!elf_file.isRelocatable());
189 assert(!elf_file.base.isRelocatable());
190190 assert(symbol.flags.needs_zig_got);
191191 if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).?.zig_got };
192192 const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file);
......@@ -237,7 +237,7 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
237237 const st_shndx = blk: {
238238 if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?;
239239 if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF;
240 if (elf_file.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
240 if (elf_file.base.isRelocatable() and esym.st_shndx == elf.SHN_COMMON) break :blk elf.SHN_COMMON;
241241 if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) break :blk elf.SHN_ABS;
242242 break :blk symbol.outputShndx() orelse elf.SHN_UNDEF;
243243 };
src/link/Elf/ZigObject.zig+68-51
......@@ -4,6 +4,7 @@
44//! Think about this as fake in-memory Object file for the Zig module.
55
66data: std.ArrayListUnmanaged(u8) = .{},
7/// Externally owned memory.
78path: []const u8,
89index: File.Index,
910
......@@ -76,7 +77,8 @@ pub const symbol_mask: u32 = 0x7fffffff;
7677pub const SHN_ATOM: u16 = 0x100;
7778
7879pub fn init(self: *ZigObject, elf_file: *Elf) !void {
79 const gpa = elf_file.base.allocator;
80 const comp = elf_file.base.comp;
81 const gpa = comp.gpa;
8082
8183 try self.atoms.append(gpa, 0); // null input section
8284 try self.relocs.append(gpa, .{}); // null relocs section
......@@ -96,14 +98,18 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void {
9698 esym.st_shndx = elf.SHN_ABS;
9799 symbol_ptr.esym_index = esym_index;
98100
99 if (!elf_file.base.options.strip) {
100 self.dwarf = Dwarf.init(gpa, &elf_file.base, .dwarf32);
101 switch (comp.config.debug_format) {
102 .strip => {},
103 .dwarf => |v| {
104 assert(v == .@"32");
105 self.dwarf = Dwarf.init(&elf_file.base, .dwarf32);
106 },
107 .code_view => unreachable,
101108 }
102109}
103110
104111pub fn deinit(self: *ZigObject, allocator: Allocator) void {
105112 self.data.deinit(allocator);
106 allocator.free(self.path);
107113 self.local_esyms.deinit(allocator);
108114 self.global_esyms.deinit(allocator);
109115 self.strtab.deinit(allocator);
......@@ -155,13 +161,13 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
155161pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
156162 // Handle any lazy symbols that were emitted by incremental compilation.
157163 if (self.lazy_syms.getPtr(.none)) |metadata| {
158 const module = elf_file.base.options.module.?;
164 const zcu = elf_file.base.comp.module.?;
159165
160166 // Most lazy symbols can be updated on first use, but
161167 // anyerror needs to wait for everything to be flushed.
162168 if (metadata.text_state != .unused) self.updateLazySymbol(
163169 elf_file,
164 link.File.LazySymbol.initDecl(.code, null, module),
170 link.File.LazySymbol.initDecl(.code, null, zcu),
165171 metadata.text_symbol_index,
166172 ) catch |err| return switch (err) {
167173 error.CodegenFail => error.FlushFailure,
......@@ -169,7 +175,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
169175 };
170176 if (metadata.rodata_state != .unused) self.updateLazySymbol(
171177 elf_file,
172 link.File.LazySymbol.initDecl(.const_data, null, module),
178 link.File.LazySymbol.initDecl(.const_data, null, zcu),
173179 metadata.rodata_symbol_index,
174180 ) catch |err| return switch (err) {
175181 error.CodegenFail => error.FlushFailure,
......@@ -182,7 +188,8 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
182188 }
183189
184190 if (self.dwarf) |*dw| {
185 try dw.flushModule(elf_file.base.options.module.?);
191 const zcu = elf_file.base.comp.module.?;
192 try dw.flushModule(zcu);
186193
187194 // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections
188195 // extracted from input object files correctly.
......@@ -195,7 +202,7 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf) !void {
195202 const text_shdr = elf_file.shdrs.items[elf_file.zig_text_section_index.?];
196203 const low_pc = text_shdr.sh_addr;
197204 const high_pc = text_shdr.sh_addr + text_shdr.sh_size;
198 try dw.writeDbgInfoHeader(elf_file.base.options.module.?, low_pc, high_pc);
205 try dw.writeDbgInfoHeader(zcu, low_pc, high_pc);
199206 self.debug_info_header_dirty = false;
200207 }
201208
......@@ -268,7 +275,7 @@ pub fn addGlobalEsym(self: *ZigObject, allocator: Allocator) !Symbol.Index {
268275}
269276
270277pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index {
271 const gpa = elf_file.base.allocator;
278 const gpa = elf_file.base.comp.gpa;
272279 const atom_index = try elf_file.addAtom();
273280 const symbol_index = try elf_file.addSymbol();
274281 const esym_index = try self.addLocalEsym(gpa);
......@@ -363,7 +370,7 @@ pub fn claimUnresolved(self: ZigObject, elf_file: *Elf) void {
363370 }
364371
365372 const is_import = blk: {
366 if (!elf_file.isDynLib()) break :blk false;
373 if (!elf_file.base.isDynLib()) break :blk false;
367374 const vis = @as(elf.STV, @enumFromInt(esym.st_other));
368375 if (vis == .HIDDEN) break :blk false;
369376 break :blk true;
......@@ -411,6 +418,7 @@ pub fn allocateTlvAtoms(self: ZigObject, elf_file: *Elf) void {
411418}
412419
413420pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
421 const gpa = elf_file.base.comp.gpa;
414422 for (self.atoms.items) |atom_index| {
415423 const atom = elf_file.atom(atom_index) orelse continue;
416424 if (!atom.flags.alive) continue;
......@@ -421,7 +429,7 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void {
421429 // Perhaps it would make sense to save the code until flushModule where we
422430 // would free all of generated code?
423431 const code = try self.codeAlloc(elf_file, atom_index);
424 defer elf_file.base.allocator.free(code);
432 defer gpa.free(code);
425433 try atom.scanRelocs(elf_file, code, undefs);
426434 } else try atom.scanRelocs(elf_file, null, undefs);
427435 }
......@@ -447,7 +455,7 @@ pub fn markLive(self: *ZigObject, elf_file: *Elf) void {
447455/// We need this so that we can write to an archive.
448456/// TODO implement writing ZigObject data directly to a buffer instead.
449457pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {
450 const gpa = elf_file.base.allocator;
458 const gpa = elf_file.base.comp.gpa;
451459 const shsize: u64 = switch (elf_file.ptr_width) {
452460 .p32 => @sizeOf(elf.Elf32_Shdr),
453461 .p64 => @sizeOf(elf.Elf64_Shdr),
......@@ -465,7 +473,7 @@ pub fn readFileContents(self: *ZigObject, elf_file: *Elf) !void {
465473}
466474
467475pub fn updateArSymtab(self: ZigObject, ar_symtab: *Archive.ArSymtab, elf_file: *Elf) error{OutOfMemory}!void {
468 const gpa = elf_file.base.allocator;
476 const gpa = elf_file.base.comp.gpa;
469477
470478 try ar_symtab.symtab.ensureUnusedCapacity(gpa, self.globals().len);
471479
......@@ -508,7 +516,7 @@ pub fn addAtomsToRelaSections(self: ZigObject, elf_file: *Elf) !void {
508516 const out_shdr = elf_file.shdrs.items[out_shndx];
509517 if (out_shdr.sh_type == elf.SHT_NOBITS) continue;
510518
511 const gpa = elf_file.base.allocator;
519 const gpa = elf_file.base.comp.gpa;
512520 const sec = elf_file.output_rela_sections.getPtr(out_shndx).?;
513521 try sec.atom_list.append(gpa, atom_index);
514522 }
......@@ -602,7 +610,7 @@ pub fn asFile(self: *ZigObject) File {
602610/// Returns atom's code.
603611/// Caller owns the memory.
604612pub fn codeAlloc(self: ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 {
605 const gpa = elf_file.base.allocator;
613 const gpa = elf_file.base.comp.gpa;
606614 const atom = elf_file.atom(atom_index).?;
607615 assert(atom.file_index == self.index);
608616 const shdr = &elf_file.shdrs.items[atom.outputShndx().?];
......@@ -668,8 +676,8 @@ pub fn lowerAnonDecl(
668676 explicit_alignment: InternPool.Alignment,
669677 src_loc: Module.SrcLoc,
670678) !codegen.Result {
671 const gpa = elf_file.base.allocator;
672 const mod = elf_file.base.options.module.?;
679 const gpa = elf_file.base.comp.gpa;
680 const mod = elf_file.base.comp.module.?;
673681 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
674682 const decl_alignment = switch (explicit_alignment) {
675683 .none => ty.abiAlignment(mod),
......@@ -716,8 +724,8 @@ pub fn getOrCreateMetadataForLazySymbol(
716724 elf_file: *Elf,
717725 lazy_sym: link.File.LazySymbol,
718726) !Symbol.Index {
719 const gpa = elf_file.base.allocator;
720 const mod = elf_file.base.options.module.?;
727 const gpa = elf_file.base.comp.gpa;
728 const mod = elf_file.base.comp.module.?;
721729 const gop = try self.lazy_syms.getOrPut(gpa, lazy_sym.getDecl(mod));
722730 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
723731 if (!gop.found_existing) gop.value_ptr.* = .{};
......@@ -752,25 +760,28 @@ pub fn getOrCreateMetadataForLazySymbol(
752760}
753761
754762fn freeUnnamedConsts(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void {
763 const gpa = elf_file.base.comp.gpa;
755764 const unnamed_consts = self.unnamed_consts.getPtr(decl_index) orelse return;
756765 for (unnamed_consts.items) |sym_index| {
757766 self.freeDeclMetadata(elf_file, sym_index);
758767 }
759 unnamed_consts.clearAndFree(elf_file.base.allocator);
768 unnamed_consts.clearAndFree(gpa);
760769}
761770
762771fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) void {
763772 _ = self;
773 const gpa = elf_file.base.comp.gpa;
764774 const sym = elf_file.symbol(sym_index);
765775 sym.atom(elf_file).?.free(elf_file);
766776 log.debug("adding %{d} to local symbols free list", .{sym_index});
767 elf_file.symbols_free_list.append(elf_file.base.allocator, sym_index) catch {};
777 elf_file.symbols_free_list.append(gpa, sym_index) catch {};
768778 elf_file.symbols.items[sym_index] = .{};
769779 // TODO free GOT entry here
770780}
771781
772782pub fn freeDecl(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void {
773 const mod = elf_file.base.options.module.?;
783 const gpa = elf_file.base.comp.gpa;
784 const mod = elf_file.base.comp.module.?;
774785 const decl = mod.declPtr(decl_index);
775786
776787 log.debug("freeDecl {*}", .{decl});
......@@ -780,7 +791,7 @@ pub fn freeDecl(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclInd
780791 const sym_index = kv.value.symbol_index;
781792 self.freeDeclMetadata(elf_file, sym_index);
782793 self.freeUnnamedConsts(elf_file, decl_index);
783 kv.value.exports.deinit(elf_file.base.allocator);
794 kv.value.exports.deinit(gpa);
784795 }
785796
786797 if (self.dwarf) |*dw| {
......@@ -793,15 +804,16 @@ pub fn getOrCreateMetadataForDecl(
793804 elf_file: *Elf,
794805 decl_index: InternPool.DeclIndex,
795806) !Symbol.Index {
796 const gop = try self.decls.getOrPut(elf_file.base.allocator, decl_index);
807 const gpa = elf_file.base.comp.gpa;
808 const gop = try self.decls.getOrPut(gpa, decl_index);
797809 if (!gop.found_existing) {
798 const single_threaded = elf_file.base.options.single_threaded;
810 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
799811 const symbol_index = try self.addAtom(elf_file);
800 const mod = elf_file.base.options.module.?;
812 const mod = elf_file.base.comp.module.?;
801813 const decl = mod.declPtr(decl_index);
802814 const sym = elf_file.symbol(symbol_index);
803815 if (decl.getOwnedVariable(mod)) |variable| {
804 if (variable.is_threadlocal and !single_threaded) {
816 if (variable.is_threadlocal and any_non_single_threaded) {
805817 sym.flags.is_tls = true;
806818 }
807819 }
......@@ -820,13 +832,13 @@ fn getDeclShdrIndex(
820832 code: []const u8,
821833) error{OutOfMemory}!u16 {
822834 _ = self;
823 const mod = elf_file.base.options.module.?;
824 const single_threaded = elf_file.base.options.single_threaded;
835 const mod = elf_file.base.comp.module.?;
836 const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded;
825837 const shdr_index = switch (decl.ty.zigTypeTag(mod)) {
826838 .Fn => elf_file.zig_text_section_index.?,
827839 else => blk: {
828840 if (decl.getOwnedVariable(mod)) |variable| {
829 if (variable.is_threadlocal and !single_threaded) {
841 if (variable.is_threadlocal and any_non_single_threaded) {
830842 const is_all_zeroes = for (code) |byte| {
831843 if (byte != 0) break false;
832844 } else true;
......@@ -846,9 +858,12 @@ fn getDeclShdrIndex(
846858 }
847859 if (variable.is_const) break :blk elf_file.zig_data_rel_ro_section_index.?;
848860 if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
849 const mode = elf_file.base.options.optimize_mode;
850 if (mode == .Debug or mode == .ReleaseSafe) break :blk elf_file.zig_data_section_index.?;
851 break :blk elf_file.zig_bss_section_index.?;
861 // TODO: get the optimize_mode from the Module that owns the decl instead
862 // of using the root module here.
863 break :blk switch (elf_file.base.comp.root_mod.optimize_mode) {
864 .Debug, .ReleaseSafe => elf_file.zig_data_section_index.?,
865 .ReleaseFast, .ReleaseSmall => elf_file.zig_bss_section_index.?,
866 };
852867 }
853868 // TODO I blatantly copied the logic from the Wasm linker, but is there a less
854869 // intrusive check for all zeroes than this?
......@@ -873,8 +888,8 @@ fn updateDeclCode(
873888 code: []const u8,
874889 stt_bits: u8,
875890) !void {
876 const gpa = elf_file.base.allocator;
877 const mod = elf_file.base.options.module.?;
891 const gpa = elf_file.base.comp.gpa;
892 const mod = elf_file.base.comp.module.?;
878893 const decl = mod.declPtr(decl_index);
879894 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
880895
......@@ -911,7 +926,7 @@ fn updateDeclCode(
911926 sym.value = atom_ptr.value;
912927 esym.st_value = atom_ptr.value;
913928
914 if (!elf_file.isRelocatable()) {
929 if (!elf_file.base.isRelocatable()) {
915930 log.debug(" (writing new offset table entry)", .{});
916931 assert(sym.flags.has_zig_got);
917932 const extra = sym.extra(elf_file).?;
......@@ -929,7 +944,7 @@ fn updateDeclCode(
929944 sym.flags.needs_zig_got = true;
930945 esym.st_value = atom_ptr.value;
931946
932 if (!elf_file.isRelocatable()) {
947 if (!elf_file.base.isRelocatable()) {
933948 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
934949 try elf_file.zig_got.writeOne(elf_file, gop.index);
935950 }
......@@ -971,8 +986,8 @@ fn updateTlv(
971986 shndx: u16,
972987 code: []const u8,
973988) !void {
974 const gpa = elf_file.base.allocator;
975 const mod = elf_file.base.options.module.?;
989 const gpa = elf_file.base.comp.gpa;
990 const mod = elf_file.base.comp.module.?;
976991 const decl = mod.declPtr(decl_index);
977992 const decl_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
978993
......@@ -1026,6 +1041,7 @@ pub fn updateFunc(
10261041 const tracy = trace(@src());
10271042 defer tracy.end();
10281043
1044 const gpa = elf_file.base.comp.gpa;
10291045 const func = mod.funcInfo(func_index);
10301046 const decl_index = func.owner_decl;
10311047 const decl = mod.declPtr(decl_index);
......@@ -1034,7 +1050,7 @@ pub fn updateFunc(
10341050 self.freeUnnamedConsts(elf_file, decl_index);
10351051 elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
10361052
1037 var code_buffer = std.ArrayList(u8).init(elf_file.base.allocator);
1053 var code_buffer = std.ArrayList(u8).init(gpa);
10381054 defer code_buffer.deinit();
10391055
10401056 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;
......@@ -1117,7 +1133,8 @@ pub fn updateDecl(
11171133 const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
11181134 elf_file.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file);
11191135
1120 var code_buffer = std.ArrayList(u8).init(elf_file.base.allocator);
1136 const gpa = elf_file.base.comp.gpa;
1137 var code_buffer = std.ArrayList(u8).init(gpa);
11211138 defer code_buffer.deinit();
11221139
11231140 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dw| try dw.initDeclState(mod, decl_index) else null;
......@@ -1179,8 +1196,8 @@ fn updateLazySymbol(
11791196 sym: link.File.LazySymbol,
11801197 symbol_index: Symbol.Index,
11811198) !void {
1182 const gpa = elf_file.base.allocator;
1183 const mod = elf_file.base.options.module.?;
1199 const gpa = elf_file.base.comp.gpa;
1200 const mod = elf_file.base.comp.module.?;
11841201
11851202 var required_alignment: InternPool.Alignment = .none;
11861203 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1245,7 +1262,7 @@ fn updateLazySymbol(
12451262 local_sym.flags.needs_zig_got = true;
12461263 local_esym.st_value = atom_ptr.value;
12471264
1248 if (!elf_file.isRelocatable()) {
1265 if (!elf_file.base.isRelocatable()) {
12491266 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
12501267 try elf_file.zig_got.writeOne(elf_file, gop.index);
12511268 }
......@@ -1261,8 +1278,8 @@ pub fn lowerUnnamedConst(
12611278 typed_value: TypedValue,
12621279 decl_index: InternPool.DeclIndex,
12631280) !u32 {
1264 const gpa = elf_file.base.allocator;
1265 const mod = elf_file.base.options.module.?;
1281 const gpa = elf_file.base.comp.gpa;
1282 const mod = elf_file.base.comp.module.?;
12661283 const gop = try self.unnamed_consts.getOrPut(gpa, decl_index);
12671284 if (!gop.found_existing) {
12681285 gop.value_ptr.* = .{};
......@@ -1308,7 +1325,7 @@ fn lowerConst(
13081325 output_section_index: u16,
13091326 src_loc: Module.SrcLoc,
13101327) !LowerConstResult {
1311 const gpa = elf_file.base.allocator;
1328 const gpa = elf_file.base.comp.gpa;
13121329
13131330 var code_buffer = std.ArrayList(u8).init(gpa);
13141331 defer code_buffer.deinit();
......@@ -1364,7 +1381,7 @@ pub fn updateExports(
13641381 const tracy = trace(@src());
13651382 defer tracy.end();
13661383
1367 const gpa = elf_file.base.allocator;
1384 const gpa = elf_file.base.comp.gpa;
13681385 const metadata = switch (exported) {
13691386 .decl_index => |decl_index| blk: {
13701387 _ = try self.getOrCreateMetadataForDecl(elf_file, decl_index);
......@@ -1467,7 +1484,7 @@ pub fn deleteDeclExport(
14671484 name: InternPool.NullTerminatedString,
14681485) void {
14691486 const metadata = self.decls.getPtr(decl_index) orelse return;
1470 const mod = elf_file.base.options.module.?;
1487 const mod = elf_file.base.comp.module.?;
14711488 const exp_name = mod.intern_pool.stringToSlice(name);
14721489 const esym_index = metadata.@"export"(self, exp_name) orelse return;
14731490 log.debug("deleting export '{s}'", .{exp_name});
......@@ -1485,7 +1502,7 @@ pub fn deleteDeclExport(
14851502
14861503pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 {
14871504 _ = lib_name;
1488 const gpa = elf_file.base.allocator;
1505 const gpa = elf_file.base.comp.gpa;
14891506 const off = try self.strtab.insert(gpa, name);
14901507 const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);
14911508 if (!lookup_gop.found_existing) {
src/link/Elf/eh_frame.zig+13-5
......@@ -233,9 +233,12 @@ pub const Iterator = struct {
233233};
234234
235235pub fn calcEhFrameSize(elf_file: *Elf) !usize {
236 const comp = elf_file.base.comp;
237 const gpa = comp.gpa;
238
236239 var offset: usize = 0;
237240
238 var cies = std.ArrayList(Cie).init(elf_file.base.allocator);
241 var cies = std.ArrayList(Cie).init(gpa);
239242 defer cies.deinit();
240243
241244 for (elf_file.objects.items) |index| {
......@@ -268,7 +271,7 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize {
268271 }
269272 }
270273
271 if (!elf_file.isRelocatable()) {
274 if (!elf_file.base.isRelocatable()) {
272275 offset += 4; // NULL terminator
273276 }
274277
......@@ -327,7 +330,8 @@ fn resolveReloc(rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela, elf_file:
327330}
328331
329332pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
330 const gpa = elf_file.base.allocator;
333 const comp = elf_file.base.comp;
334 const gpa = comp.gpa;
331335
332336 relocs_log.debug("{x}: .eh_frame", .{elf_file.shdrs.items[elf_file.eh_frame_section_index.?].sh_addr});
333337
......@@ -378,7 +382,8 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void {
378382}
379383
380384pub fn writeEhFrameObject(elf_file: *Elf, writer: anytype) !void {
381 const gpa = elf_file.base.allocator;
385 const comp = elf_file.base.comp;
386 const gpa = comp.gpa;
382387
383388 for (elf_file.objects.items) |index| {
384389 const object = elf_file.file(index).?.object;
......@@ -467,6 +472,9 @@ pub fn writeEhFrameRelocs(elf_file: *Elf, writer: anytype) !void {
467472}
468473
469474pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
475 const comp = elf_file.base.comp;
476 const gpa = comp.gpa;
477
470478 try writer.writeByte(1); // version
471479 try writer.writeByte(EH_PE.pcrel | EH_PE.sdata4);
472480 try writer.writeByte(EH_PE.udata4);
......@@ -495,7 +503,7 @@ pub fn writeEhFrameHdr(elf_file: *Elf, writer: anytype) !void {
495503 }
496504 };
497505
498 var entries = std.ArrayList(Entry).init(elf_file.base.allocator);
506 var entries = std.ArrayList(Entry).init(gpa);
499507 defer entries.deinit();
500508 try entries.ensureTotalCapacityPrecise(num_fdes);
501509
src/link/Elf/gc.zig+2-1
......@@ -1,5 +1,6 @@
11pub fn gcAtoms(elf_file: *Elf) !void {
2 const gpa = elf_file.base.allocator;
2 const comp = elf_file.base.comp;
3 const gpa = comp.gpa;
34 const num_files = elf_file.objects.items.len + @intFromBool(elf_file.zig_object_index != null);
45 var files = try std.ArrayList(File.Index).initCapacity(gpa, num_files);
56 defer files.deinit();
src/link/Elf/synthetic_sections.zig+78-39
......@@ -8,14 +8,16 @@ pub const DynamicSection = struct {
88 }
99
1010 pub fn addNeeded(dt: *DynamicSection, shared: *SharedObject, elf_file: *Elf) !void {
11 const gpa = elf_file.base.allocator;
11 const comp = elf_file.base.comp;
12 const gpa = comp.gpa;
1213 const off = try elf_file.insertDynString(shared.soname());
1314 try dt.needed.append(gpa, off);
1415 }
1516
1617 pub fn setRpath(dt: *DynamicSection, rpath_list: []const []const u8, elf_file: *Elf) !void {
1718 if (rpath_list.len == 0) return;
18 const gpa = elf_file.base.allocator;
19 const comp = elf_file.base.comp;
20 const gpa = comp.gpa;
1921 var rpath = std.ArrayList(u8).init(gpa);
2022 defer rpath.deinit();
2123 for (rpath_list, 0..) |path, i| {
......@@ -32,7 +34,7 @@ pub const DynamicSection = struct {
3234 fn getFlags(dt: DynamicSection, elf_file: *Elf) ?u64 {
3335 _ = dt;
3436 var flags: u64 = 0;
35 if (elf_file.base.options.z_now) {
37 if (elf_file.z_now) {
3638 flags |= elf.DF_BIND_NOW;
3739 }
3840 for (elf_file.got.entries.items) |entry| switch (entry.tag) {
......@@ -49,15 +51,16 @@ pub const DynamicSection = struct {
4951 }
5052
5153 fn getFlags1(dt: DynamicSection, elf_file: *Elf) ?u64 {
54 const comp = elf_file.base.comp;
5255 _ = dt;
5356 var flags_1: u64 = 0;
54 if (elf_file.base.options.z_now) {
57 if (elf_file.z_now) {
5558 flags_1 |= elf.DF_1_NOW;
5659 }
57 if (elf_file.isExe() and elf_file.base.options.pie) {
60 if (elf_file.base.isExe() and comp.config.pie) {
5861 flags_1 |= elf.DF_1_PIE;
5962 }
60 // if (elf_file.base.options.z_nodlopen) {
63 // if (elf_file.z_nodlopen) {
6164 // flags_1 |= elf.DF_1_NOOPEN;
6265 // }
6366 return if (flags_1 > 0) flags_1 else null;
......@@ -86,7 +89,7 @@ pub const DynamicSection = struct {
8689 if (elf_file.verneed_section_index != null) nentries += 2; // VERNEED
8790 if (dt.getFlags(elf_file) != null) nentries += 1; // FLAGS
8891 if (dt.getFlags1(elf_file) != null) nentries += 1; // FLAGS_1
89 if (!elf_file.isDynLib()) nentries += 1; // DEBUG
92 if (!elf_file.base.isDynLib()) nentries += 1; // DEBUG
9093 nentries += 1; // NULL
9194 return nentries * @sizeOf(elf.Elf64_Dyn);
9295 }
......@@ -213,7 +216,7 @@ pub const DynamicSection = struct {
213216 }
214217
215218 // DEBUG
216 if (!elf_file.isDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 });
219 if (!elf_file.base.isDynLib()) try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_DEBUG, .d_val = 0 });
217220
218221 // NULL
219222 try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_NULL, .d_val = 0 });
......@@ -246,12 +249,14 @@ pub const ZigGotSection = struct {
246249 }
247250
248251 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {
249 const index = try zig_got.allocateEntry(elf_file.base.allocator);
252 const comp = elf_file.base.comp;
253 const gpa = comp.gpa;
254 const index = try zig_got.allocateEntry(gpa);
250255 const entry = &zig_got.entries.items[index];
251256 entry.* = sym_index;
252257 const symbol = elf_file.symbol(sym_index);
253258 symbol.flags.has_zig_got = true;
254 if (elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) {
259 if (elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) {
255260 zig_got.flags.needs_rela = true;
256261 }
257262 if (symbol.extra(elf_file)) |extra| {
......@@ -287,7 +292,8 @@ pub const ZigGotSection = struct {
287292 zig_got.flags.dirty = false;
288293 }
289294 const entry_size: u16 = elf_file.archPtrWidthBytes();
290 const endian = elf_file.base.options.target.cpu.arch.endian();
295 const target = elf_file.base.comp.root_mod.resolved_target.result;
296 const endian = target.cpu.arch.endian();
291297 const off = zig_got.entryOffset(index, elf_file);
292298 const vaddr = zig_got.entryAddress(index, elf_file);
293299 const entry = zig_got.entries.items[index];
......@@ -346,7 +352,9 @@ pub const ZigGotSection = struct {
346352 }
347353
348354 pub fn addRela(zig_got: ZigGotSection, elf_file: *Elf) !void {
349 try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, zig_got.numRela());
355 const comp = elf_file.base.comp;
356 const gpa = comp.gpa;
357 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela());
350358 for (zig_got.entries.items) |entry| {
351359 const symbol = elf_file.symbol(entry);
352360 const offset = symbol.zigGotAddress(elf_file);
......@@ -477,14 +485,16 @@ pub const GotSection = struct {
477485 }
478486
479487 pub fn addGotSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {
480 const index = try got.allocateEntry(elf_file.base.allocator);
488 const comp = elf_file.base.comp;
489 const gpa = comp.gpa;
490 const index = try got.allocateEntry(gpa);
481491 const entry = &got.entries.items[index];
482492 entry.tag = .got;
483493 entry.symbol_index = sym_index;
484494 const symbol = elf_file.symbol(sym_index);
485495 symbol.flags.has_got = true;
486496 if (symbol.flags.import or symbol.isIFunc(elf_file) or
487 ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and !symbol.isAbs(elf_file)))
497 ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and !symbol.isAbs(elf_file)))
488498 {
489499 got.flags.needs_rela = true;
490500 }
......@@ -497,8 +507,10 @@ pub const GotSection = struct {
497507 }
498508
499509 pub fn addTlsLdSymbol(got: *GotSection, elf_file: *Elf) !void {
510 const comp = elf_file.base.comp;
511 const gpa = comp.gpa;
500512 assert(got.flags.needs_tlsld);
501 const index = try got.allocateEntry(elf_file.base.allocator);
513 const index = try got.allocateEntry(gpa);
502514 const entry = &got.entries.items[index];
503515 entry.tag = .tlsld;
504516 entry.symbol_index = undefined; // unused
......@@ -507,13 +519,15 @@ pub const GotSection = struct {
507519 }
508520
509521 pub fn addTlsGdSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
510 const index = try got.allocateEntry(elf_file.base.allocator);
522 const comp = elf_file.base.comp;
523 const gpa = comp.gpa;
524 const index = try got.allocateEntry(gpa);
511525 const entry = &got.entries.items[index];
512526 entry.tag = .tlsgd;
513527 entry.symbol_index = sym_index;
514528 const symbol = elf_file.symbol(sym_index);
515529 symbol.flags.has_tlsgd = true;
516 if (symbol.flags.import or elf_file.isDynLib()) got.flags.needs_rela = true;
530 if (symbol.flags.import or elf_file.base.isDynLib()) got.flags.needs_rela = true;
517531 if (symbol.extra(elf_file)) |extra| {
518532 var new_extra = extra;
519533 new_extra.tlsgd = index;
......@@ -522,13 +536,15 @@ pub const GotSection = struct {
522536 }
523537
524538 pub fn addGotTpSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
525 const index = try got.allocateEntry(elf_file.base.allocator);
539 const comp = elf_file.base.comp;
540 const gpa = comp.gpa;
541 const index = try got.allocateEntry(gpa);
526542 const entry = &got.entries.items[index];
527543 entry.tag = .gottp;
528544 entry.symbol_index = sym_index;
529545 const symbol = elf_file.symbol(sym_index);
530546 symbol.flags.has_gottp = true;
531 if (symbol.flags.import or elf_file.isDynLib()) got.flags.needs_rela = true;
547 if (symbol.flags.import or elf_file.base.isDynLib()) got.flags.needs_rela = true;
532548 if (symbol.extra(elf_file)) |extra| {
533549 var new_extra = extra;
534550 new_extra.gottp = index;
......@@ -537,7 +553,9 @@ pub const GotSection = struct {
537553 }
538554
539555 pub fn addTlsDescSymbol(got: *GotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
540 const index = try got.allocateEntry(elf_file.base.allocator);
556 const comp = elf_file.base.comp;
557 const gpa = comp.gpa;
558 const index = try got.allocateEntry(gpa);
541559 const entry = &got.entries.items[index];
542560 entry.tag = .tlsdesc;
543561 entry.symbol_index = sym_index;
......@@ -560,7 +578,8 @@ pub const GotSection = struct {
560578 }
561579
562580 pub fn write(got: GotSection, elf_file: *Elf, writer: anytype) !void {
563 const is_dyn_lib = elf_file.isDynLib();
581 const comp = elf_file.base.comp;
582 const is_dyn_lib = elf_file.base.isDynLib();
564583 const apply_relocs = true; // TODO add user option for this
565584
566585 for (got.entries.items) |entry| {
......@@ -575,7 +594,7 @@ pub const GotSection = struct {
575594 if (symbol.?.flags.import) break :blk 0;
576595 if (symbol.?.isIFunc(elf_file))
577596 break :blk if (apply_relocs) value else 0;
578 if ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and
597 if ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
579598 !symbol.?.isAbs(elf_file))
580599 {
581600 break :blk if (apply_relocs) value else 0;
......@@ -622,8 +641,10 @@ pub const GotSection = struct {
622641 }
623642
624643 pub fn addRela(got: GotSection, elf_file: *Elf) !void {
625 const is_dyn_lib = elf_file.isDynLib();
626 try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, got.numRela(elf_file));
644 const comp = elf_file.base.comp;
645 const gpa = comp.gpa;
646 const is_dyn_lib = elf_file.base.isDynLib();
647 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, got.numRela(elf_file));
627648
628649 for (got.entries.items) |entry| {
629650 const symbol = switch (entry.tag) {
......@@ -651,7 +672,7 @@ pub const GotSection = struct {
651672 });
652673 continue;
653674 }
654 if ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and
675 if ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
655676 !symbol.?.isAbs(elf_file))
656677 {
657678 elf_file.addRelaDynAssumeCapacity(.{
......@@ -724,7 +745,8 @@ pub const GotSection = struct {
724745 }
725746
726747 pub fn numRela(got: GotSection, elf_file: *Elf) usize {
727 const is_dyn_lib = elf_file.isDynLib();
748 const comp = elf_file.base.comp;
749 const is_dyn_lib = elf_file.base.isDynLib();
728750 var num: usize = 0;
729751 for (got.entries.items) |entry| {
730752 const symbol = switch (entry.tag) {
......@@ -733,7 +755,7 @@ pub const GotSection = struct {
733755 };
734756 switch (entry.tag) {
735757 .got => if (symbol.?.flags.import or symbol.?.isIFunc(elf_file) or
736 ((elf_file.isDynLib() or (elf_file.isExe() and elf_file.base.options.pie)) and
758 ((elf_file.base.isDynLib() or (elf_file.base.isExe() and comp.config.pie)) and
737759 !symbol.?.isAbs(elf_file)))
738760 {
739761 num += 1;
......@@ -840,6 +862,8 @@ pub const PltSection = struct {
840862 }
841863
842864 pub fn addSymbol(plt: *PltSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
865 const comp = elf_file.base.comp;
866 const gpa = comp.gpa;
843867 const index = @as(u32, @intCast(plt.symbols.items.len));
844868 const symbol = elf_file.symbol(sym_index);
845869 symbol.flags.has_plt = true;
......@@ -848,7 +872,7 @@ pub const PltSection = struct {
848872 new_extra.plt = index;
849873 symbol.setExtra(new_extra, elf_file);
850874 } else try symbol.addExtra(.{ .plt = index }, elf_file);
851 try plt.symbols.append(elf_file.base.allocator, sym_index);
875 try plt.symbols.append(gpa, sym_index);
852876 }
853877
854878 pub fn size(plt: PltSection) usize {
......@@ -888,7 +912,9 @@ pub const PltSection = struct {
888912 }
889913
890914 pub fn addRela(plt: PltSection, elf_file: *Elf) !void {
891 try elf_file.rela_plt.ensureUnusedCapacity(elf_file.base.allocator, plt.numRela());
915 const comp = elf_file.base.comp;
916 const gpa = comp.gpa;
917 try elf_file.rela_plt.ensureUnusedCapacity(gpa, plt.numRela());
892918 for (plt.symbols.items) |sym_index| {
893919 const sym = elf_file.symbol(sym_index);
894920 assert(sym.flags.import);
......@@ -1003,6 +1029,8 @@ pub const PltGotSection = struct {
10031029 }
10041030
10051031 pub fn addSymbol(plt_got: *PltGotSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
1032 const comp = elf_file.base.comp;
1033 const gpa = comp.gpa;
10061034 const index = @as(u32, @intCast(plt_got.symbols.items.len));
10071035 const symbol = elf_file.symbol(sym_index);
10081036 symbol.flags.has_plt = true;
......@@ -1012,7 +1040,7 @@ pub const PltGotSection = struct {
10121040 new_extra.plt_got = index;
10131041 symbol.setExtra(new_extra, elf_file);
10141042 } else try symbol.addExtra(.{ .plt_got = index }, elf_file);
1015 try plt_got.symbols.append(elf_file.base.allocator, sym_index);
1043 try plt_got.symbols.append(gpa, sym_index);
10161044 }
10171045
10181046 pub fn size(plt_got: PltGotSection) usize {
......@@ -1070,6 +1098,8 @@ pub const CopyRelSection = struct {
10701098 }
10711099
10721100 pub fn addSymbol(copy_rel: *CopyRelSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
1101 const comp = elf_file.base.comp;
1102 const gpa = comp.gpa;
10731103 const index = @as(u32, @intCast(copy_rel.symbols.items.len));
10741104 const symbol = elf_file.symbol(sym_index);
10751105 symbol.flags.import = true;
......@@ -1082,7 +1112,7 @@ pub const CopyRelSection = struct {
10821112 new_extra.copy_rel = index;
10831113 symbol.setExtra(new_extra, elf_file);
10841114 } else try symbol.addExtra(.{ .copy_rel = index }, elf_file);
1085 try copy_rel.symbols.append(elf_file.base.allocator, sym_index);
1115 try copy_rel.symbols.append(gpa, sym_index);
10861116
10871117 const shared_object = symbol.file(elf_file).?.shared_object;
10881118 if (shared_object.aliases == null) {
......@@ -1122,7 +1152,9 @@ pub const CopyRelSection = struct {
11221152 }
11231153
11241154 pub fn addRela(copy_rel: CopyRelSection, elf_file: *Elf) !void {
1125 try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, copy_rel.numRela());
1155 const comp = elf_file.base.comp;
1156 const gpa = comp.gpa;
1157 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, copy_rel.numRela());
11261158 for (copy_rel.symbols.items) |sym_index| {
11271159 const sym = elf_file.symbol(sym_index);
11281160 assert(sym.flags.import and sym.flags.has_copy_rel);
......@@ -1155,7 +1187,8 @@ pub const DynsymSection = struct {
11551187 }
11561188
11571189 pub fn addSymbol(dynsym: *DynsymSection, sym_index: Symbol.Index, elf_file: *Elf) !void {
1158 const gpa = elf_file.base.allocator;
1190 const comp = elf_file.base.comp;
1191 const gpa = comp.gpa;
11591192 const index = @as(u32, @intCast(dynsym.entries.items.len + 1));
11601193 const sym = elf_file.symbol(sym_index);
11611194 sym.flags.has_dynamic = true;
......@@ -1237,7 +1270,8 @@ pub const HashSection = struct {
12371270 pub fn generate(hs: *HashSection, elf_file: *Elf) !void {
12381271 if (elf_file.dynsym.count() == 1) return;
12391272
1240 const gpa = elf_file.base.allocator;
1273 const comp = elf_file.base.comp;
1274 const gpa = comp.gpa;
12411275 const nsyms = elf_file.dynsym.count();
12421276
12431277 var buckets = try gpa.alloc(u32, nsyms);
......@@ -1325,7 +1359,8 @@ pub const GnuHashSection = struct {
13251359 try cwriter.writeInt(u32, hash.num_bloom, .little);
13261360 try cwriter.writeInt(u32, bloom_shift, .little);
13271361
1328 const gpa = elf_file.base.allocator;
1362 const comp = elf_file.base.comp;
1363 const gpa = comp.gpa;
13291364 const hashes = try gpa.alloc(u32, exports.len);
13301365 defer gpa.free(hashes);
13311366 const indices = try gpa.alloc(u32, exports.len);
......@@ -1427,7 +1462,8 @@ pub const VerneedSection = struct {
14271462 }
14281463 };
14291464
1430 const gpa = elf_file.base.allocator;
1465 const comp = elf_file.base.comp;
1466 const gpa = comp.gpa;
14311467 var verneed = std.ArrayList(VersionedSymbol).init(gpa);
14321468 defer verneed.deinit();
14331469 try verneed.ensureTotalCapacity(dynsyms.len);
......@@ -1483,7 +1519,8 @@ pub const VerneedSection = struct {
14831519 }
14841520
14851521 fn addVerneed(vern: *VerneedSection, soname: []const u8, elf_file: *Elf) !*elf.Elf64_Verneed {
1486 const gpa = elf_file.base.allocator;
1522 const comp = elf_file.base.comp;
1523 const gpa = comp.gpa;
14871524 const sym = try vern.verneed.addOne(gpa);
14881525 sym.* = .{
14891526 .vn_version = 1,
......@@ -1501,7 +1538,8 @@ pub const VerneedSection = struct {
15011538 version: [:0]const u8,
15021539 elf_file: *Elf,
15031540 ) !elf.Elf64_Vernaux {
1504 const gpa = elf_file.base.allocator;
1541 const comp = elf_file.base.comp;
1542 const gpa = comp.gpa;
15051543 const sym = try vern.vernaux.addOne(gpa);
15061544 sym.* = .{
15071545 .vna_hash = HashSection.hasher(version),
......@@ -1575,7 +1613,8 @@ pub const ComdatGroupSection = struct {
15751613
15761614fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
15771615 const entry_size = elf_file.archPtrWidthBytes();
1578 const endian = elf_file.base.options.target.cpu.arch.endian();
1616 const target = elf_file.base.comp.root_mod.resolved_target.result;
1617 const endian = target.cpu.arch.endian();
15791618 switch (entry_size) {
15801619 2 => try writer.writeInt(u16, @intCast(value), endian),
15811620 4 => try writer.writeInt(u32, @intCast(value), endian),
src/link/MachO.zig+446-410
......@@ -1,6 +1,7 @@
11base: File,
2entry_name: ?[]const u8,
23
3/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
4/// If this is not null, an object file is created by LLVM and emitted to zcu_object_sub_path.
45llvm_object: ?*LlvmObject = null,
56
67/// Debug symbols bundle (or dSym).
......@@ -67,9 +68,6 @@ tlv_ptr_table: TableSection(SymbolWithLoc) = .{},
6768thunk_table: std.AutoHashMapUnmanaged(Atom.Index, thunks.Thunk.Index) = .{},
6869thunks: std.ArrayListUnmanaged(thunks.Thunk) = .{},
6970
70error_flags: File.ErrorFlags = File.ErrorFlags{},
71misc_errors: std.ArrayListUnmanaged(File.ErrorMsg) = .{},
72
7371segment_table_dirty: bool = false,
7472got_table_count_dirty: bool = false,
7573got_table_contents_dirty: bool = false,
......@@ -77,12 +75,6 @@ stub_table_count_dirty: bool = false,
7775stub_table_contents_dirty: bool = false,
7876stub_helper_preamble_allocated: bool = false,
7977
80/// A helper var to indicate if we are at the start of the incremental updates, or
81/// already somewhere further along the update-and-run chain.
82/// TODO once we add opening a prelinked output binary from file, this will become
83/// obsolete as we will carry on where we left off.
84cold_start: bool = true,
85
8678/// List of atoms that are either synthetic or map directly to the Zig source program.
8779atoms: std.ArrayListUnmanaged(Atom) = .{},
8880
......@@ -143,89 +135,167 @@ tlv_table: TlvSymbolTable = .{},
143135/// Hot-code swapping state.
144136hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
145137
146pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
147 assert(options.target.ofmt == .macho);
138sdk_layout: ?SdkLayout,
139/// Size of the __PAGEZERO segment.
140pagezero_vmsize: u64,
141/// Minimum space for future expansion of the load commands.
142headerpad_size: u32,
143/// Set enough space as if all paths were MATPATHLEN.
144headerpad_max_install_names: bool,
145/// Remove dylibs that are unreachable by the entry point or exported symbols.
146dead_strip_dylibs: bool,
147frameworks: []const Framework,
148/// Install name for the dylib.
149/// TODO: unify with soname
150install_name: ?[]const u8,
151/// Path to entitlements file.
152entitlements: ?[]const u8,
153compatibility_version: ?std.SemanticVersion,
154
155/// When adding a new field, remember to update `hashAddFrameworks`.
156pub const Framework = struct {
157 needed: bool = false,
158 weak: bool = false,
159 path: []const u8,
160};
148161
149 if (options.emit == null) {
150 return createEmpty(allocator, options);
162pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void {
163 for (hm) |value| {
164 man.hash.add(value.needed);
165 man.hash.add(value.weak);
166 _ = try man.addFile(value.path, null);
151167 }
168}
152169
153 const emit = options.emit.?;
154 const mode: Mode = mode: {
155 if (options.use_llvm or options.module == null or options.cache_mode == .whole)
156 break :mode .zld;
157 break :mode .incremental;
158 };
159 const sub_path = if (mode == .zld) blk: {
160 if (options.module == null) {
161 // No point in opening a file, we would not write anything to it.
162 // Initialize with empty.
163 return createEmpty(allocator, options);
164 }
165 // Open a temporary object file, not the final output file because we
166 // want to link with LLD.
167 break :blk try std.fmt.allocPrint(allocator, "{s}{s}", .{
168 emit.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch),
169 });
170 } else emit.sub_path;
171 errdefer if (mode == .zld) allocator.free(sub_path);
170/// The filesystem layout of darwin SDK elements.
171pub const SdkLayout = enum {
172 /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }.
173 sdk,
174 /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }.
175 vendored,
176};
177
178pub fn createEmpty(
179 arena: Allocator,
180 comp: *Compilation,
181 emit: Compilation.Emit,
182 options: link.File.OpenOptions,
183) !*MachO {
184 const target = comp.root_mod.resolved_target.result;
185 assert(target.ofmt == .macho);
186 const use_llvm = comp.config.use_llvm;
187 const gpa = comp.gpa;
188 const optimize_mode = comp.root_mod.optimize_mode;
189 const output_mode = comp.config.output_mode;
190 const link_mode = comp.config.link_mode;
191
192 // TODO: get rid of zld mode
193 const mode: Mode = if (use_llvm or !comp.config.have_zcu or comp.cache_use == .whole)
194 .zld
195 else
196 .incremental;
197
198 // If using "zld mode" to link, this code should produce an object file so that it
199 // can be passed to "zld mode". TODO: get rid of "zld mode".
200 // If using LLVM to generate the object file for the zig compilation unit,
201 // we need a place to put the object file so that it can be subsequently
202 // handled.
203 const zcu_object_sub_path = if (mode != .zld and !use_llvm)
204 null
205 else
206 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
172207
173 const self = try createEmpty(allocator, options);
208 const self = try arena.create(MachO);
209 self.* = .{
210 .base = .{
211 .tag = .macho,
212 .comp = comp,
213 .emit = emit,
214 .zcu_object_sub_path = zcu_object_sub_path,
215 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
216 .print_gc_sections = options.print_gc_sections,
217 .stack_size = options.stack_size orelse 16777216,
218 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
219 .file = null,
220 .disable_lld_caching = options.disable_lld_caching,
221 .build_id = options.build_id,
222 .rpath_list = options.rpath_list,
223 },
224 .mode = mode,
225 .pagezero_vmsize = options.pagezero_size orelse default_pagezero_vmsize,
226 .headerpad_size = options.headerpad_size orelse default_headerpad_size,
227 .headerpad_max_install_names = options.headerpad_max_install_names,
228 .dead_strip_dylibs = options.dead_strip_dylibs,
229 .sdk_layout = options.darwin_sdk_layout,
230 .frameworks = options.frameworks,
231 .install_name = options.install_name,
232 .entitlements = options.entitlements,
233 .compatibility_version = options.compatibility_version,
234 .entry_name = switch (options.entry) {
235 .disabled => null,
236 .default => if (output_mode != .Exe) null else default_entry_symbol_name,
237 .enabled => default_entry_symbol_name,
238 .named => |name| name,
239 },
240 };
241 if (use_llvm and comp.config.have_zcu) {
242 self.llvm_object = try LlvmObject.create(arena, comp);
243 }
174244 errdefer self.base.destroy();
175245
246 log.debug("selected linker mode '{s}'", .{@tagName(self.mode)});
247
176248 if (mode == .zld) {
177 // TODO this intermediary_basename isn't enough; in the case of `zig build-exe`,
178 // we also want to put the intermediary object file in the cache while the
179 // main emit directory is the cwd.
180 self.base.intermediary_basename = sub_path;
249 // TODO: get rid of zld mode
181250 return self;
182251 }
183252
184 const file = try emit.directory.handle.createFile(sub_path, .{
185 .truncate = false,
253 const file = try emit.directory.handle.createFile(emit.sub_path, .{
254 .truncate = true,
186255 .read = true,
187 .mode = link.determineMode(options),
256 .mode = link.File.determineMode(false, output_mode, link_mode),
188257 });
189 errdefer file.close();
190258 self.base.file = file;
191259
192 if (!options.strip and options.module != null) {
260 if (comp.config.debug_format != .strip and comp.module != null) {
193261 // Create dSYM bundle.
194 log.debug("creating {s}.dSYM bundle", .{sub_path});
262 log.debug("creating {s}.dSYM bundle", .{emit.sub_path});
195263
196264 const d_sym_path = try std.fmt.allocPrint(
197 allocator,
265 arena,
198266 "{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",
199 .{sub_path},
267 .{emit.sub_path},
200268 );
201 defer allocator.free(d_sym_path);
202269
203270 var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{});
204271 defer d_sym_bundle.close();
205272
206 const d_sym_file = try d_sym_bundle.createFile(sub_path, .{
273 const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{
207274 .truncate = false,
208275 .read = true,
209276 });
210277
211278 self.d_sym = .{
212 .allocator = allocator,
213 .dwarf = link.File.Dwarf.init(allocator, &self.base, .dwarf32),
279 .allocator = gpa,
280 .dwarf = link.File.Dwarf.init(&self.base, .dwarf32),
214281 .file = d_sym_file,
215282 };
216283 }
217284
218285 // Index 0 is always a null symbol.
219 try self.locals.append(allocator, .{
286 try self.locals.append(gpa, .{
220287 .n_strx = 0,
221288 .n_type = 0,
222289 .n_sect = 0,
223290 .n_desc = 0,
224291 .n_value = 0,
225292 });
226 try self.strtab.buffer.append(allocator, 0);
293 try self.strtab.buffer.append(gpa, 0);
227294
228 try self.populateMissingMetadata();
295 try self.populateMissingMetadata(.{
296 .symbol_count_hint = options.symbol_count_hint,
297 .program_code_size_hint = options.program_code_size_hint,
298 });
229299
230300 if (self.d_sym) |*d_sym| {
231301 try d_sym.populateMissingMetadata(self);
......@@ -234,75 +304,59 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
234304 return self;
235305}
236306
237pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO {
238 const self = try gpa.create(MachO);
239 errdefer gpa.destroy(self);
240
241 self.* = .{
242 .base = .{
243 .tag = .macho,
244 .options = options,
245 .allocator = gpa,
246 .file = null,
247 },
248 .mode = if (options.use_llvm or options.module == null or options.cache_mode == .whole)
249 .zld
250 else
251 .incremental,
252 };
253
254 if (options.use_llvm and options.module != null) {
255 self.llvm_object = try LlvmObject.create(gpa, options);
256 }
257
258 log.debug("selected linker mode '{s}'", .{@tagName(self.mode)});
259
260 return self;
307pub fn open(
308 arena: Allocator,
309 comp: *Compilation,
310 emit: Compilation.Emit,
311 options: link.File.OpenOptions,
312) !*MachO {
313 // TODO: restore saved linker state, don't truncate the file, and
314 // participate in incremental compilation.
315 return createEmpty(arena, comp, emit, options);
261316}
262317
263pub fn flush(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
264 if (self.base.options.emit == null) {
265 if (self.llvm_object) |llvm_object| {
266 try llvm_object.flushModule(comp, prog_node);
267 }
268 return;
269 }
318pub fn flush(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
319 const comp = self.base.comp;
320 const gpa = comp.gpa;
321 const output_mode = comp.config.output_mode;
270322
271 if (self.base.options.output_mode == .Lib and self.base.options.link_mode == .Static) {
323 if (output_mode == .Lib and comp.config.link_mode == .Static) {
272324 if (build_options.have_llvm) {
273 return self.base.linkAsArchive(comp, prog_node);
325 return self.base.linkAsArchive(arena, prog_node);
274326 } else {
275 try self.misc_errors.ensureUnusedCapacity(self.base.allocator, 1);
276 self.misc_errors.appendAssumeCapacity(.{
277 .msg = try self.base.allocator.dupe(u8, "TODO: non-LLVM archiver for MachO object files"),
327 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
328 comp.link_errors.appendAssumeCapacity(.{
329 .msg = try gpa.dupe(u8, "TODO: non-LLVM archiver for MachO object files"),
278330 });
279331 return error.FlushFailure;
280332 }
281333 }
282334
283335 switch (self.mode) {
284 .zld => return zld.linkWithZld(self, comp, prog_node),
285 .incremental => return self.flushModule(comp, prog_node),
336 .zld => return zld.linkWithZld(self, arena, prog_node),
337 .incremental => return self.flushModule(arena, prog_node),
286338 }
287339}
288340
289pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
341pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
290342 const tracy = trace(@src());
291343 defer tracy.end();
292344
345 const comp = self.base.comp;
346 const gpa = comp.gpa;
347
293348 if (self.llvm_object) |llvm_object| {
294 return try llvm_object.flushModule(comp, prog_node);
349 try self.base.emitLlvmObject(arena, llvm_object, prog_node);
350 return;
295351 }
296352
297 var arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
298 defer arena_allocator.deinit();
299 const arena = arena_allocator.allocator();
300
301353 var sub_prog_node = prog_node.start("MachO Flush", 0);
302354 sub_prog_node.activate();
303355 defer sub_prog_node.end();
304356
305 const module = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
357 const output_mode = comp.config.output_mode;
358 const module = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
359 const target = comp.root_mod.resolved_target.result;
306360
307361 if (self.lazy_syms.getPtr(.none)) |metadata| {
308362 // Most lazy symbols can be updated on first use, but
......@@ -334,97 +388,44 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
334388 }
335389
336390 var libs = std.StringArrayHashMap(link.SystemLib).init(arena);
337 try self.resolveLibSystem(arena, comp, &.{}, &libs);
338
339 const id_symlink_basename = "link.id";
391 try self.resolveLibSystem(arena, comp, &libs);
340392
341 const cache_dir_handle = module.zig_cache_artifact_directory.handle;
342 var man: Cache.Manifest = undefined;
343 defer man.deinit();
344
345 var digest: [Cache.hex_digest_len]u8 = undefined;
346 man = comp.cache_parent.obtain();
347 man.want_shared_lock = false;
348393 self.base.releaseLock();
349394
350 man.hash.addListOfBytes(libs.keys());
351
352 _ = try man.hit();
353 digest = man.final();
354
355 var prev_digest_buf: [digest.len]u8 = undefined;
356 const prev_digest: []u8 = Cache.readSmallFile(
357 cache_dir_handle,
358 id_symlink_basename,
359 &prev_digest_buf,
360 ) catch |err| blk: {
361 log.debug("MachO Zld new_digest={s} error: {s}", .{
362 std.fmt.fmtSliceHexLower(&digest),
363 @errorName(err),
364 });
365 // Handle this as a cache miss.
366 break :blk prev_digest_buf[0..0];
367 };
368 const cache_miss: bool = cache_miss: {
369 if (mem.eql(u8, prev_digest, &digest)) {
370 log.debug("MachO Zld digest={s} match", .{
371 std.fmt.fmtSliceHexLower(&digest),
372 });
373 if (!self.cold_start) {
374 log.debug(" skipping parsing linker line objects", .{});
375 break :cache_miss false;
376 } else {
377 log.debug(" TODO parse prelinked binary and continue linking where we left off", .{});
378 }
379 }
380 log.debug("MachO Zld prev_digest={s} new_digest={s}", .{
381 std.fmt.fmtSliceHexLower(prev_digest),
382 std.fmt.fmtSliceHexLower(&digest),
383 });
384 // We are about to change the output file to be different, so we invalidate the build hash now.
385 cache_dir_handle.deleteFile(id_symlink_basename) catch |err| switch (err) {
386 error.FileNotFound => {},
387 else => |e| return e,
388 };
389 break :cache_miss true;
390 };
391
392 if (cache_miss) {
393 for (self.dylibs.items) |*dylib| {
394 dylib.deinit(self.base.allocator);
395 }
396 self.dylibs.clearRetainingCapacity();
397 self.dylibs_map.clearRetainingCapacity();
398 self.referenced_dylibs.clearRetainingCapacity();
399
400 var dependent_libs = std.fifo.LinearFifo(DylibReExportInfo, .Dynamic).init(arena);
395 for (self.dylibs.items) |*dylib| {
396 dylib.deinit(gpa);
397 }
398 self.dylibs.clearRetainingCapacity();
399 self.dylibs_map.clearRetainingCapacity();
400 self.referenced_dylibs.clearRetainingCapacity();
401401
402 for (libs.keys(), libs.values()) |path, lib| {
403 const in_file = try std.fs.cwd().openFile(path, .{});
404 defer in_file.close();
402 var dependent_libs = std.fifo.LinearFifo(DylibReExportInfo, .Dynamic).init(arena);
405403
406 var parse_ctx = ParseErrorCtx.init(self.base.allocator);
407 defer parse_ctx.deinit();
404 for (libs.keys(), libs.values()) |path, lib| {
405 const in_file = try std.fs.cwd().openFile(path, .{});
406 defer in_file.close();
408407
409 self.parseLibrary(
410 in_file,
411 path,
412 lib,
413 false,
414 false,
415 null,
416 &dependent_libs,
417 &parse_ctx,
418 ) catch |err| try self.handleAndReportParseError(path, err, &parse_ctx);
419 }
408 var parse_ctx = ParseErrorCtx.init(gpa);
409 defer parse_ctx.deinit();
420410
421 try self.parseDependentLibs(&dependent_libs);
411 self.parseLibrary(
412 in_file,
413 path,
414 lib,
415 false,
416 false,
417 null,
418 &dependent_libs,
419 &parse_ctx,
420 ) catch |err| try self.handleAndReportParseError(path, err, &parse_ctx);
422421 }
423422
423 try self.parseDependentLibs(&dependent_libs);
424
424425 try self.resolveSymbols();
425426
426427 if (self.getEntryPoint() == null) {
427 self.error_flags.no_entry_point_found = true;
428 comp.link_error_flags.no_entry_point_found = true;
428429 }
429430 if (self.unresolved.count() > 0) {
430431 try self.reportUndefined();
......@@ -445,7 +446,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
445446 try self.createDyldPrivateAtom();
446447 try self.writeStubHelperPreamble();
447448
448 if (self.base.options.output_mode == .Exe and self.getEntryPoint() != null) {
449 if (output_mode == .Exe and self.getEntryPoint() != null) {
449450 const global = self.getEntryPoint().?;
450451 if (self.getSymbol(global).undf()) {
451452 // We do one additional check here in case the entry point was found in one of the dylibs.
......@@ -470,7 +471,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
470471 const section = self.sections.get(sym.n_sect - 1).header;
471472 const file_offset = section.offset + sym.n_value - section.addr;
472473
473 var code = std.ArrayList(u8).init(self.base.allocator);
474 var code = std.ArrayList(u8).init(gpa);
474475 defer code.deinit();
475476 try code.resize(math.cast(usize, atom.size) orelse return error.Overflow);
476477
......@@ -509,21 +510,21 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
509510
510511 try self.writeLinkeditSegmentData();
511512
512 var codesig: ?CodeSignature = if (requiresCodeSignature(&self.base.options)) blk: {
513 var codesig: ?CodeSignature = if (self.requiresCodeSignature()) blk: {
513514 // Preallocate space for the code signature.
514515 // We need to do this at this stage so that we have the load commands with proper values
515516 // written out to the file.
516517 // The most important here is to have the correct vm and filesize of the __LINKEDIT segment
517518 // where the code signature goes into.
518 var codesig = CodeSignature.init(getPageSize(self.base.options.target.cpu.arch));
519 codesig.code_directory.ident = self.base.options.emit.?.sub_path;
520 if (self.base.options.entitlements) |path| {
521 try codesig.addEntitlements(self.base.allocator, path);
519 var codesig = CodeSignature.init(getPageSize(target.cpu.arch));
520 codesig.code_directory.ident = self.base.emit.sub_path;
521 if (self.entitlements) |path| {
522 try codesig.addEntitlements(gpa, path);
522523 }
523524 try self.writeCodeSignaturePadding(&codesig);
524525 break :blk codesig;
525526 } else null;
526 defer if (codesig) |*csig| csig.deinit(self.base.allocator);
527 defer if (codesig) |*csig| csig.deinit(gpa);
527528
528529 // Write load commands
529530 var lc_buffer = std.ArrayList(u8).init(arena);
......@@ -535,7 +536,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
535536 try lc_writer.writeStruct(self.dysymtab_cmd);
536537 try load_commands.writeDylinkerLC(lc_writer);
537538
538 switch (self.base.options.output_mode) {
539 switch (output_mode) {
539540 .Exe => blk: {
540541 const seg_id = self.header_segment_cmd_index.?;
541542 const seg = self.segments.items[seg_id];
......@@ -551,22 +552,22 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
551552
552553 try lc_writer.writeStruct(macho.entry_point_command{
553554 .entryoff = @as(u32, @intCast(addr - seg.vmaddr)),
554 .stacksize = self.base.options.stack_size_override orelse 0,
555 .stacksize = self.base.stack_size,
555556 });
556557 },
557 .Lib => if (self.base.options.link_mode == .Dynamic) {
558 try load_commands.writeDylibIdLC(self.base.allocator, &self.base.options, lc_writer);
558 .Lib => if (comp.config.link_mode == .Dynamic) {
559 try load_commands.writeDylibIdLC(self, lc_writer);
559560 },
560561 else => {},
561562 }
562563
563 try load_commands.writeRpathLCs(self.base.allocator, &self.base.options, lc_writer);
564 try load_commands.writeRpathLCs(self, lc_writer);
564565 try lc_writer.writeStruct(macho.source_version_command{
565566 .version = 0,
566567 });
567568 {
568 const platform = Platform.fromTarget(self.base.options.target);
569 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
569 const platform = Platform.fromTarget(target);
570 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(self);
570571 if (platform.isBuildVersionCompatible()) {
571572 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
572573 } else if (platform.isVersionMinCompatible()) {
......@@ -590,7 +591,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
590591
591592 if (codesig) |*csig| {
592593 try self.writeCodeSignature(comp, csig); // code signing always comes last
593 const emit = self.base.options.emit.?;
594 const emit = self.base.emit;
594595 try invalidateKernelCache(emit.directory.handle, emit.sub_path);
595596 }
596597
......@@ -598,23 +599,6 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
598599 // Flush debug symbols bundle.
599600 try d_sym.flushModule(self);
600601 }
601
602 if (cache_miss) {
603 // Update the file with the digest. If it fails we can continue; it only
604 // means that the next invocation will have an unnecessary cache miss.
605 Cache.writeSmallFile(cache_dir_handle, id_symlink_basename, &digest) catch |err| {
606 log.debug("failed to save linking hash digest file: {s}", .{@errorName(err)});
607 };
608 // Again failure here only means an unnecessary cache miss.
609 man.writeManifest() catch |err| {
610 log.debug("failed to write cache manifest when linking: {s}", .{@errorName(err)});
611 };
612 // We hang on to this lock so that the output file path can be used without
613 // other processes clobbering it.
614 self.base.lock = man.toOwnedLock();
615 }
616
617 self.cold_start = false;
618602}
619603
620604/// XNU starting with Big Sur running on arm64 is caching inodes of running binaries.
......@@ -641,33 +625,20 @@ pub fn resolveLibSystem(
641625 self: *MachO,
642626 arena: Allocator,
643627 comp: *Compilation,
644 search_dirs: []const []const u8,
645628 out_libs: anytype,
646629) !void {
647 var tmp_arena_allocator = std.heap.ArenaAllocator.init(self.base.allocator);
648 defer tmp_arena_allocator.deinit();
649 const tmp_arena = tmp_arena_allocator.allocator();
650
651 var test_path = std.ArrayList(u8).init(tmp_arena);
652 var checked_paths = std.ArrayList([]const u8).init(tmp_arena);
630 var test_path = std.ArrayList(u8).init(arena);
631 var checked_paths = std.ArrayList([]const u8).init(arena);
653632
654633 success: {
655 for (search_dirs) |dir| if (try accessLibPath(
656 tmp_arena,
657 &test_path,
658 &checked_paths,
659 dir,
660 "libSystem",
661 )) break :success;
662
663 if (self.base.options.darwin_sdk_layout) |sdk_layout| switch (sdk_layout) {
634 if (self.sdk_layout) |sdk_layout| switch (sdk_layout) {
664635 .sdk => {
665 const dir = try fs.path.join(tmp_arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });
666 if (try accessLibPath(tmp_arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
636 const dir = try fs.path.join(arena, &[_][]const u8{ comp.sysroot.?, "usr", "lib" });
637 if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
667638 },
668639 .vendored => {
669 const dir = try comp.zig_lib_directory.join(tmp_arena, &[_][]const u8{ "libc", "darwin" });
670 if (try accessLibPath(tmp_arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
640 const dir = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "darwin" });
641 if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
671642 },
672643 };
673644
......@@ -775,7 +746,8 @@ fn parseObject(
775746 const tracy = trace(@src());
776747 defer tracy.end();
777748
778 const gpa = self.base.allocator;
749 const gpa = self.base.comp.gpa;
750 const target = self.base.comp.root_mod.resolved_target.result;
779751 const mtime: u64 = mtime: {
780752 const stat = file.stat() catch break :mtime 0;
781753 break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000)));
......@@ -798,8 +770,8 @@ fn parseObject(
798770 else => unreachable,
799771 };
800772 const detected_platform = object.getPlatform();
801 const this_cpu_arch = self.base.options.target.cpu.arch;
802 const this_platform = Platform.fromTarget(self.base.options.target);
773 const this_cpu_arch = target.cpu.arch;
774 const this_platform = Platform.fromTarget(target);
803775
804776 if (this_cpu_arch != detected_cpu_arch or
805777 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
......@@ -826,8 +798,10 @@ pub fn parseLibrary(
826798 const tracy = trace(@src());
827799 defer tracy.end();
828800
801 const target = self.base.comp.root_mod.resolved_target.result;
802
829803 if (fat.isFatLibrary(file)) {
830 const offset = try self.parseFatLibrary(file, self.base.options.target.cpu.arch, ctx);
804 const offset = try self.parseFatLibrary(file, target.cpu.arch, ctx);
831805 try file.seekTo(offset);
832806
833807 if (Archive.isArchive(file, offset)) {
......@@ -868,7 +842,7 @@ pub fn parseFatLibrary(
868842 cpu_arch: std.Target.Cpu.Arch,
869843 ctx: *ParseErrorCtx,
870844) ParseError!u64 {
871 const gpa = self.base.allocator;
845 const gpa = self.base.comp.gpa;
872846
873847 const fat_archs = try fat.parseArchs(gpa, file);
874848 defer gpa.free(fat_archs);
......@@ -892,7 +866,8 @@ fn parseArchive(
892866 must_link: bool,
893867 ctx: *ParseErrorCtx,
894868) ParseError!void {
895 const gpa = self.base.allocator;
869 const gpa = self.base.comp.gpa;
870 const target = self.base.comp.root_mod.resolved_target.result;
896871
897872 // We take ownership of the file so that we can store it for the duration of symbol resolution.
898873 // TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF?
......@@ -922,8 +897,8 @@ fn parseArchive(
922897 else => unreachable,
923898 };
924899 const detected_platform = object.getPlatform();
925 const this_cpu_arch = self.base.options.target.cpu.arch;
926 const this_platform = Platform.fromTarget(self.base.options.target);
900 const this_cpu_arch = target.cpu.arch;
901 const this_platform = Platform.fromTarget(target);
927902
928903 if (this_cpu_arch != detected_cpu_arch or
929904 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
......@@ -973,7 +948,8 @@ fn parseDylib(
973948 dylib_options: DylibOpts,
974949 ctx: *ParseErrorCtx,
975950) ParseError!void {
976 const gpa = self.base.allocator;
951 const gpa = self.base.comp.gpa;
952 const target = self.base.comp.root_mod.resolved_target.result;
977953 const file_stat = try file.stat();
978954 const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow;
979955
......@@ -997,8 +973,8 @@ fn parseDylib(
997973 else => unreachable,
998974 };
999975 const detected_platform = dylib.getPlatform(contents);
1000 const this_cpu_arch = self.base.options.target.cpu.arch;
1001 const this_platform = Platform.fromTarget(self.base.options.target);
976 const this_cpu_arch = target.cpu.arch;
977 const this_platform = Platform.fromTarget(target);
1002978
1003979 if (this_cpu_arch != detected_cpu_arch or
1004980 (detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
......@@ -1019,7 +995,9 @@ fn parseLibStub(
1019995 dylib_options: DylibOpts,
1020996 ctx: *ParseErrorCtx,
1021997) ParseError!void {
1022 const gpa = self.base.allocator;
998 const gpa = self.base.comp.gpa;
999 const target = self.base.comp.root_mod.resolved_target.result;
1000
10231001 var lib_stub = try LibStub.loadFromFile(gpa, file);
10241002 defer lib_stub.deinit();
10251003
......@@ -1027,7 +1005,7 @@ fn parseLibStub(
10271005
10281006 // Verify target
10291007 {
1030 var matcher = try Dylib.TargetMatcher.init(gpa, self.base.options.target);
1008 var matcher = try Dylib.TargetMatcher.init(gpa, target);
10311009 defer matcher.deinit();
10321010
10331011 const first_tbd = lib_stub.inner[0];
......@@ -1050,7 +1028,7 @@ fn parseLibStub(
10501028
10511029 try dylib.parseFromStub(
10521030 gpa,
1053 self.base.options.target,
1031 target,
10541032 lib_stub,
10551033 @intCast(self.dylibs.items.len), // TODO defer it till later
10561034 dependent_libs,
......@@ -1072,7 +1050,7 @@ fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts, ctx: *ParseErr
10721050 }
10731051 }
10741052
1075 const gpa = self.base.allocator;
1053 const gpa = self.base.comp.gpa;
10761054 const gop = try self.dylibs_map.getOrPut(gpa, dylib.id.?.name);
10771055 if (gop.found_existing) return error.DylibAlreadyExists;
10781056
......@@ -1080,7 +1058,7 @@ fn addDylib(self: *MachO, dylib: Dylib, dylib_options: DylibOpts, ctx: *ParseErr
10801058 try self.dylibs.append(gpa, dylib);
10811059
10821060 const should_link_dylib_even_if_unreachable = blk: {
1083 if (self.base.options.dead_strip_dylibs and !dylib_options.needed) break :blk false;
1061 if (self.dead_strip_dylibs and !dylib_options.needed) break :blk false;
10841062 break :blk !(dylib_options.dependent or self.referenced_dylibs.contains(gop.value_ptr.*));
10851063 };
10861064
......@@ -1098,7 +1076,8 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void {
10981076 // 2) afterwards, we parse dependents of the included dylibs
10991077 // TODO this should not be performed if the user specifies `-flat_namespace` flag.
11001078 // See ld64 manpages.
1101 const gpa = self.base.allocator;
1079 const comp = self.base.comp;
1080 const gpa = comp.gpa;
11021081
11031082 while (dependent_libs.readItem()) |dep_id| {
11041083 defer dep_id.id.deinit(gpa);
......@@ -1118,7 +1097,7 @@ pub fn parseDependentLibs(self: *MachO, dependent_libs: anytype) !void {
11181097 var checked_paths = std.ArrayList([]const u8).init(arena);
11191098
11201099 success: {
1121 if (self.base.options.sysroot) |root| {
1100 if (comp.sysroot) |root| {
11221101 const dir = try fs.path.join(arena, &[_][]const u8{ root, dirname });
11231102 if (try accessLibPath(gpa, &test_path, &checked_paths, dir, stem)) break :success;
11241103 }
......@@ -1162,7 +1141,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {
11621141 log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset });
11631142
11641143 // Gather relocs which can be resolved.
1165 var relocs = std.ArrayList(*Relocation).init(self.base.allocator);
1144 const gpa = self.base.comp.gpa;
1145 var relocs = std.ArrayList(*Relocation).init(gpa);
11661146 defer relocs.deinit();
11671147
11681148 if (self.relocs.getPtr(atom_index)) |rels| {
......@@ -1194,7 +1174,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {
11941174
11951175fn writeToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void {
11961176 const segment = self.segments.items[segment_index];
1197 const cpu_arch = self.base.options.target.cpu.arch;
1177 const target = self.base.comp.root_mod.resolved_target.result;
1178 const cpu_arch = target.cpu.arch;
11981179 const nwritten = if (!segment.isWriteable())
11991180 try task.writeMemProtected(addr, code, cpu_arch)
12001181 else
......@@ -1237,8 +1218,9 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
12371218fn writeStubHelperPreamble(self: *MachO) !void {
12381219 if (self.stub_helper_preamble_allocated) return;
12391220
1240 const gpa = self.base.allocator;
1241 const cpu_arch = self.base.options.target.cpu.arch;
1221 const gpa = self.base.comp.gpa;
1222 const target = self.base.comp.root_mod.resolved_target.result;
1223 const cpu_arch = target.cpu.arch;
12421224 const size = stubs.stubHelperPreambleSize(cpu_arch);
12431225
12441226 var buf = try std.ArrayList(u8).initCapacity(gpa, size);
......@@ -1264,11 +1246,12 @@ fn writeStubHelperPreamble(self: *MachO) !void {
12641246}
12651247
12661248fn writeStubTableEntry(self: *MachO, index: usize) !void {
1249 const target = self.base.comp.root_mod.resolved_target.result;
12671250 const stubs_sect_id = self.stubs_section_index.?;
12681251 const stub_helper_sect_id = self.stub_helper_section_index.?;
12691252 const laptr_sect_id = self.la_symbol_ptr_section_index.?;
12701253
1271 const cpu_arch = self.base.options.target.cpu.arch;
1254 const cpu_arch = target.cpu.arch;
12721255 const stub_entry_size = stubs.stubSize(cpu_arch);
12731256 const stub_helper_entry_size = stubs.stubHelperSize(cpu_arch);
12741257 const stub_helper_preamble_size = stubs.stubHelperPreambleSize(cpu_arch);
......@@ -1290,7 +1273,7 @@ fn writeStubTableEntry(self: *MachO, index: usize) !void {
12901273 self.stub_table_count_dirty = false;
12911274 }
12921275
1293 const gpa = self.base.allocator;
1276 const gpa = self.base.comp.gpa;
12941277
12951278 const stubs_header = self.sections.items(.header)[stubs_sect_id];
12961279 const stub_helper_header = self.sections.items(.header)[stub_helper_sect_id];
......@@ -1469,7 +1452,7 @@ const CreateAtomOpts = struct {
14691452};
14701453
14711454pub fn createAtom(self: *MachO, sym_index: u32, opts: CreateAtomOpts) !Atom.Index {
1472 const gpa = self.base.allocator;
1455 const gpa = self.base.comp.gpa;
14731456 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
14741457 const atom = try self.atoms.addOne(gpa);
14751458 atom.* = .{};
......@@ -1481,7 +1464,7 @@ pub fn createAtom(self: *MachO, sym_index: u32, opts: CreateAtomOpts) !Atom.Inde
14811464}
14821465
14831466pub fn createTentativeDefAtoms(self: *MachO) !void {
1484 const gpa = self.base.allocator;
1467 const gpa = self.base.comp.gpa;
14851468
14861469 for (self.globals.items) |global| {
14871470 const sym = self.getSymbolPtr(global);
......@@ -1536,7 +1519,8 @@ pub fn createDyldPrivateAtom(self: *MachO) !void {
15361519 .size = @sizeOf(u64),
15371520 .alignment = .@"8",
15381521 });
1539 try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, atom_index);
1522 const gpa = self.base.comp.gpa;
1523 try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
15401524
15411525 if (self.data_section_index == null) {
15421526 self.data_section_index = try self.initSection("__DATA", "__data", .{});
......@@ -1560,7 +1544,7 @@ pub fn createDyldPrivateAtom(self: *MachO) !void {
15601544}
15611545
15621546fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: SymbolWithLoc) !Atom.Index {
1563 const gpa = self.base.allocator;
1547 const gpa = self.base.comp.gpa;
15641548 const size = 3 * @sizeOf(u64);
15651549 const required_alignment: Alignment = .@"1";
15661550 const sym_index = try self.allocateSymbol();
......@@ -1593,9 +1577,10 @@ fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: S
15931577}
15941578
15951579pub fn createMhExecuteHeaderSymbol(self: *MachO) !void {
1596 if (self.base.options.output_mode != .Exe) return;
1580 const output_mode = self.base.comp.config.output_mode;
1581 if (output_mode != .Exe) return;
15971582
1598 const gpa = self.base.allocator;
1583 const gpa = self.base.comp.gpa;
15991584 const sym_index = try self.allocateSymbol();
16001585 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
16011586 const sym = self.getSymbolPtr(sym_loc);
......@@ -1622,7 +1607,7 @@ pub fn createDsoHandleSymbol(self: *MachO) !void {
16221607 const global = self.getGlobalPtr("___dso_handle") orelse return;
16231608 if (!self.getSymbol(global.*).undf()) return;
16241609
1625 const gpa = self.base.allocator;
1610 const gpa = self.base.comp.gpa;
16261611 const sym_index = try self.allocateSymbol();
16271612 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
16281613 const sym = self.getSymbolPtr(sym_loc);
......@@ -1643,16 +1628,19 @@ pub fn createDsoHandleSymbol(self: *MachO) !void {
16431628}
16441629
16451630pub fn resolveSymbols(self: *MachO) !void {
1631 const comp = self.base.comp;
1632 const output_mode = comp.config.output_mode;
16461633 // We add the specified entrypoint as the first unresolved symbols so that
16471634 // we search for it in libraries should there be no object files specified
16481635 // on the linker line.
1649 if (self.base.options.output_mode == .Exe) {
1650 const entry_name = self.base.options.entry orelse load_commands.default_entry_point;
1651 _ = try self.addUndefined(entry_name, .{});
1636 if (output_mode == .Exe) {
1637 if (self.entry_name) |entry_name| {
1638 _ = try self.addUndefined(entry_name, .{});
1639 }
16521640 }
16531641
16541642 // Force resolution of any symbols requested by the user.
1655 for (self.base.options.force_undefined_symbols.keys()) |sym_name| {
1643 for (comp.force_undefined_symbols.keys()) |sym_name| {
16561644 _ = try self.addUndefined(sym_name, .{});
16571645 }
16581646
......@@ -1667,7 +1655,7 @@ pub fn resolveSymbols(self: *MachO) !void {
16671655 if (self.unresolved.count() > 0 and self.dyld_stub_binder_index == null) {
16681656 self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .{ .add_got = true });
16691657 }
1670 if (!self.base.options.single_threaded and self.mode == .incremental) {
1658 if (comp.config.any_non_single_threaded and self.mode == .incremental) {
16711659 _ = try self.addUndefined("__tlv_bootstrap", .{});
16721660 }
16731661
......@@ -1686,7 +1674,7 @@ pub fn resolveSymbols(self: *MachO) !void {
16861674}
16871675
16881676fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void {
1689 const gpa = self.base.allocator;
1677 const gpa = self.base.comp.gpa;
16901678 const sym = self.getSymbol(current);
16911679 const sym_name = self.getSymbolName(current);
16921680
......@@ -1800,7 +1788,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u32) !void {
18001788fn resolveSymbolsInArchives(self: *MachO) !void {
18011789 if (self.archives.items.len == 0) return;
18021790
1803 const gpa = self.base.allocator;
1791 const gpa = self.base.comp.gpa;
18041792 var next_sym: usize = 0;
18051793 loop: while (next_sym < self.unresolved.count()) {
18061794 const global = self.globals.items[self.unresolved.keys()[next_sym]];
......@@ -1829,7 +1817,7 @@ fn resolveSymbolsInArchives(self: *MachO) !void {
18291817fn resolveSymbolsInDylibs(self: *MachO) !void {
18301818 if (self.dylibs.items.len == 0) return;
18311819
1832 const gpa = self.base.allocator;
1820 const gpa = self.base.comp.gpa;
18331821 var next_sym: usize = 0;
18341822 loop: while (next_sym < self.unresolved.count()) {
18351823 const global_index = self.unresolved.keys()[next_sym];
......@@ -1863,9 +1851,10 @@ fn resolveSymbolsInDylibs(self: *MachO) !void {
18631851}
18641852
18651853fn resolveSymbolsAtLoading(self: *MachO) !void {
1866 const is_lib = self.base.options.output_mode == .Lib;
1867 const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib;
1868 const allow_undef = is_dyn_lib and (self.base.options.allow_shlib_undefined orelse false);
1854 const output_mode = self.base.comp.config.output_mode;
1855 const is_lib = output_mode == .Lib;
1856 const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib;
1857 const allow_undef = is_dyn_lib and self.base.allow_shlib_undefined;
18691858
18701859 var next_sym: usize = 0;
18711860 while (next_sym < self.unresolved.count()) {
......@@ -1899,6 +1888,7 @@ fn resolveSymbolsAtLoading(self: *MachO) !void {
18991888}
19001889
19011890fn resolveBoundarySymbols(self: *MachO) !void {
1891 const gpa = self.base.comp.gpa;
19021892 var next_sym: usize = 0;
19031893 while (next_sym < self.unresolved.count()) {
19041894 const global_index = self.unresolved.keys()[next_sym];
......@@ -1909,7 +1899,7 @@ fn resolveBoundarySymbols(self: *MachO) !void {
19091899 const sym_loc = SymbolWithLoc{ .sym_index = sym_index };
19101900 const sym = self.getSymbolPtr(sym_loc);
19111901 sym.* = .{
1912 .n_strx = try self.strtab.insert(self.base.allocator, self.getSymbolName(global.*)),
1902 .n_strx = try self.strtab.insert(gpa, self.getSymbolName(global.*)),
19131903 .n_type = macho.N_SECT | macho.N_EXT,
19141904 .n_sect = 0,
19151905 .n_desc = N_BOUNDARY,
......@@ -1929,9 +1919,9 @@ fn resolveBoundarySymbols(self: *MachO) !void {
19291919}
19301920
19311921pub fn deinit(self: *MachO) void {
1932 const gpa = self.base.allocator;
1922 const gpa = self.base.comp.gpa;
19331923
1934 if (self.llvm_object) |llvm_object| llvm_object.destroy(gpa);
1924 if (self.llvm_object) |llvm_object| llvm_object.deinit();
19351925
19361926 if (self.d_sym) |*d_sym| {
19371927 d_sym.deinit();
......@@ -2024,15 +2014,10 @@ pub fn deinit(self: *MachO) void {
20242014 bindings.deinit(gpa);
20252015 }
20262016 self.bindings.deinit(gpa);
2027
2028 for (self.misc_errors.items) |*err| {
2029 err.deinit(gpa);
2030 }
2031 self.misc_errors.deinit(gpa);
20322017}
20332018
20342019fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
2035 const gpa = self.base.allocator;
2020 const gpa = self.base.comp.gpa;
20362021 log.debug("freeAtom {d}", .{atom_index});
20372022
20382023 // Remove any relocs and base relocs associated with this Atom
......@@ -2124,7 +2109,8 @@ fn growAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignment:
21242109}
21252110
21262111pub fn allocateSymbol(self: *MachO) !u32 {
2127 try self.locals.ensureUnusedCapacity(self.base.allocator, 1);
2112 const gpa = self.base.comp.gpa;
2113 try self.locals.ensureUnusedCapacity(gpa, 1);
21282114
21292115 const index = blk: {
21302116 if (self.locals_free_list.popOrNull()) |index| {
......@@ -2150,7 +2136,8 @@ pub fn allocateSymbol(self: *MachO) !u32 {
21502136}
21512137
21522138fn allocateGlobal(self: *MachO) !u32 {
2153 try self.globals.ensureUnusedCapacity(self.base.allocator, 1);
2139 const gpa = self.base.comp.gpa;
2140 try self.globals.ensureUnusedCapacity(gpa, 1);
21542141
21552142 const index = blk: {
21562143 if (self.globals_free_list.popOrNull()) |index| {
......@@ -2169,9 +2156,10 @@ fn allocateGlobal(self: *MachO) !u32 {
21692156 return index;
21702157}
21712158
2172pub fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {
2173 if (self.got_table.lookup.contains(target)) return;
2174 const got_index = try self.got_table.allocateEntry(self.base.allocator, target);
2159pub fn addGotEntry(self: *MachO, reloc_target: SymbolWithLoc) !void {
2160 if (self.got_table.lookup.contains(reloc_target)) return;
2161 const gpa = self.base.comp.gpa;
2162 const got_index = try self.got_table.allocateEntry(gpa, reloc_target);
21752163 if (self.got_section_index == null) {
21762164 self.got_section_index = try self.initSection("__DATA_CONST", "__got", .{
21772165 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
......@@ -2180,19 +2168,22 @@ pub fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {
21802168 if (self.mode == .incremental) {
21812169 try self.writeOffsetTableEntry(got_index);
21822170 self.got_table_count_dirty = true;
2183 self.markRelocsDirtyByTarget(target);
2171 self.markRelocsDirtyByTarget(reloc_target);
21842172 }
21852173}
21862174
2187pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
2188 if (self.stub_table.lookup.contains(target)) return;
2189 const stub_index = try self.stub_table.allocateEntry(self.base.allocator, target);
2175pub fn addStubEntry(self: *MachO, reloc_target: SymbolWithLoc) !void {
2176 if (self.stub_table.lookup.contains(reloc_target)) return;
2177 const comp = self.base.comp;
2178 const gpa = comp.gpa;
2179 const cpu_arch = comp.root_mod.resolved_target.result.cpu.arch;
2180 const stub_index = try self.stub_table.allocateEntry(gpa, reloc_target);
21902181 if (self.stubs_section_index == null) {
21912182 self.stubs_section_index = try self.initSection("__TEXT", "__stubs", .{
21922183 .flags = macho.S_SYMBOL_STUBS |
21932184 macho.S_ATTR_PURE_INSTRUCTIONS |
21942185 macho.S_ATTR_SOME_INSTRUCTIONS,
2195 .reserved2 = stubs.stubSize(self.base.options.target.cpu.arch),
2186 .reserved2 = stubs.stubSize(cpu_arch),
21962187 });
21972188 self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{
21982189 .flags = macho.S_REGULAR |
......@@ -2206,13 +2197,14 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
22062197 if (self.mode == .incremental) {
22072198 try self.writeStubTableEntry(stub_index);
22082199 self.stub_table_count_dirty = true;
2209 self.markRelocsDirtyByTarget(target);
2200 self.markRelocsDirtyByTarget(reloc_target);
22102201 }
22112202}
22122203
2213pub fn addTlvPtrEntry(self: *MachO, target: SymbolWithLoc) !void {
2214 if (self.tlv_ptr_table.lookup.contains(target)) return;
2215 _ = try self.tlv_ptr_table.allocateEntry(self.base.allocator, target);
2204pub fn addTlvPtrEntry(self: *MachO, reloc_target: SymbolWithLoc) !void {
2205 if (self.tlv_ptr_table.lookup.contains(reloc_target)) return;
2206 const gpa = self.base.comp.gpa;
2207 _ = try self.tlv_ptr_table.allocateEntry(gpa, reloc_target);
22162208 if (self.tlv_ptr_section_index == null) {
22172209 self.tlv_ptr_section_index = try self.initSection("__DATA", "__thread_ptrs", .{
22182210 .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS,
......@@ -2236,7 +2228,8 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air:
22362228 self.freeUnnamedConsts(decl_index);
22372229 Atom.freeRelocations(self, atom_index);
22382230
2239 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2231 const gpa = self.base.comp.gpa;
2232 var code_buffer = std.ArrayList(u8).init(gpa);
22402233 defer code_buffer.deinit();
22412234
22422235 var decl_state = if (self.d_sym) |*d_sym|
......@@ -2279,8 +2272,8 @@ pub fn updateFunc(self: *MachO, mod: *Module, func_index: InternPool.Index, air:
22792272}
22802273
22812274pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
2282 const gpa = self.base.allocator;
2283 const mod = self.base.options.module.?;
2275 const gpa = self.base.comp.gpa;
2276 const mod = self.base.comp.module.?;
22842277 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
22852278 if (!gop.found_existing) {
22862279 gop.value_ptr.* = .{};
......@@ -2318,7 +2311,7 @@ fn lowerConst(
23182311 sect_id: u8,
23192312 src_loc: Module.SrcLoc,
23202313) !LowerConstResult {
2321 const gpa = self.base.allocator;
2314 const gpa = self.base.comp.gpa;
23222315
23232316 var code_buffer = std.ArrayList(u8).init(gpa);
23242317 defer code_buffer.deinit();
......@@ -2366,6 +2359,8 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex)
23662359 const tracy = trace(@src());
23672360 defer tracy.end();
23682361
2362 const comp = self.base.comp;
2363 const gpa = comp.gpa;
23692364 const decl = mod.declPtr(decl_index);
23702365
23712366 if (decl.val.getExternFunc(mod)) |_| {
......@@ -2375,14 +2370,14 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex)
23752370 if (decl.isExtern(mod)) {
23762371 // TODO make this part of getGlobalSymbol
23772372 const name = mod.intern_pool.stringToSlice(decl.name);
2378 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
2379 defer self.base.allocator.free(sym_name);
2373 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
2374 defer gpa.free(sym_name);
23802375 _ = try self.addUndefined(sym_name, .{ .add_got = true });
23812376 return;
23822377 }
23832378
23842379 const is_threadlocal = if (decl.val.getVariable(mod)) |variable|
2385 variable.is_threadlocal and !self.base.options.single_threaded
2380 variable.is_threadlocal and comp.config.any_non_single_threaded
23862381 else
23872382 false;
23882383 if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index);
......@@ -2391,7 +2386,7 @@ pub fn updateDecl(self: *MachO, mod: *Module, decl_index: InternPool.DeclIndex)
23912386 const sym_index = self.getAtom(atom_index).getSymbolIndex().?;
23922387 Atom.freeRelocations(self, atom_index);
23932388
2394 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
2389 var code_buffer = std.ArrayList(u8).init(gpa);
23952390 defer code_buffer.deinit();
23962391
23972392 var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
......@@ -2449,8 +2444,8 @@ fn updateLazySymbolAtom(
24492444 atom_index: Atom.Index,
24502445 section_index: u8,
24512446) !void {
2452 const gpa = self.base.allocator;
2453 const mod = self.base.options.module.?;
2447 const gpa = self.base.comp.gpa;
2448 const mod = self.base.comp.module.?;
24542449
24552450 var required_alignment: Alignment = .none;
24562451 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -2514,8 +2509,9 @@ fn updateLazySymbolAtom(
25142509}
25152510
25162511pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.Index {
2517 const mod = self.base.options.module.?;
2518 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl(mod));
2512 const mod = self.base.comp.module.?;
2513 const gpa = self.base.comp.gpa;
2514 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(mod));
25192515 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
25202516 if (!gop.found_existing) gop.value_ptr.* = .{};
25212517 const metadata: struct { atom: *Atom.Index, state: *LazySymbolMetadata.State } = switch (sym.kind) {
......@@ -2529,7 +2525,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
25292525 .unused => {
25302526 const sym_index = try self.allocateSymbol();
25312527 metadata.atom.* = try self.createAtom(sym_index, .{});
2532 try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, metadata.atom.*);
2528 try self.atom_by_index_table.putNoClobber(gpa, sym_index, metadata.atom.*);
25332529 },
25342530 .pending_flush => return metadata.atom.*,
25352531 .flushed => {},
......@@ -2545,7 +2541,7 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
25452541}
25462542
25472543fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: InternPool.DeclIndex) !void {
2548 const mod = self.base.options.module.?;
2544 const mod = self.base.comp.module.?;
25492545 // Lowering a TLV on macOS involves two stages:
25502546 // 1. first we lower the initializer into appopriate section (__thread_data or __thread_bss)
25512547 // 2. next, we create a corresponding threadlocal variable descriptor in __thread_vars
......@@ -2556,7 +2552,7 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: InternPo
25562552 const init_sym_index = init_atom.getSymbolIndex().?;
25572553 Atom.freeRelocations(self, init_atom_index);
25582554
2559 const gpa = self.base.allocator;
2555 const gpa = self.base.comp.gpa;
25602556
25612557 var code_buffer = std.ArrayList(u8).init(gpa);
25622558 defer code_buffer.deinit();
......@@ -2640,11 +2636,12 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: InternPo
26402636}
26412637
26422638pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: InternPool.DeclIndex) !Atom.Index {
2643 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
2639 const gpa = self.base.comp.gpa;
2640 const gop = try self.decls.getOrPut(gpa, decl_index);
26442641 if (!gop.found_existing) {
26452642 const sym_index = try self.allocateSymbol();
26462643 const atom_index = try self.createAtom(sym_index, .{});
2647 try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, atom_index);
2644 try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
26482645 gop.value_ptr.* = .{
26492646 .atom = atom_index,
26502647 .section = self.getDeclOutputSection(decl_index),
......@@ -2655,17 +2652,17 @@ pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: InternPool.DeclIndex) !A
26552652}
26562653
26572654fn getDeclOutputSection(self: *MachO, decl_index: InternPool.DeclIndex) u8 {
2658 const decl = self.base.options.module.?.declPtr(decl_index);
2655 const decl = self.base.comp.module.?.declPtr(decl_index);
26592656 const ty = decl.ty;
26602657 const val = decl.val;
2661 const mod = self.base.options.module.?;
2658 const mod = self.base.comp.module.?;
26622659 const zig_ty = ty.zigTypeTag(mod);
2663 const mode = self.base.options.optimize_mode;
2664 const single_threaded = self.base.options.single_threaded;
2660 const any_non_single_threaded = self.base.comp.config.any_non_single_threaded;
2661 const optimize_mode = self.base.comp.root_mod.optimize_mode;
26652662 const sect_id: u8 = blk: {
26662663 // TODO finish and audit this function
26672664 if (val.isUndefDeep(mod)) {
2668 if (mode == .ReleaseFast or mode == .ReleaseSmall) {
2665 if (optimize_mode == .ReleaseFast or optimize_mode == .ReleaseSmall) {
26692666 @panic("TODO __DATA,__bss");
26702667 } else {
26712668 break :blk self.data_section_index.?;
......@@ -2673,7 +2670,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: InternPool.DeclIndex) u8 {
26732670 }
26742671
26752672 if (val.getVariable(mod)) |variable| {
2676 if (variable.is_threadlocal and !single_threaded) {
2673 if (variable.is_threadlocal and any_non_single_threaded) {
26772674 break :blk self.thread_data_section_index.?;
26782675 }
26792676 break :blk self.data_section_index.?;
......@@ -2694,8 +2691,8 @@ fn getDeclOutputSection(self: *MachO, decl_index: InternPool.DeclIndex) u8 {
26942691}
26952692
26962693fn updateDeclCode(self: *MachO, decl_index: InternPool.DeclIndex, code: []u8) !u64 {
2697 const gpa = self.base.allocator;
2698 const mod = self.base.options.module.?;
2694 const gpa = self.base.comp.gpa;
2695 const mod = self.base.comp.module.?;
26992696 const decl = mod.declPtr(decl_index);
27002697
27012698 const required_alignment = decl.getAlignment(mod);
......@@ -2782,12 +2779,10 @@ pub fn updateExports(
27822779 if (self.llvm_object) |llvm_object|
27832780 return llvm_object.updateExports(mod, exported, exports);
27842781
2785 if (self.base.options.emit == null) return;
2786
27872782 const tracy = trace(@src());
27882783 defer tracy.end();
27892784
2790 const gpa = self.base.allocator;
2785 const gpa = self.base.comp.gpa;
27912786
27922787 const metadata = switch (exported) {
27932788 .decl_index => |decl_index| blk: {
......@@ -2912,8 +2907,8 @@ pub fn deleteDeclExport(
29122907 if (self.llvm_object) |_| return;
29132908 const metadata = self.decls.getPtr(decl_index) orelse return;
29142909
2915 const gpa = self.base.allocator;
2916 const mod = self.base.options.module.?;
2910 const gpa = self.base.comp.gpa;
2911 const mod = self.base.comp.module.?;
29172912 const exp_name = try std.fmt.allocPrint(gpa, "_{s}", .{mod.intern_pool.stringToSlice(name)});
29182913 defer gpa.free(exp_name);
29192914 const sym_index = metadata.getExportPtr(self, exp_name) orelse return;
......@@ -2941,7 +2936,7 @@ pub fn deleteDeclExport(
29412936}
29422937
29432938fn freeUnnamedConsts(self: *MachO, decl_index: InternPool.DeclIndex) void {
2944 const gpa = self.base.allocator;
2939 const gpa = self.base.comp.gpa;
29452940 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
29462941 for (unnamed_consts.items) |atom| {
29472942 self.freeAtom(atom);
......@@ -2951,7 +2946,8 @@ fn freeUnnamedConsts(self: *MachO, decl_index: InternPool.DeclIndex) void {
29512946
29522947pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {
29532948 if (self.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
2954 const mod = self.base.options.module.?;
2949 const gpa = self.base.comp.gpa;
2950 const mod = self.base.comp.module.?;
29552951 const decl = mod.declPtr(decl_index);
29562952
29572953 log.debug("freeDecl {*}", .{decl});
......@@ -2960,7 +2956,7 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void {
29602956 var kv = const_kv;
29612957 self.freeAtom(kv.value.atom);
29622958 self.freeUnnamedConsts(decl_index);
2963 kv.value.exports.deinit(self.base.allocator);
2959 kv.value.exports.deinit(gpa);
29642960 }
29652961
29662962 if (self.d_sym) |*d_sym| {
......@@ -2993,8 +2989,8 @@ pub fn lowerAnonDecl(
29932989 explicit_alignment: InternPool.Alignment,
29942990 src_loc: Module.SrcLoc,
29952991) !codegen.Result {
2996 const gpa = self.base.allocator;
2997 const mod = self.base.options.module.?;
2992 const gpa = self.base.comp.gpa;
2993 const mod = self.base.comp.module.?;
29982994 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
29992995 const decl_alignment = switch (explicit_alignment) {
30002996 .none => ty.abiAlignment(mod),
......@@ -3057,11 +3053,18 @@ pub fn getAnonDeclVAddr(self: *MachO, decl_val: InternPool.Index, reloc_info: li
30573053 return 0;
30583054}
30593055
3060fn populateMissingMetadata(self: *MachO) !void {
3056const PopulateMissingMetadataOptions = struct {
3057 symbol_count_hint: u64,
3058 program_code_size_hint: u64,
3059};
3060
3061fn populateMissingMetadata(self: *MachO, options: PopulateMissingMetadataOptions) !void {
30613062 assert(self.mode == .incremental);
30623063
3063 const gpa = self.base.allocator;
3064 const cpu_arch = self.base.options.target.cpu.arch;
3064 const comp = self.base.comp;
3065 const gpa = comp.gpa;
3066 const target = comp.root_mod.resolved_target.result;
3067 const cpu_arch = target.cpu.arch;
30653068 const pagezero_vmsize = self.calcPagezeroSize();
30663069
30673070 if (self.pagezero_segment_cmd_index == null) {
......@@ -3078,7 +3081,7 @@ fn populateMissingMetadata(self: *MachO) !void {
30783081 if (self.header_segment_cmd_index == null) {
30793082 // The first __TEXT segment is immovable and covers MachO header and load commands.
30803083 self.header_segment_cmd_index = @as(u8, @intCast(self.segments.items.len));
3081 const ideal_size = @max(self.base.options.headerpad_size orelse 0, default_headerpad_size);
3084 const ideal_size = self.headerpad_size;
30823085 const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), getPageSize(cpu_arch));
30833086
30843087 log.debug("found __TEXT segment (header-only) free space 0x{x} to 0x{x}", .{ 0, needed_size });
......@@ -3098,7 +3101,7 @@ fn populateMissingMetadata(self: *MachO) !void {
30983101 if (self.text_section_index == null) {
30993102 // Sadly, segments need unique string identfiers for some reason.
31003103 self.text_section_index = try self.allocateSection("__TEXT1", "__text", .{
3101 .size = self.base.options.program_code_size_hint,
3104 .size = options.program_code_size_hint,
31023105 .alignment = switch (cpu_arch) {
31033106 .x86_64 => 1,
31043107 .aarch64 => @sizeOf(u32),
......@@ -3134,7 +3137,7 @@ fn populateMissingMetadata(self: *MachO) !void {
31343137
31353138 if (self.got_section_index == null) {
31363139 self.got_section_index = try self.allocateSection("__DATA_CONST", "__got", .{
3137 .size = @sizeOf(u64) * self.base.options.symbol_count_hint,
3140 .size = @sizeOf(u64) * options.symbol_count_hint,
31383141 .alignment = @alignOf(u64),
31393142 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
31403143 .prot = macho.PROT.READ | macho.PROT.WRITE,
......@@ -3172,7 +3175,7 @@ fn populateMissingMetadata(self: *MachO) !void {
31723175 self.segment_table_dirty = true;
31733176 }
31743177
3175 if (!self.base.options.single_threaded) {
3178 if (comp.config.any_non_single_threaded) {
31763179 if (self.thread_vars_section_index == null) {
31773180 self.thread_vars_section_index = try self.allocateSection("__DATA2", "__thread_vars", .{
31783181 .size = @sizeOf(u64) * 3,
......@@ -3207,13 +3210,14 @@ fn populateMissingMetadata(self: *MachO) !void {
32073210}
32083211
32093212fn calcPagezeroSize(self: *MachO) u64 {
3210 const pagezero_vmsize = self.base.options.pagezero_size orelse default_pagezero_vmsize;
3211 const page_size = getPageSize(self.base.options.target.cpu.arch);
3212 const aligned_pagezero_vmsize = mem.alignBackward(u64, pagezero_vmsize, page_size);
3213 if (self.base.options.output_mode == .Lib) return 0;
3213 const output_mode = self.base.comp.config.output_mode;
3214 const target = self.base.comp.root_mod.resolved_target.result;
3215 const page_size = getPageSize(target.cpu.arch);
3216 const aligned_pagezero_vmsize = mem.alignBackward(u64, self.pagezero_vmsize, page_size);
3217 if (output_mode == .Lib) return 0;
32143218 if (aligned_pagezero_vmsize == 0) return 0;
3215 if (aligned_pagezero_vmsize != pagezero_vmsize) {
3216 log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{pagezero_vmsize});
3219 if (aligned_pagezero_vmsize != self.pagezero_vmsize) {
3220 log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{self.pagezero_vmsize});
32173221 log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize});
32183222 }
32193223 return aligned_pagezero_vmsize;
......@@ -3228,7 +3232,8 @@ const InitSectionOpts = struct {
32283232pub fn initSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: InitSectionOpts) !u8 {
32293233 log.debug("creating section '{s},{s}'", .{ segname, sectname });
32303234 const index = @as(u8, @intCast(self.sections.slice().len));
3231 try self.sections.append(self.base.allocator, .{
3235 const gpa = self.base.comp.gpa;
3236 try self.sections.append(gpa, .{
32323237 .segment_index = undefined, // Segments will be created automatically later down the pipeline
32333238 .header = .{
32343239 .sectname = makeStaticString(sectname),
......@@ -3248,8 +3253,9 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
32483253 flags: u32 = macho.S_REGULAR,
32493254 reserved2: u32 = 0,
32503255}) !u8 {
3251 const gpa = self.base.allocator;
3252 const page_size = getPageSize(self.base.options.target.cpu.arch);
3256 const gpa = self.base.comp.gpa;
3257 const target = self.base.comp.root_mod.resolved_target.result;
3258 const page_size = getPageSize(target.cpu.arch);
32533259 // In incremental context, we create one section per segment pairing. This way,
32543260 // we can move the segment in raw file as we please.
32553261 const segment_id = @as(u8, @intCast(self.segments.items.len));
......@@ -3304,7 +3310,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
33043310 const segment = &self.segments.items[segment_index];
33053311 const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id];
33063312 const sect_capacity = self.allocatedSize(header.offset);
3307 const page_size = getPageSize(self.base.options.target.cpu.arch);
3313 const target = self.base.comp.root_mod.resolved_target.result;
3314 const page_size = getPageSize(target.cpu.arch);
33083315
33093316 if (needed_size > sect_capacity) {
33103317 const new_offset = self.findFreeSpace(needed_size, page_size);
......@@ -3344,7 +3351,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
33443351}
33453352
33463353fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void {
3347 const page_size = getPageSize(self.base.options.target.cpu.arch);
3354 const target = self.base.comp.root_mod.resolved_target.result;
3355 const page_size = getPageSize(target.cpu.arch);
33483356 const header = &self.sections.items(.header)[sect_id];
33493357 const segment = self.getSegmentPtr(sect_id);
33503358 const increased_size = padToIdeal(needed_size);
......@@ -3521,7 +3529,7 @@ fn allocateAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignm
35213529
35223530pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {
35233531 _ = lib_name;
3524 const gpa = self.base.allocator;
3532 const gpa = self.base.comp.gpa;
35253533 const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name});
35263534 defer gpa.free(sym_name);
35273535 return self.addUndefined(sym_name, .{ .add_stub = true });
......@@ -3555,7 +3563,8 @@ pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void {
35553563}
35563564
35573565pub fn writeLinkeditSegmentData(self: *MachO) !void {
3558 const page_size = getPageSize(self.base.options.target.cpu.arch);
3566 const target = self.base.comp.root_mod.resolved_target.result;
3567 const page_size = getPageSize(target.cpu.arch);
35593568 const seg = self.getLinkeditSegmentPtr();
35603569 seg.filesize = 0;
35613570 seg.vmsize = 0;
......@@ -3582,7 +3591,7 @@ pub fn writeLinkeditSegmentData(self: *MachO) !void {
35823591}
35833592
35843593fn collectRebaseDataFromTableSection(self: *MachO, sect_id: u8, rebase: *Rebase, table: anytype) !void {
3585 const gpa = self.base.allocator;
3594 const gpa = self.base.comp.gpa;
35863595 const header = self.sections.items(.header)[sect_id];
35873596 const segment_index = self.sections.items(.segment_index)[sect_id];
35883597 const segment = self.segments.items[segment_index];
......@@ -3605,7 +3614,7 @@ fn collectRebaseDataFromTableSection(self: *MachO, sect_id: u8, rebase: *Rebase,
36053614}
36063615
36073616fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3608 const gpa = self.base.allocator;
3617 const gpa = self.base.comp.gpa;
36093618 const slice = self.sections.slice();
36103619
36113620 for (self.rebases.keys(), 0..) |atom_index, i| {
......@@ -3642,7 +3651,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
36423651 }
36433652
36443653 // Finally, unpack the rest.
3645 const cpu_arch = self.base.options.target.cpu.arch;
3654 const target = self.base.comp.root_mod.resolved_target.result;
3655 const cpu_arch = target.cpu.arch;
36463656 for (self.objects.items) |*object| {
36473657 for (object.atoms.items) |atom_index| {
36483658 const atom = self.getAtom(atom_index);
......@@ -3688,14 +3698,14 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
36883698 },
36893699 else => unreachable,
36903700 }
3691 const target = Atom.parseRelocTarget(self, .{
3701 const reloc_target = Atom.parseRelocTarget(self, .{
36923702 .object_id = atom.getFile().?,
36933703 .rel = rel,
36943704 .code = code,
36953705 .base_offset = ctx.base_offset,
36963706 .base_addr = ctx.base_addr,
36973707 });
3698 const target_sym = self.getSymbol(target);
3708 const target_sym = self.getSymbol(reloc_target);
36993709 if (target_sym.undf()) continue;
37003710
37013711 const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr));
......@@ -3715,7 +3725,7 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
37153725}
37163726
37173727fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, table: anytype) !void {
3718 const gpa = self.base.allocator;
3728 const gpa = self.base.comp.gpa;
37193729 const header = self.sections.items(.header)[sect_id];
37203730 const segment_index = self.sections.items(.segment_index)[sect_id];
37213731 const segment = self.segments.items[segment_index];
......@@ -3746,7 +3756,7 @@ fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, tab
37463756}
37473757
37483758fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
3749 const gpa = self.base.allocator;
3759 const gpa = self.base.comp.gpa;
37503760 const slice = self.sections.slice();
37513761
37523762 for (raw_bindings.keys(), 0..) |atom_index, i| {
......@@ -3797,7 +3807,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
37973807 }
37983808
37993809 // Finally, unpack the rest.
3800 const cpu_arch = self.base.options.target.cpu.arch;
3810 const target = self.base.comp.root_mod.resolved_target.result;
3811 const cpu_arch = target.cpu.arch;
38013812 for (self.objects.items) |*object| {
38023813 for (object.atoms.items) |atom_index| {
38033814 const atom = self.getAtom(atom_index);
......@@ -3885,12 +3896,13 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
38853896
38863897fn collectLazyBindData(self: *MachO, bind: anytype) !void {
38873898 const sect_id = self.la_symbol_ptr_section_index orelse return;
3899 const gpa = self.base.comp.gpa;
38883900 try self.collectBindDataFromTableSection(sect_id, bind, self.stub_table);
3889 try bind.finalize(self.base.allocator, self);
3901 try bind.finalize(gpa, self);
38903902}
38913903
38923904fn collectExportData(self: *MachO, trie: *Trie) !void {
3893 const gpa = self.base.allocator;
3905 const gpa = self.base.comp.gpa;
38943906
38953907 // TODO handle macho.EXPORT_SYMBOL_FLAGS_REEXPORT and macho.EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER.
38963908 log.debug("generating export trie", .{});
......@@ -3922,7 +3934,7 @@ fn writeDyldInfoData(self: *MachO) !void {
39223934 const tracy = trace(@src());
39233935 defer tracy.end();
39243936
3925 const gpa = self.base.allocator;
3937 const gpa = self.base.comp.gpa;
39263938
39273939 var rebase = Rebase{};
39283940 defer rebase.deinit(gpa);
......@@ -4015,7 +4027,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: anytype) !void {
40154027
40164028 const header = self.sections.items(.header)[stub_helper_section_index];
40174029
4018 const cpu_arch = self.base.options.target.cpu.arch;
4030 const target = self.base.comp.root_mod.resolved_target.result;
4031 const cpu_arch = target.cpu.arch;
40194032 const preamble_size = stubs.stubHelperPreambleSize(cpu_arch);
40204033 const stub_size = stubs.stubHelperSize(cpu_arch);
40214034 const stub_offset = stubs.stubOffsetInStubHelper(cpu_arch);
......@@ -4046,7 +4059,7 @@ fn addSymbolToFunctionStarts(self: *MachO, sym_loc: SymbolWithLoc, addresses: *s
40464059}
40474060
40484061fn writeFunctionStarts(self: *MachO) !void {
4049 const gpa = self.base.allocator;
4062 const gpa = self.base.comp.gpa;
40504063 const seg = self.segments.items[self.header_segment_cmd_index.?];
40514064
40524065 // We need to sort by address first
......@@ -4133,7 +4146,7 @@ fn filterDataInCode(
41334146}
41344147
41354148pub fn writeDataInCode(self: *MachO) !void {
4136 const gpa = self.base.allocator;
4149 const gpa = self.base.comp.gpa;
41374150 var out_dice = std.ArrayList(macho.data_in_code_entry).init(gpa);
41384151 defer out_dice.deinit();
41394152
......@@ -4211,13 +4224,15 @@ fn addLocalToSymtab(self: *MachO, sym_loc: SymbolWithLoc, locals: *std.ArrayList
42114224 if (sym.n_desc == N_BOUNDARY) return; // boundary symbol, skip
42124225 if (sym.ext()) return; // an export lands in its own symtab section, skip
42134226 if (self.symbolIsTemp(sym_loc)) return; // local temp symbol, skip
4227 const gpa = self.base.comp.gpa;
42144228 var out_sym = sym;
4215 out_sym.n_strx = try self.strtab.insert(self.base.allocator, self.getSymbolName(sym_loc));
4229 out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(sym_loc));
42164230 try locals.append(out_sym);
42174231}
42184232
42194233fn writeSymtab(self: *MachO) !SymtabCtx {
4220 const gpa = self.base.allocator;
4234 const comp = self.base.comp;
4235 const gpa = comp.gpa;
42214236
42224237 var locals = std.ArrayList(macho.nlist_64).init(gpa);
42234238 defer locals.deinit();
......@@ -4272,7 +4287,7 @@ fn writeSymtab(self: *MachO) !SymtabCtx {
42724287
42734288 // We generate stabs last in order to ensure that the strtab always has debug info
42744289 // strings trailing
4275 if (!self.base.options.strip) {
4290 if (comp.config.debug_format != .strip) {
42764291 for (self.objects.items) |object| {
42774292 assert(self.d_sym == null); // TODO
42784293 try self.generateSymbolStabs(object, &locals);
......@@ -4322,7 +4337,7 @@ fn generateSymbolStabs(
43224337) !void {
43234338 log.debug("generating stabs for '{s}'", .{object.name});
43244339
4325 const gpa = self.base.allocator;
4340 const gpa = self.base.comp.gpa;
43264341 var debug_info = object.parseDwarfInfo();
43274342
43284343 var lookup = DwarfInfo.AbbrevLookupTable.init(gpa);
......@@ -4450,7 +4465,7 @@ fn generateSymbolStabsForSymbol(
44504465 lookup: ?DwarfInfo.SubprogramLookupByName,
44514466 buf: *[4]macho.nlist_64,
44524467) ![]const macho.nlist_64 {
4453 const gpa = self.base.allocator;
4468 const gpa = self.base.comp.gpa;
44544469 const object = self.objects.items[sym_loc.getFile().?];
44554470 const sym = self.getSymbol(sym_loc);
44564471 const sym_name = self.getSymbolName(sym_loc);
......@@ -4536,7 +4551,7 @@ fn generateSymbolStabsForSymbol(
45364551}
45374552
45384553pub fn writeStrtab(self: *MachO) !void {
4539 const gpa = self.base.allocator;
4554 const gpa = self.base.comp.gpa;
45404555 const seg = self.getLinkeditSegmentPtr();
45414556 const offset = seg.fileoff + seg.filesize;
45424557 assert(mem.isAlignedGeneric(u64, offset, @alignOf(u64)));
......@@ -4565,7 +4580,7 @@ const SymtabCtx = struct {
45654580};
45664581
45674582pub fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
4568 const gpa = self.base.allocator;
4583 const gpa = self.base.comp.gpa;
45694584 const nstubs = @as(u32, @intCast(self.stub_table.lookup.count()));
45704585 const ngot_entries = @as(u32, @intCast(self.got_table.lookup.count()));
45714586 const nindirectsyms = nstubs * 2 + ngot_entries;
......@@ -4650,13 +4665,14 @@ pub fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, h
46504665}
46514666
46524667pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {
4668 const target = self.base.comp.root_mod.resolved_target.result;
46534669 const seg = self.getLinkeditSegmentPtr();
46544670 // Code signature data has to be 16-bytes aligned for Apple tools to recognize the file
46554671 // https://github.com/opensource-apple/cctools/blob/fdb4825f303fd5c0751be524babd32958181b3ed/libstuff/checkout.c#L271
46564672 const offset = mem.alignForward(u64, seg.fileoff + seg.filesize, 16);
46574673 const needed_size = code_sig.estimateSize(offset);
46584674 seg.filesize = offset + needed_size - seg.fileoff;
4659 seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(self.base.options.target.cpu.arch));
4675 seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(target.cpu.arch));
46604676 log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ offset, offset + needed_size });
46614677 // Pad out the space. We need to do this to calculate valid hashes for everything in the file
46624678 // except for code signature data.
......@@ -4667,11 +4683,13 @@ pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {
46674683}
46684684
46694685pub fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *CodeSignature) !void {
4686 const output_mode = self.base.comp.config.output_mode;
46704687 const seg_id = self.header_segment_cmd_index.?;
46714688 const seg = self.segments.items[seg_id];
46724689 const offset = self.codesig_cmd.dataoff;
46734690
4674 var buffer = std.ArrayList(u8).init(self.base.allocator);
4691 const gpa = self.base.comp.gpa;
4692 var buffer = std.ArrayList(u8).init(gpa);
46754693 defer buffer.deinit();
46764694 try buffer.ensureTotalCapacityPrecise(code_sig.size());
46774695 try code_sig.writeAdhocSignature(comp, .{
......@@ -4679,7 +4697,7 @@ pub fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *Cod
46794697 .exec_seg_base = seg.fileoff,
46804698 .exec_seg_limit = seg.filesize,
46814699 .file_size = offset,
4682 .output_mode = self.base.options.output_mode,
4700 .output_mode = output_mode,
46834701 }, buffer.writer());
46844702 assert(buffer.items.len == code_sig.size());
46854703
......@@ -4693,10 +4711,13 @@ pub fn writeCodeSignature(self: *MachO, comp: *const Compilation, code_sig: *Cod
46934711
46944712/// Writes Mach-O file header.
46954713pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
4714 const output_mode = self.base.comp.config.output_mode;
4715
46964716 var header: macho.mach_header_64 = .{};
46974717 header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL;
46984718
4699 switch (self.base.options.target.cpu.arch) {
4719 const target = self.base.comp.root_mod.resolved_target.result;
4720 switch (target.cpu.arch) {
47004721 .aarch64 => {
47014722 header.cputype = macho.CPU_TYPE_ARM64;
47024723 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
......@@ -4708,7 +4729,7 @@ pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
47084729 else => unreachable,
47094730 }
47104731
4711 switch (self.base.options.output_mode) {
4732 switch (output_mode) {
47124733 .Exe => {
47134734 header.filetype = macho.MH_EXECUTE;
47144735 },
......@@ -4817,7 +4838,7 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void {
48174838}
48184839
48194840pub fn addUndefined(self: *MachO, name: []const u8, flags: RelocFlags) !u32 {
4820 const gpa = self.base.allocator;
4841 const gpa = self.base.comp.gpa;
48214842
48224843 const gop = try self.getOrPutGlobalPtr(name);
48234844 const global_index = self.getGlobalIndex(name).?;
......@@ -4842,7 +4863,8 @@ pub fn addUndefined(self: *MachO, name: []const u8, flags: RelocFlags) !u32 {
48424863}
48434864
48444865fn updateRelocActions(self: *MachO, global_index: u32, flags: RelocFlags) !void {
4845 const act_gop = try self.actions.getOrPut(self.base.allocator, global_index);
4866 const gpa = self.base.comp.gpa;
4867 const act_gop = try self.actions.getOrPut(gpa, global_index);
48464868 if (!act_gop.found_existing) {
48474869 act_gop.value_ptr.* = .{};
48484870 }
......@@ -5022,7 +5044,7 @@ pub fn getOrPutGlobalPtr(self: *MachO, name: []const u8) !GetOrPutGlobalPtrResul
50225044 if (self.getGlobalPtr(name)) |ptr| {
50235045 return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr };
50245046 }
5025 const gpa = self.base.allocator;
5047 const gpa = self.base.comp.gpa;
50265048 const global_index = try self.allocateGlobal();
50275049 const global_name = try gpa.dupe(u8, name);
50285050 _ = try self.resolver.put(gpa, global_name, global_index);
......@@ -5060,15 +5082,16 @@ pub fn getTlvPtrEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {
50605082}
50615083
50625084pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {
5085 const target = self.base.comp.root_mod.resolved_target.result;
50635086 const index = self.stub_table.lookup.get(sym_with_loc) orelse return null;
50645087 const header = self.sections.items(.header)[self.stubs_section_index.?];
5065 return header.addr + stubs.stubSize(self.base.options.target.cpu.arch) * index;
5088 return header.addr + stubs.stubSize(target.cpu.arch) * index;
50665089}
50675090
50685091/// Returns symbol location corresponding to the set entrypoint if any.
50695092/// Asserts output mode is executable.
50705093pub fn getEntryPoint(self: MachO) ?SymbolWithLoc {
5071 const entry_name = self.base.options.entry orelse load_commands.default_entry_point;
5094 const entry_name = self.entry_name orelse return null;
50725095 const global = self.getGlobal(entry_name) orelse return null;
50735096 return global;
50745097}
......@@ -5086,11 +5109,13 @@ pub inline fn getPageSize(cpu_arch: std.Target.Cpu.Arch) u16 {
50865109 };
50875110}
50885111
5089pub fn requiresCodeSignature(options: *const link.Options) bool {
5090 if (options.entitlements) |_| return true;
5091 const cpu_arch = options.target.cpu.arch;
5092 const os_tag = options.target.os.tag;
5093 const abi = options.target.abi;
5112pub fn requiresCodeSignature(m: *MachO) bool {
5113 if (m.entitlements) |_| return true;
5114 const comp = m.base.comp;
5115 const target = comp.root_mod.resolved_target.result;
5116 const cpu_arch = target.cpu.arch;
5117 const os_tag = target.os.tag;
5118 const abi = target.abi;
50945119 if (cpu_arch == .aarch64 and (os_tag == .macos or abi == .simulator)) return true;
50955120 return false;
50965121}
......@@ -5171,7 +5196,9 @@ pub fn handleAndReportParseError(
51715196 err: ParseError,
51725197 ctx: *const ParseErrorCtx,
51735198) error{OutOfMemory}!void {
5174 const cpu_arch = self.base.options.target.cpu.arch;
5199 const target = self.base.comp.root_mod.resolved_target.result;
5200 const gpa = self.base.comp.gpa;
5201 const cpu_arch = target.cpu.arch;
51755202 switch (err) {
51765203 error.DylibAlreadyExists => {},
51775204 error.IncompatibleDylibVersion => {
......@@ -5188,7 +5215,7 @@ pub fn handleAndReportParseError(
51885215 },
51895216 error.UnknownFileType => try self.reportParseError(path, "unknown file type", .{}),
51905217 error.InvalidTarget, error.InvalidTargetFatLibrary => {
5191 var targets_string = std.ArrayList(u8).init(self.base.allocator);
5218 var targets_string = std.ArrayList(u8).init(gpa);
51925219 defer targets_string.deinit();
51935220
51945221 if (ctx.detected_targets.items.len > 1) {
......@@ -5206,7 +5233,7 @@ pub fn handleAndReportParseError(
52065233 error.InvalidTarget => try self.reportParseError(
52075234 path,
52085235 "invalid target: expected '{}', but found '{s}'",
5209 .{ Platform.fromTarget(self.base.options.target).fmtTarget(cpu_arch), targets_string.items },
5236 .{ Platform.fromTarget(target).fmtTarget(cpu_arch), targets_string.items },
52105237 ),
52115238 error.InvalidTargetFatLibrary => try self.reportParseError(
52125239 path,
......@@ -5226,14 +5253,15 @@ fn reportMissingLibraryError(
52265253 comptime format: []const u8,
52275254 args: anytype,
52285255) error{OutOfMemory}!void {
5229 const gpa = self.base.allocator;
5230 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
5256 const comp = self.base.comp;
5257 const gpa = comp.gpa;
5258 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
52315259 const notes = try gpa.alloc(File.ErrorMsg, checked_paths.len);
52325260 errdefer gpa.free(notes);
52335261 for (checked_paths, notes) |path, *note| {
52345262 note.* = .{ .msg = try std.fmt.allocPrint(gpa, "tried {s}", .{path}) };
52355263 }
5236 self.misc_errors.appendAssumeCapacity(.{
5264 comp.link_errors.appendAssumeCapacity(.{
52375265 .msg = try std.fmt.allocPrint(gpa, format, args),
52385266 .notes = notes,
52395267 });
......@@ -5246,15 +5274,16 @@ fn reportDependencyError(
52465274 comptime format: []const u8,
52475275 args: anytype,
52485276) error{OutOfMemory}!void {
5249 const gpa = self.base.allocator;
5250 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
5277 const comp = self.base.comp;
5278 const gpa = comp.gpa;
5279 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
52515280 var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2);
52525281 defer notes.deinit();
52535282 if (path) |p| {
52545283 notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{p}) });
52555284 }
52565285 notes.appendAssumeCapacity(.{ .msg = try std.fmt.allocPrint(gpa, "a dependency of {s}", .{parent}) });
5257 self.misc_errors.appendAssumeCapacity(.{
5286 comp.link_errors.appendAssumeCapacity(.{
52585287 .msg = try std.fmt.allocPrint(gpa, format, args),
52595288 .notes = try notes.toOwnedSlice(),
52605289 });
......@@ -5266,12 +5295,13 @@ pub fn reportParseError(
52665295 comptime format: []const u8,
52675296 args: anytype,
52685297) error{OutOfMemory}!void {
5269 const gpa = self.base.allocator;
5270 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
5298 const comp = self.base.comp;
5299 const gpa = comp.gpa;
5300 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
52715301 var notes = try gpa.alloc(File.ErrorMsg, 1);
52725302 errdefer gpa.free(notes);
52735303 notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while parsing {s}", .{path}) };
5274 self.misc_errors.appendAssumeCapacity(.{
5304 comp.link_errors.appendAssumeCapacity(.{
52755305 .msg = try std.fmt.allocPrint(gpa, format, args),
52765306 .notes = notes,
52775307 });
......@@ -5283,21 +5313,23 @@ pub fn reportUnresolvedBoundarySymbol(
52835313 comptime format: []const u8,
52845314 args: anytype,
52855315) error{OutOfMemory}!void {
5286 const gpa = self.base.allocator;
5287 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
5316 const comp = self.base.comp;
5317 const gpa = comp.gpa;
5318 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
52885319 var notes = try gpa.alloc(File.ErrorMsg, 1);
52895320 errdefer gpa.free(notes);
52905321 notes[0] = .{ .msg = try std.fmt.allocPrint(gpa, "while resolving {s}", .{sym_name}) };
5291 self.misc_errors.appendAssumeCapacity(.{
5322 comp.link_errors.appendAssumeCapacity(.{
52925323 .msg = try std.fmt.allocPrint(gpa, format, args),
52935324 .notes = notes,
52945325 });
52955326}
52965327
52975328pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void {
5298 const gpa = self.base.allocator;
5329 const comp = self.base.comp;
5330 const gpa = comp.gpa;
52995331 const count = self.unresolved.count();
5300 try self.misc_errors.ensureUnusedCapacity(gpa, count);
5332 try comp.link_errors.ensureUnusedCapacity(gpa, count);
53015333
53025334 for (self.unresolved.keys()) |global_index| {
53035335 const global = self.globals.items[global_index];
......@@ -5318,7 +5350,7 @@ pub fn reportUndefined(self: *MachO) error{OutOfMemory}!void {
53185350 };
53195351 err_msg.notes = try notes.toOwnedSlice();
53205352
5321 self.misc_errors.appendAssumeCapacity(err_msg);
5353 comp.link_errors.appendAssumeCapacity(err_msg);
53225354 }
53235355}
53245356
......@@ -5327,8 +5359,9 @@ fn reportSymbolCollision(
53275359 first: SymbolWithLoc,
53285360 other: SymbolWithLoc,
53295361) error{OutOfMemory}!void {
5330 const gpa = self.base.allocator;
5331 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
5362 const comp = self.base.comp;
5363 const gpa = comp.gpa;
5364 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
53325365
53335366 var notes = try std.ArrayList(File.ErrorMsg).initCapacity(gpa, 2);
53345367 defer notes.deinit();
......@@ -5351,12 +5384,13 @@ fn reportSymbolCollision(
53515384 }) };
53525385 err_msg.notes = try notes.toOwnedSlice();
53535386
5354 self.misc_errors.appendAssumeCapacity(err_msg);
5387 comp.link_errors.appendAssumeCapacity(err_msg);
53555388}
53565389
53575390fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{OutOfMemory}!void {
5358 const gpa = self.base.allocator;
5359 try self.misc_errors.ensureUnusedCapacity(gpa, 1);
5391 const comp = self.base.comp;
5392 const gpa = comp.gpa;
5393 try comp.link_errors.ensureUnusedCapacity(gpa, 1);
53605394
53615395 const notes = try gpa.alloc(File.ErrorMsg, 1);
53625396 errdefer gpa.free(notes);
......@@ -5374,7 +5408,7 @@ fn reportUnhandledSymbolType(self: *MachO, sym_with_loc: SymbolWithLoc) error{Ou
53745408 else
53755409 unreachable;
53765410
5377 self.misc_errors.appendAssumeCapacity(.{
5411 comp.link_errors.appendAssumeCapacity(.{
53785412 .msg = try std.fmt.allocPrint(gpa, "unhandled symbol type: '{s}' has type {s}", .{
53795413 self.getSymbolName(sym_with_loc),
53805414 sym_type,
......@@ -5623,6 +5657,8 @@ pub fn logAtom(self: *MachO, atom_index: Atom.Index, logger: anytype) void {
56235657 }
56245658}
56255659
5660const default_entry_symbol_name = "_main";
5661
56265662pub const base_tag: File.Tag = File.Tag.macho;
56275663pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1)));
56285664pub const N_BOUNDARY: u16 = @as(u16, @bitCast(@as(i16, -2)));
src/link/MachO/Atom.zig+25-15
......@@ -253,7 +253,8 @@ pub fn addRelocation(macho_file: *MachO, atom_index: Index, reloc: Relocation) !
253253}
254254
255255pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Relocation) !void {
256 const gpa = macho_file.base.allocator;
256 const comp = macho_file.base.comp;
257 const gpa = comp.gpa;
257258 const gop = try macho_file.relocs.getOrPut(gpa, atom_index);
258259 if (!gop.found_existing) {
259260 gop.value_ptr.* = .{};
......@@ -269,7 +270,8 @@ pub fn addRelocations(macho_file: *MachO, atom_index: Index, relocs: []const Rel
269270}
270271
271272pub fn addRebase(macho_file: *MachO, atom_index: Index, offset: u32) !void {
272 const gpa = macho_file.base.allocator;
273 const comp = macho_file.base.comp;
274 const gpa = comp.gpa;
273275 const atom = macho_file.getAtom(atom_index);
274276 log.debug(" (adding rebase at offset 0x{x} in %{?d})", .{ offset, atom.getSymbolIndex() });
275277 const gop = try macho_file.rebases.getOrPut(gpa, atom_index);
......@@ -280,7 +282,8 @@ pub fn addRebase(macho_file: *MachO, atom_index: Index, offset: u32) !void {
280282}
281283
282284pub fn addBinding(macho_file: *MachO, atom_index: Index, binding: Binding) !void {
283 const gpa = macho_file.base.allocator;
285 const comp = macho_file.base.comp;
286 const gpa = comp.gpa;
284287 const atom = macho_file.getAtom(atom_index);
285288 log.debug(" (adding binding to symbol {s} at offset 0x{x} in %{?d})", .{
286289 macho_file.getSymbolName(binding.target),
......@@ -307,7 +310,8 @@ pub fn resolveRelocations(
307310}
308311
309312pub fn freeRelocations(macho_file: *MachO, atom_index: Index) void {
310 const gpa = macho_file.base.allocator;
313 const comp = macho_file.base.comp;
314 const gpa = comp.gpa;
311315 var removed_relocs = macho_file.relocs.fetchOrderedRemove(atom_index);
312316 if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
313317 var removed_rebases = macho_file.rebases.fetchOrderedRemove(atom_index);
......@@ -387,7 +391,8 @@ pub fn calcInnerSymbolOffset(macho_file: *MachO, atom_index: Index, sym_index: u
387391}
388392
389393pub fn scanAtomRelocs(macho_file: *MachO, atom_index: Index, relocs: []align(1) const macho.relocation_info) !void {
390 const arch = macho_file.base.options.target.cpu.arch;
394 const target = macho_file.base.comp.root_mod.resolved_target.result;
395 const arch = target.cpu.arch;
391396 const atom = macho_file.getAtom(atom_index);
392397 assert(atom.getFile() != null); // synthetic atoms do not have relocs
393398
......@@ -434,6 +439,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
434439 const tracy = trace(@src());
435440 defer tracy.end();
436441
442 const target = macho_file.base.comp.root_mod.resolved_target.result;
437443 const object = &macho_file.objects.items[ctx.object_id];
438444 log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name });
439445
......@@ -447,7 +453,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
447453 else
448454 mem.readInt(u32, ctx.code[rel_offset..][0..4], .little);
449455 } else blk: {
450 assert(macho_file.base.options.target.cpu.arch == .x86_64);
456 assert(target.cpu.arch == .x86_64);
451457 const correction: u3 = switch (@as(macho.reloc_type_x86_64, @enumFromInt(ctx.rel.r_type))) {
452458 .X86_64_RELOC_SIGNED => 0,
453459 .X86_64_RELOC_SIGNED_1 => 1,
......@@ -467,18 +473,18 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
467473
468474 const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 };
469475 const sym = macho_file.getSymbol(sym_loc);
470 const target = if (sym.sect() and !sym.ext())
476 const reloc_target = if (sym.sect() and !sym.ext())
471477 sym_loc
472478 else if (object.getGlobal(sym_index)) |global_index|
473479 macho_file.globals.items[global_index]
474480 else
475481 sym_loc;
476482 log.debug(" | target %{d} ('{s}') in object({?d})", .{
477 target.sym_index,
478 macho_file.getSymbolName(target),
479 target.getFile(),
483 reloc_target.sym_index,
484 macho_file.getSymbolName(reloc_target),
485 reloc_target.getFile(),
480486 });
481 return target;
487 return reloc_target;
482488}
483489
484490pub fn getRelocTargetAtomIndex(macho_file: *MachO, target: SymbolWithLoc) ?Index {
......@@ -599,7 +605,8 @@ pub fn resolveRelocs(
599605 atom_code: []u8,
600606 atom_relocs: []align(1) const macho.relocation_info,
601607) !void {
602 const arch = macho_file.base.options.target.cpu.arch;
608 const target = macho_file.base.comp.root_mod.resolved_target.result;
609 const arch = target.cpu.arch;
603610 const atom = macho_file.getAtom(atom_index);
604611 assert(atom.getFile() != null); // synthetic atoms do not have relocs
605612
......@@ -1192,7 +1199,8 @@ pub fn getAtomRelocs(macho_file: *MachO, atom_index: Index) []const macho.reloca
11921199}
11931200
11941201pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {
1195 switch (macho_file.base.options.target.cpu.arch) {
1202 const target = macho_file.base.comp.root_mod.resolved_target.result;
1203 switch (target.cpu.arch) {
11961204 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
11971205 .ARM64_RELOC_GOT_LOAD_PAGE21,
11981206 .ARM64_RELOC_GOT_LOAD_PAGEOFF12,
......@@ -1211,7 +1219,8 @@ pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {
12111219}
12121220
12131221pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {
1214 switch (macho_file.base.options.target.cpu.arch) {
1222 const target = macho_file.base.comp.root_mod.resolved_target.result;
1223 switch (target.cpu.arch) {
12151224 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
12161225 .ARM64_RELOC_TLVP_LOAD_PAGE21,
12171226 .ARM64_RELOC_TLVP_LOAD_PAGEOFF12,
......@@ -1227,7 +1236,8 @@ pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {
12271236}
12281237
12291238pub fn relocIsStub(macho_file: *MachO, rel: macho.relocation_info) bool {
1230 switch (macho_file.base.options.target.cpu.arch) {
1239 const target = macho_file.base.comp.root_mod.resolved_target.result;
1240 switch (target.cpu.arch) {
12311241 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
12321242 .ARM64_RELOC_BRANCH26 => return true,
12331243 else => return false,
src/link/MachO/DebugSymbols.zig+13-8
......@@ -39,10 +39,12 @@ pub const Reloc = struct {
3939/// You must call this function *after* `MachO.populateMissingMetadata()`
4040/// has been called to get a viable debug symbols output.
4141pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void {
42 const target = macho_file.base.comp.root_mod.resolved_target.result;
43
4244 if (self.dwarf_segment_cmd_index == null) {
4345 self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len));
4446
45 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
47 const page_size = MachO.getPageSize(target.cpu.arch);
4648 const off = @as(u64, @intCast(page_size));
4749 const ideal_size: u16 = 200 + 128 + 160 + 250;
4850 const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size);
......@@ -196,10 +198,10 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) u64
196198}
197199
198200pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
201 const comp = macho_file.base.comp;
199202 // TODO This linker code currently assumes there is only 1 compilation unit
200203 // and it corresponds to the Zig source code.
201 const options = macho_file.base.options;
202 const module = options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
204 const zcu = comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
203205
204206 for (self.relocs.items) |*reloc| {
205207 const sym = switch (reloc.type) {
......@@ -243,7 +245,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
243245 const text_section = macho_file.sections.items(.header)[macho_file.text_section_index.?];
244246 const low_pc = text_section.addr;
245247 const high_pc = text_section.addr + text_section.size;
246 try self.dwarf.writeDbgInfoHeader(module, low_pc, high_pc);
248 try self.dwarf.writeDbgInfoHeader(zcu, low_pc, high_pc);
247249 self.debug_info_header_dirty = false;
248250 }
249251
......@@ -332,7 +334,8 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
332334 file_size = @max(file_size, header.offset + header.size);
333335 }
334336
335 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
337 const target = macho_file.base.comp.root_mod.resolved_target.result;
338 const page_size = MachO.getPageSize(target.cpu.arch);
336339 const aligned_size = mem.alignForward(u64, file_size, page_size);
337340 dwarf_segment.vmaddr = base_vmaddr;
338341 dwarf_segment.filesize = aligned_size;
......@@ -394,10 +397,12 @@ fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype)
394397}
395398
396399fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void {
400 const target = macho_file.base.comp.root_mod.resolved_target.result;
401
397402 var header: macho.mach_header_64 = .{};
398403 header.filetype = macho.MH_DSYM;
399404
400 switch (macho_file.base.options.target.cpu.arch) {
405 switch (target.cpu.arch) {
401406 .aarch64 => {
402407 header.cputype = macho.CPU_TYPE_ARM64;
403408 header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
......@@ -435,7 +440,8 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void {
435440 try self.writeSymtab(macho_file);
436441 try self.writeStrtab();
437442
438 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
443 const target = macho_file.base.comp.root_mod.resolved_target.result;
444 const page_size = MachO.getPageSize(target.cpu.arch);
439445 const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
440446 const aligned_size = mem.alignForward(u64, seg.filesize, page_size);
441447 seg.vmsize = aligned_size;
......@@ -566,6 +572,5 @@ const trace = @import("../../tracy.zig").trace;
566572const Allocator = mem.Allocator;
567573const Dwarf = @import("../Dwarf.zig");
568574const MachO = @import("../MachO.zig");
569const Module = @import("../../Module.zig");
570575const StringTable = @import("../StringTable.zig");
571576const Type = @import("../../type.zig").Type;
src/link/MachO/Object.zig+29-20
......@@ -342,19 +342,23 @@ pub const SplitIntoAtomsError = error{
342342};
343343
344344pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIntoAtomsError!void {
345 const comp = macho_file.base.comp;
346 const gpa = comp.gpa;
345347 log.debug("splitting object({d}, {s}) into atoms", .{ object_id, self.name });
346348
347349 try self.splitRegularSections(macho_file, object_id);
348350 try self.parseEhFrameSection(macho_file, object_id);
349351 try self.parseUnwindInfo(macho_file, object_id);
350 try self.parseDataInCode(macho_file.base.allocator);
352 try self.parseDataInCode(gpa);
351353}
352354
353355/// Splits input regular sections into Atoms.
354356/// If the Object was compiled with `MH_SUBSECTIONS_VIA_SYMBOLS`, splits section
355357/// into subsections where each subsection then represents an Atom.
356358pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !void {
357 const gpa = macho_file.base.allocator;
359 const comp = macho_file.base.comp;
360 const gpa = comp.gpa;
361 const target = macho_file.base.comp.root_mod.resolved_target.result;
358362
359363 const sections = self.getSourceSections();
360364 for (sections, 0..) |sect, id| {
......@@ -448,7 +452,7 @@ pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !
448452
449453 try self.parseRelocs(gpa, section.id);
450454
451 const cpu_arch = macho_file.base.options.target.cpu.arch;
455 const cpu_arch = target.cpu.arch;
452456 const sect_loc = filterSymbolsBySection(symtab[sect_sym_index..], sect_id + 1);
453457 const sect_start_index = sect_sym_index + sect_loc.index;
454458
......@@ -554,7 +558,8 @@ fn createAtomFromSubsection(
554558 alignment: Alignment,
555559 out_sect_id: u8,
556560) !Atom.Index {
557 const gpa = macho_file.base.allocator;
561 const comp = macho_file.base.comp;
562 const gpa = comp.gpa;
558563 const atom_index = try macho_file.createAtom(sym_index, .{
559564 .size = size,
560565 .alignment = alignment,
......@@ -670,13 +675,15 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
670675
671676 log.debug("parsing __TEXT,__eh_frame section", .{});
672677
673 const gpa = macho_file.base.allocator;
678 const comp = macho_file.base.comp;
679 const gpa = comp.gpa;
674680
675681 if (macho_file.eh_frame_section_index == null) {
676682 macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{});
677683 }
678684
679 const cpu_arch = macho_file.base.options.target.cpu.arch;
685 const target = macho_file.base.comp.root_mod.resolved_target.result;
686 const cpu_arch = target.cpu.arch;
680687 try self.parseRelocs(gpa, sect_id);
681688 const relocs = self.getRelocs(sect_id);
682689
......@@ -704,7 +711,7 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
704711 });
705712
706713 if (record.tag == .fde) {
707 const target = blk: {
714 const reloc_target = blk: {
708715 switch (cpu_arch) {
709716 .aarch64 => {
710717 assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed
......@@ -714,13 +721,13 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
714721 @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)) == .ARM64_RELOC_UNSIGNED)
715722 break rel;
716723 } else unreachable;
717 const target = Atom.parseRelocTarget(macho_file, .{
724 const reloc_target = Atom.parseRelocTarget(macho_file, .{
718725 .object_id = object_id,
719726 .rel = rel,
720727 .code = it.data[offset..],
721728 .base_offset = @as(i32, @intCast(offset)),
722729 });
723 break :blk target;
730 break :blk reloc_target;
724731 },
725732 .x86_64 => {
726733 const target_address = record.getTargetSymbolAddress(.{
......@@ -728,16 +735,16 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
728735 .base_offset = offset,
729736 });
730737 const target_sym_index = self.getSymbolByAddress(target_address, null);
731 const target = if (self.getGlobal(target_sym_index)) |global_index|
738 const reloc_target = if (self.getGlobal(target_sym_index)) |global_index|
732739 macho_file.globals.items[global_index]
733740 else
734741 SymbolWithLoc{ .sym_index = target_sym_index, .file = object_id + 1 };
735 break :blk target;
742 break :blk reloc_target;
736743 },
737744 else => unreachable,
738745 }
739746 };
740 if (target.getFile() != object_id) {
747 if (reloc_target.getFile() != object_id) {
741748 log.debug("FDE at offset {x} marked DEAD", .{offset});
742749 self.eh_frame_relocs_lookup.getPtr(offset).?.dead = true;
743750 } else {
......@@ -746,12 +753,12 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
746753 // very problematic when using Zig's @export feature to re-export symbols under
747754 // additional names. For that reason, we need to ensure we record aliases here
748755 // too so that we can tie them with their matching unwind records and vice versa.
749 const aliases = self.getSymbolAliases(target.sym_index);
756 const aliases = self.getSymbolAliases(reloc_target.sym_index);
750757 var i: u32 = 0;
751758 while (i < aliases.len) : (i += 1) {
752759 const actual_target = SymbolWithLoc{
753760 .sym_index = i + aliases.start,
754 .file = target.file,
761 .file = reloc_target.file,
755762 };
756763 log.debug("FDE at offset {x} tracks {s}", .{
757764 offset,
......@@ -765,8 +772,10 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
765772}
766773
767774fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
768 const gpa = macho_file.base.allocator;
769 const cpu_arch = macho_file.base.options.target.cpu.arch;
775 const comp = macho_file.base.comp;
776 const gpa = comp.gpa;
777 const target = macho_file.base.comp.root_mod.resolved_target.result;
778 const cpu_arch = target.cpu.arch;
770779 const sect_id = self.unwind_info_sect_id orelse {
771780 // If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,
772781 // we will try fully synthesising unwind info records to somewhat match Apple ld's
......@@ -818,13 +827,13 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
818827
819828 // Find function symbol that this record describes
820829 const rel = relocs[rel_pos.start..][rel_pos.len - 1];
821 const target = Atom.parseRelocTarget(macho_file, .{
830 const reloc_target = Atom.parseRelocTarget(macho_file, .{
822831 .object_id = object_id,
823832 .rel = rel,
824833 .code = mem.asBytes(&record),
825834 .base_offset = @as(i32, @intCast(offset)),
826835 });
827 if (target.getFile() != object_id) {
836 if (reloc_target.getFile() != object_id) {
828837 log.debug("unwind record {d} marked DEAD", .{record_id});
829838 self.unwind_relocs_lookup[record_id].dead = true;
830839 } else {
......@@ -833,12 +842,12 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
833842 // very problematic when using Zig's @export feature to re-export symbols under
834843 // additional names. For that reason, we need to ensure we record aliases here
835844 // too so that we can tie them with their matching unwind records and vice versa.
836 const aliases = self.getSymbolAliases(target.sym_index);
845 const aliases = self.getSymbolAliases(reloc_target.sym_index);
837846 var i: u32 = 0;
838847 while (i < aliases.len) : (i += 1) {
839848 const actual_target = SymbolWithLoc{
840849 .sym_index = i + aliases.start,
841 .file = target.file,
850 .file = reloc_target.file,
842851 };
843852 log.debug("unwind record {d} tracks {s}", .{
844853 record_id,
src/link/MachO/Relocation.zig+4-2
......@@ -58,11 +58,12 @@ pub fn isStubTrampoline(self: Relocation, macho_file: *MachO) bool {
5858}
5959
6060pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {
61 const target = macho_file.base.comp.root_mod.resolved_target.result;
6162 if (self.isStubTrampoline(macho_file)) {
6263 const index = macho_file.stub_table.lookup.get(self.target) orelse return null;
6364 const header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];
6465 return header.addr +
65 index * @import("stubs.zig").stubSize(macho_file.base.options.target.cpu.arch);
66 index * @import("stubs.zig").stubSize(target.cpu.arch);
6667 }
6768 switch (self.type) {
6869 .got, .got_page, .got_pageoff => {
......@@ -84,7 +85,8 @@ pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {
8485}
8586
8687pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {
87 const arch = macho_file.base.options.target.cpu.arch;
88 const target = macho_file.base.comp.root_mod.resolved_target.result;
89 const arch = target.cpu.arch;
8890 const atom = macho_file.getAtom(atom_index);
8991 const source_sym = atom.getSymbol(macho_file);
9092 const source_addr = source_sym.n_value + self.offset;
src/link/MachO/UnwindInfo.zig+16-13
......@@ -184,7 +184,8 @@ pub fn deinit(info: *UnwindInfo) void {
184184pub fn scanRelocs(macho_file: *MachO) !void {
185185 if (macho_file.unwind_info_section_index == null) return;
186186
187 const cpu_arch = macho_file.base.options.target.cpu.arch;
187 const target = macho_file.base.comp.root_mod.resolved_target.result;
188 const cpu_arch = target.cpu.arch;
188189 for (macho_file.objects.items, 0..) |*object, object_id| {
189190 const unwind_records = object.getUnwindRecords();
190191 for (object.exec_atoms.items) |atom_index| {
......@@ -196,13 +197,13 @@ pub fn scanRelocs(macho_file: *MachO) !void {
196197 if (!UnwindEncoding.isDwarf(record.compactUnwindEncoding, cpu_arch)) {
197198 if (getPersonalityFunctionReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {
198199 // Personality function; add GOT pointer.
199 const target = Atom.parseRelocTarget(macho_file, .{
200 const reloc_target = Atom.parseRelocTarget(macho_file, .{
200201 .object_id = @as(u32, @intCast(object_id)),
201202 .rel = rel,
202203 .code = mem.asBytes(&record),
203204 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
204205 });
205 try macho_file.addGotEntry(target);
206 try macho_file.addGotEntry(reloc_target);
206207 }
207208 }
208209 }
......@@ -213,7 +214,8 @@ pub fn scanRelocs(macho_file: *MachO) !void {
213214pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
214215 if (macho_file.unwind_info_section_index == null) return;
215216
216 const cpu_arch = macho_file.base.options.target.cpu.arch;
217 const target = macho_file.base.comp.root_mod.resolved_target.result;
218 const cpu_arch = target.cpu.arch;
217219
218220 var records = std.ArrayList(macho.compact_unwind_entry).init(info.gpa);
219221 defer records.deinit();
......@@ -247,15 +249,15 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
247249 @as(u32, @intCast(object_id)),
248250 record_id,
249251 )) |rel| {
250 const target = Atom.parseRelocTarget(macho_file, .{
252 const reloc_target = Atom.parseRelocTarget(macho_file, .{
251253 .object_id = @as(u32, @intCast(object_id)),
252254 .rel = rel,
253255 .code = mem.asBytes(&record),
254256 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
255257 });
256 const personality_index = info.getPersonalityFunction(target) orelse inner: {
258 const personality_index = info.getPersonalityFunction(reloc_target) orelse inner: {
257259 const personality_index = info.personalities_count;
258 info.personalities[personality_index] = target;
260 info.personalities[personality_index] = reloc_target;
259261 info.personalities_count += 1;
260262 break :inner personality_index;
261263 };
......@@ -265,13 +267,13 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
265267 }
266268
267269 if (getLsdaReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {
268 const target = Atom.parseRelocTarget(macho_file, .{
270 const reloc_target = Atom.parseRelocTarget(macho_file, .{
269271 .object_id = @as(u32, @intCast(object_id)),
270272 .rel = rel,
271273 .code = mem.asBytes(&record),
272274 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
273275 });
274 record.lsda = @as(u64, @bitCast(target));
276 record.lsda = @as(u64, @bitCast(reloc_target));
275277 }
276278 }
277279 break :blk record;
......@@ -557,13 +559,14 @@ pub fn write(info: *UnwindInfo, macho_file: *MachO) !void {
557559 const text_sect = macho_file.sections.items(.header)[text_sect_id];
558560
559561 var personalities: [max_personalities]u32 = undefined;
560 const cpu_arch = macho_file.base.options.target.cpu.arch;
562 const target = macho_file.base.comp.root_mod.resolved_target.result;
563 const cpu_arch = target.cpu.arch;
561564
562565 log.debug("Personalities:", .{});
563 for (info.personalities[0..info.personalities_count], 0..) |target, i| {
564 const addr = macho_file.getGotEntryAddress(target).?;
566 for (info.personalities[0..info.personalities_count], 0..) |reloc_target, i| {
567 const addr = macho_file.getGotEntryAddress(reloc_target).?;
565568 personalities[i] = @as(u32, @intCast(addr - seg.vmaddr));
566 log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(target) });
569 log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(reloc_target) });
567570 }
568571
569572 for (info.records.items) |*rec| {
src/link/MachO/dead_strip.zig+39-32
......@@ -1,7 +1,8 @@
11//! An algorithm for dead stripping of unreferenced Atoms.
22
33pub fn gcAtoms(macho_file: *MachO) !void {
4 const gpa = macho_file.base.allocator;
4 const comp = macho_file.base.comp;
5 const gpa = comp.gpa;
56
67 var arena = std.heap.ArenaAllocator.init(gpa);
78 defer arena.deinit();
......@@ -33,7 +34,9 @@ fn addRoot(macho_file: *MachO, roots: *AtomTable, file: u32, sym_loc: SymbolWith
3334fn collectRoots(macho_file: *MachO, roots: *AtomTable) !void {
3435 log.debug("collecting roots", .{});
3536
36 switch (macho_file.base.options.output_mode) {
37 const comp = macho_file.base.comp;
38
39 switch (comp.config.output_mode) {
3740 .Exe => {
3841 // Add entrypoint as GC root
3942 if (macho_file.getEntryPoint()) |global| {
......@@ -60,7 +63,7 @@ fn collectRoots(macho_file: *MachO, roots: *AtomTable) !void {
6063 }
6164
6265 // Add all symbols force-defined by the user.
63 for (macho_file.base.options.force_undefined_symbols.keys()) |sym_name| {
66 for (comp.force_undefined_symbols.keys()) |sym_name| {
6467 const global_index = macho_file.resolver.get(sym_name).?;
6568 const global = macho_file.globals.items[global_index];
6669 const sym = macho_file.getSymbol(global);
......@@ -118,7 +121,8 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
118121
119122 alive.putAssumeCapacityNoClobber(atom_index, {});
120123
121 const cpu_arch = macho_file.base.options.target.cpu.arch;
124 const target = macho_file.base.comp.root_mod.resolved_target.result;
125 const cpu_arch = target.cpu.arch;
122126
123127 const sym = macho_file.getSymbol(atom.getSymbolWithLoc());
124128 const header = macho_file.sections.items(.header)[sym.n_sect - 1];
......@@ -129,7 +133,7 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
129133 const ctx = Atom.getRelocContext(macho_file, atom_index);
130134
131135 for (relocs) |rel| {
132 const target = switch (cpu_arch) {
136 const reloc_target = switch (cpu_arch) {
133137 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
134138 .ARM64_RELOC_ADDEND => continue,
135139 else => Atom.parseRelocTarget(macho_file, .{
......@@ -149,19 +153,19 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
149153 }),
150154 else => unreachable,
151155 };
152 const target_sym = macho_file.getSymbol(target);
156 const target_sym = macho_file.getSymbol(reloc_target);
153157
154158 if (target_sym.undf()) continue;
155 if (target.getFile() == null) {
156 const target_sym_name = macho_file.getSymbolName(target);
159 if (reloc_target.getFile() == null) {
160 const target_sym_name = macho_file.getSymbolName(reloc_target);
157161 if (mem.eql(u8, "__mh_execute_header", target_sym_name)) continue;
158162 if (mem.eql(u8, "___dso_handle", target_sym_name)) continue;
159163
160164 unreachable; // referenced symbol not found
161165 }
162166
163 const object = macho_file.objects.items[target.getFile().?];
164 const target_atom_index = object.getAtomIndexForSymbol(target.sym_index).?;
167 const object = macho_file.objects.items[reloc_target.getFile().?];
168 const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index).?;
165169 log.debug(" following ATOM({d}, %{d}, {?d})", .{
166170 target_atom_index,
167171 macho_file.getAtom(target_atom_index).sym_index,
......@@ -178,7 +182,8 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
178182
179183 log.debug("refersLive(ATOM({d}, %{d}, {?d}))", .{ atom_index, sym_loc.sym_index, sym_loc.getFile() });
180184
181 const cpu_arch = macho_file.base.options.target.cpu.arch;
185 const target = macho_file.base.comp.root_mod.resolved_target.result;
186 const cpu_arch = target.cpu.arch;
182187
183188 const sym = macho_file.getSymbol(sym_loc);
184189 const header = macho_file.sections.items(.header)[sym.n_sect - 1];
......@@ -189,7 +194,7 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
189194 const ctx = Atom.getRelocContext(macho_file, atom_index);
190195
191196 for (relocs) |rel| {
192 const target = switch (cpu_arch) {
197 const reloc_target = switch (cpu_arch) {
193198 .aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
194199 .ARM64_RELOC_ADDEND => continue,
195200 else => Atom.parseRelocTarget(macho_file, .{
......@@ -210,9 +215,9 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
210215 else => unreachable,
211216 };
212217
213 const object = macho_file.objects.items[target.getFile().?];
214 const target_atom_index = object.getAtomIndexForSymbol(target.sym_index) orelse {
215 log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(target)});
218 const object = macho_file.objects.items[reloc_target.getFile().?];
219 const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index) orelse {
220 log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(reloc_target)});
216221 continue;
217222 };
218223 if (alive.contains(target_atom_index)) {
......@@ -271,7 +276,8 @@ fn mark(macho_file: *MachO, roots: AtomTable, alive: *AtomTable) void {
271276
272277fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void {
273278 const object = &macho_file.objects.items[object_id];
274 const cpu_arch = macho_file.base.options.target.cpu.arch;
279 const target = macho_file.base.comp.root_mod.resolved_target.result;
280 const cpu_arch = target.cpu.arch;
275281
276282 const unwind_records = object.getUnwindRecords();
277283
......@@ -310,29 +316,29 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void
310316 markEhFrameRecords(macho_file, object_id, atom_index, alive);
311317 } else {
312318 if (UnwindInfo.getPersonalityFunctionReloc(macho_file, object_id, record_id)) |rel| {
313 const target = Atom.parseRelocTarget(macho_file, .{
319 const reloc_target = Atom.parseRelocTarget(macho_file, .{
314320 .object_id = object_id,
315321 .rel = rel,
316322 .code = mem.asBytes(&record),
317323 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
318324 });
319 const target_sym = macho_file.getSymbol(target);
325 const target_sym = macho_file.getSymbol(reloc_target);
320326 if (!target_sym.undf()) {
321 const target_object = macho_file.objects.items[target.getFile().?];
322 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
327 const target_object = macho_file.objects.items[reloc_target.getFile().?];
328 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
323329 markLive(macho_file, target_atom_index, alive);
324330 }
325331 }
326332
327333 if (UnwindInfo.getLsdaReloc(macho_file, object_id, record_id)) |rel| {
328 const target = Atom.parseRelocTarget(macho_file, .{
334 const reloc_target = Atom.parseRelocTarget(macho_file, .{
329335 .object_id = object_id,
330336 .rel = rel,
331337 .code = mem.asBytes(&record),
332338 .base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
333339 });
334 const target_object = macho_file.objects.items[target.getFile().?];
335 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
340 const target_object = macho_file.objects.items[reloc_target.getFile().?];
341 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
336342 markLive(macho_file, target_atom_index, alive);
337343 }
338344 }
......@@ -341,7 +347,8 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void
341347}
342348
343349fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index, alive: *AtomTable) void {
344 const cpu_arch = macho_file.base.options.target.cpu.arch;
350 const target = macho_file.base.comp.root_mod.resolved_target.result;
351 const cpu_arch = target.cpu.arch;
345352 const object = &macho_file.objects.items[object_id];
346353 var it = object.getEhFrameRecordsIterator();
347354 var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);
......@@ -361,16 +368,16 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index
361368 // Mark FDE references which should include any referenced LSDA record
362369 const relocs = eh_frame.getRelocs(macho_file, object_id, fde_offset);
363370 for (relocs) |rel| {
364 const target = Atom.parseRelocTarget(macho_file, .{
371 const reloc_target = Atom.parseRelocTarget(macho_file, .{
365372 .object_id = object_id,
366373 .rel = rel,
367374 .code = fde.data,
368375 .base_offset = @as(i32, @intCast(fde_offset)) + 4,
369376 });
370 const target_sym = macho_file.getSymbol(target);
377 const target_sym = macho_file.getSymbol(reloc_target);
371378 if (!target_sym.undf()) blk: {
372 const target_object = macho_file.objects.items[target.getFile().?];
373 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index) orelse
379 const target_object = macho_file.objects.items[reloc_target.getFile().?];
380 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index) orelse
374381 break :blk;
375382 markLive(macho_file, target_atom_index, alive);
376383 }
......@@ -394,11 +401,11 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index
394401
395402 // Mark CIE references which should include any referenced personalities
396403 // that are defined locally.
397 if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |target| {
398 const target_sym = macho_file.getSymbol(target);
404 if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |reloc_target| {
405 const target_sym = macho_file.getSymbol(reloc_target);
399406 if (!target_sym.undf()) {
400 const target_object = macho_file.objects.items[target.getFile().?];
401 const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
407 const target_object = macho_file.objects.items[reloc_target.getFile().?];
408 const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
402409 markLive(macho_file, target_atom_index, alive);
403410 }
404411 }
src/link/MachO/eh_frame.zig+26-18
......@@ -1,5 +1,6 @@
11pub fn scanRelocs(macho_file: *MachO) !void {
2 const gpa = macho_file.base.allocator;
2 const comp = macho_file.base.comp;
3 const gpa = comp.gpa;
34
45 for (macho_file.objects.items, 0..) |*object, object_id| {
56 var cies = std.AutoHashMap(u32, void).init(gpa);
......@@ -35,8 +36,10 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error
3536 sect.@"align" = 3;
3637 sect.size = 0;
3738
38 const cpu_arch = macho_file.base.options.target.cpu.arch;
39 const gpa = macho_file.base.allocator;
39 const target = macho_file.base.comp.root_mod.resolved_target.result;
40 const cpu_arch = target.cpu.arch;
41 const comp = macho_file.base.comp;
42 const gpa = comp.gpa;
4043 var size: u32 = 0;
4144
4245 for (macho_file.objects.items, 0..) |*object, object_id| {
......@@ -86,8 +89,10 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
8689 const seg_id = macho_file.sections.items(.segment_index)[sect_id];
8790 const seg = macho_file.segments.items[seg_id];
8891
89 const cpu_arch = macho_file.base.options.target.cpu.arch;
90 const gpa = macho_file.base.allocator;
92 const target = macho_file.base.comp.root_mod.resolved_target.result;
93 const cpu_arch = target.cpu.arch;
94 const comp = macho_file.base.comp;
95 const gpa = comp.gpa;
9196
9297 var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa);
9398 defer {
......@@ -109,11 +114,11 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
109114
110115 for (object.exec_atoms.items) |atom_index| {
111116 var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);
112 while (inner_syms_it.next()) |target| {
113 const fde_record_offset = object.eh_frame_records_lookup.get(target) orelse continue;
117 while (inner_syms_it.next()) |reloc_target| {
118 const fde_record_offset = object.eh_frame_records_lookup.get(reloc_target) orelse continue;
114119 if (object.eh_frame_relocs_lookup.get(fde_record_offset).?.dead) continue;
115120
116 const record_id = unwind_info.records_lookup.get(target) orelse continue;
121 const record_id = unwind_info.records_lookup.get(reloc_target) orelse continue;
117122 const record = &unwind_info.records.items[record_id];
118123
119124 // TODO skip this check if no __compact_unwind is present
......@@ -153,7 +158,7 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
153158 .aarch64 => {}, // relocs take care of LSDA pointers
154159 .x86_64 => {
155160 // We need to relocate target symbol address ourselves.
156 const atom_sym = macho_file.getSymbol(target);
161 const atom_sym = macho_file.getSymbol(reloc_target);
157162 try fde_record.setTargetSymbolAddress(atom_sym.n_value, .{
158163 .base_addr = sect.addr,
159164 .base_offset = eh_frame_offset,
......@@ -278,7 +283,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
278283 object_id: u32,
279284 source_offset: u32,
280285 ) ?SymbolWithLoc {
281 const cpu_arch = macho_file.base.options.target.cpu.arch;
286 const target = macho_file.base.comp.root_mod.resolved_target.result;
287 const cpu_arch = target.cpu.arch;
282288 const relocs = getRelocs(macho_file, object_id, source_offset);
283289 for (relocs) |rel| {
284290 switch (cpu_arch) {
......@@ -301,13 +307,13 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
301307 },
302308 else => unreachable,
303309 }
304 const target = Atom.parseRelocTarget(macho_file, .{
310 const reloc_target = Atom.parseRelocTarget(macho_file, .{
305311 .object_id = object_id,
306312 .rel = rel,
307313 .code = rec.data,
308314 .base_offset = @as(i32, @intCast(source_offset)) + 4,
309315 });
310 return target;
316 return reloc_target;
311317 }
312318 return null;
313319 }
......@@ -319,11 +325,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
319325 }) !void {
320326 comptime assert(is_mutable);
321327
322 const cpu_arch = macho_file.base.options.target.cpu.arch;
328 const target = macho_file.base.comp.root_mod.resolved_target.result;
329 const cpu_arch = target.cpu.arch;
323330 const relocs = getRelocs(macho_file, object_id, ctx.source_offset);
324331
325332 for (relocs) |rel| {
326 const target = Atom.parseRelocTarget(macho_file, .{
333 const reloc_target = Atom.parseRelocTarget(macho_file, .{
327334 .object_id = object_id,
328335 .rel = rel,
329336 .code = rec.data,
......@@ -340,14 +347,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
340347 // Address of the __eh_frame in the source object file
341348 },
342349 .ARM64_RELOC_POINTER_TO_GOT => {
343 const target_addr = macho_file.getGotEntryAddress(target).?;
350 const target_addr = macho_file.getGotEntryAddress(reloc_target).?;
344351 const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse
345352 return error.Overflow;
346353 mem.writeInt(i32, rec.data[rel_offset..][0..4], result, .little);
347354 },
348355 .ARM64_RELOC_UNSIGNED => {
349356 assert(rel.r_extern == 1);
350 const target_addr = Atom.getRelocTargetAddress(macho_file, target, false);
357 const target_addr = Atom.getRelocTargetAddress(macho_file, reloc_target, false);
351358 const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr));
352359 mem.writeInt(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)), .little);
353360 },
......@@ -358,7 +365,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
358365 const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type));
359366 switch (rel_type) {
360367 .X86_64_RELOC_GOT => {
361 const target_addr = macho_file.getGotEntryAddress(target).?;
368 const target_addr = macho_file.getGotEntryAddress(reloc_target).?;
362369 const addend = mem.readInt(i32, rec.data[rel_offset..][0..4], .little);
363370 const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
364371 const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
......@@ -374,7 +381,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
374381
375382 pub fn getCiePointerSource(rec: Record, object_id: u32, macho_file: *MachO, offset: u32) u32 {
376383 assert(rec.tag == .fde);
377 const cpu_arch = macho_file.base.options.target.cpu.arch;
384 const target = macho_file.base.comp.root_mod.resolved_target.result;
385 const cpu_arch = target.cpu.arch;
378386 const addend = mem.readInt(u32, rec.data[0..4], .little);
379387 switch (cpu_arch) {
380388 .aarch64 => {
src/link/MachO/load_commands.zig+38-31
......@@ -1,6 +1,3 @@
1/// Default implicit entrypoint symbol name.
2pub const default_entry_point: []const u8 = "_main";
3
41/// Default path to dyld.
52pub const default_dyld_path: [*:0]const u8 = "/usr/lib/dyld";
63
......@@ -17,7 +14,9 @@ const CalcLCsSizeCtx = struct {
1714 wants_function_starts: bool = true,
1815};
1916
20fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 {
17fn calcLCsSize(m: *MachO, ctx: CalcLCsSizeCtx, assume_max_path_len: bool) !u32 {
18 const comp = m.base.comp;
19 const gpa = comp.gpa;
2120 var has_text_segment: bool = false;
2221 var sizeofcmds: u64 = 0;
2322 for (ctx.segments) |seg| {
......@@ -46,15 +45,15 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx
4645 false,
4746 );
4847 // LC_MAIN
49 if (options.output_mode == .Exe) {
48 if (comp.config.output_mode == .Exe) {
5049 sizeofcmds += @sizeOf(macho.entry_point_command);
5150 }
5251 // LC_ID_DYLIB
53 if (options.output_mode == .Lib and options.link_mode == .Dynamic) {
52 if (comp.config.output_mode == .Lib and comp.config.link_mode == .Dynamic) {
5453 sizeofcmds += blk: {
55 const emit = options.emit.?;
56 const install_name = options.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path});
57 defer if (options.install_name == null) gpa.free(install_name);
54 const emit = m.base.emit;
55 const install_name = m.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path});
56 defer if (m.install_name == null) gpa.free(install_name);
5857 break :blk calcInstallNameLen(
5958 @sizeOf(macho.dylib_command),
6059 install_name,
......@@ -64,7 +63,7 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx
6463 }
6564 // LC_RPATH
6665 {
67 var it = RpathIterator.init(gpa, options.rpath_list);
66 var it = RpathIterator.init(gpa, m.base.rpath_list);
6867 defer it.deinit();
6968 while (try it.next()) |rpath| {
7069 sizeofcmds += calcInstallNameLen(
......@@ -78,7 +77,8 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx
7877 sizeofcmds += @sizeOf(macho.source_version_command);
7978 // LC_BUILD_VERSION or LC_VERSION_MIN_ or nothing
8079 {
81 const platform = Platform.fromTarget(options.target);
80 const target = comp.root_mod.resolved_target.result;
81 const platform = Platform.fromTarget(target);
8282 if (platform.isBuildVersionCompatible()) {
8383 // LC_BUILD_VERSION
8484 sizeofcmds += @sizeOf(macho.build_version_command) + @sizeOf(macho.build_tool_version);
......@@ -100,19 +100,19 @@ fn calcLCsSize(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx
100100 );
101101 }
102102 // LC_CODE_SIGNATURE
103 if (MachO.requiresCodeSignature(options)) {
103 if (m.requiresCodeSignature()) {
104104 sizeofcmds += @sizeOf(macho.linkedit_data_command);
105105 }
106106
107 return @as(u32, @intCast(sizeofcmds));
107 return @intCast(sizeofcmds);
108108}
109109
110pub fn calcMinHeaderPad(gpa: Allocator, options: *const link.Options, ctx: CalcLCsSizeCtx) !u64 {
111 var padding: u32 = (try calcLCsSize(gpa, options, ctx, false)) + (options.headerpad_size orelse 0);
110pub fn calcMinHeaderPad(m: *MachO, ctx: CalcLCsSizeCtx) !u64 {
111 var padding: u32 = (try calcLCsSize(m, ctx, false)) + m.headerpad_size;
112112 log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)});
113113
114 if (options.headerpad_max_install_names) {
115 const min_headerpad_size: u32 = try calcLCsSize(gpa, options, ctx, true);
114 if (m.headerpad_max_install_names) {
115 const min_headerpad_size: u32 = try calcLCsSize(m, ctx, true);
116116 log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{
117117 min_headerpad_size + @sizeOf(macho.mach_header_64),
118118 });
......@@ -189,17 +189,20 @@ fn writeDylibLC(ctx: WriteDylibLCCtx, lc_writer: anytype) !void {
189189 }
190190}
191191
192pub fn writeDylibIdLC(gpa: Allocator, options: *const link.Options, lc_writer: anytype) !void {
193 assert(options.output_mode == .Lib and options.link_mode == .Dynamic);
194 const emit = options.emit.?;
195 const install_name = options.install_name orelse try emit.directory.join(gpa, &.{emit.sub_path});
196 defer if (options.install_name == null) gpa.free(install_name);
197 const curr = options.version orelse std.SemanticVersion{
192pub fn writeDylibIdLC(macho_file: *MachO, lc_writer: anytype) !void {
193 const comp = macho_file.base.comp;
194 const gpa = comp.gpa;
195 assert(comp.config.output_mode == .Lib and comp.config.link_mode == .Dynamic);
196 const emit = macho_file.base.emit;
197 const install_name = macho_file.install_name orelse
198 try emit.directory.join(gpa, &.{emit.sub_path});
199 defer if (macho_file.install_name == null) gpa.free(install_name);
200 const curr = comp.version orelse std.SemanticVersion{
198201 .major = 1,
199202 .minor = 0,
200203 .patch = 0,
201204 };
202 const compat = options.compatibility_version orelse std.SemanticVersion{
205 const compat = macho_file.compatibility_version orelse std.SemanticVersion{
203206 .major = 1,
204207 .minor = 0,
205208 .patch = 0,
......@@ -237,8 +240,11 @@ const RpathIterator = struct {
237240 }
238241};
239242
240pub fn writeRpathLCs(gpa: Allocator, options: *const link.Options, lc_writer: anytype) !void {
241 var it = RpathIterator.init(gpa, options.rpath_list);
243pub fn writeRpathLCs(macho_file: *MachO, lc_writer: anytype) !void {
244 const comp = macho_file.base.comp;
245 const gpa = comp.gpa;
246
247 var it = RpathIterator.init(gpa, macho_file.base.rpath_list);
242248 defer it.deinit();
243249
244250 while (try it.next()) |rpath| {
......@@ -467,16 +473,17 @@ pub inline fn appleVersionToSemanticVersion(version: u32) std.SemanticVersion {
467473 };
468474}
469475
470pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVersion {
476pub fn inferSdkVersion(macho_file: *MachO) ?std.SemanticVersion {
477 const comp = macho_file.base.comp;
478 const gpa = comp.gpa;
479
471480 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
472481 defer arena_allocator.deinit();
473482 const arena = arena_allocator.allocator();
474483
475 const options = comp.bin_file.options;
476
477 const sdk_layout = options.darwin_sdk_layout orelse return null;
484 const sdk_layout = macho_file.sdk_layout orelse return null;
478485 const sdk_dir = switch (sdk_layout) {
479 .sdk => options.sysroot.?,
486 .sdk => comp.sysroot.?,
480487 .vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
481488 };
482489 if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
src/link/MachO/thunks.zig+4-2
......@@ -68,7 +68,8 @@ pub fn createThunks(macho_file: *MachO, sect_id: u8) !void {
6868 const header = &macho_file.sections.items(.header)[sect_id];
6969 if (header.size == 0) return;
7070
71 const gpa = macho_file.base.allocator;
71 const comp = macho_file.base.comp;
72 const gpa = comp.gpa;
7273 const first_atom_index = macho_file.sections.items(.first_atom_index)[sect_id].?;
7374
7475 header.size = 0;
......@@ -245,7 +246,8 @@ fn scanRelocs(
245246 macho_file.getSymbol(target).n_value,
246247 });
247248
248 const gpa = macho_file.base.allocator;
249 const comp = macho_file.base.comp;
250 const gpa = comp.gpa;
249251 const target_sym = macho_file.getSymbol(target);
250252 const thunk = &macho_file.thunks.items[thunk_index];
251253
src/link/MachO/zld.zig+121-124
......@@ -1,31 +1,29 @@
11pub fn linkWithZld(
22 macho_file: *MachO,
3 comp: *Compilation,
3 arena: Allocator,
44 prog_node: *std.Progress.Node,
55) link.File.FlushError!void {
66 const tracy = trace(@src());
77 defer tracy.end();
88
9 const gpa = macho_file.base.allocator;
10 const options = &macho_file.base.options;
11 const target = options.target;
9 const comp = macho_file.base.comp;
10 const gpa = comp.gpa;
11 const target = comp.root_mod.resolved_target.result;
12 const emit = macho_file.base.emit;
1213
13 var arena_allocator = std.heap.ArenaAllocator.init(gpa);
14 defer arena_allocator.deinit();
15 const arena = arena_allocator.allocator();
16
17 const directory = options.emit.?.directory; // Just an alias to make it shorter to type.
18 const full_out_path = try directory.join(arena, &[_][]const u8{options.emit.?.sub_path});
14 const directory = emit.directory; // Just an alias to make it shorter to type.
15 const full_out_path = try directory.join(arena, &[_][]const u8{emit.sub_path});
16 const opt_zcu = comp.module;
1917
2018 // If there is no Zig code to compile, then we should skip flushing the output file because it
2119 // will not be part of the linker line anyway.
22 const module_obj_path: ?[]const u8 = if (options.module != null) blk: {
23 try macho_file.flushModule(comp, prog_node);
20 const module_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
21 try macho_file.flushModule(arena, prog_node);
2422
2523 if (fs.path.dirname(full_out_path)) |dirname| {
26 break :blk try fs.path.join(arena, &.{ dirname, macho_file.base.intermediary_basename.? });
24 break :blk try fs.path.join(arena, &.{ dirname, macho_file.base.zcu_object_sub_path.? });
2725 } else {
28 break :blk macho_file.base.intermediary_basename.?;
26 break :blk macho_file.base.zcu_object_sub_path.?;
2927 }
3028 } else null;
3129
......@@ -34,22 +32,24 @@ pub fn linkWithZld(
3432 sub_prog_node.context.refresh();
3533 defer sub_prog_node.end();
3634
35 const output_mode = comp.config.output_mode;
36 const link_mode = comp.config.link_mode;
3737 const cpu_arch = target.cpu.arch;
38 const is_lib = options.output_mode == .Lib;
39 const is_dyn_lib = options.link_mode == .Dynamic and is_lib;
40 const is_exe_or_dyn_lib = is_dyn_lib or options.output_mode == .Exe;
41 const stack_size = options.stack_size_override orelse 0;
42 const is_debug_build = options.optimize_mode == .Debug;
43 const gc_sections = options.gc_sections orelse !is_debug_build;
38 const is_lib = output_mode == .Lib;
39 const is_dyn_lib = link_mode == .Dynamic and is_lib;
40 const is_exe_or_dyn_lib = is_dyn_lib or output_mode == .Exe;
41 const stack_size = macho_file.base.stack_size;
4442
4543 const id_symlink_basename = "zld.id";
4644
4745 var man: Cache.Manifest = undefined;
48 defer if (!options.disable_lld_caching) man.deinit();
46 defer if (!macho_file.base.disable_lld_caching) man.deinit();
4947
5048 var digest: [Cache.hex_digest_len]u8 = undefined;
5149
52 if (!options.disable_lld_caching) {
50 const objects = comp.objects;
51
52 if (!macho_file.base.disable_lld_caching) {
5353 man = comp.cache_parent.obtain();
5454
5555 // We are about to obtain this lock, so here we give other processes a chance first.
......@@ -57,7 +57,7 @@ pub fn linkWithZld(
5757
5858 comptime assert(Compilation.link_hash_implementation_version == 10);
5959
60 for (options.objects) |obj| {
60 for (objects) |obj| {
6161 _ = try man.addFile(obj.path, null);
6262 man.hash.add(obj.must_link);
6363 }
......@@ -68,24 +68,22 @@ pub fn linkWithZld(
6868 // We can skip hashing libc and libc++ components that we are in charge of building from Zig
6969 // installation sources because they are always a product of the compiler version + target information.
7070 man.hash.add(stack_size);
71 man.hash.addOptional(options.pagezero_size);
72 man.hash.addOptional(options.headerpad_size);
73 man.hash.add(options.headerpad_max_install_names);
74 man.hash.add(gc_sections);
75 man.hash.add(options.dead_strip_dylibs);
76 man.hash.add(options.strip);
77 man.hash.addListOfBytes(options.lib_dirs);
78 man.hash.addListOfBytes(options.framework_dirs);
79 try link.hashAddFrameworks(&man, options.frameworks);
80 man.hash.addListOfBytes(options.rpath_list);
71 man.hash.add(macho_file.pagezero_vmsize);
72 man.hash.add(macho_file.headerpad_size);
73 man.hash.add(macho_file.headerpad_max_install_names);
74 man.hash.add(macho_file.base.gc_sections);
75 man.hash.add(macho_file.dead_strip_dylibs);
76 man.hash.add(comp.root_mod.strip);
77 try MachO.hashAddFrameworks(&man, macho_file.frameworks);
78 man.hash.addListOfBytes(macho_file.base.rpath_list);
8179 if (is_dyn_lib) {
82 man.hash.addOptionalBytes(options.install_name);
83 man.hash.addOptional(options.version);
80 man.hash.addOptionalBytes(macho_file.install_name);
81 man.hash.addOptional(comp.version);
8482 }
85 try link.hashAddSystemLibs(&man, options.system_libs);
86 man.hash.addOptionalBytes(options.sysroot);
87 man.hash.addListOfBytes(options.force_undefined_symbols.keys());
88 try man.addOptionalFile(options.entitlements);
83 try link.hashAddSystemLibs(&man, comp.system_libs);
84 man.hash.addOptionalBytes(comp.sysroot);
85 man.hash.addListOfBytes(comp.force_undefined_symbols.keys());
86 try man.addOptionalFile(macho_file.entitlements);
8987
9088 // We don't actually care whether it's a cache hit or miss; we just
9189 // need the digest and the lock.
......@@ -125,13 +123,13 @@ pub fn linkWithZld(
125123 };
126124 }
127125
128 if (options.output_mode == .Obj) {
126 if (output_mode == .Obj) {
129127 // LLD's MachO driver does not support the equivalent of `-r` so we do a simple file copy
130128 // here. TODO: think carefully about how we can avoid this redundant operation when doing
131129 // build-obj. See also the corresponding TODO in linkAsArchive.
132130 const the_object_path = blk: {
133 if (options.objects.len != 0) {
134 break :blk options.objects[0].path;
131 if (objects.len != 0) {
132 break :blk objects[0].path;
135133 }
136134
137135 if (comp.c_object_table.count() != 0)
......@@ -150,7 +148,7 @@ pub fn linkWithZld(
150148 try fs.cwd().copyFile(the_object_path, fs.cwd(), full_out_path, .{});
151149 }
152150 } else {
153 const sub_path = options.emit.?.sub_path;
151 const sub_path = emit.sub_path;
154152
155153 const old_file = macho_file.base.file; // TODO is this needed at all?
156154 defer macho_file.base.file = old_file;
......@@ -158,7 +156,7 @@ pub fn linkWithZld(
158156 const file = try directory.handle.createFile(sub_path, .{
159157 .truncate = true,
160158 .read = true,
161 .mode = link.determineMode(options.*),
159 .mode = link.File.determineMode(false, output_mode, link_mode),
162160 });
163161 defer file.close();
164162 macho_file.base.file = file;
......@@ -175,8 +173,8 @@ pub fn linkWithZld(
175173
176174 // Positional arguments to the linker such as object files and static archives.
177175 var positionals = std.ArrayList(Compilation.LinkObject).init(arena);
178 try positionals.ensureUnusedCapacity(options.objects.len);
179 positionals.appendSliceAssumeCapacity(options.objects);
176 try positionals.ensureUnusedCapacity(objects.len);
177 positionals.appendSliceAssumeCapacity(objects);
180178
181179 for (comp.c_object_table.keys()) |key| {
182180 try positionals.append(.{ .path = key.status.success.object_path });
......@@ -190,7 +188,7 @@ pub fn linkWithZld(
190188 if (comp.compiler_rt_obj) |obj| try positionals.append(.{ .path = obj.full_object_path });
191189
192190 // libc++ dep
193 if (options.link_libcpp) {
191 if (comp.config.link_libcpp) {
194192 try positionals.ensureUnusedCapacity(2);
195193 positionals.appendAssumeCapacity(.{ .path = comp.libcxxabi_static_lib.?.full_object_path });
196194 positionals.appendAssumeCapacity(.{ .path = comp.libcxx_static_lib.?.full_object_path });
......@@ -199,23 +197,23 @@ pub fn linkWithZld(
199197 var libs = std.StringArrayHashMap(link.SystemLib).init(arena);
200198
201199 {
202 const vals = options.system_libs.values();
200 const vals = comp.system_libs.values();
203201 try libs.ensureUnusedCapacity(vals.len);
204202 for (vals) |v| libs.putAssumeCapacity(v.path.?, v);
205203 }
206204
207205 {
208 try libs.ensureUnusedCapacity(options.frameworks.len);
209 for (options.frameworks) |v| libs.putAssumeCapacity(v.path, .{
206 try libs.ensureUnusedCapacity(macho_file.frameworks.len);
207 for (macho_file.frameworks) |v| libs.putAssumeCapacity(v.path, .{
210208 .needed = v.needed,
211209 .weak = v.weak,
212210 .path = v.path,
213211 });
214212 }
215213
216 try macho_file.resolveLibSystem(arena, comp, options.lib_dirs, &libs);
214 try macho_file.resolveLibSystem(arena, comp, &libs);
217215
218 if (options.verbose_link) {
216 if (comp.verbose_link) {
219217 var argv = std.ArrayList([]const u8).init(arena);
220218
221219 try argv.append("zig");
......@@ -228,19 +226,19 @@ pub fn linkWithZld(
228226 if (is_dyn_lib) {
229227 try argv.append("-dylib");
230228
231 if (options.install_name) |install_name| {
229 if (macho_file.install_name) |install_name| {
232230 try argv.append("-install_name");
233231 try argv.append(install_name);
234232 }
235233 }
236234
237235 {
238 const platform = Platform.fromTarget(options.target);
236 const platform = Platform.fromTarget(target);
239237 try argv.append("-platform_version");
240238 try argv.append(@tagName(platform.os_tag));
241239 try argv.append(try std.fmt.allocPrint(arena, "{}", .{platform.version}));
242240
243 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
241 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(macho_file);
244242 if (sdk_version) |ver| {
245243 try argv.append(try std.fmt.allocPrint(arena, "{d}.{d}", .{ ver.major, ver.minor }));
246244 } else {
......@@ -248,44 +246,38 @@ pub fn linkWithZld(
248246 }
249247 }
250248
251 if (options.sysroot) |syslibroot| {
249 if (comp.sysroot) |syslibroot| {
252250 try argv.append("-syslibroot");
253251 try argv.append(syslibroot);
254252 }
255253
256 for (options.rpath_list) |rpath| {
254 for (macho_file.base.rpath_list) |rpath| {
257255 try argv.append("-rpath");
258256 try argv.append(rpath);
259257 }
260258
261 if (options.pagezero_size) |pagezero_size| {
262 try argv.append("-pagezero_size");
263 try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{pagezero_size}));
264 }
265
266 if (options.headerpad_size) |headerpad_size| {
267 try argv.append("-headerpad_size");
268 try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{headerpad_size}));
269 }
259 try argv.appendSlice(&.{
260 "-pagezero_size", try std.fmt.allocPrint(arena, "0x{x}", .{macho_file.pagezero_vmsize}),
261 "-headerpad_size", try std.fmt.allocPrint(arena, "0x{x}", .{macho_file.headerpad_size}),
262 });
270263
271 if (options.headerpad_max_install_names) {
264 if (macho_file.headerpad_max_install_names) {
272265 try argv.append("-headerpad_max_install_names");
273266 }
274267
275 if (gc_sections) {
268 if (macho_file.base.gc_sections) {
276269 try argv.append("-dead_strip");
277270 }
278271
279 if (options.dead_strip_dylibs) {
272 if (macho_file.dead_strip_dylibs) {
280273 try argv.append("-dead_strip_dylibs");
281274 }
282275
283 if (options.entry) |entry| {
284 try argv.append("-e");
285 try argv.append(entry);
276 if (macho_file.entry_name) |entry_name| {
277 try argv.appendSlice(&.{ "-e", entry_name });
286278 }
287279
288 for (options.objects) |obj| {
280 for (objects) |obj| {
289281 if (obj.must_link) {
290282 try argv.append("-force_load");
291283 }
......@@ -303,7 +295,7 @@ pub fn linkWithZld(
303295 if (comp.compiler_rt_lib) |lib| try argv.append(lib.full_object_path);
304296 if (comp.compiler_rt_obj) |obj| try argv.append(obj.full_object_path);
305297
306 if (options.link_libcpp) {
298 if (comp.config.link_libcpp) {
307299 try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
308300 try argv.append(comp.libcxx_static_lib.?.full_object_path);
309301 }
......@@ -313,8 +305,8 @@ pub fn linkWithZld(
313305
314306 try argv.append("-lSystem");
315307
316 for (options.system_libs.keys()) |l_name| {
317 const info = options.system_libs.get(l_name).?;
308 for (comp.system_libs.keys()) |l_name| {
309 const info = comp.system_libs.get(l_name).?;
318310 const arg = if (info.needed)
319311 try std.fmt.allocPrint(arena, "-needed-l{s}", .{l_name})
320312 else if (info.weak)
......@@ -324,11 +316,7 @@ pub fn linkWithZld(
324316 try argv.append(arg);
325317 }
326318
327 for (options.lib_dirs) |lib_dir| {
328 try argv.append(try std.fmt.allocPrint(arena, "-L{s}", .{lib_dir}));
329 }
330
331 for (options.frameworks) |framework| {
319 for (macho_file.frameworks) |framework| {
332320 const name = std.fs.path.stem(framework.path);
333321 const arg = if (framework.needed)
334322 try std.fmt.allocPrint(arena, "-needed_framework {s}", .{name})
......@@ -339,11 +327,7 @@ pub fn linkWithZld(
339327 try argv.append(arg);
340328 }
341329
342 for (options.framework_dirs) |framework_dir| {
343 try argv.append(try std.fmt.allocPrint(arena, "-F{s}", .{framework_dir}));
344 }
345
346 if (is_dyn_lib and (options.allow_shlib_undefined orelse false)) {
330 if (is_dyn_lib and macho_file.base.allow_shlib_undefined) {
347331 try argv.append("-undefined");
348332 try argv.append("dynamic_lookup");
349333 }
......@@ -412,14 +396,14 @@ pub fn linkWithZld(
412396 };
413397 }
414398
415 if (gc_sections) {
399 if (macho_file.base.gc_sections) {
416400 try dead_strip.gcAtoms(macho_file);
417401 }
418402
419403 try macho_file.createDyldPrivateAtom();
420404 try macho_file.createTentativeDefAtoms();
421405
422 if (macho_file.base.options.output_mode == .Exe) {
406 if (comp.config.output_mode == .Exe) {
423407 const global = macho_file.getEntryPoint().?;
424408 if (macho_file.getSymbol(global).undf()) {
425409 // We do one additional check here in case the entry point was found in one of the dylibs.
......@@ -470,7 +454,7 @@ pub fn linkWithZld(
470454 }
471455
472456 try writeAtoms(macho_file);
473 if (macho_file.base.options.target.cpu.arch == .aarch64) try writeThunks(macho_file);
457 if (target.cpu.arch == .aarch64) try writeThunks(macho_file);
474458 try writeDyldPrivateAtom(macho_file);
475459
476460 if (macho_file.stubs_section_index) |_| {
......@@ -511,7 +495,7 @@ pub fn linkWithZld(
511495 }
512496
513497 // Write code signature padding if required
514 var codesig: ?CodeSignature = if (MachO.requiresCodeSignature(&macho_file.base.options)) blk: {
498 var codesig: ?CodeSignature = if (macho_file.requiresCodeSignature()) blk: {
515499 // Preallocate space for the code signature.
516500 // We need to do this at this stage so that we have the load commands with proper values
517501 // written out to the file.
......@@ -519,7 +503,7 @@ pub fn linkWithZld(
519503 // where the code signature goes into.
520504 var codesig = CodeSignature.init(MachO.getPageSize(cpu_arch));
521505 codesig.code_directory.ident = fs.path.basename(full_out_path);
522 if (options.entitlements) |path| {
506 if (macho_file.entitlements) |path| {
523507 try codesig.addEntitlements(gpa, path);
524508 }
525509 try macho_file.writeCodeSignaturePadding(&codesig);
......@@ -539,7 +523,7 @@ pub fn linkWithZld(
539523 try lc_writer.writeStruct(macho_file.dysymtab_cmd);
540524 try load_commands.writeDylinkerLC(lc_writer);
541525
542 switch (macho_file.base.options.output_mode) {
526 switch (output_mode) {
543527 .Exe => blk: {
544528 const seg_id = macho_file.header_segment_cmd_index.?;
545529 const seg = macho_file.segments.items[seg_id];
......@@ -555,22 +539,22 @@ pub fn linkWithZld(
555539
556540 try lc_writer.writeStruct(macho.entry_point_command{
557541 .entryoff = @as(u32, @intCast(addr - seg.vmaddr)),
558 .stacksize = macho_file.base.options.stack_size_override orelse 0,
542 .stacksize = macho_file.base.stack_size,
559543 });
560544 },
561 .Lib => if (macho_file.base.options.link_mode == .Dynamic) {
562 try load_commands.writeDylibIdLC(gpa, &macho_file.base.options, lc_writer);
545 .Lib => if (link_mode == .Dynamic) {
546 try load_commands.writeDylibIdLC(macho_file, lc_writer);
563547 },
564548 else => {},
565549 }
566550
567 try load_commands.writeRpathLCs(gpa, &macho_file.base.options, lc_writer);
551 try load_commands.writeRpathLCs(macho_file, lc_writer);
568552 try lc_writer.writeStruct(macho.source_version_command{
569553 .version = 0,
570554 });
571555 {
572 const platform = Platform.fromTarget(macho_file.base.options.target);
573 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
556 const platform = Platform.fromTarget(target);
557 const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(macho_file);
574558 if (platform.isBuildVersionCompatible()) {
575559 try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
576560 } else {
......@@ -598,11 +582,11 @@ pub fn linkWithZld(
598582
599583 if (codesig) |*csig| {
600584 try macho_file.writeCodeSignature(comp, csig); // code signing always comes last
601 try MachO.invalidateKernelCache(directory.handle, macho_file.base.options.emit.?.sub_path);
585 try MachO.invalidateKernelCache(directory.handle, macho_file.base.emit.sub_path);
602586 }
603587 }
604588
605 if (!options.disable_lld_caching) {
589 if (!macho_file.base.disable_lld_caching) {
606590 // Update the file with the digest. If it fails we can continue; it only
607591 // means that the next invocation will have an unnecessary cache miss.
608592 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
......@@ -621,13 +605,14 @@ pub fn linkWithZld(
621605}
622606
623607fn createSegments(macho_file: *MachO) !void {
624 const gpa = macho_file.base.allocator;
625 const pagezero_vmsize = macho_file.base.options.pagezero_size orelse MachO.default_pagezero_vmsize;
626 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
627 const aligned_pagezero_vmsize = mem.alignBackward(u64, pagezero_vmsize, page_size);
628 if (macho_file.base.options.output_mode != .Lib and aligned_pagezero_vmsize > 0) {
629 if (aligned_pagezero_vmsize != pagezero_vmsize) {
630 log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{pagezero_vmsize});
608 const comp = macho_file.base.comp;
609 const gpa = comp.gpa;
610 const target = macho_file.base.comp.root_mod.resolved_target.result;
611 const page_size = MachO.getPageSize(target.cpu.arch);
612 const aligned_pagezero_vmsize = mem.alignBackward(u64, macho_file.pagezero_vmsize, page_size);
613 if (macho_file.base.comp.config.output_mode != .Lib and aligned_pagezero_vmsize > 0) {
614 if (aligned_pagezero_vmsize != macho_file.pagezero_vmsize) {
615 log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{macho_file.pagezero_vmsize});
631616 log.warn(" rounding down to 0x{x}", .{aligned_pagezero_vmsize});
632617 }
633618 macho_file.pagezero_segment_cmd_index = @intCast(macho_file.segments.items.len);
......@@ -695,7 +680,8 @@ fn createSegments(macho_file: *MachO) !void {
695680}
696681
697682fn writeAtoms(macho_file: *MachO) !void {
698 const gpa = macho_file.base.allocator;
683 const comp = macho_file.base.comp;
684 const gpa = comp.gpa;
699685 const slice = macho_file.sections.slice();
700686
701687 for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {
......@@ -768,8 +754,10 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void {
768754}
769755
770756fn writeThunks(macho_file: *MachO) !void {
771 assert(macho_file.base.options.target.cpu.arch == .aarch64);
772 const gpa = macho_file.base.allocator;
757 const target = macho_file.base.comp.root_mod.resolved_target.result;
758 assert(target.cpu.arch == .aarch64);
759 const comp = macho_file.base.comp;
760 const gpa = comp.gpa;
773761
774762 const sect_id = macho_file.text_section_index orelse return;
775763 const header = macho_file.sections.items(.header)[sect_id];
......@@ -789,7 +777,8 @@ fn writeThunks(macho_file: *MachO) !void {
789777}
790778
791779fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void {
792 const gpa = macho_file.base.allocator;
780 const comp = macho_file.base.comp;
781 const gpa = comp.gpa;
793782 const header = macho_file.sections.items(.header)[sect_id];
794783 const capacity = math.cast(usize, header.size) orelse return error.Overflow;
795784 var buffer = try std.ArrayList(u8).initCapacity(gpa, capacity);
......@@ -803,8 +792,10 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void {
803792}
804793
805794fn writeStubs(macho_file: *MachO) !void {
806 const gpa = macho_file.base.allocator;
807 const cpu_arch = macho_file.base.options.target.cpu.arch;
795 const comp = macho_file.base.comp;
796 const gpa = comp.gpa;
797 const target = macho_file.base.comp.root_mod.resolved_target.result;
798 const cpu_arch = target.cpu.arch;
808799 const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];
809800 const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];
810801
......@@ -825,8 +816,10 @@ fn writeStubs(macho_file: *MachO) !void {
825816}
826817
827818fn writeStubHelpers(macho_file: *MachO) !void {
828 const gpa = macho_file.base.allocator;
829 const cpu_arch = macho_file.base.options.target.cpu.arch;
819 const comp = macho_file.base.comp;
820 const gpa = comp.gpa;
821 const target = macho_file.base.comp.root_mod.resolved_target.result;
822 const cpu_arch = target.cpu.arch;
830823 const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];
831824
832825 const capacity = math.cast(usize, stub_helper_header.size) orelse return error.Overflow;
......@@ -868,8 +861,10 @@ fn writeStubHelpers(macho_file: *MachO) !void {
868861}
869862
870863fn writeLaSymbolPtrs(macho_file: *MachO) !void {
871 const gpa = macho_file.base.allocator;
872 const cpu_arch = macho_file.base.options.target.cpu.arch;
864 const comp = macho_file.base.comp;
865 const gpa = comp.gpa;
866 const target = macho_file.base.comp.root_mod.resolved_target.result;
867 const cpu_arch = target.cpu.arch;
873868 const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];
874869 const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];
875870
......@@ -900,7 +895,8 @@ fn pruneAndSortSections(macho_file: *MachO) !void {
900895 }
901896 };
902897
903 const gpa = macho_file.base.allocator;
898 const comp = macho_file.base.comp;
899 const gpa = comp.gpa;
904900
905901 var entries = try std.ArrayList(Entry).initCapacity(gpa, macho_file.sections.slice().len);
906902 defer entries.deinit();
......@@ -977,11 +973,12 @@ fn pruneAndSortSections(macho_file: *MachO) !void {
977973}
978974
979975fn calcSectionSizes(macho_file: *MachO) !void {
976 const target = macho_file.base.comp.root_mod.resolved_target.result;
980977 const slice = macho_file.sections.slice();
981978 for (slice.items(.header), 0..) |*header, sect_id| {
982979 if (header.size == 0) continue;
983980 if (macho_file.text_section_index) |txt| {
984 if (txt == sect_id and macho_file.base.options.target.cpu.arch == .aarch64) continue;
981 if (txt == sect_id and target.cpu.arch == .aarch64) continue;
985982 }
986983
987984 var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
......@@ -1004,7 +1001,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
10041001 }
10051002 }
10061003
1007 if (macho_file.text_section_index != null and macho_file.base.options.target.cpu.arch == .aarch64) {
1004 if (macho_file.text_section_index != null and target.cpu.arch == .aarch64) {
10081005 // Create jump/branch range extenders if needed.
10091006 try thunks.createThunks(macho_file, macho_file.text_section_index.?);
10101007 }
......@@ -1056,7 +1053,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
10561053 header.@"align" = 3;
10571054 }
10581055
1059 const cpu_arch = macho_file.base.options.target.cpu.arch;
1056 const cpu_arch = target.cpu.arch;
10601057
10611058 if (macho_file.stubs_section_index) |sect_id| {
10621059 const header = &macho_file.sections.items(.header)[sect_id];
......@@ -1079,11 +1076,10 @@ fn calcSectionSizes(macho_file: *MachO) !void {
10791076}
10801077
10811078fn allocateSegments(macho_file: *MachO) !void {
1082 const gpa = macho_file.base.allocator;
10831079 for (macho_file.segments.items, 0..) |*segment, segment_index| {
10841080 const is_text_segment = mem.eql(u8, segment.segName(), "__TEXT");
10851081 const base_size = if (is_text_segment)
1086 try load_commands.calcMinHeaderPad(gpa, &macho_file.base.options, .{
1082 try load_commands.calcMinHeaderPad(macho_file, .{
10871083 .segments = macho_file.segments.items,
10881084 .dylibs = macho_file.dylibs.items,
10891085 .referenced_dylibs = macho_file.referenced_dylibs.keys(),
......@@ -1106,6 +1102,7 @@ fn getSegmentAllocBase(macho_file: *MachO, segment_index: u8) struct { vmaddr: u
11061102}
11071103
11081104fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void {
1105 const target = macho_file.base.comp.root_mod.resolved_target.result;
11091106 const segment = &macho_file.segments.items[segment_index];
11101107
11111108 if (mem.eql(u8, segment.segName(), "__PAGEZERO")) return; // allocated upon creation
......@@ -1188,7 +1185,7 @@ fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void
11881185 segment.vmsize = start;
11891186 }
11901187
1191 const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
1188 const page_size = MachO.getPageSize(target.cpu.arch);
11921189 segment.filesize = mem.alignForward(u64, segment.filesize, page_size);
11931190 segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);
11941191}
src/link/NvPtx.zig+48-46
......@@ -24,46 +24,62 @@ const LlvmObject = @import("../codegen/llvm.zig").Object;
2424
2525base: link.File,
2626llvm_object: *LlvmObject,
27ptx_file_name: []const u8,
2827
29pub fn createEmpty(gpa: Allocator, options: link.Options) !*NvPtx {
30 if (!options.use_llvm) return error.PtxArchNotSupported;
31
32 if (!options.target.cpu.arch.isNvptx()) return error.PtxArchNotSupported;
33
34 switch (options.target.os.tag) {
28pub fn createEmpty(
29 arena: Allocator,
30 comp: *Compilation,
31 emit: Compilation.Emit,
32 options: link.File.OpenOptions,
33) !*NvPtx {
34 const target = comp.root_mod.resolved_target.result;
35 const use_lld = build_options.have_llvm and comp.config.use_lld;
36 const use_llvm = comp.config.use_llvm;
37
38 assert(use_llvm); // Caught by Compilation.Config.resolve.
39 assert(!use_lld); // Caught by Compilation.Config.resolve.
40 assert(target.cpu.arch.isNvptx()); // Caught by Compilation.Config.resolve.
41
42 switch (target.os.tag) {
3543 // TODO: does it also work with nvcl ?
3644 .cuda => {},
3745 else => return error.PtxArchNotSupported,
3846 }
3947
40 const llvm_object = try LlvmObject.create(gpa, options);
41 const nvptx = try gpa.create(NvPtx);
48 const llvm_object = try LlvmObject.create(arena, comp);
49 const nvptx = try arena.create(NvPtx);
4250 nvptx.* = .{
4351 .base = .{
4452 .tag = .nvptx,
45 .options = options,
53 .comp = comp,
54 .emit = emit,
55 .gc_sections = options.gc_sections orelse false,
56 .print_gc_sections = options.print_gc_sections,
57 .stack_size = options.stack_size orelse 0,
58 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
4659 .file = null,
47 .allocator = gpa,
60 .disable_lld_caching = options.disable_lld_caching,
61 .build_id = options.build_id,
62 .rpath_list = options.rpath_list,
4863 },
4964 .llvm_object = llvm_object,
50 .ptx_file_name = try std.mem.join(gpa, "", &[_][]const u8{ options.root_name, ".ptx" }),
5165 };
5266
5367 return nvptx;
5468}
5569
56pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*NvPtx {
57 if (!options.use_llvm) return error.PtxArchNotSupported;
58 assert(options.target.ofmt == .nvptx);
59
60 log.debug("Opening .ptx target file {s}", .{sub_path});
61 return createEmpty(allocator, options);
70pub fn open(
71 arena: Allocator,
72 comp: *Compilation,
73 emit: Compilation.Emit,
74 options: link.File.OpenOptions,
75) !*NvPtx {
76 const target = comp.root_mod.resolved_target.result;
77 assert(target.ofmt == .nvptx);
78 return createEmpty(arena, comp, emit, options);
6279}
6380
6481pub fn deinit(self: *NvPtx) void {
65 self.llvm_object.destroy(self.base.allocator);
66 self.base.allocator.free(self.ptx_file_name);
82 self.llvm_object.deinit();
6783}
6884
6985pub fn updateFunc(self: *NvPtx, module: *Module, func_index: InternPool.Index, air: Air, liveness: Liveness) !void {
......@@ -80,9 +96,9 @@ pub fn updateExports(
8096 exported: Module.Exported,
8197 exports: []const *Module.Export,
8298) !void {
83 if (build_options.skip_non_native and builtin.object_format != .nvptx) {
99 if (build_options.skip_non_native and builtin.object_format != .nvptx)
84100 @panic("Attempted to compile for object format that was disabled by build configuration");
85 }
101
86102 return self.llvm_object.updateExports(module, exported, exports);
87103}
88104
......@@ -90,32 +106,18 @@ pub fn freeDecl(self: *NvPtx, decl_index: InternPool.DeclIndex) void {
90106 return self.llvm_object.freeDecl(decl_index);
91107}
92108
93pub fn flush(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
94 return self.flushModule(comp, prog_node);
109pub fn flush(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
110 return self.flushModule(arena, prog_node);
95111}
96112
97pub fn flushModule(self: *NvPtx, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
98 if (build_options.skip_non_native) {
113pub fn flushModule(self: *NvPtx, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
114 if (build_options.skip_non_native)
99115 @panic("Attempted to compile for architecture that was disabled by build configuration");
100 }
101 const outfile = comp.bin_file.options.emit orelse return;
102
103 const tracy = trace(@src());
104 defer tracy.end();
105
106 // We modify 'comp' before passing it to LLVM, but restore value afterwards.
107 // We tell LLVM to not try to build a .o, only an "assembly" file.
108 // This is required by the LLVM PTX backend.
109 comp.bin_file.options.emit = null;
110 comp.emit_asm = .{
111 // 'null' means using the default cache dir: zig-cache/o/...
112 .directory = null,
113 .basename = self.ptx_file_name,
114 };
115 defer {
116 comp.bin_file.options.emit = outfile;
117 comp.emit_asm = null;
118 }
119116
120 try self.llvm_object.flushModule(comp, prog_node);
117 // The code that was here before mutated the Compilation's file emission mechanism.
118 // That's not supposed to happen in flushModule, so I deleted the code.
119 _ = arena;
120 _ = self;
121 _ = prog_node;
122 @panic("TODO: rewrite the NvPtx.flushModule function");
121123}
src/link/Plan9.zig+170-116
......@@ -28,7 +28,6 @@ pub const base_tag = .plan9;
2828
2929base: link.File,
3030sixtyfour_bit: bool,
31error_flags: File.ErrorFlags = File.ErrorFlags{},
3231bases: Bases,
3332
3433/// A symbol's value is just casted down when compiling
......@@ -174,7 +173,7 @@ pub const Atom = struct {
174173 return .{ .code_ptr = slice.ptr, .other = .{ .code_len = slice.len } };
175174 }
176175 fn getCode(self: CodePtr, plan9: *const Plan9) []u8 {
177 const mod = plan9.base.options.module.?;
176 const mod = plan9.base.comp.module.?;
178177 return if (self.code_ptr) |p| p[0..self.other.code_len] else blk: {
179178 const decl_index = self.other.decl_index;
180179 const decl = mod.declPtr(decl_index);
......@@ -206,7 +205,8 @@ pub const Atom = struct {
206205
207206 // asserts that self.got_index != null
208207 pub fn getOffsetTableAddress(self: Atom, plan9: *Plan9) u64 {
209 const ptr_bytes = @divExact(plan9.base.options.target.ptrBitWidth(), 8);
208 const target = plan9.base.comp.root_mod.resolved_target.result;
209 const ptr_bytes = @divExact(target.ptrBitWidth(), 8);
210210 const got_addr = plan9.bases.data;
211211 const got_index = self.got_index.?;
212212 return got_addr + got_index * ptr_bytes;
......@@ -293,38 +293,51 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {
293293 };
294294}
295295
296pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {
297 if (options.use_llvm)
298 return error.LLVMBackendDoesNotSupportPlan9;
299 const sixtyfour_bit: bool = switch (options.target.ptrBitWidth()) {
296pub fn createEmpty(
297 arena: Allocator,
298 comp: *Compilation,
299 emit: Compilation.Emit,
300 options: link.File.OpenOptions,
301) !*Plan9 {
302 const target = comp.root_mod.resolved_target.result;
303 const gpa = comp.gpa;
304 const optimize_mode = comp.root_mod.optimize_mode;
305 const output_mode = comp.config.output_mode;
306
307 const sixtyfour_bit: bool = switch (target.ptrBitWidth()) {
300308 0...32 => false,
301309 33...64 => true,
302310 else => return error.UnsupportedP9Architecture,
303311 };
304312
305 const arena_allocator = std.heap.ArenaAllocator.init(gpa);
306
307 const self = try gpa.create(Plan9);
313 const self = try arena.create(Plan9);
308314 self.* = .{
309 .path_arena = arena_allocator,
315 .path_arena = std.heap.ArenaAllocator.init(gpa),
310316 .base = .{
311317 .tag = .plan9,
312 .options = options,
313 .allocator = gpa,
318 .comp = comp,
319 .emit = emit,
320 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug and output_mode != .Obj),
321 .print_gc_sections = options.print_gc_sections,
322 .stack_size = options.stack_size orelse 16777216,
323 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
314324 .file = null,
325 .disable_lld_caching = options.disable_lld_caching,
326 .build_id = options.build_id,
327 .rpath_list = options.rpath_list,
315328 },
316329 .sixtyfour_bit = sixtyfour_bit,
317330 .bases = undefined,
318 .magic = try aout.magicFromArch(self.base.options.target.cpu.arch),
331 .magic = try aout.magicFromArch(target.cpu.arch),
319332 };
320333 // a / will always be in a file path
321 try self.file_segments.put(self.base.allocator, "/", 1);
334 try self.file_segments.put(gpa, "/", 1);
322335 return self;
323336}
324337
325338fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !void {
326 const gpa = self.base.allocator;
327 const mod = self.base.options.module.?;
339 const gpa = self.base.comp.gpa;
340 const mod = self.base.comp.module.?;
328341 const decl = mod.declPtr(decl_index);
329342 const fn_map_res = try self.fn_decl_table.getOrPut(gpa, decl.getFileScope(mod));
330343 if (fn_map_res.found_existing) {
......@@ -379,6 +392,7 @@ fn putFn(self: *Plan9, decl_index: InternPool.DeclIndex, out: FnDeclOutput) !voi
379392}
380393
381394fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !void {
395 const gpa = self.base.comp.gpa;
382396 const sep = std.fs.path.sep;
383397 var it = std.mem.tokenizeScalar(u8, path, sep);
384398 while (it.next()) |component| {
......@@ -386,7 +400,7 @@ fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !voi
386400 try a.writer().writeInt(u16, num, .big);
387401 } else {
388402 self.file_segments_i += 1;
389 try self.file_segments.put(self.base.allocator, component, self.file_segments_i);
403 try self.file_segments.put(gpa, component, self.file_segments_i);
390404 try a.writer().writeInt(u16, self.file_segments_i, .big);
391405 }
392406 }
......@@ -397,6 +411,8 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
397411 @panic("Attempted to compile for object format that was disabled by build configuration");
398412 }
399413
414 const gpa = self.base.comp.gpa;
415 const target = self.base.comp.root_mod.resolved_target.result;
400416 const func = mod.funcInfo(func_index);
401417 const decl_index = func.owner_decl;
402418 const decl = mod.declPtr(decl_index);
......@@ -404,15 +420,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
404420
405421 const atom_idx = try self.seeDecl(decl_index);
406422
407 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
423 var code_buffer = std.ArrayList(u8).init(gpa);
408424 defer code_buffer.deinit();
409425 var dbg_info_output: DebugInfoOutput = .{
410 .dbg_line = std.ArrayList(u8).init(self.base.allocator),
426 .dbg_line = std.ArrayList(u8).init(gpa),
411427 .start_line = null,
412428 .end_line = undefined,
413429 .pcop_change_index = null,
414430 // we have already checked the target in the linker to make sure it is compatable
415 .pc_quanta = aout.getPCQuant(self.base.options.target.cpu.arch) catch unreachable,
431 .pc_quanta = aout.getPCQuant(target.cpu.arch) catch unreachable,
416432 };
417433 defer dbg_info_output.dbg_line.deinit();
418434
......@@ -448,14 +464,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
448464}
449465
450466pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
467 const gpa = self.base.comp.gpa;
451468 _ = try self.seeDecl(decl_index);
452 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
469 var code_buffer = std.ArrayList(u8).init(gpa);
453470 defer code_buffer.deinit();
454471
455 const mod = self.base.options.module.?;
472 const mod = self.base.comp.module.?;
456473 const decl = mod.declPtr(decl_index);
457474
458 const gop = try self.unnamed_const_atoms.getOrPut(self.base.allocator, decl_index);
475 const gop = try self.unnamed_const_atoms.getOrPut(gpa, decl_index);
459476 if (!gop.found_existing) {
460477 gop.value_ptr.* = .{};
461478 }
......@@ -465,7 +482,7 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De
465482
466483 const index = unnamed_consts.items.len;
467484 // name is freed when the unnamed const is freed
468 const name = try std.fmt.allocPrint(self.base.allocator, "__unnamed_{s}_{d}", .{ decl_name, index });
485 const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
469486
470487 const sym_index = try self.allocateSymbolIndex();
471488 const new_atom_idx = try self.createAtom();
......@@ -498,17 +515,18 @@ pub fn lowerUnnamedConst(self: *Plan9, tv: TypedValue, decl_index: InternPool.De
498515 },
499516 };
500517 // duped_code is freed when the unnamed const is freed
501 const duped_code = try self.base.allocator.dupe(u8, code);
502 errdefer self.base.allocator.free(duped_code);
518 const duped_code = try gpa.dupe(u8, code);
519 errdefer gpa.free(duped_code);
503520 const new_atom = self.getAtomPtr(new_atom_idx);
504521 new_atom.* = info;
505522 new_atom.code = .{ .code_ptr = duped_code.ptr, .other = .{ .code_len = duped_code.len } };
506 try unnamed_consts.append(self.base.allocator, new_atom_idx);
523 try unnamed_consts.append(gpa, new_atom_idx);
507524 // we return the new_atom_idx to codegen
508525 return new_atom_idx;
509526}
510527
511528pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex) !void {
529 const gpa = self.base.comp.gpa;
512530 const decl = mod.declPtr(decl_index);
513531
514532 if (decl.isExtern(mod)) {
......@@ -517,7 +535,7 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex)
517535 }
518536 const atom_idx = try self.seeDecl(decl_index);
519537
520 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
538 var code_buffer = std.ArrayList(u8).init(gpa);
521539 defer code_buffer.deinit();
522540 const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
523541 // TODO we need the symbol index for symbol in the table of locals for the containing atom
......@@ -535,17 +553,18 @@ pub fn updateDecl(self: *Plan9, mod: *Module, decl_index: InternPool.DeclIndex)
535553 return;
536554 },
537555 };
538 try self.data_decl_table.ensureUnusedCapacity(self.base.allocator, 1);
539 const duped_code = try self.base.allocator.dupe(u8, code);
556 try self.data_decl_table.ensureUnusedCapacity(gpa, 1);
557 const duped_code = try gpa.dupe(u8, code);
540558 self.getAtomPtr(self.decls.get(decl_index).?.index).code = .{ .code_ptr = null, .other = .{ .decl_index = decl_index } };
541559 if (self.data_decl_table.fetchPutAssumeCapacity(decl_index, duped_code)) |old_entry| {
542 self.base.allocator.free(old_entry.value);
560 gpa.free(old_entry.value);
543561 }
544562 return self.updateFinish(decl_index);
545563}
546564/// called at the end of update{Decl,Func}
547565fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
548 const mod = self.base.options.module.?;
566 const gpa = self.base.comp.gpa;
567 const mod = self.base.comp.module.?;
549568 const decl = mod.declPtr(decl_index);
550569 const is_fn = (decl.ty.zigTypeTag(mod) == .Fn);
551570 const sym_t: aout.Sym.Type = if (is_fn) .t else .d;
......@@ -558,7 +577,7 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
558577 const sym: aout.Sym = .{
559578 .value = undefined, // the value of stuff gets filled in in flushModule
560579 .type = atom.type,
561 .name = try self.base.allocator.dupe(u8, mod.intern_pool.stringToSlice(decl.name)),
580 .name = try gpa.dupe(u8, mod.intern_pool.stringToSlice(decl.name)),
562581 };
563582
564583 if (atom.sym_index) |s| {
......@@ -571,10 +590,11 @@ fn updateFinish(self: *Plan9, decl_index: InternPool.DeclIndex) !void {
571590}
572591
573592fn allocateSymbolIndex(self: *Plan9) !usize {
593 const gpa = self.base.comp.gpa;
574594 if (self.syms_index_free_list.popOrNull()) |i| {
575595 return i;
576596 } else {
577 _ = try self.syms.addOne(self.base.allocator);
597 _ = try self.syms.addOne(gpa);
578598 return self.syms.items.len - 1;
579599 }
580600}
......@@ -588,16 +608,18 @@ fn allocateGotIndex(self: *Plan9) usize {
588608 }
589609}
590610
591pub fn flush(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
592 assert(!self.base.options.use_lld);
611pub fn flush(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
612 const comp = self.base.comp;
613 const use_lld = build_options.have_llvm and comp.config.use_lld;
614 assert(!use_lld);
593615
594 switch (self.base.options.effectiveOutputMode()) {
616 switch (link.File.effectiveOutputMode(use_lld, comp.config.output_mode)) {
595617 .Exe => {},
596618 // plan9 object files are totally different
597619 .Obj => return error.TODOImplementPlan9Objs,
598620 .Lib => return error.TODOImplementWritingLibFiles,
599621 }
600 return self.flushModule(comp, prog_node);
622 return self.flushModule(arena, prog_node);
601623}
602624
603625pub fn changeLine(l: *std.ArrayList(u8), delta_line: i32) !void {
......@@ -645,12 +667,17 @@ fn atomCount(self: *Plan9) usize {
645667 return data_decl_count + fn_decl_count + unnamed_const_count + lazy_atom_count + extern_atom_count + anon_atom_count;
646668}
647669
648pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
670pub fn flushModule(self: *Plan9, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
649671 if (build_options.skip_non_native and builtin.object_format != .plan9) {
650672 @panic("Attempted to compile for object format that was disabled by build configuration");
651673 }
652674
653 _ = comp;
675 _ = arena; // Has the same lifetime as the call to Compilation.update.
676
677 const comp = self.base.comp;
678 const gpa = comp.gpa;
679 const target = comp.root_mod.resolved_target.result;
680
654681 const tracy = trace(@src());
655682 defer tracy.end();
656683
......@@ -662,7 +689,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
662689
663690 defer assert(self.hdr.entry != 0x0);
664691
665 const mod = self.base.options.module orelse return error.LinkingWithoutZigSourceUnimplemented;
692 const mod = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
666693
667694 // finish up the lazy syms
668695 if (self.lazy_syms.getPtr(.none)) |metadata| {
......@@ -691,12 +718,12 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
691718 const atom_count = self.atomCount();
692719 assert(self.got_len == atom_count + self.got_index_free_list.items.len);
693720 const got_size = self.got_len * if (!self.sixtyfour_bit) @as(u32, 4) else 8;
694 var got_table = try self.base.allocator.alloc(u8, got_size);
695 defer self.base.allocator.free(got_table);
721 var got_table = try gpa.alloc(u8, got_size);
722 defer gpa.free(got_table);
696723
697724 // + 4 for header, got, symbols, linecountinfo
698 var iovecs = try self.base.allocator.alloc(std.os.iovec_const, self.atomCount() + 4 - self.externCount());
699 defer self.base.allocator.free(iovecs);
725 var iovecs = try gpa.alloc(std.os.iovec_const, self.atomCount() + 4 - self.externCount());
726 defer gpa.free(iovecs);
700727
701728 const file = self.base.file.?;
702729
......@@ -709,7 +736,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
709736 var iovecs_i: usize = 1;
710737 var text_i: u64 = 0;
711738
712 var linecountinfo = std.ArrayList(u8).init(self.base.allocator);
739 var linecountinfo = std.ArrayList(u8).init(gpa);
713740 defer linecountinfo.deinit();
714741 // text
715742 {
......@@ -741,9 +768,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
741768 atom.offset = off;
742769 log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
743770 if (!self.sixtyfour_bit) {
744 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
771 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
745772 } else {
746 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
773 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
747774 }
748775 self.syms.items[atom.sym_index.?].value = off;
749776 if (mod.decl_exports.get(decl_index)) |exports| {
......@@ -770,9 +797,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
770797 text_i += code.len;
771798 text_atom.offset = off;
772799 if (!self.sixtyfour_bit) {
773 mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
800 mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
774801 } else {
775 mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
802 mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
776803 }
777804 self.syms.items[text_atom.sym_index.?].value = off;
778805 }
......@@ -783,9 +810,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
783810 const val = self.getAddr(text_i, .t);
784811 self.syms.items[etext_atom.sym_index.?].value = val;
785812 if (!self.sixtyfour_bit) {
786 mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());
813 mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
787814 } else {
788 mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());
815 mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
789816 }
790817 }
791818 // global offset table is in data
......@@ -807,9 +834,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
807834 data_i += code.len;
808835 atom.offset = off;
809836 if (!self.sixtyfour_bit) {
810 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
837 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
811838 } else {
812 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
839 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
813840 }
814841 self.syms.items[atom.sym_index.?].value = off;
815842 if (mod.decl_exports.get(decl_index)) |exports| {
......@@ -830,9 +857,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
830857 data_i += code.len;
831858 atom.offset = off;
832859 if (!self.sixtyfour_bit) {
833 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
860 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
834861 } else {
835 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
862 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
836863 }
837864 self.syms.items[atom.sym_index.?].value = off;
838865 }
......@@ -851,9 +878,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
851878 data_i += code.len;
852879 atom.offset = off;
853880 if (!self.sixtyfour_bit) {
854 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
881 mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
855882 } else {
856 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
883 mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
857884 }
858885 self.syms.items[atom.sym_index.?].value = off;
859886 }
......@@ -871,9 +898,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
871898 data_i += code.len;
872899 data_atom.offset = off;
873900 if (!self.sixtyfour_bit) {
874 mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
901 mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
875902 } else {
876 mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
903 mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
877904 }
878905 self.syms.items[data_atom.sym_index.?].value = off;
879906 }
......@@ -883,9 +910,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
883910 const val = self.getAddr(data_i, .b);
884911 self.syms.items[edata_atom.sym_index.?].value = val;
885912 if (!self.sixtyfour_bit) {
886 mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());
913 mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
887914 } else {
888 mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());
915 mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
889916 }
890917 }
891918 // end symbol (same as edata because native backends don't do .bss yet)
......@@ -894,17 +921,17 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
894921 const val = self.getAddr(data_i, .b);
895922 self.syms.items[end_atom.sym_index.?].value = val;
896923 if (!self.sixtyfour_bit) {
897 mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());
924 mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
898925 } else {
899926 log.debug("write end (got_table[0x{x}] = 0x{x})", .{ end_atom.got_index.? * 8, val });
900 mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());
927 mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
901928 }
902929 }
903930 }
904 var sym_buf = std.ArrayList(u8).init(self.base.allocator);
931 var sym_buf = std.ArrayList(u8).init(gpa);
905932 try self.writeSyms(&sym_buf);
906933 const syms = try sym_buf.toOwnedSlice();
907 defer self.base.allocator.free(syms);
934 defer gpa.free(syms);
908935 assert(2 + self.atomCount() - self.externCount() == iovecs_i); // we didn't write all the decls
909936 iovecs[iovecs_i] = .{ .iov_base = syms.ptr, .iov_len = syms.len };
910937 iovecs_i += 1;
......@@ -934,7 +961,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
934961 const source_atom = self.getAtom(source_atom_index);
935962 const source_atom_symbol = self.syms.items[source_atom.sym_index.?];
936963 const code = source_atom.code.getCode(self);
937 const endian = self.base.options.target.cpu.arch.endian();
964 const endian = target.cpu.arch.endian();
938965 for (kv.value_ptr.items) |reloc| {
939966 const offset = reloc.offset;
940967 const addend = reloc.addend;
......@@ -985,6 +1012,7 @@ fn addDeclExports(
9851012 decl_index: InternPool.DeclIndex,
9861013 exports: []const *Module.Export,
9871014) !void {
1015 const gpa = self.base.comp.gpa;
9881016 const metadata = self.decls.getPtr(decl_index).?;
9891017 const atom = self.getAtom(metadata.index);
9901018
......@@ -994,7 +1022,7 @@ fn addDeclExports(
9941022 if (exp.opts.section.unwrap()) |section_name| {
9951023 if (!mod.intern_pool.stringEqlSlice(section_name, ".text") and !mod.intern_pool.stringEqlSlice(section_name, ".data")) {
9961024 try mod.failed_exports.put(mod.gpa, exp, try Module.ErrorMsg.create(
997 self.base.allocator,
1025 gpa,
9981026 mod.declPtr(decl_index).srcLoc(mod),
9991027 "plan9 does not support extra sections",
10001028 .{},
......@@ -1005,41 +1033,42 @@ fn addDeclExports(
10051033 const sym = .{
10061034 .value = atom.offset.?,
10071035 .type = atom.type.toGlobal(),
1008 .name = try self.base.allocator.dupe(u8, exp_name),
1036 .name = try gpa.dupe(u8, exp_name),
10091037 };
10101038
10111039 if (metadata.getExport(self, exp_name)) |i| {
10121040 self.syms.items[i] = sym;
10131041 } else {
1014 try self.syms.append(self.base.allocator, sym);
1015 try metadata.exports.append(self.base.allocator, self.syms.items.len - 1);
1042 try self.syms.append(gpa, sym);
1043 try metadata.exports.append(gpa, self.syms.items.len - 1);
10161044 }
10171045 }
10181046}
10191047
10201048pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1049 const gpa = self.base.comp.gpa;
10211050 // TODO audit the lifetimes of decls table entries. It's possible to get
10221051 // freeDecl without any updateDecl in between.
10231052 // However that is planned to change, see the TODO comment in Module.zig
10241053 // in the deleteUnusedDecl function.
1025 const mod = self.base.options.module.?;
1054 const mod = self.base.comp.module.?;
10261055 const decl = mod.declPtr(decl_index);
10271056 const is_fn = decl.val.isFuncBody(mod);
10281057 if (is_fn) {
10291058 const symidx_and_submap = self.fn_decl_table.get(decl.getFileScope(mod)).?;
10301059 var submap = symidx_and_submap.functions;
10311060 if (submap.fetchSwapRemove(decl_index)) |removed_entry| {
1032 self.base.allocator.free(removed_entry.value.code);
1033 self.base.allocator.free(removed_entry.value.lineinfo);
1061 gpa.free(removed_entry.value.code);
1062 gpa.free(removed_entry.value.lineinfo);
10341063 }
10351064 if (submap.count() == 0) {
10361065 self.syms.items[symidx_and_submap.sym_index] = aout.Sym.undefined_symbol;
1037 self.syms_index_free_list.append(self.base.allocator, symidx_and_submap.sym_index) catch {};
1038 submap.deinit(self.base.allocator);
1066 self.syms_index_free_list.append(gpa, symidx_and_submap.sym_index) catch {};
1067 submap.deinit(gpa);
10391068 }
10401069 } else {
10411070 if (self.data_decl_table.fetchSwapRemove(decl_index)) |removed_entry| {
1042 self.base.allocator.free(removed_entry.value);
1071 gpa.free(removed_entry.value);
10431072 }
10441073 }
10451074 if (self.decls.fetchRemove(decl_index)) |const_kv| {
......@@ -1047,35 +1076,36 @@ pub fn freeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) void {
10471076 const atom = self.getAtom(kv.value.index);
10481077 if (atom.got_index) |i| {
10491078 // TODO: if this catch {} is triggered, an assertion in flushModule will be triggered, because got_index_free_list will have the wrong length
1050 self.got_index_free_list.append(self.base.allocator, i) catch {};
1079 self.got_index_free_list.append(gpa, i) catch {};
10511080 }
10521081 if (atom.sym_index) |i| {
1053 self.syms_index_free_list.append(self.base.allocator, i) catch {};
1082 self.syms_index_free_list.append(gpa, i) catch {};
10541083 self.syms.items[i] = aout.Sym.undefined_symbol;
10551084 }
1056 kv.value.exports.deinit(self.base.allocator);
1085 kv.value.exports.deinit(gpa);
10571086 }
10581087 self.freeUnnamedConsts(decl_index);
10591088 {
10601089 const atom_index = self.decls.get(decl_index).?.index;
10611090 const relocs = self.relocs.getPtr(atom_index) orelse return;
1062 relocs.clearAndFree(self.base.allocator);
1091 relocs.clearAndFree(gpa);
10631092 assert(self.relocs.remove(atom_index));
10641093 }
10651094}
10661095fn freeUnnamedConsts(self: *Plan9, decl_index: InternPool.DeclIndex) void {
1096 const gpa = self.base.comp.gpa;
10671097 const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return;
10681098 for (unnamed_consts.items) |atom_idx| {
10691099 const atom = self.getAtom(atom_idx);
1070 self.base.allocator.free(self.syms.items[atom.sym_index.?].name);
1100 gpa.free(self.syms.items[atom.sym_index.?].name);
10711101 self.syms.items[atom.sym_index.?] = aout.Sym.undefined_symbol;
1072 self.syms_index_free_list.append(self.base.allocator, atom.sym_index.?) catch {};
1102 self.syms_index_free_list.append(gpa, atom.sym_index.?) catch {};
10731103 }
1074 unnamed_consts.clearAndFree(self.base.allocator);
1104 unnamed_consts.clearAndFree(gpa);
10751105}
10761106
10771107fn createAtom(self: *Plan9) !Atom.Index {
1078 const gpa = self.base.allocator;
1108 const gpa = self.base.comp.gpa;
10791109 const index = @as(Atom.Index, @intCast(self.atoms.items.len));
10801110 const atom = try self.atoms.addOne(gpa);
10811111 atom.* = .{
......@@ -1089,7 +1119,8 @@ fn createAtom(self: *Plan9) !Atom.Index {
10891119}
10901120
10911121pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {
1092 const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
1122 const gpa = self.base.comp.gpa;
1123 const gop = try self.decls.getOrPut(gpa, decl_index);
10931124 if (!gop.found_existing) {
10941125 const index = try self.createAtom();
10951126 self.getAtomPtr(index).got_index = self.allocateGotIndex();
......@@ -1100,7 +1131,7 @@ pub fn seeDecl(self: *Plan9, decl_index: InternPool.DeclIndex) !Atom.Index {
11001131 }
11011132 const atom_idx = gop.value_ptr.index;
11021133 // handle externs here because they might not get updateDecl called on them
1103 const mod = self.base.options.module.?;
1134 const mod = self.base.comp.module.?;
11041135 const decl = mod.declPtr(decl_index);
11051136 const name = mod.intern_pool.stringToSlice(decl.name);
11061137 if (decl.isExtern(mod)) {
......@@ -1134,7 +1165,8 @@ pub fn updateExports(
11341165}
11351166
11361167pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.Index {
1137 const gop = try self.lazy_syms.getOrPut(self.base.allocator, sym.getDecl(self.base.options.module.?));
1168 const gpa = self.base.comp.gpa;
1169 const gop = try self.lazy_syms.getOrPut(gpa, sym.getDecl(self.base.comp.module.?));
11381170 errdefer _ = if (!gop.found_existing) self.lazy_syms.pop();
11391171
11401172 if (!gop.found_existing) gop.value_ptr.* = .{};
......@@ -1153,15 +1185,15 @@ pub fn getOrCreateAtomForLazySymbol(self: *Plan9, sym: File.LazySymbol) !Atom.In
11531185 _ = try self.getAtomPtr(atom).getOrCreateSymbolTableEntry(self);
11541186 _ = self.getAtomPtr(atom).getOrCreateOffsetTableEntry(self);
11551187 // anyerror needs to be deferred until flushModule
1156 if (sym.getDecl(self.base.options.module.?) != .none) {
1188 if (sym.getDecl(self.base.comp.module.?) != .none) {
11571189 try self.updateLazySymbolAtom(sym, atom);
11581190 }
11591191 return atom;
11601192}
11611193
11621194fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Index) !void {
1163 const gpa = self.base.allocator;
1164 const mod = self.base.options.module.?;
1195 const gpa = self.base.comp.gpa;
1196 const mod = self.base.comp.module.?;
11651197
11661198 var required_alignment: InternPool.Alignment = .none;
11671199 var code_buffer = std.ArrayList(u8).init(gpa);
......@@ -1206,8 +1238,8 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
12061238 },
12071239 };
12081240 // duped_code is freed when the atom is freed
1209 const duped_code = try self.base.allocator.dupe(u8, code);
1210 errdefer self.base.allocator.free(duped_code);
1241 const duped_code = try gpa.dupe(u8, code);
1242 errdefer gpa.free(duped_code);
12111243 self.getAtomPtr(atom_index).code = .{
12121244 .code_ptr = duped_code.ptr,
12131245 .other = .{ .code_len = duped_code.len },
......@@ -1215,13 +1247,13 @@ fn updateLazySymbolAtom(self: *Plan9, sym: File.LazySymbol, atom_index: Atom.Ind
12151247}
12161248
12171249pub fn deinit(self: *Plan9) void {
1218 const gpa = self.base.allocator;
1250 const gpa = self.base.comp.gpa;
12191251 {
12201252 var it = self.relocs.valueIterator();
12211253 while (it.next()) |relocs| {
1222 relocs.deinit(self.base.allocator);
1254 relocs.deinit(gpa);
12231255 }
1224 self.relocs.deinit(self.base.allocator);
1256 self.relocs.deinit(gpa);
12251257 }
12261258 // free the unnamed consts
12271259 var it_unc = self.unnamed_const_atoms.iterator();
......@@ -1280,24 +1312,39 @@ pub fn deinit(self: *Plan9) void {
12801312 }
12811313}
12821314
1283pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Plan9 {
1284 if (options.use_llvm)
1285 return error.LLVMBackendDoesNotSupportPlan9;
1286 assert(options.target.ofmt == .plan9);
1287
1288 const self = try createEmpty(allocator, options);
1315pub fn open(
1316 arena: Allocator,
1317 comp: *Compilation,
1318 emit: Compilation.Emit,
1319 options: link.File.OpenOptions,
1320) !*Plan9 {
1321 const target = comp.root_mod.resolved_target.result;
1322 const use_lld = build_options.have_llvm and comp.config.use_lld;
1323 const use_llvm = comp.config.use_llvm;
1324
1325 assert(!use_llvm); // Caught by Compilation.Config.resolve.
1326 assert(!use_lld); // Caught by Compilation.Config.resolve.
1327 assert(target.ofmt == .plan9);
1328
1329 const self = try createEmpty(arena, comp, emit, options);
12891330 errdefer self.base.destroy();
12901331
1291 const file = try options.emit.?.directory.handle.createFile(sub_path, .{
1332 const file = try emit.directory.handle.createFile(emit.sub_path, .{
12921333 .read = true,
1293 .mode = link.determineMode(options),
1334 .mode = link.File.determineMode(
1335 use_lld,
1336 comp.config.output_mode,
1337 comp.config.link_mode,
1338 ),
12941339 });
12951340 errdefer file.close();
12961341 self.base.file = file;
12971342
1298 self.bases = defaultBaseAddrs(options.target.cpu.arch);
1343 self.bases = defaultBaseAddrs(target.cpu.arch);
12991344
1300 try self.syms.appendSlice(self.base.allocator, &.{
1345 const gpa = comp.gpa;
1346
1347 try self.syms.appendSlice(gpa, &.{
13011348 // we include the global offset table to make it easier for debugging
13021349 .{
13031350 .value = self.getAddr(0, .d), // the global offset table starts at 0
......@@ -1323,7 +1370,7 @@ pub fn writeSym(self: *Plan9, w: anytype, sym: aout.Sym) !void {
13231370}
13241371
13251372pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
1326 const mod = self.base.options.module.?;
1373 const mod = self.base.comp.module.?;
13271374 const ip = &mod.intern_pool;
13281375 const writer = buf.writer();
13291376 // write __GOT
......@@ -1349,7 +1396,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
13491396 const atom = self.getAtom(decl_metadata.index);
13501397 const sym = self.syms.items[atom.sym_index.?];
13511398 try self.writeSym(writer, sym);
1352 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
1399 if (self.base.comp.module.?.decl_exports.get(decl_index)) |exports| {
13531400 for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| {
13541401 try self.writeSym(writer, self.syms.items[exp_i]);
13551402 };
......@@ -1396,7 +1443,7 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
13961443 const atom = self.getAtom(decl_metadata.index);
13971444 const sym = self.syms.items[atom.sym_index.?];
13981445 try self.writeSym(writer, sym);
1399 if (self.base.options.module.?.decl_exports.get(decl_index)) |exports| {
1446 if (self.base.comp.module.?.decl_exports.get(decl_index)) |exports| {
14001447 for (exports.items) |e| if (decl_metadata.getExport(self, ip.stringToSlice(e.opts.name))) |exp_i| {
14011448 const s = self.syms.items[exp_i];
14021449 if (mem.eql(u8, s.name, "_start"))
......@@ -1439,7 +1486,7 @@ pub fn getDeclVAddr(
14391486 decl_index: InternPool.DeclIndex,
14401487 reloc_info: link.File.RelocInfo,
14411488) !u64 {
1442 const mod = self.base.options.module.?;
1489 const mod = self.base.comp.module.?;
14431490 const decl = mod.declPtr(decl_index);
14441491 log.debug("getDeclVAddr for {s}", .{mod.intern_pool.stringToSlice(decl.name)});
14451492 if (decl.isExtern(mod)) {
......@@ -1480,7 +1527,13 @@ pub fn getDeclVAddr(
14801527 return undefined;
14811528}
14821529
1483pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
1530pub fn lowerAnonDecl(
1531 self: *Plan9,
1532 decl_val: InternPool.Index,
1533 explicit_alignment: InternPool.Alignment,
1534 src_loc: Module.SrcLoc,
1535) !codegen.Result {
1536 _ = explicit_alignment;
14841537 // This is basically the same as lowerUnnamedConst.
14851538 // example:
14861539 // const ty = mod.intern_pool.typeOf(decl_val).toType();
......@@ -1490,9 +1543,9 @@ pub fn lowerAnonDecl(self: *Plan9, decl_val: InternPool.Index, src_loc: Module.S
14901543 // be used by more than one function, however, its address is being used so we need
14911544 // to put it in some location.
14921545 // ...
1493 const gpa = self.base.allocator;
1546 const gpa = self.base.comp.gpa;
14941547 const gop = try self.anon_decls.getOrPut(gpa, decl_val);
1495 const mod = self.base.options.module.?;
1548 const mod = self.base.comp.module.?;
14961549 if (!gop.found_existing) {
14971550 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
14981551 const val = Value.fromInterned(decl_val);
......@@ -1538,11 +1591,12 @@ pub fn getAnonDeclVAddr(self: *Plan9, decl_val: InternPool.Index, reloc_info: li
15381591}
15391592
15401593pub fn addReloc(self: *Plan9, parent_index: Atom.Index, reloc: Reloc) !void {
1541 const gop = try self.relocs.getOrPut(self.base.allocator, parent_index);
1594 const gpa = self.base.comp.gpa;
1595 const gop = try self.relocs.getOrPut(gpa, parent_index);
15421596 if (!gop.found_existing) {
15431597 gop.value_ptr.* = .{};
15441598 }
1545 try gop.value_ptr.append(self.base.allocator, reloc);
1599 try gop.value_ptr.append(gpa, reloc);
15461600}
15471601
15481602pub fn getAtom(self: *const Plan9, index: Atom.Index) Atom {
src/link/SpirV.zig+62-34
......@@ -24,7 +24,6 @@ const SpirV = @This();
2424
2525const std = @import("std");
2626const Allocator = std.mem.Allocator;
27const ArenaAllocator = std.heap.ArenaAllocator;
2827const assert = std.debug.assert;
2928const log = std.log.scoped(.link);
3029
......@@ -47,48 +46,73 @@ base: link.File,
4746
4847object: codegen.Object,
4948
50pub fn createEmpty(gpa: Allocator, options: link.Options) !*SpirV {
51 const self = try gpa.create(SpirV);
49pub const base_tag: link.File.Tag = .spirv;
50
51pub fn createEmpty(
52 arena: Allocator,
53 comp: *Compilation,
54 emit: Compilation.Emit,
55 options: link.File.OpenOptions,
56) !*SpirV {
57 const gpa = comp.gpa;
58 const target = comp.root_mod.resolved_target.result;
59
60 const self = try arena.create(SpirV);
5261 self.* = .{
5362 .base = .{
5463 .tag = .spirv,
55 .options = options,
64 .comp = comp,
65 .emit = emit,
66 .gc_sections = options.gc_sections orelse false,
67 .print_gc_sections = options.print_gc_sections,
68 .stack_size = options.stack_size orelse 0,
69 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
5670 .file = null,
57 .allocator = gpa,
71 .disable_lld_caching = options.disable_lld_caching,
72 .build_id = options.build_id,
73 .rpath_list = options.rpath_list,
5874 },
5975 .object = codegen.Object.init(gpa),
6076 };
6177 errdefer self.deinit();
6278
63 // TODO: Figure out where to put all of these
64 switch (options.target.cpu.arch) {
79 switch (target.cpu.arch) {
6580 .spirv32, .spirv64 => {},
66 else => return error.TODOArchNotSupported,
81 else => unreachable, // Caught by Compilation.Config.resolve.
6782 }
6883
69 switch (options.target.os.tag) {
84 switch (target.os.tag) {
7085 .opencl, .glsl450, .vulkan => {},
71 else => return error.TODOOsNotSupported,
86 else => unreachable, // Caught by Compilation.Config.resolve.
7287 }
7388
74 if (options.target.abi != .none) {
75 return error.TODOAbiNotSupported;
76 }
89 assert(target.abi != .none); // Caught by Compilation.Config.resolve.
7790
7891 return self;
7992}
8093
81pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*SpirV {
82 assert(options.target.ofmt == .spirv);
83
84 if (options.use_llvm) return error.LLVM_BackendIsTODO_ForSpirV; // TODO: LLVM Doesn't support SpirV at all.
85 if (options.use_lld) return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all.
86
87 const spirv = try createEmpty(allocator, options);
94pub fn open(
95 arena: Allocator,
96 comp: *Compilation,
97 emit: Compilation.Emit,
98 options: link.File.OpenOptions,
99) !*SpirV {
100 const target = comp.root_mod.resolved_target.result;
101 const use_lld = build_options.have_llvm and comp.config.use_lld;
102 const use_llvm = comp.config.use_llvm;
103
104 assert(!use_llvm); // Caught by Compilation.Config.resolve.
105 assert(!use_lld); // Caught by Compilation.Config.resolve.
106 assert(target.ofmt == .spirv); // Caught by Compilation.Config.resolve.
107
108 const spirv = try createEmpty(arena, comp, emit, options);
88109 errdefer spirv.base.destroy();
89110
90111 // TODO: read the file and keep valid parts instead of truncating
91 const file = try options.emit.?.directory.handle.createFile(sub_path, .{ .truncate = true, .read = true });
112 const file = try emit.directory.handle.createFile(emit.sub_path, .{
113 .truncate = true,
114 .read = true,
115 });
92116 spirv.base.file = file;
93117 return spirv;
94118}
......@@ -149,19 +173,17 @@ pub fn freeDecl(self: *SpirV, decl_index: InternPool.DeclIndex) void {
149173 _ = decl_index;
150174}
151175
152pub fn flush(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
153 if (build_options.have_llvm and self.base.options.use_lld) {
154 return error.LLD_LinkingIsTODO_ForSpirV; // TODO: LLD Doesn't support SpirV at all.
155 } else {
156 return self.flushModule(comp, prog_node);
157 }
176pub fn flush(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
177 return self.flushModule(arena, prog_node);
158178}
159179
160pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
180pub fn flushModule(self: *SpirV, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
161181 if (build_options.skip_non_native) {
162182 @panic("Attempted to compile for architecture that was disabled by build configuration");
163183 }
164184
185 _ = arena; // Has the same lifetime as the call to Compilation.update.
186
165187 const tracy = trace(@src());
166188 defer tracy.end();
167189
......@@ -171,7 +193,10 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
171193
172194 const spv = &self.object.spv;
173195
196 const comp = self.base.comp;
197 const gpa = comp.gpa;
174198 const target = comp.getTarget();
199
175200 try writeCapabilities(spv, target);
176201 try writeMemoryModel(spv, target);
177202
......@@ -183,7 +208,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
183208 defer error_info.deinit();
184209
185210 try error_info.appendSlice("zig_errors");
186 const module = self.base.options.module.?;
211 const module = self.base.comp.module.?;
187212 for (module.global_error_set.keys()) |name_nts| {
188213 const name = module.intern_pool.stringToSlice(name_nts);
189214 // Errors can contain pretty much any character - to encode them in a string we must escape
......@@ -191,11 +216,11 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
191216 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.
192217 // We're using : as separator, which is a reserved character.
193218
194 const escaped_name = try std.Uri.escapeString(self.base.allocator, name);
195 defer self.base.allocator.free(escaped_name);
219 const escaped_name = try std.Uri.escapeString(gpa, name);
220 defer gpa.free(escaped_name);
196221 try error_info.writer().print(":{s}", .{escaped_name});
197222 }
198 try spv.sections.debug_strings.emit(spv.gpa, .OpSourceExtension, .{
223 try spv.sections.debug_strings.emit(gpa, .OpSourceExtension, .{
199224 .extension = error_info.items,
200225 });
201226
......@@ -203,6 +228,7 @@ pub fn flushModule(self: *SpirV, comp: *Compilation, prog_node: *std.Progress.No
203228}
204229
205230fn writeCapabilities(spv: *SpvModule, target: std.Target) !void {
231 const gpa = spv.gpa;
206232 // TODO: Integrate with a hypothetical feature system
207233 const caps: []const spec.Capability = switch (target.os.tag) {
208234 .opencl => &.{ .Kernel, .Addresses, .Int8, .Int16, .Int64, .Float64, .Float16, .GenericPointer },
......@@ -212,13 +238,15 @@ fn writeCapabilities(spv: *SpvModule, target: std.Target) !void {
212238 };
213239
214240 for (caps) |cap| {
215 try spv.sections.capabilities.emit(spv.gpa, .OpCapability, .{
241 try spv.sections.capabilities.emit(gpa, .OpCapability, .{
216242 .capability = cap,
217243 });
218244 }
219245}
220246
221247fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void {
248 const gpa = spv.gpa;
249
222250 const addressing_model = switch (target.os.tag) {
223251 .opencl => switch (target.cpu.arch) {
224252 .spirv32 => spec.AddressingModel.Physical32,
......@@ -237,7 +265,7 @@ fn writeMemoryModel(spv: *SpvModule, target: std.Target) !void {
237265 };
238266
239267 // TODO: Put this in a proper section.
240 try spv.sections.extensions.emit(spv.gpa, .OpMemoryModel, .{
268 try spv.sections.extensions.emit(gpa, .OpMemoryModel, .{
241269 .addressing_model = addressing_model,
242270 .memory_model = memory_model,
243271 });
src/link/Wasm.zig+609-460
......@@ -37,6 +37,12 @@ pub const Relocation = types.Relocation;
3737pub const base_tag: link.File.Tag = .wasm;
3838
3939base: link.File,
40entry_name: ?[]const u8,
41import_symbols: bool,
42export_symbol_names: []const []const u8,
43global_base: ?u64,
44initial_memory: ?u64,
45max_memory: ?u64,
4046/// Output name of the file
4147name: []const u8,
4248/// If this is not null, an object file is created by LLVM and linked with LLD afterwards.
......@@ -191,6 +197,9 @@ synthetic_functions: std.ArrayListUnmanaged(Atom.Index) = .{},
191197/// Map for storing anonymous declarations. Each anonymous decl maps to its Atom's index.
192198anon_decls: std.AutoArrayHashMapUnmanaged(InternPool.Index, Atom.Index) = .{},
193199
200import_table: bool,
201export_table: bool,
202
194203pub const Alignment = types.Alignment;
195204
196205pub const Segment = struct {
......@@ -363,63 +372,126 @@ pub const StringTable = struct {
363372 }
364373};
365374
366pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Options) !*Wasm {
367 assert(options.target.ofmt == .wasm);
375pub fn open(
376 arena: Allocator,
377 comp: *Compilation,
378 emit: Compilation.Emit,
379 options: link.File.OpenOptions,
380) !*Wasm {
381 // TODO: restore saved linker state, don't truncate the file, and
382 // participate in incremental compilation.
383 return createEmpty(arena, comp, emit, options);
384}
368385
369 if (options.use_llvm and options.use_lld) {
370 return createEmpty(allocator, options);
386pub fn createEmpty(
387 arena: Allocator,
388 comp: *Compilation,
389 emit: Compilation.Emit,
390 options: link.File.OpenOptions,
391) !*Wasm {
392 const gpa = comp.gpa;
393 const target = comp.root_mod.resolved_target.result;
394 assert(target.ofmt == .wasm);
395
396 const use_lld = build_options.have_llvm and comp.config.use_lld;
397 const use_llvm = comp.config.use_llvm;
398 const output_mode = comp.config.output_mode;
399 const shared_memory = comp.config.shared_memory;
400 const wasi_exec_model = comp.config.wasi_exec_model;
401
402 // If using LLD to link, this code should produce an object file so that it
403 // can be passed to LLD.
404 // If using LLVM to generate the object file for the zig compilation unit,
405 // we need a place to put the object file so that it can be subsequently
406 // handled.
407 const zcu_object_sub_path = if (!use_lld and !use_llvm)
408 null
409 else
410 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
411
412 const wasm = try arena.create(Wasm);
413 wasm.* = .{
414 .base = .{
415 .tag = .wasm,
416 .comp = comp,
417 .emit = emit,
418 .zcu_object_sub_path = zcu_object_sub_path,
419 .gc_sections = options.gc_sections orelse (output_mode != .Obj),
420 .print_gc_sections = options.print_gc_sections,
421 .stack_size = options.stack_size orelse std.wasm.page_size * 16, // 1MB
422 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,
423 .file = null,
424 .disable_lld_caching = options.disable_lld_caching,
425 .build_id = options.build_id,
426 .rpath_list = options.rpath_list,
427 },
428 .name = undefined,
429 .import_table = options.import_table,
430 .export_table = options.export_table,
431 .import_symbols = options.import_symbols,
432 .export_symbol_names = options.export_symbol_names,
433 .global_base = options.global_base,
434 .initial_memory = options.initial_memory,
435 .max_memory = options.max_memory,
436
437 .entry_name = switch (options.entry) {
438 .disabled => null,
439 .default => if (output_mode != .Exe) null else defaultEntrySymbolName(wasi_exec_model),
440 .enabled => defaultEntrySymbolName(wasi_exec_model),
441 .named => |name| name,
442 },
443 };
444 if (use_llvm and comp.config.have_zcu) {
445 wasm.llvm_object = try LlvmObject.create(arena, comp);
371446 }
447 errdefer wasm.base.destroy();
372448
373 const wasm_bin = try createEmpty(allocator, options);
374 errdefer wasm_bin.base.destroy();
375
376 // We are not using LLD at this point, so ensure we set the intermediary basename
377 if (build_options.have_llvm and options.use_llvm and options.module != null) {
378 // TODO this intermediary_basename isn't enough; in the case of `zig build-exe`,
379 // we also want to put the intermediary object file in the cache while the
380 // main emit directory is the cwd.
381 wasm_bin.base.intermediary_basename = try std.fmt.allocPrint(allocator, "{s}{s}", .{
382 options.emit.?.sub_path, options.target.ofmt.fileExt(options.target.cpu.arch),
383 });
449 if (use_lld and (use_llvm or !comp.config.have_zcu)) {
450 // LLVM emits the object file (if any); LLD links it into the final product.
451 return wasm;
384452 }
385453
386 // TODO: read the file and keep valid parts instead of truncating
387 const file = try options.emit.?.directory.handle.createFile(sub_path, .{
454 // What path should this Wasm linker code output to?
455 // If using LLD to link, this code should produce an object file so that it
456 // can be passed to LLD.
457 const sub_path = if (use_lld) zcu_object_sub_path.? else emit.sub_path;
458
459 const file = try emit.directory.handle.createFile(sub_path, .{
388460 .truncate = true,
389461 .read = true,
390462 .mode = if (fs.has_executable_bit)
391 if (options.target.os.tag == .wasi and options.output_mode == .Exe)
463 if (target.os.tag == .wasi and output_mode == .Exe)
392464 fs.File.default_mode | 0b001_000_000
393465 else
394466 fs.File.default_mode
395467 else
396468 0,
397469 });
398 wasm_bin.base.file = file;
399 wasm_bin.name = sub_path;
470 wasm.base.file = file;
471 wasm.name = sub_path;
400472
401473 // create stack pointer symbol
402474 {
403 const loc = try wasm_bin.createSyntheticSymbol("__stack_pointer", .global);
404 const symbol = loc.getSymbol(wasm_bin);
475 const loc = try wasm.createSyntheticSymbol("__stack_pointer", .global);
476 const symbol = loc.getSymbol(wasm);
405477 // For object files we will import the stack pointer symbol
406 if (options.output_mode == .Obj) {
478 if (output_mode == .Obj) {
407479 symbol.setUndefined(true);
408 symbol.index = @as(u32, @intCast(wasm_bin.imported_globals_count));
409 wasm_bin.imported_globals_count += 1;
410 try wasm_bin.imports.putNoClobber(
411 allocator,
480 symbol.index = @intCast(wasm.imported_globals_count);
481 wasm.imported_globals_count += 1;
482 try wasm.imports.putNoClobber(
483 gpa,
412484 loc,
413485 .{
414 .module_name = try wasm_bin.string_table.put(allocator, wasm_bin.host_name),
486 .module_name = try wasm.string_table.put(gpa, wasm.host_name),
415487 .name = symbol.name,
416488 .kind = .{ .global = .{ .valtype = .i32, .mutable = true } },
417489 },
418490 );
419491 } else {
420 symbol.index = @intCast(wasm_bin.imported_globals_count + wasm_bin.wasm_globals.items.len);
492 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
421493 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
422 const global = try wasm_bin.wasm_globals.addOne(allocator);
494 const global = try wasm.wasm_globals.addOne(gpa);
423495 global.* = .{
424496 .global_type = .{
425497 .valtype = .i32,
......@@ -432,25 +504,25 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
432504
433505 // create indirect function pointer symbol
434506 {
435 const loc = try wasm_bin.createSyntheticSymbol("__indirect_function_table", .table);
436 const symbol = loc.getSymbol(wasm_bin);
507 const loc = try wasm.createSyntheticSymbol("__indirect_function_table", .table);
508 const symbol = loc.getSymbol(wasm);
437509 const table: std.wasm.Table = .{
438510 .limits = .{ .flags = 0, .min = 0, .max = undefined }, // will be overwritten during `mapFunctionTable`
439511 .reftype = .funcref,
440512 };
441 if (options.output_mode == .Obj or options.import_table) {
513 if (output_mode == .Obj or options.import_table) {
442514 symbol.setUndefined(true);
443 symbol.index = @intCast(wasm_bin.imported_tables_count);
444 wasm_bin.imported_tables_count += 1;
445 try wasm_bin.imports.put(allocator, loc, .{
446 .module_name = try wasm_bin.string_table.put(allocator, wasm_bin.host_name),
515 symbol.index = @intCast(wasm.imported_tables_count);
516 wasm.imported_tables_count += 1;
517 try wasm.imports.put(gpa, loc, .{
518 .module_name = try wasm.string_table.put(gpa, wasm.host_name),
447519 .name = symbol.name,
448520 .kind = .{ .table = table },
449521 });
450522 } else {
451 symbol.index = @as(u32, @intCast(wasm_bin.imported_tables_count + wasm_bin.tables.items.len));
452 try wasm_bin.tables.append(allocator, table);
453 if (options.export_table) {
523 symbol.index = @as(u32, @intCast(wasm.imported_tables_count + wasm.tables.items.len));
524 try wasm.tables.append(gpa, table);
525 if (wasm.export_table) {
454526 symbol.setFlag(.WASM_SYM_EXPORTED);
455527 } else {
456528 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
......@@ -460,8 +532,8 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
460532
461533 // create __wasm_call_ctors
462534 {
463 const loc = try wasm_bin.createSyntheticSymbol("__wasm_call_ctors", .function);
464 const symbol = loc.getSymbol(wasm_bin);
535 const loc = try wasm.createSyntheticSymbol("__wasm_call_ctors", .function);
536 const symbol = loc.getSymbol(wasm);
465537 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
466538 // we do not know the function index until after we merged all sections.
467539 // Therefore we set `symbol.index` and create its corresponding references
......@@ -469,90 +541,68 @@ pub fn openPath(allocator: Allocator, sub_path: []const u8, options: link.Option
469541 }
470542
471543 // shared-memory symbols for TLS support
472 if (wasm_bin.base.options.shared_memory) {
544 if (shared_memory) {
473545 {
474 const loc = try wasm_bin.createSyntheticSymbol("__tls_base", .global);
475 const symbol = loc.getSymbol(wasm_bin);
546 const loc = try wasm.createSyntheticSymbol("__tls_base", .global);
547 const symbol = loc.getSymbol(wasm);
476548 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
477 symbol.index = @intCast(wasm_bin.imported_globals_count + wasm_bin.wasm_globals.items.len);
478 try wasm_bin.wasm_globals.append(wasm_bin.base.allocator, .{
549 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
550 try wasm.wasm_globals.append(gpa, .{
479551 .global_type = .{ .valtype = .i32, .mutable = true },
480552 .init = .{ .i32_const = undefined },
481553 });
482554 }
483555 {
484 const loc = try wasm_bin.createSyntheticSymbol("__tls_size", .global);
485 const symbol = loc.getSymbol(wasm_bin);
556 const loc = try wasm.createSyntheticSymbol("__tls_size", .global);
557 const symbol = loc.getSymbol(wasm);
486558 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
487 symbol.index = @intCast(wasm_bin.imported_globals_count + wasm_bin.wasm_globals.items.len);
488 try wasm_bin.wasm_globals.append(wasm_bin.base.allocator, .{
559 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
560 try wasm.wasm_globals.append(gpa, .{
489561 .global_type = .{ .valtype = .i32, .mutable = false },
490562 .init = .{ .i32_const = undefined },
491563 });
492564 }
493565 {
494 const loc = try wasm_bin.createSyntheticSymbol("__tls_align", .global);
495 const symbol = loc.getSymbol(wasm_bin);
566 const loc = try wasm.createSyntheticSymbol("__tls_align", .global);
567 const symbol = loc.getSymbol(wasm);
496568 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
497 symbol.index = @intCast(wasm_bin.imported_globals_count + wasm_bin.wasm_globals.items.len);
498 try wasm_bin.wasm_globals.append(wasm_bin.base.allocator, .{
569 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
570 try wasm.wasm_globals.append(gpa, .{
499571 .global_type = .{ .valtype = .i32, .mutable = false },
500572 .init = .{ .i32_const = undefined },
501573 });
502574 }
503575 {
504 const loc = try wasm_bin.createSyntheticSymbol("__wasm_init_tls", .function);
505 const symbol = loc.getSymbol(wasm_bin);
576 const loc = try wasm.createSyntheticSymbol("__wasm_init_tls", .function);
577 const symbol = loc.getSymbol(wasm);
506578 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
507579 }
508580 }
509581
510 // if (!options.strip and options.module != null) {
511 // wasm_bin.dwarf = Dwarf.init(allocator, &wasm_bin.base, .dwarf32);
512 // try wasm_bin.initDebugSections();
513 // }
514
515 return wasm_bin;
516}
517
518pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm {
519 const wasm = try gpa.create(Wasm);
520 errdefer gpa.destroy(wasm);
521 wasm.* = .{
522 .base = .{
523 .tag = .wasm,
524 .options = options,
525 .file = null,
526 .allocator = gpa,
527 },
528 .name = undefined,
529 };
530
531 if (options.use_llvm) {
532 wasm.llvm_object = try LlvmObject.create(gpa, options);
533 }
534582 return wasm;
535583}
536584
537585/// For a given name, creates a new global synthetic symbol.
538586/// Leaves index undefined and the default flags (0).
539587fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !SymbolLoc {
540 const name_offset = try wasm.string_table.put(wasm.base.allocator, name);
588 const gpa = wasm.base.comp.gpa;
589 const name_offset = try wasm.string_table.put(gpa, name);
541590 return wasm.createSyntheticSymbolOffset(name_offset, tag);
542591}
543592
544593fn createSyntheticSymbolOffset(wasm: *Wasm, name_offset: u32, tag: Symbol.Tag) !SymbolLoc {
545594 const sym_index = @as(u32, @intCast(wasm.symbols.items.len));
546595 const loc: SymbolLoc = .{ .index = sym_index, .file = null };
547 try wasm.symbols.append(wasm.base.allocator, .{
596 const gpa = wasm.base.comp.gpa;
597 try wasm.symbols.append(gpa, .{
548598 .name = name_offset,
549599 .flags = 0,
550600 .tag = tag,
551601 .index = undefined,
552602 .virtual_address = undefined,
553603 });
554 try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, loc, {});
555 try wasm.globals.put(wasm.base.allocator, name_offset, loc);
604 try wasm.resolved_symbols.putNoClobber(gpa, loc, {});
605 try wasm.globals.put(gpa, name_offset, loc);
556606 return loc;
557607}
558608
......@@ -589,12 +639,13 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool {
589639 const file = try fs.cwd().openFile(path, .{});
590640 errdefer file.close();
591641
592 var object = Object.create(wasm.base.allocator, file, path, null) catch |err| switch (err) {
642 const gpa = wasm.base.comp.gpa;
643 var object = Object.create(gpa, file, path, null) catch |err| switch (err) {
593644 error.InvalidMagicByte, error.NotObjectFile => return false,
594645 else => |e| return e,
595646 };
596 errdefer object.deinit(wasm.base.allocator);
597 try wasm.objects.append(wasm.base.allocator, object);
647 errdefer object.deinit(gpa);
648 try wasm.objects.append(gpa, object);
598649 return true;
599650}
600651
......@@ -602,27 +653,29 @@ fn parseObjectFile(wasm: *Wasm, path: []const u8) !bool {
602653/// When the index was not found, a new `Atom` will be created, and its index will be returned.
603654/// The newly created Atom is empty with default fields as specified by `Atom.empty`.
604655pub fn getOrCreateAtomForDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) !Atom.Index {
605 const gop = try wasm.decls.getOrPut(wasm.base.allocator, decl_index);
656 const gpa = wasm.base.comp.gpa;
657 const gop = try wasm.decls.getOrPut(gpa, decl_index);
606658 if (!gop.found_existing) {
607659 const atom_index = try wasm.createAtom();
608660 gop.value_ptr.* = atom_index;
609661 const atom = wasm.getAtom(atom_index);
610662 const symbol = atom.symbolLoc().getSymbol(wasm);
611 const mod = wasm.base.options.module.?;
663 const mod = wasm.base.comp.module.?;
612664 const decl = mod.declPtr(decl_index);
613665 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
614 symbol.name = try wasm.string_table.put(wasm.base.allocator, full_name);
666 symbol.name = try wasm.string_table.put(gpa, full_name);
615667 }
616668 return gop.value_ptr.*;
617669}
618670
619671/// Creates a new empty `Atom` and returns its `Atom.Index`
620672fn createAtom(wasm: *Wasm) !Atom.Index {
621 const index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len));
622 const atom = try wasm.managed_atoms.addOne(wasm.base.allocator);
673 const gpa = wasm.base.comp.gpa;
674 const index: Atom.Index = @intCast(wasm.managed_atoms.items.len);
675 const atom = try wasm.managed_atoms.addOne(gpa);
623676 atom.* = Atom.empty;
624677 atom.sym_index = try wasm.allocateSymbol();
625 try wasm.symbol_atom.putNoClobber(wasm.base.allocator, .{ .file = null, .index = atom.sym_index }, index);
678 try wasm.symbol_atom.putNoClobber(gpa, .{ .file = null, .index = atom.sym_index }, index);
626679
627680 return index;
628681}
......@@ -644,6 +697,8 @@ pub inline fn getAtomPtr(wasm: *Wasm, index: Atom.Index) *Atom {
644697/// When false, it will only link with object files that contain symbols that
645698/// are referenced by other object files or Zig code.
646699fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool {
700 const gpa = wasm.base.comp.gpa;
701
647702 const file = try fs.cwd().openFile(path, .{});
648703 errdefer file.close();
649704
......@@ -651,25 +706,25 @@ fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool {
651706 .file = file,
652707 .name = path,
653708 };
654 archive.parse(wasm.base.allocator) catch |err| switch (err) {
709 archive.parse(gpa) catch |err| switch (err) {
655710 error.EndOfStream, error.NotArchive => {
656 archive.deinit(wasm.base.allocator);
711 archive.deinit(gpa);
657712 return false;
658713 },
659714 else => |e| return e,
660715 };
661716
662717 if (!force_load) {
663 errdefer archive.deinit(wasm.base.allocator);
664 try wasm.archives.append(wasm.base.allocator, archive);
718 errdefer archive.deinit(gpa);
719 try wasm.archives.append(gpa, archive);
665720 return true;
666721 }
667 defer archive.deinit(wasm.base.allocator);
722 defer archive.deinit(gpa);
668723
669724 // In this case we must force link all embedded object files within the archive
670725 // We loop over all symbols, and then group them by offset as the offset
671726 // notates where the object file starts.
672 var offsets = std.AutoArrayHashMap(u32, void).init(wasm.base.allocator);
727 var offsets = std.AutoArrayHashMap(u32, void).init(gpa);
673728 defer offsets.deinit();
674729 for (archive.toc.values()) |symbol_offsets| {
675730 for (symbol_offsets.items) |sym_offset| {
......@@ -678,8 +733,8 @@ fn parseArchive(wasm: *Wasm, path: []const u8, force_load: bool) !bool {
678733 }
679734
680735 for (offsets.keys()) |file_offset| {
681 const object = try wasm.objects.addOne(wasm.base.allocator);
682 object.* = try archive.parseObject(wasm.base.allocator, file_offset);
736 const object = try wasm.objects.addOne(gpa);
737 object.* = try archive.parseObject(gpa, file_offset);
683738 }
684739
685740 return true;
......@@ -695,6 +750,7 @@ fn requiresTLSReloc(wasm: *const Wasm) bool {
695750}
696751
697752fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
753 const gpa = wasm.base.comp.gpa;
698754 const object: Object = wasm.objects.items[object_index];
699755 log.debug("Resolving symbols in object: '{s}'", .{object.name});
700756
......@@ -708,7 +764,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
708764 if (mem.eql(u8, sym_name, "__indirect_function_table")) {
709765 continue;
710766 }
711 const sym_name_index = try wasm.string_table.put(wasm.base.allocator, sym_name);
767 const sym_name_index = try wasm.string_table.put(gpa, sym_name);
712768
713769 if (symbol.isLocal()) {
714770 if (symbol.isUndefined()) {
......@@ -716,17 +772,17 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
716772 log.err(" symbol '{s}' defined in '{s}'", .{ sym_name, object.name });
717773 return error.UndefinedLocal;
718774 }
719 try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, location, {});
775 try wasm.resolved_symbols.putNoClobber(gpa, location, {});
720776 continue;
721777 }
722778
723 const maybe_existing = try wasm.globals.getOrPut(wasm.base.allocator, sym_name_index);
779 const maybe_existing = try wasm.globals.getOrPut(gpa, sym_name_index);
724780 if (!maybe_existing.found_existing) {
725781 maybe_existing.value_ptr.* = location;
726 try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, location, {});
782 try wasm.resolved_symbols.putNoClobber(gpa, location, {});
727783
728784 if (symbol.isUndefined()) {
729 try wasm.undefs.putNoClobber(wasm.base.allocator, sym_name_index, location);
785 try wasm.undefs.putNoClobber(gpa, sym_name_index, location);
730786 }
731787 continue;
732788 }
......@@ -753,7 +809,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
753809 return error.SymbolCollision;
754810 }
755811
756 try wasm.discarded.put(wasm.base.allocator, location, existing_loc);
812 try wasm.discarded.put(gpa, location, existing_loc);
757813 continue; // Do not overwrite defined symbols with undefined symbols
758814 }
759815
......@@ -791,7 +847,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
791847 }
792848
793849 // both undefined so skip overwriting existing symbol and discard the new symbol
794 try wasm.discarded.put(wasm.base.allocator, location, existing_loc);
850 try wasm.discarded.put(gpa, location, existing_loc);
795851 continue;
796852 }
797853
......@@ -822,7 +878,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
822878 // symbol is weak and the new one isn't, in which case we *do* overwrite it.
823879 if (existing_sym.isWeak() and symbol.isWeak()) blk: {
824880 if (existing_sym.isUndefined() and !symbol.isUndefined()) break :blk;
825 try wasm.discarded.put(wasm.base.allocator, location, existing_loc);
881 try wasm.discarded.put(gpa, location, existing_loc);
826882 continue;
827883 }
828884
......@@ -830,10 +886,10 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
830886 log.debug("Overwriting symbol '{s}'", .{sym_name});
831887 log.debug(" old definition in '{s}'", .{existing_file_path});
832888 log.debug(" new definition in '{s}'", .{object.name});
833 try wasm.discarded.putNoClobber(wasm.base.allocator, existing_loc, location);
889 try wasm.discarded.putNoClobber(gpa, existing_loc, location);
834890 maybe_existing.value_ptr.* = location;
835 try wasm.globals.put(wasm.base.allocator, sym_name_index, location);
836 try wasm.resolved_symbols.put(wasm.base.allocator, location, {});
891 try wasm.globals.put(gpa, sym_name_index, location);
892 try wasm.resolved_symbols.put(gpa, location, {});
837893 assert(wasm.resolved_symbols.swapRemove(existing_loc));
838894 if (existing_sym.isUndefined()) {
839895 _ = wasm.undefs.swapRemove(sym_name_index);
......@@ -842,6 +898,7 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
842898}
843899
844900fn resolveSymbolsInArchives(wasm: *Wasm) !void {
901 const gpa = wasm.base.comp.gpa;
845902 if (wasm.archives.items.len == 0) return;
846903
847904 log.debug("Resolving symbols in archives", .{});
......@@ -860,9 +917,9 @@ fn resolveSymbolsInArchives(wasm: *Wasm) !void {
860917 // Symbol is found in unparsed object file within current archive.
861918 // Parse object and and resolve symbols again before we check remaining
862919 // undefined symbols.
863 const object_file_index = @as(u16, @intCast(wasm.objects.items.len));
864 const object = try archive.parseObject(wasm.base.allocator, offset.items[0]);
865 try wasm.objects.append(wasm.base.allocator, object);
920 const object_file_index: u16 = @intCast(wasm.objects.items.len);
921 const object = try archive.parseObject(gpa, offset.items[0]);
922 try wasm.objects.append(gpa, object);
866923 try wasm.resolveSymbolsInObject(object_file_index);
867924
868925 // continue loop for any remaining undefined symbols that still exist
......@@ -880,6 +937,11 @@ fn writeI32Const(writer: anytype, val: u32) !void {
880937}
881938
882939fn setupInitMemoryFunction(wasm: *Wasm) !void {
940 const comp = wasm.base.comp;
941 const gpa = comp.gpa;
942 const shared_memory = comp.config.shared_memory;
943 const import_memory = comp.config.import_memory;
944
883945 // Passive segments are used to avoid memory being reinitialized on each
884946 // thread's instantiation. These passive segments are initialized and
885947 // dropped in __wasm_init_memory, which is registered as the start function
......@@ -889,21 +951,21 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {
889951 return;
890952 }
891953
892 const flag_address: u32 = if (wasm.base.options.shared_memory) address: {
954 const flag_address: u32 = if (shared_memory) address: {
893955 // when we have passive initialization segments and shared memory
894956 // `setupMemory` will create this symbol and set its virtual address.
895957 const loc = wasm.findGlobalSymbol("__wasm_init_memory_flag").?;
896958 break :address loc.getSymbol(wasm).virtual_address;
897959 } else 0;
898960
899 var function_body = std.ArrayList(u8).init(wasm.base.allocator);
961 var function_body = std.ArrayList(u8).init(gpa);
900962 defer function_body.deinit();
901963 const writer = function_body.writer();
902964
903965 // we have 0 locals
904966 try leb.writeULEB128(writer, @as(u32, 0));
905967
906 if (wasm.base.options.shared_memory) {
968 if (shared_memory) {
907969 // destination blocks
908970 // based on values we jump to corresponding label
909971 try writer.writeByte(std.wasm.opcode(.block)); // $drop
......@@ -937,14 +999,14 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {
937999 var segment_index: u32 = 0;
9381000 while (it.next()) |entry| : (segment_index += 1) {
9391001 const segment: Segment = wasm.segments.items[entry.value_ptr.*];
940 if (segment.needsPassiveInitialization(wasm.base.options.import_memory, entry.key_ptr.*)) {
1002 if (segment.needsPassiveInitialization(import_memory, entry.key_ptr.*)) {
9411003 // For passive BSS segments we can simple issue a memory.fill(0).
9421004 // For non-BSS segments we do a memory.init. Both these
9431005 // instructions take as their first argument the destination
9441006 // address.
9451007 try writeI32Const(writer, segment.offset);
9461008
947 if (wasm.base.options.shared_memory and std.mem.eql(u8, entry.key_ptr.*, ".tdata")) {
1009 if (shared_memory and std.mem.eql(u8, entry.key_ptr.*, ".tdata")) {
9481010 // When we initialize the TLS segment we also set the `__tls_base`
9491011 // global. This allows the runtime to use this static copy of the
9501012 // TLS data for the first/main thread.
......@@ -969,7 +1031,7 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {
9691031 }
9701032 }
9711033
972 if (wasm.base.options.shared_memory) {
1034 if (shared_memory) {
9731035 // we set the init memory flag to value '2'
9741036 try writeI32Const(writer, flag_address);
9751037 try writeI32Const(writer, 2);
......@@ -1012,12 +1074,12 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {
10121074 while (it.next()) |entry| : (segment_index += 1) {
10131075 const name = entry.key_ptr.*;
10141076 const segment: Segment = wasm.segments.items[entry.value_ptr.*];
1015 if (segment.needsPassiveInitialization(wasm.base.options.import_memory, name) and
1077 if (segment.needsPassiveInitialization(import_memory, name) and
10161078 !std.mem.eql(u8, name, ".bss"))
10171079 {
10181080 // The TLS region should not be dropped since its is needed
10191081 // during the initialization of each thread (__wasm_init_tls).
1020 if (wasm.base.options.shared_memory and std.mem.eql(u8, name, ".tdata")) {
1082 if (shared_memory and std.mem.eql(u8, name, ".tdata")) {
10211083 continue;
10221084 }
10231085
......@@ -1040,14 +1102,18 @@ fn setupInitMemoryFunction(wasm: *Wasm) !void {
10401102/// Constructs a synthetic function that performs runtime relocations for
10411103/// TLS symbols. This function is called by `__wasm_init_tls`.
10421104fn setupTLSRelocationsFunction(wasm: *Wasm) !void {
1105 const comp = wasm.base.comp;
1106 const gpa = comp.gpa;
1107 const shared_memory = comp.config.shared_memory;
1108
10431109 // When we have TLS GOT entries and shared memory is enabled,
10441110 // we must perform runtime relocations or else we don't create the function.
1045 if (!wasm.base.options.shared_memory or !wasm.requiresTLSReloc()) {
1111 if (!shared_memory or !wasm.requiresTLSReloc()) {
10461112 return;
10471113 }
10481114
10491115 // const loc = try wasm.createSyntheticSymbol("__wasm_apply_global_tls_relocs");
1050 var function_body = std.ArrayList(u8).init(wasm.base.allocator);
1116 var function_body = std.ArrayList(u8).init(gpa);
10511117 defer function_body.deinit();
10521118 const writer = function_body.writer();
10531119
......@@ -1086,7 +1152,10 @@ fn validateFeatures(
10861152 to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool,
10871153 emit_features_count: *u32,
10881154) !void {
1089 const cpu_features = wasm.base.options.target.cpu.features;
1155 const comp = wasm.base.comp;
1156 const target = comp.root_mod.resolved_target.result;
1157 const shared_memory = comp.config.shared_memory;
1158 const cpu_features = target.cpu.features;
10901159 const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects.
10911160 const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len;
10921161
......@@ -1156,7 +1225,7 @@ fn validateFeatures(
11561225 return error.InvalidFeatureSet;
11571226 }
11581227
1159 if (wasm.base.options.shared_memory) {
1228 if (shared_memory) {
11601229 const disallowed_feature = disallowed[@intFromEnum(types.Feature.Tag.shared_mem)];
11611230 if (@as(u1, @truncate(disallowed_feature)) != 0) {
11621231 log.err(
......@@ -1221,10 +1290,14 @@ fn validateFeatures(
12211290/// if one or multiple undefined references exist. When none exist, the symbol will
12221291/// not be created, ensuring we don't unneccesarily emit unreferenced symbols.
12231292fn resolveLazySymbols(wasm: *Wasm) !void {
1293 const comp = wasm.base.comp;
1294 const gpa = comp.gpa;
1295 const shared_memory = comp.config.shared_memory;
1296
12241297 if (wasm.string_table.getOffset("__heap_base")) |name_offset| {
12251298 if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| {
12261299 const loc = try wasm.createSyntheticSymbolOffset(name_offset, .data);
1227 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
1300 try wasm.discarded.putNoClobber(gpa, kv.value, loc);
12281301 _ = wasm.resolved_symbols.swapRemove(loc); // we don't want to emit this symbol, only use it for relocations.
12291302 }
12301303 }
......@@ -1232,21 +1305,21 @@ fn resolveLazySymbols(wasm: *Wasm) !void {
12321305 if (wasm.string_table.getOffset("__heap_end")) |name_offset| {
12331306 if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| {
12341307 const loc = try wasm.createSyntheticSymbolOffset(name_offset, .data);
1235 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
1308 try wasm.discarded.putNoClobber(gpa, kv.value, loc);
12361309 _ = wasm.resolved_symbols.swapRemove(loc);
12371310 }
12381311 }
12391312
1240 if (!wasm.base.options.shared_memory) {
1313 if (!shared_memory) {
12411314 if (wasm.string_table.getOffset("__tls_base")) |name_offset| {
12421315 if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| {
12431316 const loc = try wasm.createSyntheticSymbolOffset(name_offset, .global);
1244 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
1317 try wasm.discarded.putNoClobber(gpa, kv.value, loc);
12451318 _ = wasm.resolved_symbols.swapRemove(kv.value);
12461319 const symbol = loc.getSymbol(wasm);
12471320 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
12481321 symbol.index = @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len);
1249 try wasm.wasm_globals.append(wasm.base.allocator, .{
1322 try wasm.wasm_globals.append(gpa, .{
12501323 .global_type = .{ .valtype = .i32, .mutable = true },
12511324 .init = .{ .i32_const = undefined },
12521325 });
......@@ -1256,7 +1329,7 @@ fn resolveLazySymbols(wasm: *Wasm) !void {
12561329 if (wasm.string_table.getOffset("__zig_errors_len")) |name_offset| {
12571330 if (wasm.undefs.fetchSwapRemove(name_offset)) |kv| {
12581331 const loc = try wasm.createSyntheticSymbolOffset(name_offset, .data);
1259 try wasm.discarded.putNoClobber(wasm.base.allocator, kv.value, loc);
1332 try wasm.discarded.putNoClobber(gpa, kv.value, loc);
12601333 _ = wasm.resolved_symbols.swapRemove(kv.value);
12611334 }
12621335 }
......@@ -1270,8 +1343,9 @@ pub fn findGlobalSymbol(wasm: *Wasm, name: []const u8) ?SymbolLoc {
12701343}
12711344
12721345fn checkUndefinedSymbols(wasm: *const Wasm) !void {
1273 if (wasm.base.options.output_mode == .Obj) return;
1274 if (wasm.base.options.import_symbols) return;
1346 const comp = wasm.base.comp;
1347 if (comp.config.output_mode == .Obj) return;
1348 if (wasm.import_symbols) return;
12751349
12761350 var found_undefined_symbols = false;
12771351 for (wasm.undefs.values()) |undef| {
......@@ -1292,8 +1366,8 @@ fn checkUndefinedSymbols(wasm: *const Wasm) !void {
12921366}
12931367
12941368pub fn deinit(wasm: *Wasm) void {
1295 const gpa = wasm.base.allocator;
1296 if (wasm.llvm_object) |llvm_object| llvm_object.destroy(gpa);
1369 const gpa = wasm.base.comp.gpa;
1370 if (wasm.llvm_object) |llvm_object| llvm_object.deinit();
12971371
12981372 for (wasm.func_types.items) |*func_type| {
12991373 func_type.deinit(gpa);
......@@ -1378,7 +1452,9 @@ pub fn deinit(wasm: *Wasm) void {
13781452/// Allocates a new symbol and returns its index.
13791453/// Will re-use slots when a symbol was freed at an earlier stage.
13801454pub fn allocateSymbol(wasm: *Wasm) !u32 {
1381 try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1);
1455 const gpa = wasm.base.comp.gpa;
1456
1457 try wasm.symbols.ensureUnusedCapacity(gpa, 1);
13821458 const symbol: Symbol = .{
13831459 .name = std.math.maxInt(u32), // will be set after updateDecl as well as during atom creation for decls
13841460 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
......@@ -1404,6 +1480,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air:
14041480 const tracy = trace(@src());
14051481 defer tracy.end();
14061482
1483 const gpa = wasm.base.comp.gpa;
14071484 const func = mod.funcInfo(func_index);
14081485 const decl_index = func.owner_decl;
14091486 const decl = mod.declPtr(decl_index);
......@@ -1414,7 +1491,7 @@ pub fn updateFunc(wasm: *Wasm, mod: *Module, func_index: InternPool.Index, air:
14141491 // var decl_state: ?Dwarf.DeclState = if (wasm.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl_index) else null;
14151492 // defer if (decl_state) |*ds| ds.deinit();
14161493
1417 var code_writer = std.ArrayList(u8).init(wasm.base.allocator);
1494 var code_writer = std.ArrayList(u8).init(gpa);
14181495 defer code_writer.deinit();
14191496 // const result = try codegen.generateFunction(
14201497 // &wasm.base,
......@@ -1477,6 +1554,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !
14771554 return;
14781555 }
14791556
1557 const gpa = wasm.base.comp.gpa;
14801558 const atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
14811559 const atom = wasm.getAtomPtr(atom_index);
14821560 atom.clear();
......@@ -1489,7 +1567,7 @@ pub fn updateDecl(wasm: *Wasm, mod: *Module, decl_index: InternPool.DeclIndex) !
14891567 }
14901568 const val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
14911569
1492 var code_writer = std.ArrayList(u8).init(wasm.base.allocator);
1570 var code_writer = std.ArrayList(u8).init(gpa);
14931571 defer code_writer.deinit();
14941572
14951573 const res = try codegen.generateSymbol(
......@@ -1528,16 +1606,17 @@ pub fn updateDeclLineNumber(wasm: *Wasm, mod: *Module, decl_index: InternPool.De
15281606}
15291607
15301608fn finishUpdateDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex, code: []const u8, symbol_tag: Symbol.Tag) !void {
1531 const mod = wasm.base.options.module.?;
1609 const gpa = wasm.base.comp.gpa;
1610 const mod = wasm.base.comp.module.?;
15321611 const decl = mod.declPtr(decl_index);
15331612 const atom_index = wasm.decls.get(decl_index).?;
15341613 const atom = wasm.getAtomPtr(atom_index);
15351614 const symbol = &wasm.symbols.items[atom.sym_index];
15361615 const full_name = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1537 symbol.name = try wasm.string_table.put(wasm.base.allocator, full_name);
1616 symbol.name = try wasm.string_table.put(gpa, full_name);
15381617 symbol.tag = symbol_tag;
1539 try atom.code.appendSlice(wasm.base.allocator, code);
1540 try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});
1618 try atom.code.appendSlice(gpa, code);
1619 try wasm.resolved_symbols.put(gpa, atom.symbolLoc(), {});
15411620
15421621 atom.size = @intCast(code.len);
15431622 if (code.len == 0) return;
......@@ -1591,7 +1670,8 @@ fn getFunctionSignature(wasm: *const Wasm, loc: SymbolLoc) std.wasm.Type {
15911670/// Returns the symbol index of the local
15921671/// The given `decl` is the parent decl whom owns the constant.
15931672pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.DeclIndex) !u32 {
1594 const mod = wasm.base.options.module.?;
1673 const gpa = wasm.base.comp.gpa;
1674 const mod = wasm.base.comp.module.?;
15951675 assert(tv.ty.zigTypeTag(mod) != .Fn); // cannot create local symbols for functions
15961676 const decl = mod.declPtr(decl_index);
15971677
......@@ -1599,14 +1679,14 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: InternPool.Dec
15991679 const parent_atom = wasm.getAtom(parent_atom_index);
16001680 const local_index = parent_atom.locals.items.len;
16011681 const fqn = mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod));
1602 const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__unnamed_{s}_{d}", .{
1682 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{s}_{d}", .{
16031683 fqn, local_index,
16041684 });
1605 defer wasm.base.allocator.free(name);
1685 defer gpa.free(name);
16061686
16071687 switch (try wasm.lowerConst(name, tv, decl.srcLoc(mod))) {
16081688 .ok => |atom_index| {
1609 try wasm.getAtomPtr(parent_atom_index).locals.append(wasm.base.allocator, atom_index);
1689 try wasm.getAtomPtr(parent_atom_index).locals.append(gpa, atom_index);
16101690 return wasm.getAtom(atom_index).getSymbolIndex().?;
16111691 },
16121692 .fail => |em| {
......@@ -1623,24 +1703,25 @@ const LowerConstResult = union(enum) {
16231703};
16241704
16251705fn lowerConst(wasm: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.SrcLoc) !LowerConstResult {
1626 const mod = wasm.base.options.module.?;
1706 const gpa = wasm.base.comp.gpa;
1707 const mod = wasm.base.comp.module.?;
16271708
16281709 // Create and initialize a new local symbol and atom
16291710 const atom_index = try wasm.createAtom();
1630 var value_bytes = std.ArrayList(u8).init(wasm.base.allocator);
1711 var value_bytes = std.ArrayList(u8).init(gpa);
16311712 defer value_bytes.deinit();
16321713
16331714 const code = code: {
16341715 const atom = wasm.getAtomPtr(atom_index);
16351716 atom.alignment = tv.ty.abiAlignment(mod);
16361717 wasm.symbols.items[atom.sym_index] = .{
1637 .name = try wasm.string_table.put(wasm.base.allocator, name),
1718 .name = try wasm.string_table.put(gpa, name),
16381719 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
16391720 .tag = .data,
16401721 .index = undefined,
16411722 .virtual_address = undefined,
16421723 };
1643 try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, atom.symbolLoc(), {});
1724 try wasm.resolved_symbols.putNoClobber(gpa, atom.symbolLoc(), {});
16441725
16451726 const result = try codegen.generateSymbol(
16461727 &wasm.base,
......@@ -1663,7 +1744,7 @@ fn lowerConst(wasm: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.Src
16631744
16641745 const atom = wasm.getAtomPtr(atom_index);
16651746 atom.size = @intCast(code.len);
1666 try atom.code.appendSlice(wasm.base.allocator, code);
1747 try atom.code.appendSlice(gpa, code);
16671748 return .{ .ok = atom_index };
16681749}
16691750
......@@ -1673,8 +1754,9 @@ fn lowerConst(wasm: *Wasm, name: []const u8, tv: TypedValue, src_loc: Module.Src
16731754/// and then returns the index to it.
16741755pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u32 {
16751756 _ = lib_name;
1676 const name_index = try wasm.string_table.put(wasm.base.allocator, name);
1677 const gop = try wasm.globals.getOrPut(wasm.base.allocator, name_index);
1757 const gpa = wasm.base.comp.gpa;
1758 const name_index = try wasm.string_table.put(gpa, name);
1759 const gop = try wasm.globals.getOrPut(gpa, name_index);
16781760 if (gop.found_existing) {
16791761 return gop.value_ptr.*.index;
16801762 }
......@@ -1691,14 +1773,14 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8, lib_name: ?[]const u8) !u3
16911773
16921774 const sym_index = if (wasm.symbols_free_list.popOrNull()) |index| index else blk: {
16931775 const index: u32 = @intCast(wasm.symbols.items.len);
1694 try wasm.symbols.ensureUnusedCapacity(wasm.base.allocator, 1);
1776 try wasm.symbols.ensureUnusedCapacity(gpa, 1);
16951777 wasm.symbols.items.len += 1;
16961778 break :blk index;
16971779 };
16981780 wasm.symbols.items[sym_index] = symbol;
16991781 gop.value_ptr.* = .{ .index = sym_index, .file = null };
1700 try wasm.resolved_symbols.put(wasm.base.allocator, gop.value_ptr.*, {});
1701 try wasm.undefs.putNoClobber(wasm.base.allocator, name_index, gop.value_ptr.*);
1782 try wasm.resolved_symbols.put(gpa, gop.value_ptr.*, {});
1783 try wasm.undefs.putNoClobber(gpa, name_index, gop.value_ptr.*);
17021784 return sym_index;
17031785}
17041786
......@@ -1709,7 +1791,9 @@ pub fn getDeclVAddr(
17091791 decl_index: InternPool.DeclIndex,
17101792 reloc_info: link.File.RelocInfo,
17111793) !u64 {
1712 const mod = wasm.base.options.module.?;
1794 const target = wasm.base.comp.root_mod.resolved_target.result;
1795 const gpa = wasm.base.comp.gpa;
1796 const mod = wasm.base.comp.module.?;
17131797 const decl = mod.declPtr(decl_index);
17141798
17151799 const target_atom_index = try wasm.getOrCreateAtomForDecl(decl_index);
......@@ -1718,24 +1802,24 @@ pub fn getDeclVAddr(
17181802 assert(reloc_info.parent_atom_index != 0);
17191803 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
17201804 const atom = wasm.getAtomPtr(atom_index);
1721 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
1805 const is_wasm32 = target.cpu.arch == .wasm32;
17221806 if (decl.ty.zigTypeTag(mod) == .Fn) {
17231807 assert(reloc_info.addend == 0); // addend not allowed for function relocations
17241808 // We found a function pointer, so add it to our table,
17251809 // as function pointers are not allowed to be stored inside the data section.
17261810 // They are instead stored in a function table which are called by index.
17271811 try wasm.addTableFunction(target_symbol_index);
1728 try atom.relocs.append(wasm.base.allocator, .{
1812 try atom.relocs.append(gpa, .{
17291813 .index = target_symbol_index,
1730 .offset = @as(u32, @intCast(reloc_info.offset)),
1814 .offset = @intCast(reloc_info.offset),
17311815 .relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64,
17321816 });
17331817 } else {
1734 try atom.relocs.append(wasm.base.allocator, .{
1818 try atom.relocs.append(gpa, .{
17351819 .index = target_symbol_index,
1736 .offset = @as(u32, @intCast(reloc_info.offset)),
1820 .offset = @intCast(reloc_info.offset),
17371821 .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_I32 else .R_WASM_MEMORY_ADDR_I64,
1738 .addend = @as(i32, @intCast(reloc_info.addend)),
1822 .addend = @intCast(reloc_info.addend),
17391823 });
17401824 }
17411825 // we do not know the final address at this point,
......@@ -1751,9 +1835,10 @@ pub fn lowerAnonDecl(
17511835 explicit_alignment: Alignment,
17521836 src_loc: Module.SrcLoc,
17531837) !codegen.Result {
1754 const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
1838 const gpa = wasm.base.comp.gpa;
1839 const gop = try wasm.anon_decls.getOrPut(gpa, decl_val);
17551840 if (!gop.found_existing) {
1756 const mod = wasm.base.options.module.?;
1841 const mod = wasm.base.comp.module.?;
17571842 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
17581843 const tv: TypedValue = .{ .ty = ty, .val = Value.fromInterned(decl_val) };
17591844 var name_buf: [32]u8 = undefined;
......@@ -1779,13 +1864,15 @@ pub fn lowerAnonDecl(
17791864}
17801865
17811866pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
1867 const gpa = wasm.base.comp.gpa;
1868 const target = wasm.base.comp.root_mod.resolved_target.result;
17821869 const atom_index = wasm.anon_decls.get(decl_val).?;
17831870 const target_symbol_index = wasm.getAtom(atom_index).getSymbolIndex().?;
17841871
17851872 const parent_atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
17861873 const parent_atom = wasm.getAtomPtr(parent_atom_index);
1787 const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
1788 const mod = wasm.base.options.module.?;
1874 const is_wasm32 = target.cpu.arch == .wasm32;
1875 const mod = wasm.base.comp.module.?;
17891876 const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
17901877 if (ty.zigTypeTag(mod) == .Fn) {
17911878 assert(reloc_info.addend == 0); // addend not allowed for function relocations
......@@ -1793,17 +1880,17 @@ pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: lin
17931880 // as function pointers are not allowed to be stored inside the data section.
17941881 // They are instead stored in a function table which are called by index.
17951882 try wasm.addTableFunction(target_symbol_index);
1796 try parent_atom.relocs.append(wasm.base.allocator, .{
1883 try parent_atom.relocs.append(gpa, .{
17971884 .index = target_symbol_index,
1798 .offset = @as(u32, @intCast(reloc_info.offset)),
1885 .offset = @intCast(reloc_info.offset),
17991886 .relocation_type = if (is_wasm32) .R_WASM_TABLE_INDEX_I32 else .R_WASM_TABLE_INDEX_I64,
18001887 });
18011888 } else {
1802 try parent_atom.relocs.append(wasm.base.allocator, .{
1889 try parent_atom.relocs.append(gpa, .{
18031890 .index = target_symbol_index,
1804 .offset = @as(u32, @intCast(reloc_info.offset)),
1891 .offset = @intCast(reloc_info.offset),
18051892 .relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_I32 else .R_WASM_MEMORY_ADDR_I64,
1806 .addend = @as(i32, @intCast(reloc_info.addend)),
1893 .addend = @intCast(reloc_info.addend),
18071894 });
18081895 }
18091896
......@@ -1814,7 +1901,12 @@ pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: lin
18141901 return target_symbol_index;
18151902}
18161903
1817pub fn deleteDeclExport(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
1904pub fn deleteDeclExport(
1905 wasm: *Wasm,
1906 decl_index: InternPool.DeclIndex,
1907 name: InternPool.NullTerminatedString,
1908) void {
1909 _ = name;
18181910 if (wasm.llvm_object) |_| return;
18191911 const atom_index = wasm.decls.get(decl_index) orelse return;
18201912 const sym_index = wasm.getAtom(atom_index).sym_index;
......@@ -1840,8 +1932,6 @@ pub fn updateExports(
18401932 }
18411933 if (wasm.llvm_object) |llvm_object| return llvm_object.updateExports(mod, exported, exports);
18421934
1843 if (wasm.base.options.emit == null) return;
1844
18451935 const decl_index = switch (exported) {
18461936 .decl_index => |i| i,
18471937 .value => |val| {
......@@ -1880,7 +1970,7 @@ pub fn updateExports(
18801970 };
18811971 const exported_atom_index = try wasm.getOrCreateAtomForDecl(exported_decl_index);
18821972 const exported_atom = wasm.getAtom(exported_atom_index);
1883 const export_name = try wasm.string_table.put(wasm.base.allocator, mod.intern_pool.stringToSlice(exp.opts.name));
1973 const export_name = try wasm.string_table.put(gpa, mod.intern_pool.stringToSlice(exp.opts.name));
18841974 const sym_loc = exported_atom.symbolLoc();
18851975 const symbol = sym_loc.getSymbol(wasm);
18861976 symbol.setGlobal(true);
......@@ -1915,7 +2005,7 @@ pub fn updateExports(
19152005
19162006 if (!existing_sym.isUndefined()) blk: {
19172007 if (symbol.isWeak()) {
1918 try wasm.discarded.put(wasm.base.allocator, existing_loc, sym_loc);
2008 try wasm.discarded.put(gpa, existing_loc, sym_loc);
19192009 continue; // to-be-exported symbol is weak, so we keep the existing symbol
19202010 }
19212011
......@@ -1939,18 +2029,18 @@ pub fn updateExports(
19392029 }
19402030
19412031 // in this case the existing symbol must be replaced either because it's weak or undefined.
1942 try wasm.discarded.put(wasm.base.allocator, existing_loc, sym_loc);
2032 try wasm.discarded.put(gpa, existing_loc, sym_loc);
19432033 _ = wasm.imports.remove(existing_loc);
19442034 _ = wasm.undefs.swapRemove(existing_sym.name);
19452035 }
19462036
19472037 // Ensure the symbol will be exported using the given name
19482038 if (!mod.intern_pool.stringEqlSlice(exp.opts.name, sym_loc.getName(wasm))) {
1949 try wasm.export_names.put(wasm.base.allocator, sym_loc, export_name);
2039 try wasm.export_names.put(gpa, sym_loc, export_name);
19502040 }
19512041
19522042 try wasm.globals.put(
1953 wasm.base.allocator,
2043 gpa,
19542044 export_name,
19552045 sym_loc,
19562046 );
......@@ -1959,18 +2049,19 @@ pub fn updateExports(
19592049
19602050pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
19612051 if (wasm.llvm_object) |llvm_object| return llvm_object.freeDecl(decl_index);
1962 const mod = wasm.base.options.module.?;
2052 const gpa = wasm.base.comp.gpa;
2053 const mod = wasm.base.comp.module.?;
19632054 const decl = mod.declPtr(decl_index);
19642055 const atom_index = wasm.decls.get(decl_index).?;
19652056 const atom = wasm.getAtomPtr(atom_index);
1966 wasm.symbols_free_list.append(wasm.base.allocator, atom.sym_index) catch {};
2057 wasm.symbols_free_list.append(gpa, atom.sym_index) catch {};
19672058 _ = wasm.decls.remove(decl_index);
19682059 wasm.symbols.items[atom.sym_index].tag = .dead;
19692060 for (atom.locals.items) |local_atom_index| {
19702061 const local_atom = wasm.getAtom(local_atom_index);
19712062 const local_symbol = &wasm.symbols.items[local_atom.sym_index];
19722063 local_symbol.tag = .dead; // also for any local symbol
1973 wasm.symbols_free_list.append(wasm.base.allocator, local_atom.sym_index) catch {};
2064 wasm.symbols_free_list.append(gpa, local_atom.sym_index) catch {};
19742065 assert(wasm.resolved_symbols.swapRemove(local_atom.symbolLoc()));
19752066 assert(wasm.symbol_atom.remove(local_atom.symbolLoc()));
19762067 }
......@@ -1999,8 +2090,9 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void {
19992090
20002091/// Appends a new entry to the indirect function table
20012092pub fn addTableFunction(wasm: *Wasm, symbol_index: u32) !void {
2002 const index = @as(u32, @intCast(wasm.function_table.count()));
2003 try wasm.function_table.put(wasm.base.allocator, .{ .file = null, .index = symbol_index }, index);
2093 const gpa = wasm.base.comp.gpa;
2094 const index: u32 = @intCast(wasm.function_table.count());
2095 try wasm.function_table.put(gpa, .{ .file = null, .index = symbol_index }, index);
20042096}
20052097
20062098/// Assigns indexes to all indirect functions.
......@@ -2019,7 +2111,7 @@ fn mapFunctionTable(wasm: *Wasm) void {
20192111 }
20202112 }
20212113
2022 if (wasm.base.options.import_table or wasm.base.options.output_mode == .Obj) {
2114 if (wasm.import_table or wasm.base.comp.config.output_mode == .Obj) {
20232115 const sym_loc = wasm.findGlobalSymbol("__indirect_function_table").?;
20242116 const import = wasm.imports.getPtr(sym_loc).?;
20252117 import.kind.table.limits.min = index - 1; // we start at index 1.
......@@ -2048,6 +2140,7 @@ pub fn addOrUpdateImport(
20482140 /// is asserted instead.
20492141 type_index: ?u32,
20502142) !void {
2143 const gpa = wasm.base.comp.gpa;
20512144 assert(symbol_index != 0);
20522145 // For the import name, we use the decl's name, rather than the fully qualified name
20532146 // Also mangle the name when the lib name is set and not equal to "C" so imports with the same
......@@ -2055,11 +2148,11 @@ pub fn addOrUpdateImport(
20552148 const mangle_name = lib_name != null and
20562149 !std.mem.eql(u8, lib_name.?, "c");
20572150 const full_name = if (mangle_name) full_name: {
2058 break :full_name try std.fmt.allocPrint(wasm.base.allocator, "{s}|{s}", .{ name, lib_name.? });
2151 break :full_name try std.fmt.allocPrint(gpa, "{s}|{s}", .{ name, lib_name.? });
20592152 } else name;
2060 defer if (mangle_name) wasm.base.allocator.free(full_name);
2153 defer if (mangle_name) gpa.free(full_name);
20612154
2062 const decl_name_index = try wasm.string_table.put(wasm.base.allocator, full_name);
2155 const decl_name_index = try wasm.string_table.put(gpa, full_name);
20632156 const symbol: *Symbol = &wasm.symbols.items[symbol_index];
20642157 symbol.setUndefined(true);
20652158 symbol.setGlobal(true);
......@@ -2068,12 +2161,12 @@ pub fn addOrUpdateImport(
20682161 // we specified a specific name for the symbol that does not match the import name
20692162 symbol.setFlag(.WASM_SYM_EXPLICIT_NAME);
20702163 }
2071 const global_gop = try wasm.globals.getOrPut(wasm.base.allocator, decl_name_index);
2164 const global_gop = try wasm.globals.getOrPut(gpa, decl_name_index);
20722165 if (!global_gop.found_existing) {
20732166 const loc: SymbolLoc = .{ .file = null, .index = symbol_index };
20742167 global_gop.value_ptr.* = loc;
2075 try wasm.resolved_symbols.put(wasm.base.allocator, loc, {});
2076 try wasm.undefs.putNoClobber(wasm.base.allocator, decl_name_index, loc);
2168 try wasm.resolved_symbols.put(gpa, loc, {});
2169 try wasm.undefs.putNoClobber(gpa, decl_name_index, loc);
20772170 } else if (global_gop.value_ptr.*.index != symbol_index) {
20782171 // We are not updating a symbol, but found an existing global
20792172 // symbol with the same name. This means we always favor the
......@@ -2081,21 +2174,21 @@ pub fn addOrUpdateImport(
20812174 // We can also skip storing the import as we will not output
20822175 // this symbol.
20832176 return wasm.discarded.put(
2084 wasm.base.allocator,
2177 gpa,
20852178 .{ .file = null, .index = symbol_index },
20862179 global_gop.value_ptr.*,
20872180 );
20882181 }
20892182
20902183 if (type_index) |ty_index| {
2091 const gop = try wasm.imports.getOrPut(wasm.base.allocator, .{ .index = symbol_index, .file = null });
2184 const gop = try wasm.imports.getOrPut(gpa, .{ .index = symbol_index, .file = null });
20922185 const module_name = if (lib_name) |l_name| blk: {
20932186 break :blk l_name;
20942187 } else wasm.host_name;
20952188 if (!gop.found_existing) {
20962189 gop.value_ptr.* = .{
2097 .module_name = try wasm.string_table.put(wasm.base.allocator, module_name),
2098 .name = try wasm.string_table.put(wasm.base.allocator, name),
2190 .module_name = try wasm.string_table.put(gpa, module_name),
2191 .name = try wasm.string_table.put(gpa, name),
20992192 .kind = .{ .function = ty_index },
21002193 };
21012194 }
......@@ -2132,10 +2225,13 @@ const Kind = union(enum) {
21322225
21332226/// Parses an Atom and inserts its metadata into the corresponding sections.
21342227fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
2228 const comp = wasm.base.comp;
2229 const gpa = comp.gpa;
2230 const shared_memory = comp.config.shared_memory;
2231 const import_memory = comp.config.import_memory;
21352232 const atom = wasm.getAtomPtr(atom_index);
21362233 const symbol = (SymbolLoc{ .file = null, .index = atom.sym_index }).getSymbol(wasm);
2137 const do_garbage_collect = wasm.base.options.gc_sections orelse
2138 (wasm.base.options.output_mode != .Obj);
2234 const do_garbage_collect = wasm.base.gc_sections;
21392235
21402236 if (symbol.isDead() and do_garbage_collect) {
21412237 // Prevent unreferenced symbols from being parsed.
......@@ -2147,7 +2243,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
21472243 const index: u32 = @intCast(wasm.functions.count() + wasm.imported_functions_count);
21482244 const type_index = wasm.atom_types.get(atom_index).?;
21492245 try wasm.functions.putNoClobber(
2150 wasm.base.allocator,
2246 gpa,
21512247 .{ .file = null, .index = index },
21522248 .{ .func = .{ .type_index = type_index }, .sym_index = atom.sym_index },
21532249 );
......@@ -2156,7 +2252,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
21562252
21572253 if (wasm.code_section_index == null) {
21582254 wasm.code_section_index = @intCast(wasm.segments.items.len);
2159 try wasm.segments.append(wasm.base.allocator, .{
2255 try wasm.segments.append(gpa, .{
21602256 .alignment = atom.alignment,
21612257 .size = atom.size,
21622258 .offset = 0,
......@@ -2167,11 +2263,11 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
21672263 break :result wasm.code_section_index.?;
21682264 },
21692265 .data => result: {
2170 const segment_name = try std.mem.concat(wasm.base.allocator, u8, &.{
2266 const segment_name = try std.mem.concat(gpa, u8, &.{
21712267 kind.segmentName(),
21722268 wasm.string_table.get(symbol.name),
21732269 });
2174 errdefer wasm.base.allocator.free(segment_name);
2270 errdefer gpa.free(segment_name);
21752271 const segment_info: types.Segment = .{
21762272 .name = segment_name,
21772273 .alignment = atom.alignment,
......@@ -2183,27 +2279,27 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
21832279 // we set the entire region of it to zeroes.
21842280 // We do not have to do this when exporting the memory (the default) because the runtime
21852281 // will do it for us, and we do not emit the bss segment at all.
2186 if ((wasm.base.options.output_mode == .Obj or wasm.base.options.import_memory) and kind.data == .uninitialized) {
2282 if ((wasm.base.comp.config.output_mode == .Obj or import_memory) and kind.data == .uninitialized) {
21872283 @memset(atom.code.items, 0);
21882284 }
21892285
2190 const should_merge = wasm.base.options.output_mode != .Obj;
2191 const gop = try wasm.data_segments.getOrPut(wasm.base.allocator, segment_info.outputName(should_merge));
2286 const should_merge = wasm.base.comp.config.output_mode != .Obj;
2287 const gop = try wasm.data_segments.getOrPut(gpa, segment_info.outputName(should_merge));
21922288 if (gop.found_existing) {
21932289 const index = gop.value_ptr.*;
21942290 wasm.segments.items[index].size += atom.size;
21952291
21962292 symbol.index = @intCast(wasm.segment_info.getIndex(index).?);
21972293 // segment info already exists, so free its memory
2198 wasm.base.allocator.free(segment_name);
2294 gpa.free(segment_name);
21992295 break :result index;
22002296 } else {
22012297 const index: u32 = @intCast(wasm.segments.items.len);
22022298 var flags: u32 = 0;
2203 if (wasm.base.options.shared_memory) {
2299 if (shared_memory) {
22042300 flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE);
22052301 }
2206 try wasm.segments.append(wasm.base.allocator, .{
2302 try wasm.segments.append(gpa, .{
22072303 .alignment = atom.alignment,
22082304 .size = 0,
22092305 .offset = 0,
......@@ -2212,7 +2308,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
22122308 gop.value_ptr.* = index;
22132309
22142310 const info_index: u32 = @intCast(wasm.segment_info.count());
2215 try wasm.segment_info.put(wasm.base.allocator, index, segment_info);
2311 try wasm.segment_info.put(gpa, index, segment_info);
22162312 symbol.index = info_index;
22172313 break :result index;
22182314 }
......@@ -2228,6 +2324,7 @@ fn parseAtom(wasm: *Wasm, atom_index: Atom.Index, kind: Kind) !void {
22282324/// From a given index, append the given `Atom` at the back of the linked list.
22292325/// Simply inserts it into the map of atoms when it doesn't exist yet.
22302326pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void {
2327 const gpa = wasm.base.comp.gpa;
22312328 const atom = wasm.getAtomPtr(atom_index);
22322329 if (wasm.atoms.getPtr(index)) |last_index_ptr| {
22332330 const last = wasm.getAtomPtr(last_index_ptr.*);
......@@ -2235,7 +2332,7 @@ pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void
22352332 atom.prev = last_index_ptr.*;
22362333 last_index_ptr.* = atom_index;
22372334 } else {
2238 try wasm.atoms.putNoClobber(wasm.base.allocator, index, atom_index);
2335 try wasm.atoms.putNoClobber(gpa, index, atom_index);
22392336 }
22402337}
22412338
......@@ -2344,7 +2441,7 @@ fn allocateVirtualAddresses(wasm: *Wasm) void {
23442441 };
23452442
23462443 const atom = wasm.getAtom(atom_index);
2347 const merge_segment = wasm.base.options.output_mode != .Obj;
2444 const merge_segment = wasm.base.comp.config.output_mode != .Obj;
23482445 const segment_info = if (atom.file) |object_index| blk: {
23492446 break :blk wasm.objects.items[object_index].segment_info;
23502447 } else wasm.segment_info.values();
......@@ -2363,12 +2460,13 @@ fn allocateVirtualAddresses(wasm: *Wasm) void {
23632460}
23642461
23652462fn sortDataSegments(wasm: *Wasm) !void {
2463 const gpa = wasm.base.comp.gpa;
23662464 var new_mapping: std.StringArrayHashMapUnmanaged(u32) = .{};
2367 try new_mapping.ensureUnusedCapacity(wasm.base.allocator, wasm.data_segments.count());
2368 errdefer new_mapping.deinit(wasm.base.allocator);
2465 try new_mapping.ensureUnusedCapacity(gpa, wasm.data_segments.count());
2466 errdefer new_mapping.deinit(gpa);
23692467
2370 const keys = try wasm.base.allocator.dupe([]const u8, wasm.data_segments.keys());
2371 defer wasm.base.allocator.free(keys);
2468 const keys = try gpa.dupe([]const u8, wasm.data_segments.keys());
2469 defer gpa.free(keys);
23722470
23732471 const SortContext = struct {
23742472 fn sort(_: void, lhs: []const u8, rhs: []const u8) bool {
......@@ -2388,7 +2486,7 @@ fn sortDataSegments(wasm: *Wasm) !void {
23882486 const segment_index = wasm.data_segments.get(key).?;
23892487 new_mapping.putAssumeCapacity(key, segment_index);
23902488 }
2391 wasm.data_segments.deinit(wasm.base.allocator);
2489 wasm.data_segments.deinit(gpa);
23922490 wasm.data_segments = new_mapping;
23932491}
23942492
......@@ -2401,8 +2499,9 @@ fn sortDataSegments(wasm: *Wasm) !void {
24012499/// original functions and their types. We need to know the type to verify it doesn't
24022500/// contain any parameters.
24032501fn setupInitFunctions(wasm: *Wasm) !void {
2502 const gpa = wasm.base.comp.gpa;
24042503 for (wasm.objects.items, 0..) |object, file_index| {
2405 try wasm.init_funcs.ensureUnusedCapacity(wasm.base.allocator, object.init_funcs.len);
2504 try wasm.init_funcs.ensureUnusedCapacity(gpa, object.init_funcs.len);
24062505 for (object.init_funcs) |init_func| {
24072506 const symbol = object.symtable[init_func.symbol_index];
24082507 const ty: std.wasm.Type = if (symbol.isUndefined()) ty: {
......@@ -2439,9 +2538,10 @@ fn setupInitFunctions(wasm: *Wasm) !void {
24392538/// Generates an atom containing the global error set' size.
24402539/// This will only be generated if the symbol exists.
24412540fn setupErrorsLen(wasm: *Wasm) !void {
2541 const gpa = wasm.base.comp.gpa;
24422542 const loc = wasm.findGlobalSymbol("__zig_errors_len") orelse return;
24432543
2444 const errors_len = wasm.base.options.module.?.global_error_set.count();
2544 const errors_len = wasm.base.comp.module.?.global_error_set.count();
24452545 // overwrite existing atom if it already exists (maybe the error set has increased)
24462546 // if not, allcoate a new atom.
24472547 const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: {
......@@ -2456,19 +2556,19 @@ fn setupErrorsLen(wasm: *Wasm) !void {
24562556 prev_atom.next = atom.next;
24572557 atom.prev = null;
24582558 }
2459 atom.deinit(wasm.base.allocator);
2559 atom.deinit(gpa);
24602560 break :blk index;
24612561 } else new_atom: {
24622562 const atom_index: Atom.Index = @intCast(wasm.managed_atoms.items.len);
2463 try wasm.symbol_atom.put(wasm.base.allocator, loc, atom_index);
2464 try wasm.managed_atoms.append(wasm.base.allocator, undefined);
2563 try wasm.symbol_atom.put(gpa, loc, atom_index);
2564 try wasm.managed_atoms.append(gpa, undefined);
24652565 break :new_atom atom_index;
24662566 };
24672567 const atom = wasm.getAtomPtr(atom_index);
24682568 atom.* = Atom.empty;
24692569 atom.sym_index = loc.index;
24702570 atom.size = 2;
2471 try atom.code.writer(wasm.base.allocator).writeInt(u16, @intCast(errors_len), .little);
2571 try atom.code.writer(gpa).writeInt(u16, @intCast(errors_len), .little);
24722572
24732573 try wasm.parseAtom(atom_index, .{ .data = .read_only });
24742574}
......@@ -2480,16 +2580,17 @@ fn setupErrorsLen(wasm: *Wasm) !void {
24802580/// references to the function stored in the symbol have been finalized so we end
24812581/// up calling the resolved function.
24822582fn initializeCallCtorsFunction(wasm: *Wasm) !void {
2583 const gpa = wasm.base.comp.gpa;
24832584 // No code to emit, so also no ctors to call
24842585 if (wasm.code_section_index == null) {
24852586 // Make sure to remove it from the resolved symbols so we do not emit
24862587 // it within any section. TODO: Remove this once we implement garbage collection.
24872588 const loc = wasm.findGlobalSymbol("__wasm_call_ctors").?;
2488 std.debug.assert(wasm.resolved_symbols.swapRemove(loc));
2589 assert(wasm.resolved_symbols.swapRemove(loc));
24892590 return;
24902591 }
24912592
2492 var function_body = std.ArrayList(u8).init(wasm.base.allocator);
2593 var function_body = std.ArrayList(u8).init(gpa);
24932594 defer function_body.deinit();
24942595 const writer = function_body.writer();
24952596
......@@ -2531,6 +2632,7 @@ fn createSyntheticFunction(
25312632 func_ty: std.wasm.Type,
25322633 function_body: *std.ArrayList(u8),
25332634) !void {
2635 const gpa = wasm.base.comp.gpa;
25342636 const loc = wasm.findGlobalSymbol(symbol_name) orelse
25352637 try wasm.createSyntheticSymbol(symbol_name, .function);
25362638 const symbol = loc.getSymbol(wasm);
......@@ -2541,7 +2643,7 @@ fn createSyntheticFunction(
25412643 // create function with above type
25422644 const func_index = wasm.imported_functions_count + @as(u32, @intCast(wasm.functions.count()));
25432645 try wasm.functions.putNoClobber(
2544 wasm.base.allocator,
2646 gpa,
25452647 .{ .file = null, .index = func_index },
25462648 .{ .func = .{ .type_index = ty_index }, .sym_index = loc.index },
25472649 );
......@@ -2549,7 +2651,7 @@ fn createSyntheticFunction(
25492651
25502652 // create the atom that will be output into the final binary
25512653 const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len));
2552 const atom = try wasm.managed_atoms.addOne(wasm.base.allocator);
2654 const atom = try wasm.managed_atoms.addOne(gpa);
25532655 atom.* = .{
25542656 .size = @as(u32, @intCast(function_body.items.len)),
25552657 .offset = 0,
......@@ -2562,7 +2664,7 @@ fn createSyntheticFunction(
25622664 .original_offset = 0,
25632665 };
25642666 try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index);
2565 try wasm.symbol_atom.putNoClobber(wasm.base.allocator, loc, atom_index);
2667 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);
25662668
25672669 // `allocateAtoms` has already been called, set the atom's offset manually.
25682670 // This is fine to do manually as we insert the atom at the very end.
......@@ -2582,10 +2684,11 @@ pub fn createFunction(
25822684 function_body: *std.ArrayList(u8),
25832685 relocations: *std.ArrayList(Relocation),
25842686) !u32 {
2687 const gpa = wasm.base.comp.gpa;
25852688 const loc = try wasm.createSyntheticSymbol(symbol_name, .function);
25862689
2587 const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len));
2588 const atom = try wasm.managed_atoms.addOne(wasm.base.allocator);
2690 const atom_index: Atom.Index = @intCast(wasm.managed_atoms.items.len);
2691 const atom = try wasm.managed_atoms.addOne(gpa);
25892692 atom.* = .{
25902693 .size = @intCast(function_body.items.len),
25912694 .offset = 0,
......@@ -2607,9 +2710,9 @@ pub fn createFunction(
26072710 break :idx index;
26082711 };
26092712 try wasm.appendAtomAtIndex(section_index, atom_index);
2610 try wasm.symbol_atom.putNoClobber(wasm.base.allocator, loc, atom_index);
2611 try wasm.atom_types.put(wasm.base.allocator, atom_index, try wasm.putOrGetFuncType(func_ty));
2612 try wasm.synthetic_functions.append(wasm.base.allocator, atom_index);
2713 try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index);
2714 try wasm.atom_types.put(gpa, atom_index, try wasm.putOrGetFuncType(func_ty));
2715 try wasm.synthetic_functions.append(gpa, atom_index);
26132716
26142717 return loc.index;
26152718}
......@@ -2622,9 +2725,13 @@ fn setupStartSection(wasm: *Wasm) !void {
26222725}
26232726
26242727fn initializeTLSFunction(wasm: *Wasm) !void {
2625 if (!wasm.base.options.shared_memory) return;
2728 const comp = wasm.base.comp;
2729 const gpa = comp.gpa;
2730 const shared_memory = comp.config.shared_memory;
2731
2732 if (!shared_memory) return;
26262733
2627 var function_body = std.ArrayList(u8).init(wasm.base.allocator);
2734 var function_body = std.ArrayList(u8).init(gpa);
26282735 defer function_body.deinit();
26292736 const writer = function_body.writer();
26302737
......@@ -2684,6 +2791,7 @@ fn initializeTLSFunction(wasm: *Wasm) !void {
26842791}
26852792
26862793fn setupImports(wasm: *Wasm) !void {
2794 const gpa = wasm.base.comp.gpa;
26872795 log.debug("Merging imports", .{});
26882796 var discarded_it = wasm.discarded.keyIterator();
26892797 while (discarded_it.next()) |discarded| {
......@@ -2718,12 +2826,12 @@ fn setupImports(wasm: *Wasm) !void {
27182826 // We copy the import to a new import to ensure the names contain references
27192827 // to the internal string table, rather than of the object file.
27202828 const new_imp: types.Import = .{
2721 .module_name = try wasm.string_table.put(wasm.base.allocator, object.string_table.get(import.module_name)),
2722 .name = try wasm.string_table.put(wasm.base.allocator, object.string_table.get(import.name)),
2829 .module_name = try wasm.string_table.put(gpa, object.string_table.get(import.module_name)),
2830 .name = try wasm.string_table.put(gpa, object.string_table.get(import.name)),
27232831 .kind = import.kind,
27242832 };
27252833 // TODO: De-duplicate imports when they contain the same names and type
2726 try wasm.imports.putNoClobber(wasm.base.allocator, symbol_loc, new_imp);
2834 try wasm.imports.putNoClobber(gpa, symbol_loc, new_imp);
27272835 }
27282836
27292837 // Assign all indexes of the imports to their representing symbols
......@@ -2764,7 +2872,9 @@ fn setupImports(wasm: *Wasm) !void {
27642872/// Takes the global, function and table section from each linked object file
27652873/// and merges it into a single section for each.
27662874fn mergeSections(wasm: *Wasm) !void {
2767 var removed_duplicates = std.ArrayList(SymbolLoc).init(wasm.base.allocator);
2875 const gpa = wasm.base.comp.gpa;
2876
2877 var removed_duplicates = std.ArrayList(SymbolLoc).init(gpa);
27682878 defer removed_duplicates.deinit();
27692879
27702880 for (wasm.resolved_symbols.keys()) |sym_loc| {
......@@ -2791,7 +2901,7 @@ fn mergeSections(wasm: *Wasm) !void {
27912901 switch (symbol.tag) {
27922902 .function => {
27932903 const gop = try wasm.functions.getOrPut(
2794 wasm.base.allocator,
2904 gpa,
27952905 .{ .file = sym_loc.file, .index = symbol.index },
27962906 );
27972907 if (gop.found_existing) {
......@@ -2800,7 +2910,7 @@ fn mergeSections(wasm: *Wasm) !void {
28002910 // we only emit a single function, instead of duplicates.
28012911 symbol.unmark();
28022912 try wasm.discarded.putNoClobber(
2803 wasm.base.allocator,
2913 gpa,
28042914 sym_loc,
28052915 .{ .file = gop.key_ptr.*.file, .index = gop.value_ptr.*.sym_index },
28062916 );
......@@ -2813,12 +2923,12 @@ fn mergeSections(wasm: *Wasm) !void {
28132923 .global => {
28142924 const original_global = object.globals[index];
28152925 symbol.index = @as(u32, @intCast(wasm.wasm_globals.items.len)) + wasm.imported_globals_count;
2816 try wasm.wasm_globals.append(wasm.base.allocator, original_global);
2926 try wasm.wasm_globals.append(gpa, original_global);
28172927 },
28182928 .table => {
28192929 const original_table = object.tables[index];
28202930 symbol.index = @as(u32, @intCast(wasm.tables.items.len)) + wasm.imported_tables_count;
2821 try wasm.tables.append(wasm.base.allocator, original_table);
2931 try wasm.tables.append(gpa, original_table);
28222932 },
28232933 else => unreachable,
28242934 }
......@@ -2838,10 +2948,11 @@ fn mergeSections(wasm: *Wasm) !void {
28382948/// 'types' section, while assigning the type index to the representing
28392949/// section (import, export, function).
28402950fn mergeTypes(wasm: *Wasm) !void {
2951 const gpa = wasm.base.comp.gpa;
28412952 // A map to track which functions have already had their
28422953 // type inserted. If we do this for the same function multiple times,
28432954 // it will be overwritten with the incorrect type.
2844 var dirty = std.AutoHashMap(u32, void).init(wasm.base.allocator);
2955 var dirty = std.AutoHashMap(u32, void).init(gpa);
28452956 try dirty.ensureUnusedCapacity(@as(u32, @intCast(wasm.functions.count())));
28462957 defer dirty.deinit();
28472958
......@@ -2873,10 +2984,12 @@ fn mergeTypes(wasm: *Wasm) !void {
28732984}
28742985
28752986fn setupExports(wasm: *Wasm) !void {
2876 if (wasm.base.options.output_mode == .Obj) return;
2987 const comp = wasm.base.comp;
2988 const gpa = comp.gpa;
2989 if (comp.config.output_mode == .Obj) return;
28772990 log.debug("Building exports from symbols", .{});
28782991
2879 const force_exp_names = wasm.base.options.export_symbol_names;
2992 const force_exp_names = wasm.export_symbol_names;
28802993 if (force_exp_names.len > 0) {
28812994 var failed_exports = false;
28822995
......@@ -2898,16 +3011,16 @@ fn setupExports(wasm: *Wasm) !void {
28983011
28993012 for (wasm.resolved_symbols.keys()) |sym_loc| {
29003013 const symbol = sym_loc.getSymbol(wasm);
2901 if (!symbol.isExported(wasm.base.options.rdynamic)) continue;
3014 if (!symbol.isExported(comp.config.rdynamic)) continue;
29023015
29033016 const sym_name = sym_loc.getName(wasm);
29043017 const export_name = if (wasm.export_names.get(sym_loc)) |name| name else blk: {
29053018 if (sym_loc.file == null) break :blk symbol.name;
2906 break :blk try wasm.string_table.put(wasm.base.allocator, sym_name);
3019 break :blk try wasm.string_table.put(gpa, sym_name);
29073020 };
29083021 const exp: types.Export = if (symbol.tag == .data) exp: {
29093022 const global_index = @as(u32, @intCast(wasm.imported_globals_count + wasm.wasm_globals.items.len));
2910 try wasm.wasm_globals.append(wasm.base.allocator, .{
3023 try wasm.wasm_globals.append(gpa, .{
29113024 .global_type = .{ .valtype = .i32, .mutable = false },
29123025 .init = .{ .i32_const = @as(i32, @intCast(symbol.virtual_address)) },
29133026 });
......@@ -2926,15 +3039,16 @@ fn setupExports(wasm: *Wasm) !void {
29263039 wasm.string_table.get(exp.name),
29273040 exp.index,
29283041 });
2929 try wasm.exports.append(wasm.base.allocator, exp);
3042 try wasm.exports.append(gpa, exp);
29303043 }
29313044
29323045 log.debug("Completed building exports. Total count: ({d})", .{wasm.exports.items.len});
29333046}
29343047
29353048fn setupStart(wasm: *Wasm) !void {
3049 const comp = wasm.base.comp;
29363050 // do not export entry point if user set none or no default was set.
2937 const entry_name = wasm.base.options.entry orelse return;
3051 const entry_name = wasm.entry_name orelse return;
29383052
29393053 const symbol_loc = wasm.findGlobalSymbol(entry_name) orelse {
29403054 log.err("Entry symbol '{s}' missing, use '-fno-entry' to suppress", .{entry_name});
......@@ -2948,33 +3062,33 @@ fn setupStart(wasm: *Wasm) !void {
29483062 }
29493063
29503064 // Ensure the symbol is exported so host environment can access it
2951 if (wasm.base.options.output_mode != .Obj) {
3065 if (comp.config.output_mode != .Obj) {
29523066 symbol.setFlag(.WASM_SYM_EXPORTED);
29533067 }
29543068}
29553069
29563070/// Sets up the memory section of the wasm module, as well as the stack.
29573071fn setupMemory(wasm: *Wasm) !void {
3072 const comp = wasm.base.comp;
3073 const shared_memory = comp.config.shared_memory;
29583074 log.debug("Setting up memory layout", .{});
29593075 const page_size = std.wasm.page_size; // 64kb
2960 // Use the user-provided stack size or else we use 1MB by default
2961 const stack_size = wasm.base.options.stack_size_override orelse page_size * 16;
29623076 const stack_alignment: Alignment = .@"16"; // wasm's stack alignment as specified by tool-convention
29633077 const heap_alignment: Alignment = .@"16"; // wasm's heap alignment as specified by tool-convention
29643078
29653079 // Always place the stack at the start by default
29663080 // unless the user specified the global-base flag
29673081 var place_stack_first = true;
2968 var memory_ptr: u64 = if (wasm.base.options.global_base) |base| blk: {
3082 var memory_ptr: u64 = if (wasm.global_base) |base| blk: {
29693083 place_stack_first = false;
29703084 break :blk base;
29713085 } else 0;
29723086
2973 const is_obj = wasm.base.options.output_mode == .Obj;
3087 const is_obj = comp.config.output_mode == .Obj;
29743088
29753089 if (place_stack_first and !is_obj) {
29763090 memory_ptr = stack_alignment.forward(memory_ptr);
2977 memory_ptr += stack_size;
3091 memory_ptr += wasm.base.stack_size;
29783092 // We always put the stack pointer global at index 0
29793093 wasm.wasm_globals.items[0].init.i32_const = @as(i32, @bitCast(@as(u32, @intCast(memory_ptr))));
29803094 }
......@@ -2997,7 +3111,7 @@ fn setupMemory(wasm: *Wasm) !void {
29973111 }
29983112 if (wasm.findGlobalSymbol("__tls_base")) |loc| {
29993113 const sym = loc.getSymbol(wasm);
3000 wasm.wasm_globals.items[sym.index - wasm.imported_globals_count].init.i32_const = if (wasm.base.options.shared_memory)
3114 wasm.wasm_globals.items[sym.index - wasm.imported_globals_count].init.i32_const = if (shared_memory)
30013115 @as(i32, 0)
30023116 else
30033117 @as(i32, @intCast(memory_ptr));
......@@ -3010,7 +3124,7 @@ fn setupMemory(wasm: *Wasm) !void {
30103124 }
30113125
30123126 // create the memory init flag which is used by the init memory function
3013 if (wasm.base.options.shared_memory and wasm.hasPassiveInitializationSegments()) {
3127 if (shared_memory and wasm.hasPassiveInitializationSegments()) {
30143128 // align to pointer size
30153129 memory_ptr = mem.alignForward(u64, memory_ptr, 4);
30163130 const loc = try wasm.createSyntheticSymbol("__wasm_init_memory_flag", .data);
......@@ -3021,7 +3135,7 @@ fn setupMemory(wasm: *Wasm) !void {
30213135
30223136 if (!place_stack_first and !is_obj) {
30233137 memory_ptr = stack_alignment.forward(memory_ptr);
3024 memory_ptr += stack_size;
3138 memory_ptr += wasm.base.stack_size;
30253139 wasm.wasm_globals.items[0].init.i32_const = @as(i32, @bitCast(@as(u32, @intCast(memory_ptr))));
30263140 }
30273141
......@@ -3036,7 +3150,7 @@ fn setupMemory(wasm: *Wasm) !void {
30363150 // For now we only support wasm32 by setting the maximum allowed memory size 2^32-1
30373151 const max_memory_allowed: u64 = (1 << 32) - 1;
30383152
3039 if (wasm.base.options.initial_memory) |initial_memory| {
3153 if (wasm.initial_memory) |initial_memory| {
30403154 if (!std.mem.isAlignedGeneric(u64, initial_memory, page_size)) {
30413155 log.err("Initial memory must be {d}-byte aligned", .{page_size});
30423156 return error.MissAlignment;
......@@ -3062,7 +3176,7 @@ fn setupMemory(wasm: *Wasm) !void {
30623176 symbol.virtual_address = @as(u32, @intCast(memory_ptr));
30633177 }
30643178
3065 if (wasm.base.options.max_memory) |max_memory| {
3179 if (wasm.max_memory) |max_memory| {
30663180 if (!std.mem.isAlignedGeneric(u64, max_memory, page_size)) {
30673181 log.err("Maximum memory must be {d}-byte aligned", .{page_size});
30683182 return error.MissAlignment;
......@@ -3077,7 +3191,7 @@ fn setupMemory(wasm: *Wasm) !void {
30773191 }
30783192 wasm.memories.limits.max = @as(u32, @intCast(max_memory / page_size));
30793193 wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_HAS_MAX);
3080 if (wasm.base.options.shared_memory) {
3194 if (shared_memory) {
30813195 wasm.memories.limits.setFlag(.WASM_LIMITS_FLAG_IS_SHARED);
30823196 }
30833197 log.debug("Maximum memory pages: {?d}", .{wasm.memories.limits.max});
......@@ -3088,29 +3202,32 @@ fn setupMemory(wasm: *Wasm) !void {
30883202/// index of the segment within the final data section. When the segment does not yet
30893203/// exist, a new one will be initialized and appended. The new index will be returned in that case.
30903204pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u32 {
3205 const comp = wasm.base.comp;
3206 const gpa = comp.gpa;
30913207 const object: Object = wasm.objects.items[object_index];
30923208 const symbol = object.symtable[symbol_index];
3093 const index = @as(u32, @intCast(wasm.segments.items.len));
3209 const index: u32 = @intCast(wasm.segments.items.len);
3210 const shared_memory = comp.config.shared_memory;
30943211
30953212 switch (symbol.tag) {
30963213 .data => {
30973214 const segment_info = object.segment_info[symbol.index];
3098 const merge_segment = wasm.base.options.output_mode != .Obj;
3099 const result = try wasm.data_segments.getOrPut(wasm.base.allocator, segment_info.outputName(merge_segment));
3215 const merge_segment = comp.config.output_mode != .Obj;
3216 const result = try wasm.data_segments.getOrPut(gpa, segment_info.outputName(merge_segment));
31003217 if (!result.found_existing) {
31013218 result.value_ptr.* = index;
31023219 var flags: u32 = 0;
3103 if (wasm.base.options.shared_memory) {
3220 if (shared_memory) {
31043221 flags |= @intFromEnum(Segment.Flag.WASM_DATA_SEGMENT_IS_PASSIVE);
31053222 }
3106 try wasm.segments.append(wasm.base.allocator, .{
3223 try wasm.segments.append(gpa, .{
31073224 .alignment = .@"1",
31083225 .size = 0,
31093226 .offset = 0,
31103227 .flags = flags,
31113228 });
3112 try wasm.segment_info.putNoClobber(wasm.base.allocator, index, .{
3113 .name = try wasm.base.allocator.dupe(u8, segment_info.name),
3229 try wasm.segment_info.putNoClobber(gpa, index, .{
3230 .name = try gpa.dupe(u8, segment_info.name),
31143231 .alignment = segment_info.alignment,
31153232 .flags = segment_info.flags,
31163233 });
......@@ -3183,7 +3300,8 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3
31833300
31843301/// Appends a new segment with default field values
31853302fn appendDummySegment(wasm: *Wasm) !void {
3186 try wasm.segments.append(wasm.base.allocator, .{
3303 const gpa = wasm.base.comp.gpa;
3304 try wasm.segments.append(gpa, .{
31873305 .alignment = .@"1",
31883306 .size = 0,
31893307 .offset = 0,
......@@ -3203,14 +3321,15 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {
32033321 // and then return said symbol's index. The final table will be populated
32043322 // during `flush` when we know all possible error names.
32053323
3324 const gpa = wasm.base.comp.gpa;
32063325 const atom_index = try wasm.createAtom();
32073326 const atom = wasm.getAtomPtr(atom_index);
32083327 const slice_ty = Type.slice_const_u8_sentinel_0;
3209 const mod = wasm.base.options.module.?;
3328 const mod = wasm.base.comp.module.?;
32103329 atom.alignment = slice_ty.abiAlignment(mod);
32113330 const sym_index = atom.sym_index;
32123331
3213 const sym_name = try wasm.string_table.put(wasm.base.allocator, "__zig_err_name_table");
3332 const sym_name = try wasm.string_table.put(gpa, "__zig_err_name_table");
32143333 const symbol = &wasm.symbols.items[sym_index];
32153334 symbol.* = .{
32163335 .name = sym_name,
......@@ -3222,7 +3341,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {
32223341 symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN);
32233342 symbol.mark();
32243343
3225 try wasm.resolved_symbols.put(wasm.base.allocator, atom.symbolLoc(), {});
3344 try wasm.resolved_symbols.put(gpa, atom.symbolLoc(), {});
32263345
32273346 log.debug("Error name table was created with symbol index: ({d})", .{sym_index});
32283347 wasm.error_table_symbol = sym_index;
......@@ -3234,6 +3353,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 {
32343353/// This creates a table that consists of pointers and length to each error name.
32353354/// The table is what is being pointed to within the runtime bodies that are generated.
32363355fn populateErrorNameTable(wasm: *Wasm) !void {
3356 const gpa = wasm.base.comp.gpa;
32373357 const symbol_index = wasm.error_table_symbol orelse return;
32383358 const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = symbol_index }).?;
32393359
......@@ -3243,7 +3363,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
32433363 const names_atom_index = try wasm.createAtom();
32443364 const names_atom = wasm.getAtomPtr(names_atom_index);
32453365 names_atom.alignment = .@"1";
3246 const sym_name = try wasm.string_table.put(wasm.base.allocator, "__zig_err_names");
3366 const sym_name = try wasm.string_table.put(gpa, "__zig_err_names");
32473367 const names_symbol = &wasm.symbols.items[names_atom.sym_index];
32483368 names_symbol.* = .{
32493369 .name = sym_name,
......@@ -3259,7 +3379,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
32593379
32603380 // Addend for each relocation to the table
32613381 var addend: u32 = 0;
3262 const mod = wasm.base.options.module.?;
3382 const mod = wasm.base.comp.module.?;
32633383 for (mod.global_error_set.keys()) |error_name_nts| {
32643384 const atom = wasm.getAtomPtr(atom_index);
32653385
......@@ -3269,10 +3389,10 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
32693389 const slice_ty = Type.slice_const_u8_sentinel_0;
32703390 const offset = @as(u32, @intCast(atom.code.items.len));
32713391 // first we create the data for the slice of the name
3272 try atom.code.appendNTimes(wasm.base.allocator, 0, 4); // ptr to name, will be relocated
3273 try atom.code.writer(wasm.base.allocator).writeInt(u32, len - 1, .little);
3392 try atom.code.appendNTimes(gpa, 0, 4); // ptr to name, will be relocated
3393 try atom.code.writer(gpa).writeInt(u32, len - 1, .little);
32743394 // create relocation to the error name
3275 try atom.relocs.append(wasm.base.allocator, .{
3395 try atom.relocs.append(gpa, .{
32763396 .index = names_atom.sym_index,
32773397 .relocation_type = .R_WASM_MEMORY_ADDR_I32,
32783398 .offset = offset,
......@@ -3282,7 +3402,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
32823402 addend += len;
32833403
32843404 // as we updated the error name table, we now store the actual name within the names atom
3285 try names_atom.code.ensureUnusedCapacity(wasm.base.allocator, len);
3405 try names_atom.code.ensureUnusedCapacity(gpa, len);
32863406 names_atom.code.appendSliceAssumeCapacity(error_name);
32873407 names_atom.code.appendAssumeCapacity(0);
32883408
......@@ -3291,8 +3411,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
32913411 names_atom.size = addend;
32923412
32933413 const name_loc = names_atom.symbolLoc();
3294 try wasm.resolved_symbols.put(wasm.base.allocator, name_loc, {});
3295 try wasm.symbol_atom.put(wasm.base.allocator, name_loc, names_atom_index);
3414 try wasm.resolved_symbols.put(gpa, name_loc, {});
3415 try wasm.symbol_atom.put(gpa, name_loc, names_atom_index);
32963416
32973417 // link the atoms with the rest of the binary so they can be allocated
32983418 // and relocations will be performed.
......@@ -3304,7 +3424,8 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
33043424/// This initializes the index, appends a new segment,
33053425/// and finally, creates a managed `Atom`.
33063426pub fn createDebugSectionForIndex(wasm: *Wasm, index: *?u32, name: []const u8) !Atom.Index {
3307 const new_index = @as(u32, @intCast(wasm.segments.items.len));
3427 const gpa = wasm.base.comp.gpa;
3428 const new_index: u32 = @intCast(wasm.segments.items.len);
33083429 index.* = new_index;
33093430 try wasm.appendDummySegment();
33103431
......@@ -3312,7 +3433,7 @@ pub fn createDebugSectionForIndex(wasm: *Wasm, index: *?u32, name: []const u8) !
33123433 const atom = wasm.getAtomPtr(atom_index);
33133434 wasm.symbols.items[atom.sym_index] = .{
33143435 .tag = .section,
3315 .name = try wasm.string_table.put(wasm.base.allocator, name),
3436 .name = try wasm.string_table.put(gpa, name),
33163437 .index = 0,
33173438 .flags = @intFromEnum(Symbol.Flag.WASM_SYM_BINDING_LOCAL),
33183439 };
......@@ -3322,8 +3443,10 @@ pub fn createDebugSectionForIndex(wasm: *Wasm, index: *?u32, name: []const u8) !
33223443}
33233444
33243445fn resetState(wasm: *Wasm) void {
3446 const gpa = wasm.base.comp.gpa;
3447
33253448 for (wasm.segment_info.values()) |segment_info| {
3326 wasm.base.allocator.free(segment_info.name);
3449 gpa.free(segment_info.name);
33273450 }
33283451
33293452 var atom_it = wasm.decls.valueIterator();
......@@ -3357,49 +3480,44 @@ fn resetState(wasm: *Wasm) void {
33573480 wasm.debug_pubtypes_index = null;
33583481}
33593482
3360pub fn flush(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
3361 if (wasm.base.options.emit == null) {
3362 if (wasm.llvm_object) |llvm_object| {
3363 return try llvm_object.flushModule(comp, prog_node);
3364 }
3365 return;
3366 }
3483pub fn flush(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
3484 const comp = wasm.base.comp;
3485 const use_lld = build_options.have_llvm and comp.config.use_lld;
3486 const use_llvm = comp.config.use_llvm;
33673487
3368 if (build_options.have_llvm and wasm.base.options.use_lld) {
3369 return wasm.linkWithLLD(comp, prog_node);
3370 } else if (wasm.base.options.use_llvm and !wasm.base.options.use_lld) {
3371 return wasm.linkWithZld(comp, prog_node);
3488 if (use_lld) {
3489 return wasm.linkWithLLD(arena, prog_node);
3490 } else if (use_llvm) {
3491 return wasm.linkWithZld(arena, prog_node);
33723492 } else {
3373 return wasm.flushModule(comp, prog_node);
3493 return wasm.flushModule(arena, prog_node);
33743494 }
33753495}
33763496
33773497/// Uses the in-house linker to link one or multiple object -and archive files into a WebAssembly binary.
3378fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
3498fn linkWithZld(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
33793499 const tracy = trace(@src());
33803500 defer tracy.end();
33813501
3382 const gpa = wasm.base.allocator;
3383 const options = wasm.base.options;
3502 const comp = wasm.base.comp;
3503 const shared_memory = comp.config.shared_memory;
3504 const import_memory = comp.config.import_memory;
33843505
3385 // Used for all temporary memory allocated during flushin
3386 var arena_instance = std.heap.ArenaAllocator.init(gpa);
3387 defer arena_instance.deinit();
3388 const arena = arena_instance.allocator();
3389
3390 const directory = options.emit.?.directory; // Just an alias to make it shorter to type.
3391 const full_out_path = try directory.join(arena, &[_][]const u8{options.emit.?.sub_path});
3506 const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
3507 const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
3508 const opt_zcu = comp.module;
3509 const use_llvm = comp.config.use_llvm;
33923510
33933511 // If there is no Zig code to compile, then we should skip flushing the output file because it
33943512 // will not be part of the linker line anyway.
3395 const module_obj_path: ?[]const u8 = if (options.module != null) blk: {
3396 assert(options.use_llvm); // `linkWithZld` should never be called when the Wasm backend is used
3397 try wasm.flushModule(comp, prog_node);
3513 const module_obj_path: ?[]const u8 = if (opt_zcu != null) blk: {
3514 assert(use_llvm); // `linkWithZld` should never be called when the Wasm backend is used
3515 try wasm.flushModule(arena, prog_node);
33983516
33993517 if (fs.path.dirname(full_out_path)) |dirname| {
3400 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.intermediary_basename.? });
3518 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
34013519 } else {
3402 break :blk wasm.base.intermediary_basename.?;
3520 break :blk wasm.base.zcu_object_sub_path.?;
34033521 }
34043522 } else null;
34053523
......@@ -3416,12 +3534,14 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
34163534 const id_symlink_basename = "zld.id";
34173535
34183536 var man: Cache.Manifest = undefined;
3419 defer if (!options.disable_lld_caching) man.deinit();
3537 defer if (!wasm.base.disable_lld_caching) man.deinit();
34203538 var digest: [Cache.hex_digest_len]u8 = undefined;
34213539
3540 const objects = comp.objects;
3541
34223542 // NOTE: The following section must be maintained to be equal
34233543 // as the section defined in `linkWithLLD`
3424 if (!options.disable_lld_caching) {
3544 if (!wasm.base.disable_lld_caching) {
34253545 man = comp.cache_parent.obtain();
34263546
34273547 // We are about to obtain this lock, so here we give other processes a chance first.
......@@ -3429,7 +3549,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
34293549
34303550 comptime assert(Compilation.link_hash_implementation_version == 10);
34313551
3432 for (options.objects) |obj| {
3552 for (objects) |obj| {
34333553 _ = try man.addFile(obj.path, null);
34343554 man.hash.add(obj.must_link);
34353555 }
......@@ -3438,19 +3558,19 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
34383558 }
34393559 try man.addOptionalFile(module_obj_path);
34403560 try man.addOptionalFile(compiler_rt_path);
3441 man.hash.addOptionalBytes(options.entry);
3442 man.hash.addOptional(options.stack_size_override);
3443 man.hash.add(wasm.base.options.build_id);
3444 man.hash.add(options.import_memory);
3445 man.hash.add(options.import_table);
3446 man.hash.add(options.export_table);
3447 man.hash.addOptional(options.initial_memory);
3448 man.hash.addOptional(options.max_memory);
3449 man.hash.add(options.shared_memory);
3450 man.hash.addOptional(options.global_base);
3451 man.hash.add(options.export_symbol_names.len);
3561 man.hash.addOptionalBytes(wasm.entry_name);
3562 man.hash.add(wasm.base.stack_size);
3563 man.hash.add(wasm.base.build_id);
3564 man.hash.add(import_memory);
3565 man.hash.add(shared_memory);
3566 man.hash.add(wasm.import_table);
3567 man.hash.add(wasm.export_table);
3568 man.hash.addOptional(wasm.initial_memory);
3569 man.hash.addOptional(wasm.max_memory);
3570 man.hash.addOptional(wasm.global_base);
3571 man.hash.add(wasm.export_symbol_names.len);
34523572 // strip does not need to go into the linker hash because it is part of the hash namespace
3453 for (options.export_symbol_names) |symbol_name| {
3573 for (wasm.export_symbol_names) |symbol_name| {
34543574 man.hash.addBytes(symbol_name);
34553575 }
34563576
......@@ -3485,30 +3605,36 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
34853605
34863606 // Positional arguments to the linker such as object files and static archives.
34873607 var positionals = std.ArrayList([]const u8).init(arena);
3488 try positionals.ensureUnusedCapacity(options.objects.len);
3608 try positionals.ensureUnusedCapacity(objects.len);
3609
3610 const target = comp.root_mod.resolved_target.result;
3611 const output_mode = comp.config.output_mode;
3612 const link_mode = comp.config.link_mode;
3613 const link_libc = comp.config.link_libc;
3614 const link_libcpp = comp.config.link_libcpp;
3615 const wasi_exec_model = comp.config.wasi_exec_model;
34893616
34903617 // When the target os is WASI, we allow linking with WASI-LIBC
3491 if (options.target.os.tag == .wasi) {
3492 const is_exe_or_dyn_lib = wasm.base.options.output_mode == .Exe or
3493 (wasm.base.options.output_mode == .Lib and wasm.base.options.link_mode == .Dynamic);
3618 if (target.os.tag == .wasi) {
3619 const is_exe_or_dyn_lib = output_mode == .Exe or
3620 (output_mode == .Lib and link_mode == .Dynamic);
34943621 if (is_exe_or_dyn_lib) {
3495 const wasi_emulated_libs = wasm.base.options.wasi_emulated_libs;
3496 for (wasi_emulated_libs) |crt_file| {
3622 for (comp.wasi_emulated_libs) |crt_file| {
34973623 try positionals.append(try comp.get_libc_crt_file(
34983624 arena,
34993625 wasi_libc.emulatedLibCRFileLibName(crt_file),
35003626 ));
35013627 }
35023628
3503 if (wasm.base.options.link_libc) {
3629 if (link_libc) {
35043630 try positionals.append(try comp.get_libc_crt_file(
35053631 arena,
3506 wasi_libc.execModelCrtFileFullName(wasm.base.options.wasi_exec_model),
3632 wasi_libc.execModelCrtFileFullName(wasi_exec_model),
35073633 ));
35083634 try positionals.append(try comp.get_libc_crt_file(arena, "libc.a"));
35093635 }
35103636
3511 if (wasm.base.options.link_libcpp) {
3637 if (link_libcpp) {
35123638 try positionals.append(comp.libcxx_static_lib.?.full_object_path);
35133639 try positionals.append(comp.libcxxabi_static_lib.?.full_object_path);
35143640 }
......@@ -3519,7 +3645,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
35193645 try positionals.append(path);
35203646 }
35213647
3522 for (options.objects) |object| {
3648 for (objects) |object| {
35233649 try positionals.append(object.path);
35243650 }
35253651
......@@ -3562,7 +3688,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
35623688 try wasm.setupExports();
35633689 try wasm.writeToFile(enabled_features, emit_features_count, arena);
35643690
3565 if (!wasm.base.options.disable_lld_caching) {
3691 if (!wasm.base.disable_lld_caching) {
35663692 // Update the file with the digest. If it fails we can continue; it only
35673693 // means that the next invocation will have an unnecessary cache miss.
35683694 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
......@@ -3578,12 +3704,15 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l
35783704 }
35793705}
35803706
3581pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void {
3707pub fn flushModule(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) link.File.FlushError!void {
35823708 const tracy = trace(@src());
35833709 defer tracy.end();
35843710
3711 const comp = wasm.base.comp;
3712
35853713 if (wasm.llvm_object) |llvm_object| {
3586 return try llvm_object.flushModule(comp, prog_node);
3714 try wasm.base.emitLlvmObject(arena, llvm_object, prog_node);
3715 return;
35873716 }
35883717
35893718 var sub_prog_node = prog_node.start("Wasm Flush", 0);
......@@ -3593,16 +3722,13 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
35933722 // ensure the error names table is populated when an error name is referenced
35943723 try wasm.populateErrorNameTable();
35953724
3596 // Used for all temporary memory allocated during flushin
3597 var arena_instance = std.heap.ArenaAllocator.init(wasm.base.allocator);
3598 defer arena_instance.deinit();
3599 const arena = arena_instance.allocator();
3725 const objects = comp.objects;
36003726
36013727 // Positional arguments to the linker such as object files and static archives.
36023728 var positionals = std.ArrayList([]const u8).init(arena);
3603 try positionals.ensureUnusedCapacity(wasm.base.options.objects.len);
3729 try positionals.ensureUnusedCapacity(objects.len);
36043730
3605 for (wasm.base.options.objects) |object| {
3731 for (objects) |object| {
36063732 positionals.appendAssumeCapacity(object.path);
36073733 }
36083734
......@@ -3634,7 +3760,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
36343760 try wasm.markReferences();
36353761 try wasm.setupErrorsLen();
36363762 try wasm.setupImports();
3637 if (wasm.base.options.module) |mod| {
3763 if (comp.module) |mod| {
36383764 var decl_it = wasm.decls.iterator();
36393765 while (decl_it.next()) |entry| {
36403766 const decl = mod.declPtr(entry.key_ptr.*);
......@@ -3649,8 +3775,12 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
36493775 } else if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
36503776 // for safe build modes, we store the atom in the data segment,
36513777 // whereas for unsafe build modes we store it in bss.
3652 const is_initialized = wasm.base.options.optimize_mode == .Debug or
3653 wasm.base.options.optimize_mode == .ReleaseSafe;
3778 const decl_namespace = mod.namespacePtr(decl.src_namespace);
3779 const optimize_mode = decl_namespace.file_scope.mod.optimize_mode;
3780 const is_initialized = switch (optimize_mode) {
3781 .Debug, .ReleaseSafe => true,
3782 .ReleaseFast, .ReleaseSmall => false,
3783 };
36543784 try wasm.parseAtom(atom_index, .{ .data = if (is_initialized) .initialized else .uninitialized });
36553785 } else {
36563786 // when the decl is all zeroes, we store the atom in the bss segment,
......@@ -3685,7 +3815,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
36853815 }
36863816
36873817 if (wasm.dwarf) |*dwarf| {
3688 try dwarf.flushModule(wasm.base.options.module.?);
3818 try dwarf.flushModule(comp.module.?);
36893819 }
36903820 }
36913821
......@@ -3711,6 +3841,14 @@ fn writeToFile(
37113841 feature_count: u32,
37123842 arena: Allocator,
37133843) !void {
3844 const comp = wasm.base.comp;
3845 const gpa = comp.gpa;
3846 const use_llvm = comp.config.use_llvm;
3847 const use_lld = build_options.have_llvm and comp.config.use_lld;
3848 const shared_memory = comp.config.shared_memory;
3849 const import_memory = comp.config.import_memory;
3850 const export_memory = comp.config.export_memory;
3851
37143852 // Size of each section header
37153853 const header_size = 5 + 1;
37163854 // The amount of sections that will be written
......@@ -3719,9 +3857,9 @@ fn writeToFile(
37193857 var code_section_index: ?u32 = null;
37203858 // Index of the data section. Used to tell relocation table where the section lives.
37213859 var data_section_index: ?u32 = null;
3722 const is_obj = wasm.base.options.output_mode == .Obj or (!wasm.base.options.use_llvm and wasm.base.options.use_lld);
3860 const is_obj = comp.config.output_mode == .Obj or (!use_llvm and use_lld);
37233861
3724 var binary_bytes = std.ArrayList(u8).init(wasm.base.allocator);
3862 var binary_bytes = std.ArrayList(u8).init(gpa);
37253863 defer binary_bytes.deinit();
37263864 const binary_writer = binary_bytes.writer();
37273865
......@@ -3759,8 +3897,6 @@ fn writeToFile(
37593897 }
37603898
37613899 // Import section
3762 const import_memory = wasm.base.options.import_memory or is_obj;
3763 const export_memory = wasm.base.options.export_memory;
37643900 if (wasm.imports.count() != 0 or import_memory) {
37653901 const header_offset = try reserveVecSectionHeader(&binary_bytes);
37663902
......@@ -3774,8 +3910,8 @@ fn writeToFile(
37743910 if (import_memory) {
37753911 const mem_name = if (is_obj) "__linear_memory" else "memory";
37763912 const mem_imp: types.Import = .{
3777 .module_name = try wasm.string_table.put(wasm.base.allocator, wasm.host_name),
3778 .name = try wasm.string_table.put(wasm.base.allocator, mem_name),
3913 .module_name = try wasm.string_table.put(gpa, wasm.host_name),
3914 .name = try wasm.string_table.put(gpa, mem_name),
37793915 .kind = .{ .memory = wasm.memories.limits },
37803916 };
37813917 try wasm.emitImport(binary_writer, mem_imp);
......@@ -3937,7 +4073,7 @@ fn writeToFile(
39374073
39384074 // When the shared-memory option is enabled, we *must* emit the 'data count' section.
39394075 const data_segments_count = wasm.data_segments.count() - @intFromBool(wasm.data_segments.contains(".bss") and !import_memory);
3940 if (data_segments_count != 0 and wasm.base.options.shared_memory) {
4076 if (data_segments_count != 0 and shared_memory) {
39414077 const header_offset = try reserveVecSectionHeader(&binary_bytes);
39424078 try writeVecSectionHeader(
39434079 binary_bytes.items,
......@@ -3955,7 +4091,7 @@ fn writeToFile(
39554091 var atom_index = wasm.atoms.get(code_index).?;
39564092
39574093 // The code section must be sorted in line with the function order.
3958 var sorted_atoms = try std.ArrayList(*const Atom).initCapacity(wasm.base.allocator, wasm.functions.count());
4094 var sorted_atoms = try std.ArrayList(*const Atom).initCapacity(gpa, wasm.functions.count());
39594095 defer sorted_atoms.deinit();
39604096
39614097 while (true) {
......@@ -3966,7 +4102,7 @@ fn writeToFile(
39664102 sorted_atoms.appendAssumeCapacity(atom); // found more code atoms than functions
39674103 atom_index = atom.prev orelse break;
39684104 }
3969 std.debug.assert(wasm.functions.count() == sorted_atoms.items.len);
4105 assert(wasm.functions.count() == sorted_atoms.items.len);
39704106
39714107 const atom_sort_fn = struct {
39724108 fn sort(ctx: *const Wasm, lhs: *const Atom, rhs: *const Atom) bool {
......@@ -4079,14 +4215,14 @@ fn writeToFile(
40794215 if (data_section_index) |data_index| {
40804216 try wasm.emitDataRelocations(&binary_bytes, data_index, symbol_table);
40814217 }
4082 } else if (!wasm.base.options.strip) {
4218 } else if (comp.config.debug_format != .strip) {
40834219 try wasm.emitNameSection(&binary_bytes, arena);
40844220 }
40854221
4086 if (!wasm.base.options.strip) {
4222 if (comp.config.debug_format != .strip) {
40874223 // The build id must be computed on the main sections only,
40884224 // so we have to do it now, before the debug sections.
4089 switch (wasm.base.options.build_id) {
4225 switch (wasm.base.build_id) {
40904226 .none => {},
40914227 .fast => {
40924228 var id: [16]u8 = undefined;
......@@ -4112,7 +4248,7 @@ fn writeToFile(
41124248 }
41134249
41144250 // if (wasm.dwarf) |*dwarf| {
4115 // const mod = wasm.base.options.module.?;
4251 // const mod = comp.module.?;
41164252 // try dwarf.writeDbgAbbrev();
41174253 // // for debug info and ranges, the address is always 0,
41184254 // // as locations are always offsets relative to 'code' section.
......@@ -4121,7 +4257,7 @@ fn writeToFile(
41214257 // try dwarf.writeDbgLineHeader();
41224258 // }
41234259
4124 var debug_bytes = std.ArrayList(u8).init(wasm.base.allocator);
4260 var debug_bytes = std.ArrayList(u8).init(gpa);
41254261 defer debug_bytes.deinit();
41264262
41274263 const DebugSection = struct {
......@@ -4299,6 +4435,8 @@ fn emitFeaturesSection(binary_bytes: *std.ArrayList(u8), enabled_features: []con
42994435}
43004436
43014437fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem.Allocator) !void {
4438 const comp = wasm.base.comp;
4439 const import_memory = comp.config.import_memory;
43024440 const Name = struct {
43034441 index: u32,
43044442 name: []const u8,
......@@ -4337,7 +4475,7 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem
43374475 for (wasm.data_segments.keys()) |key| {
43384476 // bss section is not emitted when this condition holds true, so we also
43394477 // do not output a name for it.
4340 if (!wasm.base.options.import_memory and std.mem.eql(u8, key, ".bss")) continue;
4478 if (!import_memory and std.mem.eql(u8, key, ".bss")) continue;
43414479 segments.appendAssumeCapacity(.{ .index = data_segment_index, .name = key });
43424480 data_segment_index += 1;
43434481 }
......@@ -4362,8 +4500,10 @@ fn emitNameSection(wasm: *Wasm, binary_bytes: *std.ArrayList(u8), arena: std.mem
43624500}
43634501
43644502fn emitNameSubsection(wasm: *Wasm, section_id: std.wasm.NameSubsection, names: anytype, writer: anytype) !void {
4503 const gpa = wasm.base.comp.gpa;
4504
43654505 // We must emit subsection size, so first write to a temporary list
4366 var section_list = std.ArrayList(u8).init(wasm.base.allocator);
4506 var section_list = std.ArrayList(u8).init(gpa);
43674507 defer section_list.deinit();
43684508 const sub_writer = section_list.writer();
43694509
......@@ -4441,26 +4581,30 @@ fn emitImport(wasm: *Wasm, writer: anytype, import: types.Import) !void {
44414581 }
44424582}
44434583
4444fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !void {
4584fn linkWithLLD(wasm: *Wasm, arena: Allocator, prog_node: *std.Progress.Node) !void {
44454585 const tracy = trace(@src());
44464586 defer tracy.end();
44474587
4448 var arena_allocator = std.heap.ArenaAllocator.init(wasm.base.allocator);
4449 defer arena_allocator.deinit();
4450 const arena = arena_allocator.allocator();
4588 const comp = wasm.base.comp;
4589 const shared_memory = comp.config.shared_memory;
4590 const export_memory = comp.config.export_memory;
4591 const import_memory = comp.config.import_memory;
4592 const target = comp.root_mod.resolved_target.result;
44514593
4452 const directory = wasm.base.options.emit.?.directory; // Just an alias to make it shorter to type.
4453 const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.options.emit.?.sub_path});
4594 const gpa = comp.gpa;
4595
4596 const directory = wasm.base.emit.directory; // Just an alias to make it shorter to type.
4597 const full_out_path = try directory.join(arena, &[_][]const u8{wasm.base.emit.sub_path});
44544598
44554599 // If there is no Zig code to compile, then we should skip flushing the output file because it
44564600 // will not be part of the linker line anyway.
4457 const module_obj_path: ?[]const u8 = if (wasm.base.options.module != null) blk: {
4458 try wasm.flushModule(comp, prog_node);
4601 const module_obj_path: ?[]const u8 = if (comp.module != null) blk: {
4602 try wasm.flushModule(arena, prog_node);
44594603
44604604 if (fs.path.dirname(full_out_path)) |dirname| {
4461 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.intermediary_basename.? });
4605 break :blk try fs.path.join(arena, &.{ dirname, wasm.base.zcu_object_sub_path.? });
44624606 } else {
4463 break :blk wasm.base.intermediary_basename.?;
4607 break :blk wasm.base.zcu_object_sub_path.?;
44644608 }
44654609 } else null;
44664610
......@@ -4469,23 +4613,21 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
44694613 sub_prog_node.context.refresh();
44704614 defer sub_prog_node.end();
44714615
4472 const is_obj = wasm.base.options.output_mode == .Obj;
4616 const is_obj = comp.config.output_mode == .Obj;
44734617 const compiler_rt_path: ?[]const u8 = blk: {
44744618 if (comp.compiler_rt_lib) |lib| break :blk lib.full_object_path;
44754619 if (comp.compiler_rt_obj) |obj| break :blk obj.full_object_path;
44764620 break :blk null;
44774621 };
44784622
4479 const target = wasm.base.options.target;
4480
44814623 const id_symlink_basename = "lld.id";
44824624
44834625 var man: Cache.Manifest = undefined;
4484 defer if (!wasm.base.options.disable_lld_caching) man.deinit();
4626 defer if (!wasm.base.disable_lld_caching) man.deinit();
44854627
44864628 var digest: [Cache.hex_digest_len]u8 = undefined;
44874629
4488 if (!wasm.base.options.disable_lld_caching) {
4630 if (!wasm.base.disable_lld_caching) {
44894631 man = comp.cache_parent.obtain();
44904632
44914633 // We are about to obtain this lock, so here we give other processes a chance first.
......@@ -4493,7 +4635,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
44934635
44944636 comptime assert(Compilation.link_hash_implementation_version == 10);
44954637
4496 for (wasm.base.options.objects) |obj| {
4638 for (comp.objects) |obj| {
44974639 _ = try man.addFile(obj.path, null);
44984640 man.hash.add(obj.must_link);
44994641 }
......@@ -4502,20 +4644,20 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
45024644 }
45034645 try man.addOptionalFile(module_obj_path);
45044646 try man.addOptionalFile(compiler_rt_path);
4505 man.hash.addOptionalBytes(wasm.base.options.entry);
4506 man.hash.addOptional(wasm.base.options.stack_size_override);
4507 man.hash.add(wasm.base.options.build_id);
4508 man.hash.add(wasm.base.options.import_memory);
4509 man.hash.add(wasm.base.options.export_memory);
4510 man.hash.add(wasm.base.options.import_table);
4511 man.hash.add(wasm.base.options.export_table);
4512 man.hash.addOptional(wasm.base.options.initial_memory);
4513 man.hash.addOptional(wasm.base.options.max_memory);
4514 man.hash.add(wasm.base.options.shared_memory);
4515 man.hash.addOptional(wasm.base.options.global_base);
4516 man.hash.add(wasm.base.options.export_symbol_names.len);
4647 man.hash.addOptionalBytes(wasm.entry_name);
4648 man.hash.add(wasm.base.stack_size);
4649 man.hash.add(wasm.base.build_id);
4650 man.hash.add(import_memory);
4651 man.hash.add(export_memory);
4652 man.hash.add(wasm.import_table);
4653 man.hash.add(wasm.export_table);
4654 man.hash.addOptional(wasm.initial_memory);
4655 man.hash.addOptional(wasm.max_memory);
4656 man.hash.add(shared_memory);
4657 man.hash.addOptional(wasm.global_base);
4658 man.hash.add(wasm.export_symbol_names.len);
45174659 // strip does not need to go into the linker hash because it is part of the hash namespace
4518 for (wasm.base.options.export_symbol_names) |symbol_name| {
4660 for (wasm.export_symbol_names) |symbol_name| {
45194661 man.hash.addBytes(symbol_name);
45204662 }
45214663
......@@ -4553,8 +4695,8 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
45534695 // here. TODO: think carefully about how we can avoid this redundant operation when doing
45544696 // build-obj. See also the corresponding TODO in linkAsArchive.
45554697 const the_object_path = blk: {
4556 if (wasm.base.options.objects.len != 0)
4557 break :blk wasm.base.options.objects[0].path;
4698 if (comp.objects.len != 0)
4699 break :blk comp.objects[0].path;
45584700
45594701 if (comp.c_object_table.count() != 0)
45604702 break :blk comp.c_object_table.keys()[0].status.success.object_path;
......@@ -4573,7 +4715,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
45734715 }
45744716 } else {
45754717 // Create an LLD command line and invoke it.
4576 var argv = std.ArrayList([]const u8).init(wasm.base.allocator);
4718 var argv = std.ArrayList([]const u8).init(gpa);
45774719 defer argv.deinit();
45784720 // We will invoke ourselves as a child process to gain access to LLD.
45794721 // This is necessary because LLD does not behave properly as a library -
......@@ -4582,59 +4724,57 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
45824724 try argv.appendSlice(&[_][]const u8{ comp.self_exe_path.?, linker_command });
45834725 try argv.append("--error-limit=0");
45844726
4585 if (wasm.base.options.lto) {
4586 switch (wasm.base.options.optimize_mode) {
4727 if (comp.config.lto) {
4728 switch (comp.root_mod.optimize_mode) {
45874729 .Debug => {},
45884730 .ReleaseSmall => try argv.append("-O2"),
45894731 .ReleaseFast, .ReleaseSafe => try argv.append("-O3"),
45904732 }
45914733 }
45924734
4593 if (wasm.base.options.import_memory) {
4735 if (import_memory) {
45944736 try argv.append("--import-memory");
45954737 }
45964738
4597 if (wasm.base.options.export_memory) {
4739 if (export_memory) {
45984740 try argv.append("--export-memory");
45994741 }
46004742
4601 if (wasm.base.options.import_table) {
4602 assert(!wasm.base.options.export_table);
4743 if (wasm.import_table) {
4744 assert(!wasm.export_table);
46034745 try argv.append("--import-table");
46044746 }
46054747
4606 if (wasm.base.options.export_table) {
4607 assert(!wasm.base.options.import_table);
4748 if (wasm.export_table) {
4749 assert(!wasm.import_table);
46084750 try argv.append("--export-table");
46094751 }
46104752
4611 if (wasm.base.options.gc_sections) |gc| {
4612 // For wasm-ld we only need to specify '--no-gc-sections' when the user explicitly
4613 // specified it as garbage collection is enabled by default.
4614 if (!gc) {
4615 try argv.append("--no-gc-sections");
4616 }
4753 // For wasm-ld we only need to specify '--no-gc-sections' when the user explicitly
4754 // specified it as garbage collection is enabled by default.
4755 if (!wasm.base.gc_sections) {
4756 try argv.append("--no-gc-sections");
46174757 }
46184758
4619 if (wasm.base.options.strip) {
4759 if (comp.config.debug_format == .strip) {
46204760 try argv.append("-s");
46214761 }
46224762
4623 if (wasm.base.options.initial_memory) |initial_memory| {
4763 if (wasm.initial_memory) |initial_memory| {
46244764 const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory});
46254765 try argv.append(arg);
46264766 }
46274767
4628 if (wasm.base.options.max_memory) |max_memory| {
4768 if (wasm.max_memory) |max_memory| {
46294769 const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory});
46304770 try argv.append(arg);
46314771 }
46324772
4633 if (wasm.base.options.shared_memory) {
4773 if (shared_memory) {
46344774 try argv.append("--shared-memory");
46354775 }
46364776
4637 if (wasm.base.options.global_base) |global_base| {
4777 if (wasm.global_base) |global_base| {
46384778 const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});
46394779 try argv.append(arg);
46404780 } else {
......@@ -4646,42 +4786,39 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
46464786 }
46474787
46484788 // Users are allowed to specify which symbols they want to export to the wasm host.
4649 for (wasm.base.options.export_symbol_names) |symbol_name| {
4789 for (wasm.export_symbol_names) |symbol_name| {
46504790 const arg = try std.fmt.allocPrint(arena, "--export={s}", .{symbol_name});
46514791 try argv.append(arg);
46524792 }
46534793
4654 if (wasm.base.options.rdynamic) {
4794 if (comp.config.rdynamic) {
46554795 try argv.append("--export-dynamic");
46564796 }
46574797
4658 if (wasm.base.options.entry) |entry| {
4659 try argv.append("--entry");
4660 try argv.append(entry);
4798 if (wasm.entry_name) |entry_name| {
4799 try argv.appendSlice(&.{ "--entry", entry_name });
46614800 } else {
46624801 try argv.append("--no-entry");
46634802 }
46644803
4665 // Increase the default stack size to a more reasonable value of 1MB instead of
4666 // the default of 1 Wasm page being 64KB, unless overridden by the user.
4667 try argv.append("-z");
4668 const stack_size = wasm.base.options.stack_size_override orelse std.wasm.page_size * 16;
4669 const arg = try std.fmt.allocPrint(arena, "stack-size={d}", .{stack_size});
4670 try argv.append(arg);
4804 try argv.appendSlice(&.{
4805 "-z",
4806 try std.fmt.allocPrint(arena, "stack-size={d}", .{wasm.base.stack_size}),
4807 });
46714808
4672 if (wasm.base.options.import_symbols) {
4809 if (wasm.import_symbols) {
46734810 try argv.append("--allow-undefined");
46744811 }
46754812
4676 if (wasm.base.options.output_mode == .Lib and wasm.base.options.link_mode == .Dynamic) {
4813 if (comp.config.output_mode == .Lib and comp.config.link_mode == .Dynamic) {
46774814 try argv.append("--shared");
46784815 }
4679 if (wasm.base.options.pie) {
4816 if (comp.config.pie) {
46804817 try argv.append("--pie");
46814818 }
46824819
46834820 // XXX - TODO: add when wasm-ld supports --build-id.
4684 // if (wasm.base.options.build_id) {
4821 // if (wasm.base.build_id) {
46854822 // try argv.append("--build-id=tree");
46864823 // }
46874824
......@@ -4692,26 +4829,25 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
46924829 }
46934830
46944831 if (target.os.tag == .wasi) {
4695 const is_exe_or_dyn_lib = wasm.base.options.output_mode == .Exe or
4696 (wasm.base.options.output_mode == .Lib and wasm.base.options.link_mode == .Dynamic);
4832 const is_exe_or_dyn_lib = comp.config.output_mode == .Exe or
4833 (comp.config.output_mode == .Lib and comp.config.link_mode == .Dynamic);
46974834 if (is_exe_or_dyn_lib) {
4698 const wasi_emulated_libs = wasm.base.options.wasi_emulated_libs;
4699 for (wasi_emulated_libs) |crt_file| {
4835 for (comp.wasi_emulated_libs) |crt_file| {
47004836 try argv.append(try comp.get_libc_crt_file(
47014837 arena,
47024838 wasi_libc.emulatedLibCRFileLibName(crt_file),
47034839 ));
47044840 }
47054841
4706 if (wasm.base.options.link_libc) {
4842 if (comp.config.link_libc) {
47074843 try argv.append(try comp.get_libc_crt_file(
47084844 arena,
4709 wasi_libc.execModelCrtFileFullName(wasm.base.options.wasi_exec_model),
4845 wasi_libc.execModelCrtFileFullName(comp.config.wasi_exec_model),
47104846 ));
47114847 try argv.append(try comp.get_libc_crt_file(arena, "libc.a"));
47124848 }
47134849
4714 if (wasm.base.options.link_libcpp) {
4850 if (comp.config.link_libcpp) {
47154851 try argv.append(comp.libcxx_static_lib.?.full_object_path);
47164852 try argv.append(comp.libcxxabi_static_lib.?.full_object_path);
47174853 }
......@@ -4720,7 +4856,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
47204856
47214857 // Positional arguments to the linker such as object files.
47224858 var whole_archive = false;
4723 for (wasm.base.options.objects) |obj| {
4859 for (comp.objects) |obj| {
47244860 if (obj.must_link and !whole_archive) {
47254861 try argv.append("-whole-archive");
47264862 whole_archive = true;
......@@ -4742,9 +4878,9 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
47424878 try argv.append(p);
47434879 }
47444880
4745 if (wasm.base.options.output_mode != .Obj and
4746 !wasm.base.options.skip_linker_dependencies and
4747 !wasm.base.options.link_libc)
4881 if (comp.config.output_mode != .Obj and
4882 !comp.skip_linker_dependencies and
4883 !comp.config.link_libc)
47484884 {
47494885 try argv.append(comp.libc_static_lib.?.full_object_path);
47504886 }
......@@ -4753,7 +4889,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
47534889 try argv.append(p);
47544890 }
47554891
4756 if (wasm.base.options.verbose_link) {
4892 if (comp.verbose_link) {
47574893 // Skip over our own name so that the LLD linker name is the first argv item.
47584894 Compilation.dump_argv(argv.items[1..]);
47594895 }
......@@ -4828,7 +4964,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
48284964 // it, and then can react to that in the same way as trying to run an ELF file
48294965 // from a foreign CPU architecture.
48304966 if (fs.has_executable_bit and target.os.tag == .wasi and
4831 wasm.base.options.output_mode == .Exe)
4967 comp.config.output_mode == .Exe)
48324968 {
48334969 // TODO: what's our strategy for reporting linker errors from this function?
48344970 // report a nice error here with the file path if it fails instead of
......@@ -4838,7 +4974,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
48384974 }
48394975 }
48404976
4841 if (!wasm.base.options.disable_lld_caching) {
4977 if (!wasm.base.disable_lld_caching) {
48424978 // Update the file with the digest. If it fails we can continue; it only
48434979 // means that the next invocation will have an unnecessary cache miss.
48444980 Cache.writeSmallFile(directory.handle, id_symlink_basename, &digest) catch |err| {
......@@ -5089,10 +5225,13 @@ fn emitDataRelocations(
50895225}
50905226
50915227fn hasPassiveInitializationSegments(wasm: *const Wasm) bool {
5228 const comp = wasm.base.comp;
5229 const import_memory = comp.config.import_memory;
5230
50925231 var it = wasm.data_segments.iterator();
50935232 while (it.next()) |entry| {
50945233 const segment: Segment = wasm.segments.items[entry.value_ptr.*];
5095 if (segment.needsPassiveInitialization(wasm.base.options.import_memory, entry.key_ptr.*)) {
5234 if (segment.needsPassiveInitialization(import_memory, entry.key_ptr.*)) {
50965235 return true;
50975236 }
50985237 }
......@@ -5113,14 +5252,15 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
51135252 if (wasm.getTypeIndex(func_type)) |index| {
51145253 return index;
51155254 }
5255 const gpa = wasm.base.comp.gpa;
51165256
51175257 // functype does not exist.
5118 const index = @as(u32, @intCast(wasm.func_types.items.len));
5119 const params = try wasm.base.allocator.dupe(std.wasm.Valtype, func_type.params);
5120 errdefer wasm.base.allocator.free(params);
5121 const returns = try wasm.base.allocator.dupe(std.wasm.Valtype, func_type.returns);
5122 errdefer wasm.base.allocator.free(returns);
5123 try wasm.func_types.append(wasm.base.allocator, .{
5258 const index: u32 = @intCast(wasm.func_types.items.len);
5259 const params = try gpa.dupe(std.wasm.Valtype, func_type.params);
5260 errdefer gpa.free(params);
5261 const returns = try gpa.dupe(std.wasm.Valtype, func_type.returns);
5262 errdefer gpa.free(returns);
5263 try wasm.func_types.append(gpa, .{
51245264 .params = params,
51255265 .returns = returns,
51265266 });
......@@ -5131,9 +5271,10 @@ pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 {
51315271/// Asserts declaration has an associated `Atom`.
51325272/// Returns the index into the list of types.
51335273pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: std.wasm.Type) !u32 {
5274 const gpa = wasm.base.comp.gpa;
51345275 const atom_index = wasm.decls.get(decl_index).?;
51355276 const index = try wasm.putOrGetFuncType(func_type);
5136 try wasm.atom_types.put(wasm.base.allocator, atom_index, index);
5277 try wasm.atom_types.put(gpa, atom_index, index);
51375278 return index;
51385279}
51395280
......@@ -5142,19 +5283,20 @@ pub fn storeDeclType(wasm: *Wasm, decl_index: InternPool.DeclIndex, func_type: s
51425283fn markReferences(wasm: *Wasm) !void {
51435284 const tracy = trace(@src());
51445285 defer tracy.end();
5145 const do_garbage_collect = wasm.base.options.gc_sections orelse
5146 (wasm.base.options.output_mode != .Obj);
5286
5287 const do_garbage_collect = wasm.base.gc_sections;
5288 const comp = wasm.base.comp;
51475289
51485290 for (wasm.resolved_symbols.keys()) |sym_loc| {
51495291 const sym = sym_loc.getSymbol(wasm);
5150 if (sym.isExported(wasm.base.options.rdynamic) or sym.isNoStrip() or !do_garbage_collect) {
5292 if (sym.isExported(comp.config.rdynamic) or sym.isNoStrip() or !do_garbage_collect) {
51515293 try wasm.mark(sym_loc);
51525294 continue;
51535295 }
51545296
51555297 // Debug sections may require to be parsed and marked when it contains
51565298 // relocations to alive symbols.
5157 if (sym.tag == .section and !wasm.base.options.strip) {
5299 if (sym.tag == .section and comp.config.debug_format != .strip) {
51585300 const file = sym_loc.file orelse continue; // Incremental debug info is done independently
51595301 const object = &wasm.objects.items[file];
51605302 const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm);
......@@ -5200,3 +5342,10 @@ fn mark(wasm: *Wasm, loc: SymbolLoc) !void {
52005342 try wasm.mark(target_loc.finalLoc(wasm));
52015343 }
52025344}
5345
5346fn defaultEntrySymbolName(wasi_exec_model: std.builtin.WasiExecModel) []const u8 {
5347 return switch (wasi_exec_model) {
5348 .reactor => "_initialize",
5349 .command => "_start",
5350 };
5351}
src/link/Wasm/Object.zig+6-4
......@@ -883,6 +883,8 @@ fn assertEnd(reader: anytype) !void {
883883
884884/// Parses an object file into atoms, for code and data sections
885885pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32, wasm: *Wasm) !Atom.Index {
886 const comp = wasm.base.comp;
887 const gpa = comp.gpa;
886888 const symbol = &object.symtable[symbol_index];
887889 const relocatable_data: RelocatableData = switch (symbol.tag) {
888890 .function => object.relocatable_data.get(.code).?[symbol.index - object.importedCountByKind(.function)],
......@@ -900,7 +902,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
900902 };
901903 const final_index = try wasm.getMatchingSegment(object_index, symbol_index);
902904 const atom_index = @as(Atom.Index, @intCast(wasm.managed_atoms.items.len));
903 const atom = try wasm.managed_atoms.addOne(wasm.base.allocator);
905 const atom = try wasm.managed_atoms.addOne(gpa);
904906 atom.* = Atom.empty;
905907 try wasm.appendAtomAtIndex(final_index, atom_index);
906908
......@@ -910,7 +912,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
910912 atom.alignment = relocatable_data.getAlignment(object);
911913 atom.code = std.ArrayListUnmanaged(u8).fromOwnedSlice(relocatable_data.data[0..relocatable_data.size]);
912914 atom.original_offset = relocatable_data.offset;
913 try wasm.symbol_atom.putNoClobber(wasm.base.allocator, atom.symbolLoc(), atom_index);
915 try wasm.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom_index);
914916 const segment: *Wasm.Segment = &wasm.segments.items[final_index];
915917 if (relocatable_data.type == .data) { //code section and custom sections are 1-byte aligned
916918 segment.alignment = segment.alignment.max(atom.alignment);
......@@ -927,7 +929,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
927929 .R_WASM_TABLE_INDEX_SLEB,
928930 .R_WASM_TABLE_INDEX_SLEB64,
929931 => {
930 try wasm.function_table.put(wasm.base.allocator, .{
932 try wasm.function_table.put(gpa, .{
931933 .file = object_index,
932934 .index = reloc.index,
933935 }, 0);
......@@ -938,7 +940,7 @@ pub fn parseSymbolIntoAtom(object: *Object, object_index: u16, symbol_index: u32
938940 const sym = object.symtable[reloc.index];
939941 if (sym.tag != .global) {
940942 try wasm.got_symbols.append(
941 wasm.base.allocator,
943 gpa,
942944 .{ .file = object_index, .index = reloc.index },
943945 );
944946 }
src/main.zig+1582-1315
......@@ -21,7 +21,6 @@ const introspect = @import("introspect.zig");
2121const EnvVar = introspect.EnvVar;
2222const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
2323const wasi_libc = @import("wasi_libc.zig");
24const BuildId = std.Build.CompileStep.BuildId;
2524const Cache = std.Build.Cache;
2625const target_util = @import("target.zig");
2726const crash_report = @import("crash_report.zig");
......@@ -88,13 +87,15 @@ const normal_usage =
8887 \\ fetch Copy a package into global cache and print its hash
8988 \\ init Initialize a Zig package in the current directory
9089 \\
91 \\ ast-check Look for simple compile errors in any set of files
9290 \\ build-exe Create executable from source or object files
9391 \\ build-lib Create library from source or object files
9492 \\ build-obj Create object from source or object files
95 \\ fmt Reformat Zig source into canonical form
93 \\ test Perform unit testing
9694 \\ run Create executable and run immediately
97 \\ test Create and run a test build
95 \\
96 \\ ast-check Look for simple compile errors in any set of files
97 \\ fmt Reformat Zig source into canonical form
98 \\ reduce Minimize a bug report
9899 \\ translate-c Convert C code to Zig code
99100 \\
100101 \\ ar Use Zig as a drop-in archiver
......@@ -270,8 +271,6 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
270271 }
271272 }
272273
273 defer log_scopes.deinit(gpa);
274
275274 const cmd = args[1];
276275 const cmd_args = args[2..];
277276 if (mem.eql(u8, cmd, "build-exe")) {
......@@ -322,13 +321,14 @@ pub fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
322321 } else if (mem.eql(u8, cmd, "init")) {
323322 return cmdInit(gpa, arena, cmd_args);
324323 } else if (mem.eql(u8, cmd, "targets")) {
325 const info = try detectNativeTargetInfo(.{});
324 const host = resolveTargetQueryOrFatal(.{});
326325 const stdout = io.getStdOut().writer();
327 return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, info.target);
326 return @import("print_targets.zig").cmdTargets(arena, cmd_args, stdout, host);
328327 } else if (mem.eql(u8, cmd, "version")) {
329328 try std.io.getStdOut().writeAll(build_options.version ++ "\n");
330 // Check libc++ linkage to make sure Zig was built correctly, but only for "env" and "version"
331 // to avoid affecting the startup time for build-critical commands (check takes about ~10 μs)
329 // Check libc++ linkage to make sure Zig was built correctly, but only
330 // for "env" and "version" to avoid affecting the startup time for
331 // build-critical commands (check takes about ~10 μs)
332332 return verifyLibcxxCorrectlyLinked();
333333 } else if (mem.eql(u8, cmd, "env")) {
334334 verifyLibcxxCorrectlyLinked();
......@@ -404,37 +404,69 @@ const usage_build_generic =
404404 \\ --global-cache-dir [path] Override the global cache directory
405405 \\ --zig-lib-dir [path] Override path to Zig installation lib directory
406406 \\
407 \\Compile Options:
407 \\Global Compile Options:
408 \\ --name [name] Compilation unit name (not a file path)
409 \\ --libc [file] Provide a file which specifies libc paths
410 \\ -x language Treat subsequent input files as having type <language>
411 \\ --dep [[import=]name] Add an entry to the next module's import table
412 \\ --mod [name] [src] Create a module based on the current per-module settings.
413 \\ The first module is the main module.
414 \\ "std" can be configured by leaving src blank.
415 \\ After a --mod argument, per-module settings are reset.
416 \\ --error-limit [num] Set the maximum amount of distinct error values
417 \\ -fllvm Force using LLVM as the codegen backend
418 \\ -fno-llvm Prevent using LLVM as the codegen backend
419 \\ -flibllvm Force using the LLVM API in the codegen backend
420 \\ -fno-libllvm Prevent using the LLVM API in the codegen backend
421 \\ -fclang Force using Clang as the C/C++ compilation backend
422 \\ -fno-clang Prevent using Clang as the C/C++ compilation backend
423 \\ -fPIE Force-enable Position Independent Executable
424 \\ -fno-PIE Force-disable Position Independent Executable
425 \\ -flto Force-enable Link Time Optimization (requires LLVM extensions)
426 \\ -fno-lto Force-disable Link Time Optimization
427 \\ -fdll-export-fns Mark exported functions as DLL exports (Windows)
428 \\ -fno-dll-export-fns Force-disable marking exported functions as DLL exports
429 \\ -freference-trace[=num] Show num lines of reference trace per compile error
430 \\ -fno-reference-trace Disable reference trace
431 \\ -fbuiltin Enable implicit builtin knowledge of functions
432 \\ -fno-builtin Disable implicit builtin knowledge of functions
433 \\ -ffunction-sections Places each function in a separate section
434 \\ -fno-function-sections All functions go into same section
435 \\ -fdata-sections Places each data in a separate section
436 \\ -fno-data-sections All data go into same section
437 \\ -fformatted-panics Enable formatted safety panics
438 \\ -fno-formatted-panics Disable formatted safety panics
439 \\ -fstructured-cfg (SPIR-V) force SPIR-V kernels to use structured control flow
440 \\ -fno-structured-cfg (SPIR-V) force SPIR-V kernels to not use structured control flow
441 \\ -mexec-model=[value] (WASI) Execution model
442 \\
443 \\Per-Module Compile Options:
408444 \\ -target [name] <arch><sub>-<os>-<abi> see the targets command
445 \\ -O [mode] Choose what to optimize for
446 \\ Debug (default) Optimizations off, safety on
447 \\ ReleaseFast Optimize for performance, safety off
448 \\ ReleaseSafe Optimize for performance, safety on
449 \\ ReleaseSmall Optimize for small binary, safety off
450 \\ -ofmt=[fmt] Override target object format
451 \\ elf Executable and Linking Format
452 \\ c C source code
453 \\ wasm WebAssembly
454 \\ coff Common Object File Format (Windows)
455 \\ macho macOS relocatables
456 \\ spirv Standard, Portable Intermediate Representation V (SPIR-V)
457 \\ plan9 Plan 9 from Bell Labs object format
458 \\ hex (planned feature) Intel IHEX
459 \\ raw (planned feature) Dump machine code directly
409460 \\ -mcpu [cpu] Specify target CPU and feature set
410461 \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses
411462 \\ small|kernel|
412463 \\ medium|large]
413 \\ -x language Treat subsequent input files as having type <language>
414464 \\ -mred-zone Force-enable the "red-zone"
415465 \\ -mno-red-zone Force-disable the "red-zone"
416466 \\ -fomit-frame-pointer Omit the stack frame pointer
417467 \\ -fno-omit-frame-pointer Store the stack frame pointer
418 \\ -mexec-model=[value] (WASI) Execution model
419 \\ --name [name] Override root name (not a file path)
420 \\ -O [mode] Choose what to optimize for
421 \\ Debug (default) Optimizations off, safety on
422 \\ ReleaseFast Optimize for performance, safety off
423 \\ ReleaseSafe Optimize for performance, safety on
424 \\ ReleaseSmall Optimize for small binary, safety off
425 \\ --mod [name]:[deps]:[src] Make a module available for dependency under the given name
426 \\ deps: [dep],[dep],...
427 \\ dep: [[import=]name]
428 \\ --deps [dep],[dep],... Set dependency names for the root package
429 \\ dep: [[import=]name]
430 \\ --main-mod-path Set the directory of the root module
431 \\ --error-limit [num] Set the maximum amount of distinct error values
432468 \\ -fPIC Force-enable Position Independent Code
433469 \\ -fno-PIC Force-disable Position Independent Code
434 \\ -fPIE Force-enable Position Independent Executable
435 \\ -fno-PIE Force-disable Position Independent Executable
436 \\ -flto Force-enable Link Time Optimization (requires LLVM extensions)
437 \\ -fno-lto Force-disable Link Time Optimization
438470 \\ -fstack-check Enable stack probing in unsafe builds
439471 \\ -fno-stack-check Disable stack probing in safe builds
440472 \\ -fstack-protector Enable stack protection in unsafe builds
......@@ -445,47 +477,18 @@ const usage_build_generic =
445477 \\ -fno-valgrind Omit valgrind client requests in debug builds
446478 \\ -fsanitize-thread Enable Thread Sanitizer
447479 \\ -fno-sanitize-thread Disable Thread Sanitizer
448 \\ -fdll-export-fns Mark exported functions as DLL exports (Windows)
449 \\ -fno-dll-export-fns Force-disable marking exported functions as DLL exports
450480 \\ -funwind-tables Always produce unwind table entries for all functions
451481 \\ -fno-unwind-tables Never produce unwind table entries
452 \\ -fllvm Force using LLVM as the codegen backend
453 \\ -fno-llvm Prevent using LLVM as the codegen backend
454 \\ -flibllvm Force using the LLVM API in the codegen backend
455 \\ -fno-libllvm Prevent using the LLVM API in the codegen backend
456 \\ -fclang Force using Clang as the C/C++ compilation backend
457 \\ -fno-clang Prevent using Clang as the C/C++ compilation backend
458 \\ -freference-trace[=num] How many lines of reference trace should be shown per compile error
459 \\ -fno-reference-trace Disable reference trace
460482 \\ -ferror-tracing Enable error tracing in ReleaseFast mode
461483 \\ -fno-error-tracing Disable error tracing in Debug and ReleaseSafe mode
462484 \\ -fsingle-threaded Code assumes there is only one thread
463485 \\ -fno-single-threaded Code may not assume there is only one thread
464 \\ -fbuiltin Enable implicit builtin knowledge of functions
465 \\ -fno-builtin Disable implicit builtin knowledge of functions
466 \\ -ffunction-sections Places each function in a separate section
467 \\ -fno-function-sections All functions go into same section
468 \\ -fdata-sections Places each data in a separate section
469 \\ -fno-data-sections All data go into same section
470486 \\ -fstrip Omit debug symbols
471487 \\ -fno-strip Keep debug symbols
472 \\ -fformatted-panics Enable formatted safety panics
473 \\ -fno-formatted-panics Disable formatted safety panics
474 \\ -ofmt=[mode] Override target object format
475 \\ elf Executable and Linking Format
476 \\ c C source code
477 \\ wasm WebAssembly
478 \\ coff Common Object File Format (Windows)
479 \\ macho macOS relocatables
480 \\ spirv Standard, Portable Intermediate Representation V (SPIR-V)
481 \\ plan9 Plan 9 from Bell Labs object format
482 \\ hex (planned feature) Intel IHEX
483 \\ raw (planned feature) Dump machine code directly
484488 \\ -idirafter [dir] Add directory to AFTER include search path
485489 \\ -isystem [dir] Add directory to SYSTEM include search path
486490 \\ -I[dir] Add directory to include search path
487491 \\ -D[macro]=[value] Define C [macro] to [value] (1 if [value] omitted)
488 \\ --libc [file] Provide a file which specifies libc paths
489492 \\ -cflags [flags] -- Set extra flags for the next positional C source files
490493 \\ -rcflags [flags] -- Set extra flags for the next positional .rc source files
491494 \\ -rcincludes=[type] Set the type of includes to use when compiling .rc source files
......@@ -493,26 +496,8 @@ const usage_build_generic =
493496 \\ msvc Use msvc include paths (must be present on the system)
494497 \\ gnu Use mingw include paths (distributed with Zig)
495498 \\ none Do not use any autodetected include paths
496 \\ -fstructured-cfg (SPIR-V) force SPIR-V kernels to use structured control flow
497 \\ -fno-structured-cfg (SPIR-V) force SPIR-V kernels to not use structured control flow
498499 \\
499 \\Link Options:
500 \\ -l[lib], --library [lib] Link against system library (only if actually used)
501 \\ -needed-l[lib], Link against system library (even if unused)
502 \\ --needed-library [lib]
503 \\ -weak-l[lib] link against system library marking it and all
504 \\ -weak_library [lib] referenced symbols as weak
505 \\ -L[d], --library-directory [d] Add a directory to the library search path
506 \\ -search_paths_first For each library search path, check for dynamic
507 \\ lib then static lib before proceeding to next path.
508 \\ -search_paths_first_static For each library search path, check for static
509 \\ lib then dynamic lib before proceeding to next path.
510 \\ -search_dylibs_first Search for dynamic libs in all library search
511 \\ paths, then static libs.
512 \\ -search_static_first Search for static libs in all library search
513 \\ paths, then dynamic libs.
514 \\ -search_dylibs_only Only search for dynamic libs.
515 \\ -search_static_only Only search for static libs.
500 \\Global Link Options:
516501 \\ -T[script], --script [script] Use a custom linker script
517502 \\ --version-script [path] Provide a version .map file
518503 \\ --dynamic-linker [path] Set the dynamic interpreter path (usually ld.so)
......@@ -529,7 +514,6 @@ const usage_build_generic =
529514 \\ -fcompiler-rt Always include compiler-rt symbols in output
530515 \\ -fno-compiler-rt Prevent including compiler-rt symbols in output
531516 \\ -rdynamic Add all symbols to the dynamic symbol table
532 \\ -rpath [path] Add directory to the runtime library search path
533517 \\ -feach-lib-rpath Ensure adding rpath for each used dynamic library
534518 \\ -fno-each-lib-rpath Prevent adding rpath for each used dynamic library
535519 \\ -fallow-shlib-undefined Allows undefined symbols in shared libraries
......@@ -566,11 +550,6 @@ const usage_build_generic =
566550 \\ --subsystem [subsystem] (Windows) /SUBSYSTEM:<subsystem> to the linker
567551 \\ --stack [size] Override default stack size
568552 \\ --image-base [addr] Set base address for executable image
569 \\ -framework [name] (Darwin) link against framework
570 \\ -needed_framework [name] (Darwin) link against framework (even if unused)
571 \\ -needed_library [lib] link against system library (even if unused)
572 \\ -weak_framework [name] (Darwin) link against framework and mark it and all referenced symbols as weak
573 \\ -F[dir] (Darwin) add search path for frameworks
574553 \\ -install_name=[value] (Darwin) add dylib's install name
575554 \\ --entitlements [path] (Darwin) add path to entitlements file for embedding in code signature
576555 \\ -pagezero_size [value] (Darwin) size of the __PAGEZERO segment in hexadecimal notation
......@@ -587,6 +566,30 @@ const usage_build_generic =
587566 \\ --max-memory=[bytes] (WebAssembly) maximum size of the linear memory
588567 \\ --shared-memory (WebAssembly) use shared linear memory
589568 \\ --global-base=[addr] (WebAssembly) where to start to place global data
569 \\
570 \\Per-Module Link Options:
571 \\ -l[lib], --library [lib] Link against system library (only if actually used)
572 \\ -needed-l[lib], Link against system library (even if unused)
573 \\ --needed-library [lib]
574 \\ -weak-l[lib] link against system library marking it and all
575 \\ -weak_library [lib] referenced symbols as weak
576 \\ -L[d], --library-directory [d] Add a directory to the library search path
577 \\ -search_paths_first For each library search path, check for dynamic
578 \\ lib then static lib before proceeding to next path.
579 \\ -search_paths_first_static For each library search path, check for static
580 \\ lib then dynamic lib before proceeding to next path.
581 \\ -search_dylibs_first Search for dynamic libs in all library search
582 \\ paths, then static libs.
583 \\ -search_static_first Search for static libs in all library search
584 \\ paths, then dynamic libs.
585 \\ -search_dylibs_only Only search for dynamic libs.
586 \\ -search_static_only Only search for static libs.
587 \\ -rpath [path] Add directory to the runtime library search path
588 \\ -framework [name] (Darwin) link against framework
589 \\ -needed_framework [name] (Darwin) link against framework (even if unused)
590 \\ -needed_library [lib] link against system library (even if unused)
591 \\ -weak_framework [name] (Darwin) link against framework and mark it and all referenced symbols as weak
592 \\ -F[dir] (Darwin) add search path for frameworks
590593 \\ --export=[value] (WebAssembly) Force a symbol to be exported
591594 \\
592595 \\Test Options:
......@@ -758,9 +761,24 @@ const Framework = struct {
758761};
759762
760763const CliModule = struct {
761 mod: *Package.Module,
762 /// still in CLI arg format
763 deps_str: []const u8,
764 paths: Package.Module.CreateOptions.Paths,
765 cc_argv: []const []const u8,
766 inherited: Package.Module.CreateOptions.Inherited,
767 target_arch_os_abi: ?[]const u8,
768 target_mcpu: ?[]const u8,
769
770 deps: []const Dep,
771 resolved: ?*Package.Module,
772
773 c_source_files_start: usize,
774 c_source_files_end: usize,
775 rc_source_files_start: usize,
776 rc_source_files_end: usize,
777
778 pub const Dep = struct {
779 key: []const u8,
780 value: []const u8,
781 };
764782};
765783
766784fn buildOutputType(
......@@ -769,17 +787,11 @@ fn buildOutputType(
769787 all_args: []const []const u8,
770788 arg_mode: ArgMode,
771789) !void {
772 var color: Color = .auto;
773 var optimize_mode: std.builtin.OptimizeMode = .Debug;
774790 var provided_name: ?[]const u8 = null;
775 var link_mode: ?std.builtin.LinkMode = null;
776 var dll_export_fns: ?bool = null;
777 var single_threaded: ?bool = null;
778791 var root_src_file: ?[]const u8 = null;
779792 var version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 };
780793 var have_version = false;
781794 var compatibility_version: ?std.SemanticVersion = null;
782 var strip: ?bool = null;
783795 var formatted_panics: ?bool = null;
784796 var function_sections = false;
785797 var data_sections = false;
......@@ -807,54 +819,29 @@ fn buildOutputType(
807819 var emit_docs: Emit = .no;
808820 var emit_implib: Emit = .yes_default_path;
809821 var emit_implib_arg_provided = false;
810 var target_arch_os_abi: []const u8 = "native";
822 var target_arch_os_abi: ?[]const u8 = null;
811823 var target_mcpu: ?[]const u8 = null;
812 var target_dynamic_linker: ?[]const u8 = null;
813 var target_ofmt: ?[]const u8 = null;
814 var output_mode: std.builtin.OutputMode = undefined;
815824 var emit_h: Emit = .no;
816825 var soname: SOName = undefined;
817 var ensure_libc_on_non_freestanding = false;
818 var ensure_libcpp_on_non_freestanding = false;
819 var link_libc = false;
820 var link_libcpp = false;
821 var link_libunwind = false;
822 var want_native_include_dirs = false;
823 var want_pic: ?bool = null;
824 var want_pie: ?bool = null;
825 var want_lto: ?bool = null;
826 var want_unwind_tables: ?bool = null;
827 var want_sanitize_c: ?bool = null;
828 var want_stack_check: ?bool = null;
829 var want_stack_protector: ?u32 = null;
830 var want_red_zone: ?bool = null;
831 var omit_frame_pointer: ?bool = null;
832 var want_valgrind: ?bool = null;
833 var want_tsan: ?bool = null;
834826 var want_compiler_rt: ?bool = null;
835 var rdynamic: bool = false;
836827 var linker_script: ?[]const u8 = null;
837828 var version_script: ?[]const u8 = null;
838829 var disable_c_depfile = false;
839 var linker_sort_section: ?link.SortSection = null;
830 var linker_sort_section: ?link.File.Elf.SortSection = null;
840831 var linker_gc_sections: ?bool = null;
841 var linker_compress_debug_sections: ?link.CompressDebugSections = null;
832 var linker_compress_debug_sections: ?link.File.Elf.CompressDebugSections = null;
842833 var linker_allow_shlib_undefined: ?bool = null;
843834 var linker_bind_global_refs_locally: ?bool = null;
844 var linker_import_memory: ?bool = null;
845 var linker_export_memory: ?bool = null;
846835 var linker_import_symbols: bool = false;
847836 var linker_import_table: bool = false;
848837 var linker_export_table: bool = false;
849 var linker_force_entry: ?bool = null;
850838 var linker_initial_memory: ?u64 = null;
851839 var linker_max_memory: ?u64 = null;
852 var linker_shared_memory: bool = false;
853840 var linker_global_base: ?u64 = null;
854841 var linker_print_gc_sections: bool = false;
855842 var linker_print_icf_sections: bool = false;
856843 var linker_print_map: bool = false;
857 var linker_opt_bisect_limit: i32 = -1;
844 var llvm_opt_bisect_limit: c_int = -1;
858845 var linker_z_nocopyreloc = false;
859846 var linker_z_nodelete = false;
860847 var linker_z_notext = false;
......@@ -867,25 +854,17 @@ fn buildOutputType(
867854 var linker_tsaware = false;
868855 var linker_nxcompat = false;
869856 var linker_dynamicbase = true;
870 var linker_optimization: ?u8 = null;
857 var linker_optimization: ?[]const u8 = null;
871858 var linker_module_definition_file: ?[]const u8 = null;
872 var test_evented_io = false;
873859 var test_no_exec = false;
874 var entry: ?[]const u8 = null;
860 var entry: Compilation.CreateOptions.Entry = .default;
875861 var force_undefined_symbols: std.StringArrayHashMapUnmanaged(void) = .{};
876 var stack_size_override: ?u64 = null;
877 var image_base_override: ?u64 = null;
878 var use_llvm: ?bool = null;
879 var use_lib_llvm: ?bool = null;
880 var use_lld: ?bool = null;
881 var use_clang: ?bool = null;
862 var stack_size: ?u64 = null;
863 var image_base: ?u64 = null;
882864 var link_eh_frame_hdr = false;
883865 var link_emit_relocs = false;
884866 var each_lib_rpath: ?bool = null;
885 var build_id: ?BuildId = null;
886 var sysroot: ?[]const u8 = null;
887 var libc_paths_file: ?[]const u8 = try EnvVar.ZIG_LIBC.get(arena);
888 var machine_code_model: std.builtin.CodeModel = .default;
867 var build_id: ?std.zig.BuildId = null;
889868 var runtime_args_start: ?usize = null;
890869 var test_filter: ?[]const u8 = null;
891870 var test_name_prefix: ?[]const u8 = null;
......@@ -893,16 +872,14 @@ fn buildOutputType(
893872 var override_local_cache_dir: ?[]const u8 = try EnvVar.ZIG_LOCAL_CACHE_DIR.get(arena);
894873 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
895874 var override_lib_dir: ?[]const u8 = try EnvVar.ZIG_LIB_DIR.get(arena);
896 var main_mod_path: ?[]const u8 = null;
897875 var clang_preprocessor_mode: Compilation.ClangPreprocessorMode = .no;
898876 var subsystem: ?std.Target.SubSystem = null;
899 var major_subsystem_version: ?u32 = null;
900 var minor_subsystem_version: ?u32 = null;
901 var wasi_exec_model: ?std.builtin.WasiExecModel = null;
877 var major_subsystem_version: ?u16 = null;
878 var minor_subsystem_version: ?u16 = null;
902879 var enable_link_snapshots: bool = false;
903880 var debug_incremental: bool = false;
904881 var install_name: ?[]const u8 = null;
905 var hash_style: link.HashStyle = .both;
882 var hash_style: link.File.Elf.HashStyle = .both;
906883 var entitlements: ?[]const u8 = null;
907884 var pagezero_size: ?u64 = null;
908885 var lib_search_strategy: SystemLib.SearchStrategy = .paths_first;
......@@ -910,63 +887,103 @@ fn buildOutputType(
910887 var headerpad_size: ?u32 = null;
911888 var headerpad_max_install_names: bool = false;
912889 var dead_strip_dylibs: bool = false;
890 var contains_res_file: bool = false;
913891 var reference_trace: ?u32 = null;
914 var error_tracing: ?bool = null;
915892 var pdb_out_path: ?[]const u8 = null;
916 var dwarf_format: ?std.dwarf.Format = null;
917893 var error_limit: ?Module.ErrorInt = null;
918 var want_structured_cfg: ?bool = null;
919 // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
920 // This array is populated by zig cc frontend and then has to be converted to zig-style
921 // CPU features.
922 var llvm_m_args = std.ArrayList([]const u8).init(arena);
923 var system_libs = std.StringArrayHashMap(SystemLib).init(arena);
924 var wasi_emulated_libs = std.ArrayList(wasi_libc.CRTFile).init(arena);
925 var clang_argv = std.ArrayList([]const u8).init(arena);
926 var extra_cflags = std.ArrayList([]const u8).init(arena);
927 var extra_rcflags = std.ArrayList([]const u8).init(arena);
928894 // These are before resolving sysroot.
929 var lib_dir_args = std.ArrayList([]const u8).init(arena);
930 var rpath_list = std.ArrayList([]const u8).init(arena);
895 var extra_cflags: std.ArrayListUnmanaged([]const u8) = .{};
896 var extra_rcflags: std.ArrayListUnmanaged([]const u8) = .{};
931897 var symbol_wrap_set: std.StringArrayHashMapUnmanaged(void) = .{};
932 var c_source_files = std.ArrayList(Compilation.CSourceFile).init(arena);
933 var rc_source_files = std.ArrayList(Compilation.RcSourceFile).init(arena);
934898 var rc_includes: Compilation.RcIncludes = .any;
935 var res_files = std.ArrayList(Compilation.LinkObject).init(arena);
936899 var manifest_file: ?[]const u8 = null;
937 var link_objects = std.ArrayList(Compilation.LinkObject).init(arena);
938 var framework_dirs = std.ArrayList([]const u8).init(arena);
939 var frameworks: std.StringArrayHashMapUnmanaged(Framework) = .{};
900 var linker_export_symbol_names: std.ArrayListUnmanaged([]const u8) = .{};
901
902 // Tracks the position in c_source_files which have already their owner populated.
903 var c_source_files_owner_index: usize = 0;
904 // Tracks the position in rc_source_files which have already their owner populated.
905 var rc_source_files_owner_index: usize = 0;
906
940907 // null means replace with the test executable binary
941908 var test_exec_args = std.ArrayList(?[]const u8).init(arena);
942 var linker_export_symbol_names = std.ArrayList([]const u8).init(arena);
909
910 // These get set by CLI flags and then snapshotted when a `--mod` flag is
911 // encountered.
912 var mod_opts: Package.Module.CreateOptions.Inherited = .{};
913
914 // These get appended to by CLI flags and then slurped when a `--mod` flag
915 // is encountered.
916 var cssan: ClangSearchSanitizer = .{};
917 var cc_argv: std.ArrayListUnmanaged([]const u8) = .{};
918 var deps: std.ArrayListUnmanaged(CliModule.Dep) = .{};
919
943920 // Contains every module specified via --mod. The dependencies are added
944921 // after argument parsing is completed. We use a StringArrayHashMap to make
945 // error output consistent.
946 var modules = std.StringArrayHashMap(CliModule).init(arena);
947
948 // The dependency string for the root package
949 var root_deps_str: ?[]const u8 = null;
922 // error output consistent. "root" is special.
923 var create_module: CreateModule = .{
924 // Populated just before the call to `createModule`.
925 .global_cache_directory = undefined,
926 .object_format = null,
927 .dynamic_linker = null,
928 .modules = .{},
929 .opts = .{
930 .is_test = arg_mode == .zig_test,
931 // Populated while parsing CLI args.
932 .output_mode = undefined,
933 // Populated in the call to `createModule` for the root module.
934 .resolved_target = undefined,
935 .have_zcu = false,
936 // Populated just before the call to `createModule`.
937 .emit_llvm_ir = undefined,
938 // Populated just before the call to `createModule`.
939 .emit_llvm_bc = undefined,
940 // Populated just before the call to `createModule`.
941 .emit_bin = undefined,
942 // Populated just before the call to `createModule`.
943 .any_c_source_files = undefined,
944 },
945 // Populated in the call to `createModule` for the root module.
946 .resolved_options = undefined,
947
948 .system_libs = .{},
949 .resolved_system_libs = .{},
950 .wasi_emulated_libs = .{},
951
952 .c_source_files = .{},
953 .rc_source_files = .{},
954
955 .llvm_m_args = .{},
956 .sysroot = null,
957 .lib_dirs = .{}, // populated by createModule()
958 .lib_dir_args = .{}, // populated from CLI arg parsing
959 .libc_installation = null,
960 .want_native_include_dirs = false,
961 .frameworks = .{},
962 .framework_dirs = .{},
963 .rpath_list = .{},
964 .libc_paths_file = try EnvVar.ZIG_LIBC.get(arena),
965 .link_objects = .{},
966 .native_system_include_paths = &.{},
967 };
950968
951969 // before arg parsing, check for the NO_COLOR environment variable
952970 // if it exists, default the color setting to .off
953971 // explicit --color arguments will still override this setting.
954972 // Disable color on WASI per https://github.com/WebAssembly/WASI/issues/162
955 color = if (builtin.os.tag == .wasi or EnvVar.NO_COLOR.isSet()) .off else .auto;
973 var color: Color = if (builtin.os.tag == .wasi or EnvVar.NO_COLOR.isSet()) .off else .auto;
956974
957975 switch (arg_mode) {
958976 .build, .translate_c, .zig_test, .run => {
959 var optimize_mode_string: ?[]const u8 = null;
960977 switch (arg_mode) {
961978 .build => |m| {
962 output_mode = m;
979 create_module.opts.output_mode = m;
963980 },
964981 .translate_c => {
965982 emit_bin = .no;
966 output_mode = .Obj;
983 create_module.opts.output_mode = .Obj;
967984 },
968985 .zig_test, .run => {
969 output_mode = .Exe;
986 create_module.opts.output_mode = .Exe;
970987 },
971988 else => unreachable,
972989 }
......@@ -977,9 +994,6 @@ fn buildOutputType(
977994 .args = all_args[2..],
978995 };
979996
980 var cssan = ClangSearchSanitizer.init(gpa, &clang_argv);
981 defer cssan.map.deinit();
982
983997 var file_ext: ?Compilation.FileExt = null;
984998 args_loop: while (args_iter.next()) |arg| {
985999 if (mem.startsWith(u8, arg, "@")) {
......@@ -1002,49 +1016,77 @@ fn buildOutputType(
10021016 } else {
10031017 fatal("unexpected end-of-parameter mark: --", .{});
10041018 }
1005 } else if (mem.eql(u8, arg, "--mod")) {
1006 const info = args_iter.nextOrFatal();
1007 var info_it = mem.splitScalar(u8, info, ':');
1008 const mod_name = info_it.next() orelse fatal("expected non-empty argument after {s}", .{arg});
1009 const deps_str = info_it.next() orelse fatal("expected 'name:deps:path' after {s}", .{arg});
1010 const root_src_orig = info_it.rest();
1011 if (root_src_orig.len == 0) fatal("expected 'name:deps:path' after {s}", .{arg});
1012 if (mod_name.len == 0) fatal("empty name for module at '{s}'", .{root_src_orig});
1013
1014 const root_src = try introspect.resolvePath(arena, root_src_orig);
1015
1016 for ([_][]const u8{ "std", "root", "builtin" }) |name| {
1017 if (mem.eql(u8, mod_name, name)) {
1018 fatal("unable to add module '{s}' -> '{s}': conflicts with builtin module", .{
1019 mod_name, root_src,
1019 } else if (mem.eql(u8, arg, "--dep")) {
1020 var it = mem.splitScalar(u8, args_iter.nextOrFatal(), '=');
1021 const key = it.next().?;
1022 const value = it.next() orelse key;
1023 if (mem.eql(u8, key, "std") and !mem.eql(u8, value, "std")) {
1024 fatal("unable to import as '{s}': conflicts with builtin module", .{
1025 key,
1026 });
1027 }
1028 for ([_][]const u8{ "root", "builtin" }) |name| {
1029 if (mem.eql(u8, key, name)) {
1030 fatal("unable to import as '{s}': conflicts with builtin module", .{
1031 key,
10201032 });
10211033 }
10221034 }
1035 try deps.append(arena, .{
1036 .key = key,
1037 .value = value,
1038 });
1039 } else if (mem.eql(u8, arg, "--mod")) {
1040 const mod_name = args_iter.nextOrFatal();
1041 const root_src_orig = args_iter.nextOrFatal();
10231042
1024 if (modules.get(mod_name)) |value| {
1025 fatal("unable to add module '{s}' -> '{s}': already exists as '{s}'", .{
1026 mod_name, root_src, value.mod.root_src_path,
1043 const gop = try create_module.modules.getOrPut(arena, mod_name);
1044
1045 if (gop.found_existing) {
1046 fatal("unable to add module '{s}': already exists as '{s}'", .{
1047 mod_name, gop.value_ptr.paths.root_src_path,
10271048 });
10281049 }
10291050
1030 try modules.put(mod_name, .{
1031 .mod = try Package.Module.create(arena, .{
1051 // See duplicate logic: ModCreationGlobalFlags
1052 create_module.opts.have_zcu = true;
1053 if (mod_opts.single_threaded == false)
1054 create_module.opts.any_non_single_threaded = true;
1055 if (mod_opts.sanitize_thread == true)
1056 create_module.opts.any_sanitize_thread = true;
1057 if (mod_opts.unwind_tables == true)
1058 create_module.opts.any_unwind_tables = true;
1059 if (mod_opts.strip == false)
1060 create_module.opts.any_non_stripped = true;
1061 if (mod_opts.error_tracing == true)
1062 create_module.opts.any_error_tracing = true;
1063
1064 const root_src = try introspect.resolvePath(arena, root_src_orig);
1065 gop.value_ptr.* = .{
1066 .paths = .{
10321067 .root = .{
10331068 .root_dir = Cache.Directory.cwd(),
10341069 .sub_path = fs.path.dirname(root_src) orelse "",
10351070 },
10361071 .root_src_path = fs.path.basename(root_src),
1037 .fully_qualified_name = mod_name,
1038 }),
1039 .deps_str = deps_str,
1040 });
1041 } else if (mem.eql(u8, arg, "--deps")) {
1042 if (root_deps_str != null) {
1043 fatal("only one --deps argument is allowed", .{});
1044 }
1045 root_deps_str = args_iter.nextOrFatal();
1046 } else if (mem.eql(u8, arg, "--main-mod-path")) {
1047 main_mod_path = args_iter.nextOrFatal();
1072 },
1073 .cc_argv = try cc_argv.toOwnedSlice(arena),
1074 .inherited = mod_opts,
1075 .target_arch_os_abi = target_arch_os_abi,
1076 .target_mcpu = target_mcpu,
1077 .deps = try deps.toOwnedSlice(arena),
1078 .resolved = null,
1079 .c_source_files_start = c_source_files_owner_index,
1080 .c_source_files_end = create_module.c_source_files.items.len,
1081 .rc_source_files_start = rc_source_files_owner_index,
1082 .rc_source_files_end = create_module.rc_source_files.items.len,
1083 };
1084 cssan.reset();
1085 mod_opts = .{};
1086 target_arch_os_abi = null;
1087 target_mcpu = null;
1088 c_source_files_owner_index = create_module.c_source_files.items.len;
1089 rc_source_files_owner_index = create_module.rc_source_files.items.len;
10481090 } else if (mem.eql(u8, arg, "--error-limit")) {
10491091 const next_arg = args_iter.nextOrFatal();
10501092 error_limit = std.fmt.parseUnsigned(Module.ErrorInt, next_arg, 0) catch |err| {
......@@ -1057,7 +1099,7 @@ fn buildOutputType(
10571099 fatal("expected -- after -cflags", .{});
10581100 };
10591101 if (mem.eql(u8, next_arg, "--")) break;
1060 try extra_cflags.append(next_arg);
1102 try extra_cflags.append(arena, next_arg);
10611103 }
10621104 } else if (mem.eql(u8, arg, "-rcincludes")) {
10631105 rc_includes = parseRcIncludes(args_iter.nextOrFatal());
......@@ -1070,12 +1112,12 @@ fn buildOutputType(
10701112 fatal("expected -- after -rcflags", .{});
10711113 };
10721114 if (mem.eql(u8, next_arg, "--")) break;
1073 try extra_rcflags.append(next_arg);
1115 try extra_rcflags.append(arena, next_arg);
10741116 }
10751117 } else if (mem.startsWith(u8, arg, "-fstructured-cfg")) {
1076 want_structured_cfg = true;
1118 mod_opts.structured_cfg = true;
10771119 } else if (mem.startsWith(u8, arg, "-fno-structured-cfg")) {
1078 want_structured_cfg = false;
1120 mod_opts.structured_cfg = false;
10791121 } else if (mem.eql(u8, arg, "--color")) {
10801122 const next_arg = args_iter.next() orelse {
10811123 fatal("expected [auto|on|off] after --color", .{});
......@@ -1086,46 +1128,40 @@ fn buildOutputType(
10861128 } else if (mem.eql(u8, arg, "--subsystem")) {
10871129 subsystem = try parseSubSystem(args_iter.nextOrFatal());
10881130 } else if (mem.eql(u8, arg, "-O")) {
1089 optimize_mode_string = args_iter.nextOrFatal();
1131 mod_opts.optimize_mode = parseOptimizeMode(args_iter.nextOrFatal());
10901132 } else if (mem.startsWith(u8, arg, "-fentry=")) {
1091 entry = arg["-fentry=".len..];
1133 entry = .{ .named = arg["-fentry=".len..] };
10921134 } else if (mem.eql(u8, arg, "--force_undefined")) {
1093 try force_undefined_symbols.put(gpa, args_iter.nextOrFatal(), {});
1135 try force_undefined_symbols.put(arena, args_iter.nextOrFatal(), {});
10941136 } else if (mem.eql(u8, arg, "--stack")) {
1095 const next_arg = args_iter.nextOrFatal();
1096 stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
1097 fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) });
1098 };
1137 stack_size = parseStackSize(args_iter.nextOrFatal());
10991138 } else if (mem.eql(u8, arg, "--image-base")) {
1100 const next_arg = args_iter.nextOrFatal();
1101 image_base_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
1102 fatal("unable to parse image base override '{s}': {s}", .{ next_arg, @errorName(err) });
1103 };
1139 image_base = parseImageBase(args_iter.nextOrFatal());
11041140 } else if (mem.eql(u8, arg, "--name")) {
11051141 provided_name = args_iter.nextOrFatal();
11061142 if (!mem.eql(u8, provided_name.?, fs.path.basename(provided_name.?)))
11071143 fatal("invalid package name '{s}': cannot contain folder separators", .{provided_name.?});
11081144 } else if (mem.eql(u8, arg, "-rpath")) {
1109 try rpath_list.append(args_iter.nextOrFatal());
1145 try create_module.rpath_list.append(arena, args_iter.nextOrFatal());
11101146 } else if (mem.eql(u8, arg, "--library-directory") or mem.eql(u8, arg, "-L")) {
1111 try lib_dir_args.append(args_iter.nextOrFatal());
1147 try create_module.lib_dir_args.append(arena, args_iter.nextOrFatal());
11121148 } else if (mem.eql(u8, arg, "-F")) {
1113 try framework_dirs.append(args_iter.nextOrFatal());
1149 try create_module.framework_dirs.append(arena, args_iter.nextOrFatal());
11141150 } else if (mem.eql(u8, arg, "-framework")) {
1115 try frameworks.put(gpa, args_iter.nextOrFatal(), .{});
1151 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{});
11161152 } else if (mem.eql(u8, arg, "-weak_framework")) {
1117 try frameworks.put(gpa, args_iter.nextOrFatal(), .{ .weak = true });
1153 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{ .weak = true });
11181154 } else if (mem.eql(u8, arg, "-needed_framework")) {
1119 try frameworks.put(gpa, args_iter.nextOrFatal(), .{ .needed = true });
1155 try create_module.frameworks.put(arena, args_iter.nextOrFatal(), .{ .needed = true });
11201156 } else if (mem.eql(u8, arg, "-install_name")) {
11211157 install_name = args_iter.nextOrFatal();
11221158 } else if (mem.startsWith(u8, arg, "--compress-debug-sections=")) {
11231159 const param = arg["--compress-debug-sections=".len..];
1124 linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, param) orelse {
1160 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, param) orelse {
11251161 fatal("expected --compress-debug-sections=[none|zlib|zstd], found '{s}'", .{param});
11261162 };
11271163 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {
1128 linker_compress_debug_sections = link.CompressDebugSections.zlib;
1164 linker_compress_debug_sections = link.File.Elf.CompressDebugSections.zlib;
11291165 } else if (mem.eql(u8, arg, "-pagezero_size")) {
11301166 const next_arg = args_iter.nextOrFatal();
11311167 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {
......@@ -1168,7 +1204,7 @@ fn buildOutputType(
11681204 // We don't know whether this library is part of libc
11691205 // or libc++ until we resolve the target, so we append
11701206 // to the list for now.
1171 try system_libs.put(args_iter.nextOrFatal(), .{
1207 try create_module.system_libs.put(arena, args_iter.nextOrFatal(), .{
11721208 .needed = false,
11731209 .weak = false,
11741210 .preferred_mode = lib_preferred_mode,
......@@ -1179,38 +1215,37 @@ fn buildOutputType(
11791215 mem.eql(u8, arg, "-needed_library"))
11801216 {
11811217 const next_arg = args_iter.nextOrFatal();
1182 try system_libs.put(next_arg, .{
1218 try create_module.system_libs.put(arena, next_arg, .{
11831219 .needed = true,
11841220 .weak = false,
11851221 .preferred_mode = lib_preferred_mode,
11861222 .search_strategy = lib_search_strategy,
11871223 });
11881224 } else if (mem.eql(u8, arg, "-weak_library") or mem.eql(u8, arg, "-weak-l")) {
1189 try system_libs.put(args_iter.nextOrFatal(), .{
1225 try create_module.system_libs.put(arena, args_iter.nextOrFatal(), .{
11901226 .needed = false,
11911227 .weak = true,
11921228 .preferred_mode = lib_preferred_mode,
11931229 .search_strategy = lib_search_strategy,
11941230 });
11951231 } else if (mem.eql(u8, arg, "-D")) {
1196 try clang_argv.append(arg);
1197 try clang_argv.append(args_iter.nextOrFatal());
1232 try cc_argv.appendSlice(arena, &.{ arg, args_iter.nextOrFatal() });
11981233 } else if (mem.eql(u8, arg, "-I")) {
1199 try cssan.addIncludePath(.I, arg, args_iter.nextOrFatal(), false);
1234 try cssan.addIncludePath(arena, &cc_argv, .I, arg, args_iter.nextOrFatal(), false);
12001235 } else if (mem.eql(u8, arg, "-isystem")) {
1201 try cssan.addIncludePath(.isystem, arg, args_iter.nextOrFatal(), false);
1236 try cssan.addIncludePath(arena, &cc_argv, .isystem, arg, args_iter.nextOrFatal(), false);
12021237 } else if (mem.eql(u8, arg, "-iwithsysroot")) {
1203 try cssan.addIncludePath(.iwithsysroot, arg, args_iter.nextOrFatal(), false);
1238 try cssan.addIncludePath(arena, &cc_argv, .iwithsysroot, arg, args_iter.nextOrFatal(), false);
12041239 } else if (mem.eql(u8, arg, "-idirafter")) {
1205 try cssan.addIncludePath(.idirafter, arg, args_iter.nextOrFatal(), false);
1240 try cssan.addIncludePath(arena, &cc_argv, .idirafter, arg, args_iter.nextOrFatal(), false);
12061241 } else if (mem.eql(u8, arg, "-iframework")) {
12071242 const path = args_iter.nextOrFatal();
1208 try cssan.addIncludePath(.iframework, arg, path, false);
1209 try framework_dirs.append(path); // Forward to the backend as -F
1243 try cssan.addIncludePath(arena, &cc_argv, .iframework, arg, path, false);
1244 try create_module.framework_dirs.append(arena, path); // Forward to the backend as -F
12101245 } else if (mem.eql(u8, arg, "-iframeworkwithsysroot")) {
12111246 const path = args_iter.nextOrFatal();
1212 try cssan.addIncludePath(.iframeworkwithsysroot, arg, path, false);
1213 try framework_dirs.append(path); // Forward to the backend as -F
1247 try cssan.addIncludePath(arena, &cc_argv, .iframeworkwithsysroot, arg, path, false);
1248 try create_module.framework_dirs.append(arena, path); // Forward to the backend as -F
12141249 } else if (mem.eql(u8, arg, "--version")) {
12151250 const next_arg = args_iter.nextOrFatal();
12161251 version = std.SemanticVersion.parse(next_arg) catch |err| {
......@@ -1222,23 +1257,23 @@ fn buildOutputType(
12221257 } else if (mem.eql(u8, arg, "-mcpu")) {
12231258 target_mcpu = args_iter.nextOrFatal();
12241259 } else if (mem.eql(u8, arg, "-mcmodel")) {
1225 machine_code_model = parseCodeModel(args_iter.nextOrFatal());
1260 mod_opts.code_model = parseCodeModel(args_iter.nextOrFatal());
1261 } else if (mem.startsWith(u8, arg, "-mcmodel=")) {
1262 mod_opts.code_model = parseCodeModel(arg["-mcmodel=".len..]);
12261263 } else if (mem.startsWith(u8, arg, "-ofmt=")) {
1227 target_ofmt = arg["-ofmt=".len..];
1264 create_module.object_format = arg["-ofmt=".len..];
12281265 } else if (mem.startsWith(u8, arg, "-mcpu=")) {
12291266 target_mcpu = arg["-mcpu=".len..];
1230 } else if (mem.startsWith(u8, arg, "-mcmodel=")) {
1231 machine_code_model = parseCodeModel(arg["-mcmodel=".len..]);
12321267 } else if (mem.startsWith(u8, arg, "-O")) {
1233 optimize_mode_string = arg["-O".len..];
1268 mod_opts.optimize_mode = parseOptimizeMode(arg["-O".len..]);
12341269 } else if (mem.eql(u8, arg, "--dynamic-linker")) {
1235 target_dynamic_linker = args_iter.nextOrFatal();
1270 create_module.dynamic_linker = args_iter.nextOrFatal();
12361271 } else if (mem.eql(u8, arg, "--sysroot")) {
1237 sysroot = args_iter.nextOrFatal();
1238 try clang_argv.append("-isysroot");
1239 try clang_argv.append(sysroot.?);
1272 const next_arg = args_iter.nextOrFatal();
1273 create_module.sysroot = next_arg;
1274 try cc_argv.appendSlice(arena, &.{ "-isysroot", next_arg });
12401275 } else if (mem.eql(u8, arg, "--libc")) {
1241 libc_paths_file = args_iter.nextOrFatal();
1276 create_module.libc_paths_file = args_iter.nextOrFatal();
12421277 } else if (mem.eql(u8, arg, "--test-filter")) {
12431278 test_filter = args_iter.nextOrFatal();
12441279 } else if (mem.eql(u8, arg, "--test-name-prefix")) {
......@@ -1258,7 +1293,7 @@ fn buildOutputType(
12581293 warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
12591294 _ = args_iter.nextOrFatal();
12601295 } else {
1261 try log_scopes.append(gpa, args_iter.nextOrFatal());
1296 try log_scopes.append(arena, args_iter.nextOrFatal());
12621297 }
12631298 } else if (mem.eql(u8, arg, "--listen")) {
12641299 const next_arg = args_iter.nextOrFatal();
......@@ -1298,7 +1333,7 @@ fn buildOutputType(
12981333 } else if (mem.eql(u8, arg, "--test-cmd-bin")) {
12991334 try test_exec_args.append(null);
13001335 } else if (mem.eql(u8, arg, "--test-evented-io")) {
1301 test_evented_io = true;
1336 create_module.opts.test_evented_io = true;
13021337 } else if (mem.eql(u8, arg, "--test-no-exec")) {
13031338 test_no_exec = true;
13041339 } else if (mem.eql(u8, arg, "-ftime-report")) {
......@@ -1306,65 +1341,65 @@ fn buildOutputType(
13061341 } else if (mem.eql(u8, arg, "-fstack-report")) {
13071342 stack_report = true;
13081343 } else if (mem.eql(u8, arg, "-fPIC")) {
1309 want_pic = true;
1344 mod_opts.pic = true;
13101345 } else if (mem.eql(u8, arg, "-fno-PIC")) {
1311 want_pic = false;
1346 mod_opts.pic = false;
13121347 } else if (mem.eql(u8, arg, "-fPIE")) {
1313 want_pie = true;
1348 create_module.opts.pie = true;
13141349 } else if (mem.eql(u8, arg, "-fno-PIE")) {
1315 want_pie = false;
1350 create_module.opts.pie = false;
13161351 } else if (mem.eql(u8, arg, "-flto")) {
1317 want_lto = true;
1352 create_module.opts.lto = true;
13181353 } else if (mem.eql(u8, arg, "-fno-lto")) {
1319 want_lto = false;
1354 create_module.opts.lto = false;
13201355 } else if (mem.eql(u8, arg, "-funwind-tables")) {
1321 want_unwind_tables = true;
1356 mod_opts.unwind_tables = true;
13221357 } else if (mem.eql(u8, arg, "-fno-unwind-tables")) {
1323 want_unwind_tables = false;
1358 mod_opts.unwind_tables = false;
13241359 } else if (mem.eql(u8, arg, "-fstack-check")) {
1325 want_stack_check = true;
1360 mod_opts.stack_check = true;
13261361 } else if (mem.eql(u8, arg, "-fno-stack-check")) {
1327 want_stack_check = false;
1362 mod_opts.stack_check = false;
13281363 } else if (mem.eql(u8, arg, "-fstack-protector")) {
1329 want_stack_protector = Compilation.default_stack_protector_buffer_size;
1364 mod_opts.stack_protector = Compilation.default_stack_protector_buffer_size;
13301365 } else if (mem.eql(u8, arg, "-fno-stack-protector")) {
1331 want_stack_protector = 0;
1366 mod_opts.stack_protector = 0;
13321367 } else if (mem.eql(u8, arg, "-mred-zone")) {
1333 want_red_zone = true;
1368 mod_opts.red_zone = true;
13341369 } else if (mem.eql(u8, arg, "-mno-red-zone")) {
1335 want_red_zone = false;
1370 mod_opts.red_zone = false;
13361371 } else if (mem.eql(u8, arg, "-fomit-frame-pointer")) {
1337 omit_frame_pointer = true;
1372 mod_opts.omit_frame_pointer = true;
13381373 } else if (mem.eql(u8, arg, "-fno-omit-frame-pointer")) {
1339 omit_frame_pointer = false;
1374 mod_opts.omit_frame_pointer = false;
13401375 } else if (mem.eql(u8, arg, "-fsanitize-c")) {
1341 want_sanitize_c = true;
1376 mod_opts.sanitize_c = true;
13421377 } else if (mem.eql(u8, arg, "-fno-sanitize-c")) {
1343 want_sanitize_c = false;
1378 mod_opts.sanitize_c = false;
13441379 } else if (mem.eql(u8, arg, "-fvalgrind")) {
1345 want_valgrind = true;
1380 mod_opts.valgrind = true;
13461381 } else if (mem.eql(u8, arg, "-fno-valgrind")) {
1347 want_valgrind = false;
1382 mod_opts.valgrind = false;
13481383 } else if (mem.eql(u8, arg, "-fsanitize-thread")) {
1349 want_tsan = true;
1384 mod_opts.sanitize_thread = true;
13501385 } else if (mem.eql(u8, arg, "-fno-sanitize-thread")) {
1351 want_tsan = false;
1386 mod_opts.sanitize_thread = false;
13521387 } else if (mem.eql(u8, arg, "-fllvm")) {
1353 use_llvm = true;
1388 create_module.opts.use_llvm = true;
13541389 } else if (mem.eql(u8, arg, "-fno-llvm")) {
1355 use_llvm = false;
1390 create_module.opts.use_llvm = false;
13561391 } else if (mem.eql(u8, arg, "-flibllvm")) {
1357 use_lib_llvm = true;
1392 create_module.opts.use_lib_llvm = true;
13581393 } else if (mem.eql(u8, arg, "-fno-libllvm")) {
1359 use_lib_llvm = false;
1394 create_module.opts.use_lib_llvm = false;
13601395 } else if (mem.eql(u8, arg, "-flld")) {
1361 use_lld = true;
1396 create_module.opts.use_lld = true;
13621397 } else if (mem.eql(u8, arg, "-fno-lld")) {
1363 use_lld = false;
1398 create_module.opts.use_lld = false;
13641399 } else if (mem.eql(u8, arg, "-fclang")) {
1365 use_clang = true;
1400 create_module.opts.use_clang = true;
13661401 } else if (mem.eql(u8, arg, "-fno-clang")) {
1367 use_clang = false;
1402 create_module.opts.use_clang = false;
13681403 } else if (mem.eql(u8, arg, "-freference-trace")) {
13691404 reference_trace = 256;
13701405 } else if (mem.startsWith(u8, arg, "-freference-trace=")) {
......@@ -1375,11 +1410,11 @@ fn buildOutputType(
13751410 } else if (mem.eql(u8, arg, "-fno-reference-trace")) {
13761411 reference_trace = null;
13771412 } else if (mem.eql(u8, arg, "-ferror-tracing")) {
1378 error_tracing = true;
1413 mod_opts.error_tracing = true;
13791414 } else if (mem.eql(u8, arg, "-fno-error-tracing")) {
1380 error_tracing = false;
1415 mod_opts.error_tracing = false;
13811416 } else if (mem.eql(u8, arg, "-rdynamic")) {
1382 rdynamic = true;
1417 create_module.opts.rdynamic = true;
13831418 } else if (mem.eql(u8, arg, "-fsoname")) {
13841419 soname = .yes_default_value;
13851420 } else if (mem.startsWith(u8, arg, "-fsoname=")) {
......@@ -1432,36 +1467,36 @@ fn buildOutputType(
14321467 emit_implib = .no;
14331468 emit_implib_arg_provided = true;
14341469 } else if (mem.eql(u8, arg, "-dynamic")) {
1435 link_mode = .Dynamic;
1470 create_module.opts.link_mode = .Dynamic;
14361471 lib_preferred_mode = .Dynamic;
14371472 lib_search_strategy = .mode_first;
14381473 } else if (mem.eql(u8, arg, "-static")) {
1439 link_mode = .Static;
1474 create_module.opts.link_mode = .Static;
14401475 lib_preferred_mode = .Static;
14411476 lib_search_strategy = .no_fallback;
14421477 } else if (mem.eql(u8, arg, "-fdll-export-fns")) {
1443 dll_export_fns = true;
1478 create_module.opts.dll_export_fns = true;
14441479 } else if (mem.eql(u8, arg, "-fno-dll-export-fns")) {
1445 dll_export_fns = false;
1480 create_module.opts.dll_export_fns = false;
14461481 } else if (mem.eql(u8, arg, "--show-builtin")) {
14471482 show_builtin = true;
14481483 emit_bin = .no;
14491484 } else if (mem.eql(u8, arg, "-fstrip")) {
1450 strip = true;
1485 mod_opts.strip = true;
14511486 } else if (mem.eql(u8, arg, "-fno-strip")) {
1452 strip = false;
1487 mod_opts.strip = false;
14531488 } else if (mem.eql(u8, arg, "-gdwarf32")) {
1454 dwarf_format = .@"32";
1489 create_module.opts.debug_format = .{ .dwarf = .@"32" };
14551490 } else if (mem.eql(u8, arg, "-gdwarf64")) {
1456 dwarf_format = .@"64";
1491 create_module.opts.debug_format = .{ .dwarf = .@"64" };
14571492 } else if (mem.eql(u8, arg, "-fformatted-panics")) {
14581493 formatted_panics = true;
14591494 } else if (mem.eql(u8, arg, "-fno-formatted-panics")) {
14601495 formatted_panics = false;
14611496 } else if (mem.eql(u8, arg, "-fsingle-threaded")) {
1462 single_threaded = true;
1497 mod_opts.single_threaded = true;
14631498 } else if (mem.eql(u8, arg, "-fno-single-threaded")) {
1464 single_threaded = false;
1499 mod_opts.single_threaded = false;
14651500 } else if (mem.eql(u8, arg, "-ffunction-sections")) {
14661501 function_sections = true;
14671502 } else if (mem.eql(u8, arg, "-fno-function-sections")) {
......@@ -1475,7 +1510,9 @@ fn buildOutputType(
14751510 } else if (mem.eql(u8, arg, "-fno-builtin")) {
14761511 no_builtin = true;
14771512 } else if (mem.startsWith(u8, arg, "-fopt-bisect-limit=")) {
1478 linker_opt_bisect_limit = std.math.lossyCast(i32, parseIntSuffix(arg, "-fopt-bisect-limit=".len));
1513 const next_arg = arg["-fopt-bisect-limit=".len..];
1514 llvm_opt_bisect_limit = std.fmt.parseInt(c_int, next_arg, 0) catch |err|
1515 fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
14791516 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {
14801517 link_eh_frame_hdr = true;
14811518 } else if (mem.eql(u8, arg, "--dynamicbase")) {
......@@ -1518,13 +1555,16 @@ fn buildOutputType(
15181555 fatal("unsupported linker extension flag: -z {s}", .{z_arg});
15191556 }
15201557 } else if (mem.eql(u8, arg, "--import-memory")) {
1521 linker_import_memory = true;
1558 create_module.opts.import_memory = true;
15221559 } else if (mem.eql(u8, arg, "-fentry")) {
1523 linker_force_entry = true;
1560 switch (entry) {
1561 .default, .disabled => entry = .enabled,
1562 .enabled, .named => {},
1563 }
15241564 } else if (mem.eql(u8, arg, "-fno-entry")) {
1525 linker_force_entry = false;
1565 entry = .disabled;
15261566 } else if (mem.eql(u8, arg, "--export-memory")) {
1527 linker_export_memory = true;
1567 create_module.opts.export_memory = true;
15281568 } else if (mem.eql(u8, arg, "--import-symbols")) {
15291569 linker_import_symbols = true;
15301570 } else if (mem.eql(u8, arg, "--import-table")) {
......@@ -1536,11 +1576,11 @@ fn buildOutputType(
15361576 } else if (mem.startsWith(u8, arg, "--max-memory=")) {
15371577 linker_max_memory = parseIntSuffix(arg, "--max-memory=".len);
15381578 } else if (mem.eql(u8, arg, "--shared-memory")) {
1539 linker_shared_memory = true;
1579 create_module.opts.shared_memory = true;
15401580 } else if (mem.startsWith(u8, arg, "--global-base=")) {
15411581 linker_global_base = parseIntSuffix(arg, "--global-base=".len);
15421582 } else if (mem.startsWith(u8, arg, "--export=")) {
1543 try linker_export_symbol_names.append(arg["--export=".len..]);
1583 try linker_export_symbol_names.append(arena, arg["--export=".len..]);
15441584 } else if (mem.eql(u8, arg, "-Bsymbolic")) {
15451585 linker_bind_global_refs_locally = true;
15461586 } else if (mem.eql(u8, arg, "--gc-sections")) {
......@@ -1551,7 +1591,7 @@ fn buildOutputType(
15511591 build_id = .fast;
15521592 } else if (mem.startsWith(u8, arg, "--build-id=")) {
15531593 const style = arg["--build-id=".len..];
1554 build_id = BuildId.parse(style) catch |err| {
1594 build_id = std.zig.BuildId.parse(style) catch |err| {
15551595 fatal("unable to parse --build-id style '{s}': {s}", .{
15561596 style, @errorName(err),
15571597 });
......@@ -1585,37 +1625,37 @@ fn buildOutputType(
15851625 } else if (mem.startsWith(u8, arg, "-T")) {
15861626 linker_script = arg[2..];
15871627 } else if (mem.startsWith(u8, arg, "-L")) {
1588 try lib_dir_args.append(arg[2..]);
1628 try create_module.lib_dir_args.append(arena, arg[2..]);
15891629 } else if (mem.startsWith(u8, arg, "-F")) {
1590 try framework_dirs.append(arg[2..]);
1630 try create_module.framework_dirs.append(arena, arg[2..]);
15911631 } else if (mem.startsWith(u8, arg, "-l")) {
15921632 // We don't know whether this library is part of libc
15931633 // or libc++ until we resolve the target, so we append
15941634 // to the list for now.
1595 try system_libs.put(arg["-l".len..], .{
1635 try create_module.system_libs.put(arena, arg["-l".len..], .{
15961636 .needed = false,
15971637 .weak = false,
15981638 .preferred_mode = lib_preferred_mode,
15991639 .search_strategy = lib_search_strategy,
16001640 });
16011641 } else if (mem.startsWith(u8, arg, "-needed-l")) {
1602 try system_libs.put(arg["-needed-l".len..], .{
1642 try create_module.system_libs.put(arena, arg["-needed-l".len..], .{
16031643 .needed = true,
16041644 .weak = false,
16051645 .preferred_mode = lib_preferred_mode,
16061646 .search_strategy = lib_search_strategy,
16071647 });
16081648 } else if (mem.startsWith(u8, arg, "-weak-l")) {
1609 try system_libs.put(arg["-weak-l".len..], .{
1649 try create_module.system_libs.put(arena, arg["-weak-l".len..], .{
16101650 .needed = false,
16111651 .weak = true,
16121652 .preferred_mode = lib_preferred_mode,
16131653 .search_strategy = lib_search_strategy,
16141654 });
16151655 } else if (mem.startsWith(u8, arg, "-D")) {
1616 try clang_argv.append(arg);
1656 try cc_argv.append(arena, arg);
16171657 } else if (mem.startsWith(u8, arg, "-I")) {
1618 try cssan.addIncludePath(.I, arg, arg[2..], true);
1658 try cssan.addIncludePath(arena, &cc_argv, .I, arg, arg[2..], true);
16191659 } else if (mem.eql(u8, arg, "-x")) {
16201660 const lang = args_iter.nextOrFatal();
16211661 if (mem.eql(u8, lang, "none")) {
......@@ -1626,23 +1666,31 @@ fn buildOutputType(
16261666 fatal("language not recognized: '{s}'", .{lang});
16271667 }
16281668 } else if (mem.startsWith(u8, arg, "-mexec-model=")) {
1629 wasi_exec_model = std.meta.stringToEnum(std.builtin.WasiExecModel, arg["-mexec-model=".len..]) orelse {
1630 fatal("expected [command|reactor] for -mexec-mode=[value], found '{s}'", .{arg["-mexec-model=".len..]});
1631 };
1669 create_module.opts.wasi_exec_model = parseWasiExecModel(arg["-mexec-model=".len..]);
16321670 } else {
16331671 fatal("unrecognized parameter: '{s}'", .{arg});
16341672 }
1635 } else switch (file_ext orelse
1636 Compilation.classifyFileExt(arg)) {
1637 .object, .static_library, .shared_library => try link_objects.append(.{ .path = arg }),
1638 .res => try res_files.append(.{ .path = arg }),
1673 } else switch (file_ext orelse Compilation.classifyFileExt(arg)) {
1674 .shared_library => {
1675 try create_module.link_objects.append(arena, .{ .path = arg });
1676 create_module.opts.any_dyn_libs = true;
1677 },
1678 .object, .static_library => {
1679 try create_module.link_objects.append(arena, .{ .path = arg });
1680 },
1681 .res => {
1682 try create_module.link_objects.append(arena, .{ .path = arg });
1683 contains_res_file = true;
1684 },
16391685 .manifest => {
16401686 if (manifest_file) |other| {
16411687 fatal("only one manifest file can be specified, found '{s}' after '{s}'", .{ arg, other });
16421688 } else manifest_file = arg;
16431689 },
16441690 .assembly, .assembly_with_cpp, .c, .cpp, .h, .ll, .bc, .m, .mm, .cu => {
1645 try c_source_files.append(.{
1691 try create_module.c_source_files.append(arena, .{
1692 // Populated after module creation.
1693 .owner = undefined,
16461694 .src_path = arg,
16471695 .extra_flags = try arena.dupe([]const u8, extra_cflags.items),
16481696 // duped when parsing the args.
......@@ -1650,7 +1698,9 @@ fn buildOutputType(
16501698 });
16511699 },
16521700 .rc => {
1653 try rc_source_files.append(.{
1701 try create_module.rc_source_files.append(arena, .{
1702 // Populated after module creation.
1703 .owner = undefined,
16541704 .src_path = arg,
16551705 .extra_flags = try arena.dupe([]const u8, extra_rcflags.items),
16561706 });
......@@ -1668,19 +1718,15 @@ fn buildOutputType(
16681718 },
16691719 }
16701720 }
1671 if (optimize_mode_string) |s| {
1672 optimize_mode = std.meta.stringToEnum(std.builtin.OptimizeMode, s) orelse
1673 fatal("unrecognized optimization mode: '{s}'", .{s});
1674 }
16751721 },
16761722 .cc, .cpp => {
16771723 if (build_options.only_c) unreachable;
16781724
16791725 emit_h = .no;
16801726 soname = .no;
1681 ensure_libc_on_non_freestanding = true;
1682 ensure_libcpp_on_non_freestanding = arg_mode == .cpp;
1683 want_native_include_dirs = true;
1727 create_module.opts.ensure_libc_on_non_freestanding = true;
1728 create_module.opts.ensure_libcpp_on_non_freestanding = arg_mode == .cpp;
1729 create_module.want_native_include_dirs = true;
16841730 // Clang's driver enables this switch unconditionally.
16851731 // Disabling the emission of .eh_frame_hdr can unexpectedly break
16861732 // some functionality that depend on it, such as C++ exceptions and
......@@ -1733,24 +1779,37 @@ fn buildOutputType(
17331779 }
17341780 },
17351781 .other => {
1736 try clang_argv.appendSlice(it.other_args);
1782 try cc_argv.appendSlice(arena, it.other_args);
17371783 },
1738 .positional => switch (file_ext orelse
1739 Compilation.classifyFileExt(mem.sliceTo(it.only_arg, 0))) {
1784 .positional => switch (file_ext orelse Compilation.classifyFileExt(mem.sliceTo(it.only_arg, 0))) {
17401785 .assembly, .assembly_with_cpp, .c, .cpp, .ll, .bc, .h, .m, .mm, .cu => {
1741 try c_source_files.append(.{
1786 try create_module.c_source_files.append(arena, .{
1787 // Populated after module creation.
1788 .owner = undefined,
17421789 .src_path = it.only_arg,
17431790 .ext = file_ext, // duped while parsing the args.
17441791 });
17451792 },
1746 .unknown, .shared_library, .object, .static_library => try link_objects.append(.{
1747 .path = it.only_arg,
1748 .must_link = must_link,
1749 }),
1750 .res => try res_files.append(.{
1751 .path = it.only_arg,
1752 .must_link = must_link,
1753 }),
1793 .shared_library => {
1794 try create_module.link_objects.append(arena, .{
1795 .path = it.only_arg,
1796 .must_link = must_link,
1797 });
1798 create_module.opts.any_dyn_libs = true;
1799 },
1800 .unknown, .object, .static_library => {
1801 try create_module.link_objects.append(arena, .{
1802 .path = it.only_arg,
1803 .must_link = must_link,
1804 });
1805 },
1806 .res => {
1807 try create_module.link_objects.append(arena, .{
1808 .path = it.only_arg,
1809 .must_link = must_link,
1810 });
1811 contains_res_file = true;
1812 },
17541813 .manifest => {
17551814 if (manifest_file) |other| {
17561815 fatal("only one manifest file can be specified, found '{s}' after previously specified manifest '{s}'", .{ it.only_arg, other });
......@@ -1760,7 +1819,11 @@ fn buildOutputType(
17601819 linker_module_definition_file = it.only_arg;
17611820 },
17621821 .rc => {
1763 try rc_source_files.append(.{ .src_path = it.only_arg });
1822 try create_module.rc_source_files.append(arena, .{
1823 // Populated after module creation.
1824 .owner = undefined,
1825 .src_path = it.only_arg,
1826 });
17641827 },
17651828 .zig => {
17661829 if (root_src_file) |other| {
......@@ -1777,13 +1840,13 @@ fn buildOutputType(
17771840 // more control over what's in the resulting
17781841 // binary: no extra rpaths and DSO filename exactly
17791842 // as provided. Hello, Go.
1780 try link_objects.append(.{
1843 try create_module.link_objects.append(arena, .{
17811844 .path = it.only_arg,
17821845 .must_link = must_link,
17831846 .loption = true,
17841847 });
17851848 } else {
1786 try system_libs.put(it.only_arg, .{
1849 try create_module.system_libs.put(arena, it.only_arg, .{
17871850 .needed = needed,
17881851 .weak = false,
17891852 .preferred_mode = lib_preferred_mode,
......@@ -1796,16 +1859,16 @@ fn buildOutputType(
17961859 // Never mind what we're doing, just pass the args directly. For example --help.
17971860 return process.exit(try clangMain(arena, all_args));
17981861 },
1799 .pic => want_pic = true,
1800 .no_pic => want_pic = false,
1801 .pie => want_pie = true,
1802 .no_pie => want_pie = false,
1803 .lto => want_lto = true,
1804 .no_lto => want_lto = false,
1805 .red_zone => want_red_zone = true,
1806 .no_red_zone => want_red_zone = false,
1807 .omit_frame_pointer => omit_frame_pointer = true,
1808 .no_omit_frame_pointer => omit_frame_pointer = false,
1862 .pic => mod_opts.pic = true,
1863 .no_pic => mod_opts.pic = false,
1864 .pie => create_module.opts.pie = true,
1865 .no_pie => create_module.opts.pie = false,
1866 .lto => create_module.opts.lto = true,
1867 .no_lto => create_module.opts.lto = false,
1868 .red_zone => mod_opts.red_zone = true,
1869 .no_red_zone => mod_opts.red_zone = false,
1870 .omit_frame_pointer => mod_opts.omit_frame_pointer = true,
1871 .no_omit_frame_pointer => mod_opts.omit_frame_pointer = false,
18091872 .function_sections => function_sections = true,
18101873 .no_function_sections => function_sections = false,
18111874 .data_sections => data_sections = true,
......@@ -1814,26 +1877,26 @@ fn buildOutputType(
18141877 .no_builtin => no_builtin = true,
18151878 .color_diagnostics => color = .on,
18161879 .no_color_diagnostics => color = .off,
1817 .stack_check => want_stack_check = true,
1818 .no_stack_check => want_stack_check = false,
1880 .stack_check => mod_opts.stack_check = true,
1881 .no_stack_check => mod_opts.stack_check = false,
18191882 .stack_protector => {
1820 if (want_stack_protector == null) {
1821 want_stack_protector = Compilation.default_stack_protector_buffer_size;
1883 if (mod_opts.stack_protector == null) {
1884 mod_opts.stack_protector = Compilation.default_stack_protector_buffer_size;
18221885 }
18231886 },
1824 .no_stack_protector => want_stack_protector = 0,
1825 .unwind_tables => want_unwind_tables = true,
1826 .no_unwind_tables => want_unwind_tables = false,
1887 .no_stack_protector => mod_opts.stack_protector = 0,
1888 .unwind_tables => mod_opts.unwind_tables = true,
1889 .no_unwind_tables => mod_opts.unwind_tables = false,
18271890 .nostdlib => {
1828 ensure_libc_on_non_freestanding = false;
1829 ensure_libcpp_on_non_freestanding = false;
1891 create_module.opts.ensure_libc_on_non_freestanding = false;
1892 create_module.opts.ensure_libcpp_on_non_freestanding = false;
18301893 },
1831 .nostdlib_cpp => ensure_libcpp_on_non_freestanding = false,
1894 .nostdlib_cpp => create_module.opts.ensure_libcpp_on_non_freestanding = false,
18321895 .shared => {
1833 link_mode = .Dynamic;
1896 create_module.opts.link_mode = .Dynamic;
18341897 is_shared_lib = true;
18351898 },
1836 .rdynamic => rdynamic = true,
1899 .rdynamic => create_module.opts.rdynamic = true,
18371900 .wl => {
18381901 var split_it = mem.splitScalar(u8, it.only_arg, ',');
18391902 while (split_it.next()) |linker_arg| {
......@@ -1847,7 +1910,7 @@ fn buildOutputType(
18471910 const key = linker_arg[0..equals_pos];
18481911 const value = linker_arg[equals_pos + 1 ..];
18491912 if (mem.eql(u8, key, "--build-id")) {
1850 build_id = BuildId.parse(value) catch |err| {
1913 build_id = std.zig.BuildId.parse(value) catch |err| {
18511914 fatal("unable to parse --build-id style '{s}': {s}", .{
18521915 value, @errorName(err),
18531916 });
......@@ -1870,7 +1933,7 @@ fn buildOutputType(
18701933 } else if (mem.eql(u8, linker_arg, "--no-as-needed")) {
18711934 needed = true;
18721935 } else if (mem.eql(u8, linker_arg, "-no-pie")) {
1873 want_pie = false;
1936 create_module.opts.pie = false;
18741937 } else if (mem.eql(u8, linker_arg, "--sort-common")) {
18751938 // from ld.lld(1): --sort-common is ignored for GNU compatibility,
18761939 // this ignores plain --sort-common
......@@ -1912,50 +1975,50 @@ fn buildOutputType(
19121975 if (mem.eql(u8, level, "s") or
19131976 mem.eql(u8, level, "z"))
19141977 {
1915 optimize_mode = .ReleaseSmall;
1978 mod_opts.optimize_mode = .ReleaseSmall;
19161979 } else if (mem.eql(u8, level, "1") or
19171980 mem.eql(u8, level, "2") or
19181981 mem.eql(u8, level, "3") or
19191982 mem.eql(u8, level, "4") or
19201983 mem.eql(u8, level, "fast"))
19211984 {
1922 optimize_mode = .ReleaseFast;
1985 mod_opts.optimize_mode = .ReleaseFast;
19231986 } else if (mem.eql(u8, level, "g") or
19241987 mem.eql(u8, level, "0"))
19251988 {
1926 optimize_mode = .Debug;
1989 mod_opts.optimize_mode = .Debug;
19271990 } else {
1928 try clang_argv.appendSlice(it.other_args);
1991 try cc_argv.appendSlice(arena, it.other_args);
19291992 }
19301993 },
19311994 .debug => {
1932 strip = false;
1995 mod_opts.strip = false;
19331996 if (mem.eql(u8, it.only_arg, "g")) {
19341997 // We handled with strip = false above.
19351998 } else if (mem.eql(u8, it.only_arg, "g1") or
19361999 mem.eql(u8, it.only_arg, "gline-tables-only"))
19372000 {
19382001 // We handled with strip = false above. but we also want reduced debug info.
1939 try clang_argv.append("-gline-tables-only");
2002 try cc_argv.append(arena, "-gline-tables-only");
19402003 } else {
1941 try clang_argv.appendSlice(it.other_args);
2004 try cc_argv.appendSlice(arena, it.other_args);
19422005 }
19432006 },
19442007 .gdwarf32 => {
1945 strip = false;
1946 dwarf_format = .@"32";
2008 mod_opts.strip = false;
2009 create_module.opts.debug_format = .{ .dwarf = .@"32" };
19472010 },
19482011 .gdwarf64 => {
1949 strip = false;
1950 dwarf_format = .@"64";
2012 mod_opts.strip = false;
2013 create_module.opts.debug_format = .{ .dwarf = .@"64" };
19512014 },
19522015 .sanitize => {
19532016 if (mem.eql(u8, it.only_arg, "undefined")) {
1954 want_sanitize_c = true;
2017 mod_opts.sanitize_c = true;
19552018 } else if (mem.eql(u8, it.only_arg, "thread")) {
1956 want_tsan = true;
2019 mod_opts.sanitize_thread = true;
19572020 } else {
1958 try clang_argv.appendSlice(it.other_args);
2021 try cc_argv.appendSlice(arena, it.other_args);
19592022 }
19602023 },
19612024 .linker_script => linker_script = it.only_arg,
......@@ -1964,65 +2027,63 @@ fn buildOutputType(
19642027 // Have Clang print more infos, some tools such as CMake
19652028 // parse this to discover any implicit include and
19662029 // library dir to look-up into.
1967 try clang_argv.append("-v");
2030 try cc_argv.append(arena, "-v");
19682031 },
19692032 .dry_run => {
19702033 // This flag means "dry run". Clang will not actually output anything
19712034 // to the file system.
19722035 verbose_link = true;
19732036 disable_c_depfile = true;
1974 try clang_argv.append("-###");
2037 try cc_argv.append(arena, "-###");
19752038 },
19762039 .for_linker => try linker_args.append(it.only_arg),
19772040 .linker_input_z => {
19782041 try linker_args.append("-z");
19792042 try linker_args.append(it.only_arg);
19802043 },
1981 .lib_dir => try lib_dir_args.append(it.only_arg),
2044 .lib_dir => try create_module.lib_dir_args.append(arena, it.only_arg),
19822045 .mcpu => target_mcpu = it.only_arg,
1983 .m => try llvm_m_args.append(it.only_arg),
2046 .m => try create_module.llvm_m_args.append(arena, it.only_arg),
19842047 .dep_file => {
19852048 disable_c_depfile = true;
1986 try clang_argv.appendSlice(it.other_args);
2049 try cc_argv.appendSlice(arena, it.other_args);
19872050 },
19882051 .dep_file_to_stdout => { // -M, -MM
19892052 // "Like -MD, but also implies -E and writes to stdout by default"
19902053 // "Like -MMD, but also implies -E and writes to stdout by default"
19912054 c_out_mode = .preprocessor;
19922055 disable_c_depfile = true;
1993 try clang_argv.appendSlice(it.other_args);
2056 try cc_argv.appendSlice(arena, it.other_args);
19942057 },
1995 .framework_dir => try framework_dirs.append(it.only_arg),
1996 .framework => try frameworks.put(gpa, it.only_arg, .{}),
1997 .nostdlibinc => want_native_include_dirs = false,
1998 .strip => strip = true,
2058 .framework_dir => try create_module.framework_dirs.append(arena, it.only_arg),
2059 .framework => try create_module.frameworks.put(arena, it.only_arg, .{}),
2060 .nostdlibinc => create_module.want_native_include_dirs = false,
2061 .strip => mod_opts.strip = true,
19992062 .exec_model => {
2000 wasi_exec_model = std.meta.stringToEnum(std.builtin.WasiExecModel, it.only_arg) orelse {
2001 fatal("expected [command|reactor] for -mexec-mode=[value], found '{s}'", .{it.only_arg});
2002 };
2063 create_module.opts.wasi_exec_model = parseWasiExecModel(it.only_arg);
20032064 },
20042065 .sysroot => {
2005 sysroot = it.only_arg;
2066 create_module.sysroot = it.only_arg;
20062067 },
20072068 .entry => {
2008 entry = it.only_arg;
2069 entry = .{ .named = it.only_arg };
20092070 },
20102071 .force_undefined_symbol => {
2011 try force_undefined_symbols.put(gpa, it.only_arg, {});
2072 try force_undefined_symbols.put(arena, it.only_arg, {});
20122073 },
2013 .weak_library => try system_libs.put(it.only_arg, .{
2074 .weak_library => try create_module.system_libs.put(arena, it.only_arg, .{
20142075 .needed = false,
20152076 .weak = true,
20162077 .preferred_mode = lib_preferred_mode,
20172078 .search_strategy = lib_search_strategy,
20182079 }),
2019 .weak_framework => try frameworks.put(gpa, it.only_arg, .{ .weak = true }),
2080 .weak_framework => try create_module.frameworks.put(arena, it.only_arg, .{ .weak = true }),
20202081 .headerpad_max_install_names => headerpad_max_install_names = true,
20212082 .compress_debug_sections => {
20222083 if (it.only_arg.len == 0) {
20232084 linker_compress_debug_sections = .zlib;
20242085 } else {
2025 linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, it.only_arg) orelse {
2086 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, it.only_arg) orelse {
20262087 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{it.only_arg});
20272088 };
20282089 }
......@@ -2077,30 +2138,25 @@ fn buildOutputType(
20772138 }
20782139 provided_name = name[prefix..end];
20792140 } else if (mem.eql(u8, arg, "-rpath")) {
2080 try rpath_list.append(linker_args_it.nextOrFatal());
2141 try create_module.rpath_list.append(arena, linker_args_it.nextOrFatal());
20812142 } else if (mem.eql(u8, arg, "--subsystem")) {
20822143 subsystem = try parseSubSystem(linker_args_it.nextOrFatal());
20832144 } else if (mem.eql(u8, arg, "-I") or
20842145 mem.eql(u8, arg, "--dynamic-linker") or
20852146 mem.eql(u8, arg, "-dynamic-linker"))
20862147 {
2087 target_dynamic_linker = linker_args_it.nextOrFatal();
2148 create_module.dynamic_linker = linker_args_it.nextOrFatal();
20882149 } else if (mem.eql(u8, arg, "-E") or
20892150 mem.eql(u8, arg, "--export-dynamic") or
20902151 mem.eql(u8, arg, "-export-dynamic"))
20912152 {
2092 rdynamic = true;
2153 create_module.opts.rdynamic = true;
20932154 } else if (mem.eql(u8, arg, "-version-script") or mem.eql(u8, arg, "--version-script")) {
20942155 version_script = linker_args_it.nextOrFatal();
20952156 } else if (mem.eql(u8, arg, "-O")) {
2096 const opt = linker_args_it.nextOrFatal();
2097 linker_optimization = std.fmt.parseUnsigned(u8, opt, 10) catch |err| {
2098 fatal("unable to parse optimization level '{s}': {s}", .{ opt, @errorName(err) });
2099 };
2157 linker_optimization = linker_args_it.nextOrFatal();
21002158 } else if (mem.startsWith(u8, arg, "-O")) {
2101 linker_optimization = std.fmt.parseUnsigned(u8, arg["-O".len..], 10) catch |err| {
2102 fatal("unable to parse optimization level '{s}': {s}", .{ arg, @errorName(err) });
2103 };
2159 linker_optimization = arg["-O".len..];
21042160 } else if (mem.eql(u8, arg, "-pagezero_size")) {
21052161 const next_arg = linker_args_it.nextOrFatal();
21062162 pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| {
......@@ -2131,7 +2187,7 @@ fn buildOutputType(
21312187 linker_print_map = true;
21322188 } else if (mem.eql(u8, arg, "--sort-section")) {
21332189 const arg1 = linker_args_it.nextOrFatal();
2134 linker_sort_section = std.meta.stringToEnum(link.SortSection, arg1) orelse {
2190 linker_sort_section = std.meta.stringToEnum(link.File.Elf.SortSection, arg1) orelse {
21352191 fatal("expected [name|alignment] after --sort-section, found '{s}'", .{arg1});
21362192 };
21372193 } else if (mem.eql(u8, arg, "--allow-shlib-undefined") or
......@@ -2145,9 +2201,9 @@ fn buildOutputType(
21452201 } else if (mem.eql(u8, arg, "-Bsymbolic")) {
21462202 linker_bind_global_refs_locally = true;
21472203 } else if (mem.eql(u8, arg, "--import-memory")) {
2148 linker_import_memory = true;
2204 create_module.opts.import_memory = true;
21492205 } else if (mem.eql(u8, arg, "--export-memory")) {
2150 linker_export_memory = true;
2206 create_module.opts.export_memory = true;
21512207 } else if (mem.eql(u8, arg, "--import-symbols")) {
21522208 linker_import_symbols = true;
21532209 } else if (mem.eql(u8, arg, "--import-table")) {
......@@ -2155,7 +2211,7 @@ fn buildOutputType(
21552211 } else if (mem.eql(u8, arg, "--export-table")) {
21562212 linker_export_table = true;
21572213 } else if (mem.eql(u8, arg, "--no-entry")) {
2158 linker_force_entry = false;
2214 entry = .disabled;
21592215 } else if (mem.eql(u8, arg, "--initial-memory")) {
21602216 const next_arg = linker_args_it.nextOrFatal();
21612217 linker_initial_memory = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| {
......@@ -2167,17 +2223,17 @@ fn buildOutputType(
21672223 fatal("unable to parse max memory size '{s}': {s}", .{ next_arg, @errorName(err) });
21682224 };
21692225 } else if (mem.eql(u8, arg, "--shared-memory")) {
2170 linker_shared_memory = true;
2226 create_module.opts.shared_memory = true;
21712227 } else if (mem.eql(u8, arg, "--global-base")) {
21722228 const next_arg = linker_args_it.nextOrFatal();
21732229 linker_global_base = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| {
21742230 fatal("unable to parse global base '{s}': {s}", .{ next_arg, @errorName(err) });
21752231 };
21762232 } else if (mem.eql(u8, arg, "--export")) {
2177 try linker_export_symbol_names.append(linker_args_it.nextOrFatal());
2233 try linker_export_symbol_names.append(arena, linker_args_it.nextOrFatal());
21782234 } else if (mem.eql(u8, arg, "--compress-debug-sections")) {
21792235 const arg1 = linker_args_it.nextOrFatal();
2180 linker_compress_debug_sections = std.meta.stringToEnum(link.CompressDebugSections, arg1) orelse {
2236 linker_compress_debug_sections = std.meta.stringToEnum(link.File.Elf.CompressDebugSections, arg1) orelse {
21812237 fatal("expected [none|zlib|zstd] after --compress-debug-sections, found '{s}'", .{arg1});
21822238 };
21832239 } else if (mem.startsWith(u8, arg, "-z")) {
......@@ -2208,10 +2264,7 @@ fn buildOutputType(
22082264 } else if (mem.eql(u8, z_arg, "norelro")) {
22092265 linker_z_relro = false;
22102266 } else if (mem.startsWith(u8, z_arg, "stack-size=")) {
2211 const next_arg = z_arg["stack-size=".len..];
2212 stack_size_override = std.fmt.parseUnsigned(u64, next_arg, 0) catch |err| {
2213 fatal("unable to parse stack size '{s}': {s}", .{ next_arg, @errorName(err) });
2214 };
2267 stack_size = parseStackSize(z_arg["stack-size=".len..]);
22152268 } else if (mem.startsWith(u8, z_arg, "common-page-size=")) {
22162269 linker_z_common_page_size = parseIntSuffix(z_arg, "common-page-size=".len);
22172270 } else if (mem.startsWith(u8, z_arg, "max-page-size=")) {
......@@ -2232,19 +2285,13 @@ fn buildOutputType(
22322285 };
22332286 have_version = true;
22342287 } else if (mem.eql(u8, arg, "-e") or mem.eql(u8, arg, "--entry")) {
2235 entry = linker_args_it.nextOrFatal();
2288 entry = .{ .named = linker_args_it.nextOrFatal() };
22362289 } else if (mem.eql(u8, arg, "-u")) {
2237 try force_undefined_symbols.put(gpa, linker_args_it.nextOrFatal(), {});
2290 try force_undefined_symbols.put(arena, linker_args_it.nextOrFatal(), {});
22382291 } else if (mem.eql(u8, arg, "--stack") or mem.eql(u8, arg, "-stack_size")) {
2239 const stack_size = linker_args_it.nextOrFatal();
2240 stack_size_override = std.fmt.parseUnsigned(u64, stack_size, 0) catch |err| {
2241 fatal("unable to parse stack size override '{s}': {s}", .{ stack_size, @errorName(err) });
2242 };
2292 stack_size = parseStackSize(linker_args_it.nextOrFatal());
22432293 } else if (mem.eql(u8, arg, "--image-base")) {
2244 const image_base = linker_args_it.nextOrFatal();
2245 image_base_override = std.fmt.parseUnsigned(u64, image_base, 0) catch |err| {
2246 fatal("unable to parse image base override '{s}': {s}", .{ image_base, @errorName(err) });
2247 };
2294 image_base = parseImageBase(linker_args_it.nextOrFatal());
22482295 } else if (mem.eql(u8, arg, "-T") or mem.eql(u8, arg, "--script")) {
22492296 linker_script = linker_args_it.nextOrFatal();
22502297 } else if (mem.eql(u8, arg, "--eh-frame-hdr")) {
......@@ -2262,7 +2309,7 @@ fn buildOutputType(
22622309 } else if (mem.eql(u8, arg, "--high-entropy-va")) {
22632310 // This option does not do anything.
22642311 } else if (mem.eql(u8, arg, "--export-all-symbols")) {
2265 rdynamic = true;
2312 create_module.opts.rdynamic = true;
22662313 } else if (mem.eql(u8, arg, "--color-diagnostics") or
22672314 mem.eql(u8, arg, "--color-diagnostics=always"))
22682315 {
......@@ -2276,7 +2323,7 @@ fn buildOutputType(
22762323 {
22772324 // -s, --strip-all Strip all symbols
22782325 // -S, --strip-debug Strip debugging symbols
2279 strip = true;
2326 mod_opts.strip = true;
22802327 } else if (mem.eql(u8, arg, "--start-group") or
22812328 mem.eql(u8, arg, "--end-group"))
22822329 {
......@@ -2290,44 +2337,40 @@ fn buildOutputType(
22902337 _ = linker_args_it.nextOrFatal();
22912338 } else if (mem.eql(u8, arg, "--major-subsystem-version")) {
22922339 const major = linker_args_it.nextOrFatal();
2293 major_subsystem_version = std.fmt.parseUnsigned(
2294 u32,
2295 major,
2296 10,
2297 ) catch |err| {
2298 fatal("unable to parse major subsystem version '{s}': {s}", .{ major, @errorName(err) });
2340 major_subsystem_version = std.fmt.parseUnsigned(u16, major, 10) catch |err| {
2341 fatal("unable to parse major subsystem version '{s}': {s}", .{
2342 major, @errorName(err),
2343 });
22992344 };
23002345 } else if (mem.eql(u8, arg, "--minor-subsystem-version")) {
23012346 const minor = linker_args_it.nextOrFatal();
2302 minor_subsystem_version = std.fmt.parseUnsigned(
2303 u32,
2304 minor,
2305 10,
2306 ) catch |err| {
2307 fatal("unable to parse minor subsystem version '{s}': {s}", .{ minor, @errorName(err) });
2347 minor_subsystem_version = std.fmt.parseUnsigned(u16, minor, 10) catch |err| {
2348 fatal("unable to parse minor subsystem version '{s}': {s}", .{
2349 minor, @errorName(err),
2350 });
23082351 };
23092352 } else if (mem.eql(u8, arg, "-framework")) {
2310 try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{});
2353 try create_module.frameworks.put(arena, linker_args_it.nextOrFatal(), .{});
23112354 } else if (mem.eql(u8, arg, "-weak_framework")) {
2312 try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .weak = true });
2355 try create_module.frameworks.put(arena, linker_args_it.nextOrFatal(), .{ .weak = true });
23132356 } else if (mem.eql(u8, arg, "-needed_framework")) {
2314 try frameworks.put(gpa, linker_args_it.nextOrFatal(), .{ .needed = true });
2357 try create_module.frameworks.put(arena, linker_args_it.nextOrFatal(), .{ .needed = true });
23152358 } else if (mem.eql(u8, arg, "-needed_library")) {
2316 try system_libs.put(linker_args_it.nextOrFatal(), .{
2359 try create_module.system_libs.put(arena, linker_args_it.nextOrFatal(), .{
23172360 .weak = false,
23182361 .needed = true,
23192362 .preferred_mode = lib_preferred_mode,
23202363 .search_strategy = lib_search_strategy,
23212364 });
23222365 } else if (mem.startsWith(u8, arg, "-weak-l")) {
2323 try system_libs.put(arg["-weak-l".len..], .{
2366 try create_module.system_libs.put(arena, arg["-weak-l".len..], .{
23242367 .weak = true,
23252368 .needed = false,
23262369 .preferred_mode = lib_preferred_mode,
23272370 .search_strategy = lib_search_strategy,
23282371 });
23292372 } else if (mem.eql(u8, arg, "-weak_library")) {
2330 try system_libs.put(linker_args_it.nextOrFatal(), .{
2373 try create_module.system_libs.put(arena, linker_args_it.nextOrFatal(), .{
23312374 .weak = true,
23322375 .needed = false,
23332376 .preferred_mode = lib_preferred_mode,
......@@ -2361,7 +2404,7 @@ fn buildOutputType(
23612404 } else if (mem.eql(u8, arg, "-install_name")) {
23622405 install_name = linker_args_it.nextOrFatal();
23632406 } else if (mem.eql(u8, arg, "-force_load")) {
2364 try link_objects.append(.{
2407 try create_module.link_objects.append(arena, .{
23652408 .path = linker_args_it.nextOrFatal(),
23662409 .must_link = true,
23672410 });
......@@ -2369,7 +2412,7 @@ fn buildOutputType(
23692412 mem.eql(u8, arg, "--hash-style"))
23702413 {
23712414 const next_arg = linker_args_it.nextOrFatal();
2372 hash_style = std.meta.stringToEnum(link.HashStyle, next_arg) orelse {
2415 hash_style = std.meta.stringToEnum(link.File.Elf.HashStyle, next_arg) orelse {
23732416 fatal("expected [sysv|gnu|both] after --hash-style, found '{s}'", .{
23742417 next_arg,
23752418 });
......@@ -2402,22 +2445,22 @@ fn buildOutputType(
24022445 }
24032446 }
24042447
2405 if (want_sanitize_c) |wsc| {
2406 if (wsc and optimize_mode == .ReleaseFast) {
2407 optimize_mode = .ReleaseSafe;
2448 if (mod_opts.sanitize_c) |wsc| {
2449 if (wsc and mod_opts.optimize_mode == .ReleaseFast) {
2450 mod_opts.optimize_mode = .ReleaseSafe;
24082451 }
24092452 }
24102453
24112454 switch (c_out_mode) {
24122455 .link => {
2413 output_mode = if (is_shared_lib) .Lib else .Exe;
2456 create_module.opts.output_mode = if (is_shared_lib) .Lib else .Exe;
24142457 emit_bin = if (out_path) |p| .{ .yes = p } else EmitBin.yes_a_out;
24152458 if (emit_llvm) {
24162459 fatal("-emit-llvm cannot be used when linking", .{});
24172460 }
24182461 },
24192462 .object => {
2420 output_mode = .Obj;
2463 create_module.opts.output_mode = .Obj;
24212464 if (emit_llvm) {
24222465 emit_bin = .no;
24232466 if (out_path) |p| {
......@@ -2434,7 +2477,7 @@ fn buildOutputType(
24342477 }
24352478 },
24362479 .assembly => {
2437 output_mode = .Obj;
2480 create_module.opts.output_mode = .Obj;
24382481 emit_bin = .no;
24392482 if (emit_llvm) {
24402483 if (out_path) |p| {
......@@ -2451,9 +2494,9 @@ fn buildOutputType(
24512494 }
24522495 },
24532496 .preprocessor => {
2454 output_mode = .Obj;
2497 create_module.opts.output_mode = .Obj;
24552498 // An error message is generated when there is more than 1 C source file.
2456 if (c_source_files.items.len != 1) {
2499 if (create_module.c_source_files.items.len != 1) {
24572500 // For example `zig cc` and no args should print the "no input files" message.
24582501 return process.exit(try clangMain(arena, all_args));
24592502 }
......@@ -2465,8 +2508,8 @@ fn buildOutputType(
24652508 }
24662509 },
24672510 }
2468 if (c_source_files.items.len == 0 and
2469 link_objects.items.len == 0 and
2511 if (create_module.c_source_files.items.len == 0 and
2512 create_module.link_objects.items.len == 0 and
24702513 root_src_file == null)
24712514 {
24722515 // For example `zig cc` and no args should print the "no input files" message.
......@@ -2476,258 +2519,115 @@ fn buildOutputType(
24762519 },
24772520 }
24782521
2479 {
2480 // Resolve module dependencies
2481 var it = modules.iterator();
2482 while (it.next()) |kv| {
2483 const deps_str = kv.value_ptr.deps_str;
2484 var deps_it = ModuleDepIterator.init(deps_str);
2485 while (deps_it.next()) |dep| {
2486 if (dep.expose.len == 0) {
2487 fatal("module '{s}' depends on '{s}' with a blank name", .{
2488 kv.key_ptr.*, dep.name,
2489 });
2490 }
2491
2492 for ([_][]const u8{ "std", "root", "builtin" }) |name| {
2493 if (mem.eql(u8, dep.expose, name)) {
2494 fatal("unable to add module '{s}' under name '{s}': conflicts with builtin module", .{
2495 dep.name, dep.expose,
2496 });
2497 }
2498 }
2499
2500 const dep_mod = modules.get(dep.name) orelse {
2501 fatal("module '{s}' depends on module '{s}' which does not exist", .{
2502 kv.key_ptr.*, dep.name,
2503 });
2504 };
2505
2506 try kv.value_ptr.mod.deps.put(arena, dep.expose, dep_mod.mod);
2507 }
2508 }
2509 }
2510
2511 if (arg_mode == .build and optimize_mode == .ReleaseSmall and strip == null)
2512 strip = true;
2513
2514 if (arg_mode == .translate_c and c_source_files.items.len != 1) {
2515 fatal("translate-c expects exactly 1 source file (found {d})", .{c_source_files.items.len});
2522 if (arg_mode == .translate_c and create_module.c_source_files.items.len != 1) {
2523 fatal("translate-c expects exactly 1 source file (found {d})", .{create_module.c_source_files.items.len});
25162524 }
25172525
2518 if (root_src_file == null and arg_mode == .zig_test) {
2519 fatal("`zig test` expects a zig source file argument", .{});
2526 if (show_builtin and root_src_file == null) {
2527 // Without this, there will be no main module created and no zig
2528 // compilation unit, and therefore also no builtin.zig contents
2529 // created.
2530 root_src_file = "builtin.zig";
25202531 }
25212532
2522 const root_name = if (provided_name) |n| n else blk: {
2523 if (arg_mode == .zig_test) {
2524 break :blk "test";
2525 } else if (root_src_file) |file| {
2526 const basename = fs.path.basename(file);
2527 break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
2528 } else if (c_source_files.items.len >= 1) {
2529 const basename = fs.path.basename(c_source_files.items[0].src_path);
2530 break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
2531 } else if (link_objects.items.len >= 1) {
2532 const basename = fs.path.basename(link_objects.items[0].path);
2533 break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
2534 } else if (emit_bin == .yes) {
2535 const basename = fs.path.basename(emit_bin.yes);
2536 break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
2537 } else if (rc_source_files.items.len >= 1) {
2538 const basename = fs.path.basename(rc_source_files.items[0].src_path);
2539 break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
2540 } else if (res_files.items.len >= 1) {
2541 const basename = fs.path.basename(res_files.items[0].path);
2542 break :blk basename[0 .. basename.len - fs.path.extension(basename).len];
2543 } else if (show_builtin) {
2544 break :blk "builtin";
2545 } else if (arg_mode == .run) {
2546 fatal("`zig run` expects at least one positional argument", .{});
2547 // TODO once the attempt to unwrap error: LinkingWithoutZigSourceUnimplemented
2548 // is solved, remove the above fatal() and uncomment the `break` below.
2549 //break :blk "run";
2550 } else {
2551 fatal("expected a positional argument, -femit-bin=[path], --show-builtin, or --name [name]", .{});
2552 }
2553 };
2554
2555 var target_parse_options: std.zig.CrossTarget.ParseOptions = .{
2556 .arch_os_abi = target_arch_os_abi,
2557 .cpu_features = target_mcpu,
2558 .dynamic_linker = target_dynamic_linker,
2559 .object_format = target_ofmt,
2560 };
2561
2562 // Before passing the mcpu string in for parsing, we convert any -m flags that were
2563 // passed in via zig cc to zig-style.
2564 if (llvm_m_args.items.len != 0) {
2565 // If this returns null, we let it fall through to the case below which will
2566 // run the full parse function and do proper error handling.
2567 if (std.zig.CrossTarget.parseCpuArch(target_parse_options)) |cpu_arch| {
2568 var llvm_to_zig_name = std.StringHashMap([]const u8).init(gpa);
2569 defer llvm_to_zig_name.deinit();
2570
2571 for (cpu_arch.allFeaturesList()) |feature| {
2572 const llvm_name = feature.llvm_name orelse continue;
2573 try llvm_to_zig_name.put(llvm_name, feature.name);
2533 implicit_root_mod: {
2534 const unresolved_src_path = b: {
2535 if (root_src_file) |src_path| {
2536 if (create_module.modules.count() != 0) {
2537 fatal("main module provided both by '--mod {s} {}{s}' and by positional argument '{s}'", .{
2538 create_module.modules.keys()[0],
2539 create_module.modules.values()[0].paths.root,
2540 create_module.modules.values()[0].paths.root_src_path,
2541 src_path,
2542 });
2543 }
2544 create_module.opts.have_zcu = true;
2545 break :b src_path;
25742546 }
25752547
2576 var mcpu_buffer = std.ArrayList(u8).init(gpa);
2577 defer mcpu_buffer.deinit();
2578
2579 try mcpu_buffer.appendSlice(target_mcpu orelse "baseline");
2548 if (create_module.modules.count() != 0)
2549 break :implicit_root_mod;
25802550
2581 for (llvm_m_args.items) |llvm_m_arg| {
2582 if (mem.startsWith(u8, llvm_m_arg, "mno-")) {
2583 const llvm_name = llvm_m_arg["mno-".len..];
2584 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {
2585 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{
2586 @tagName(cpu_arch), llvm_name,
2587 });
2588 };
2589 try mcpu_buffer.append('-');
2590 try mcpu_buffer.appendSlice(zig_name);
2591 } else if (mem.startsWith(u8, llvm_m_arg, "m")) {
2592 const llvm_name = llvm_m_arg["m".len..];
2593 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {
2594 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{
2595 @tagName(cpu_arch), llvm_name,
2596 });
2597 };
2598 try mcpu_buffer.append('+');
2599 try mcpu_buffer.appendSlice(zig_name);
2600 } else {
2601 unreachable;
2602 }
2603 }
2551 if (create_module.c_source_files.items.len >= 1)
2552 break :b create_module.c_source_files.items[0].src_path;
26042553
2605 const adjusted_target_mcpu = try arena.dupe(u8, mcpu_buffer.items);
2606 std.log.debug("adjusted target_mcpu: {s}", .{adjusted_target_mcpu});
2607 target_parse_options.cpu_features = adjusted_target_mcpu;
2608 }
2609 }
2554 if (create_module.link_objects.items.len >= 1)
2555 break :b create_module.link_objects.items[0].path;
26102556
2611 const cross_target = try parseCrossTargetOrReportFatalError(arena, target_parse_options);
2612 const target_info = try detectNativeTargetInfo(cross_target);
2557 if (emit_bin == .yes)
2558 break :b emit_bin.yes;
26132559
2614 if (target_info.target.os.tag != .freestanding) {
2615 if (ensure_libc_on_non_freestanding)
2616 link_libc = true;
2617 if (ensure_libcpp_on_non_freestanding)
2618 link_libcpp = true;
2619 }
2560 if (create_module.rc_source_files.items.len >= 1)
2561 break :b create_module.rc_source_files.items[0].src_path;
26202562
2621 if (linker_force_entry) |force| {
2622 if (!force) {
2623 entry = null;
2624 } else if (entry == null and output_mode == .Exe) {
2625 entry = switch (target_info.target.ofmt) {
2626 .coff => "wWinMainCRTStartup",
2627 .macho => "_main",
2628 .elf, .plan9 => "_start",
2629 .wasm => defaultWasmEntryName(wasi_exec_model),
2630 else => |tag| fatal("No default entry point available for output format {s}", .{@tagName(tag)}),
2631 };
2632 }
2633 } else if (entry == null and target_info.target.isWasm() and output_mode == .Exe) {
2634 // For WebAssembly the compiler defaults to setting the entry name when no flags are set.
2635 entry = defaultWasmEntryName(wasi_exec_model);
2636 }
2563 if (arg_mode == .run)
2564 fatal("`zig run` expects at least one positional argument", .{});
26372565
2638 if (target_info.target.ofmt == .coff) {
2639 // Now that we know the target supports resources,
2640 // we can add the res files as link objects.
2641 for (res_files.items) |res_file| {
2642 try link_objects.append(res_file);
2643 }
2644 } else {
2645 if (manifest_file != null) {
2646 fatal("manifest file is not allowed unless the target object format is coff (Windows/UEFI)", .{});
2647 }
2648 if (rc_source_files.items.len != 0) {
2649 fatal("rc files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
2650 }
2651 if (res_files.items.len != 0) {
2652 fatal("res files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
2653 }
2654 }
2566 fatal("expected a positional argument, -femit-bin=[path], --show-builtin, or --name [name]", .{});
26552567
2656 if (target_info.target.cpu.arch.isWasm()) blk: {
2657 if (single_threaded == null) {
2658 single_threaded = true;
2659 }
2660 if (link_mode) |mode| {
2661 if (mode == .Dynamic) {
2662 if (linker_export_memory != null and linker_export_memory.?) {
2663 fatal("flags '-dynamic' and '--export-memory' are incompatible", .{});
2664 }
2665 // User did not supply `--export-memory` which is incompatible with -dynamic, therefore
2666 // set the flag to false to ensure it does not get enabled by default.
2667 linker_export_memory = false;
2668 }
2669 }
2670 if (wasi_exec_model != null and wasi_exec_model.? == .reactor) {
2671 if (entry) |entry_name| {
2672 if (!mem.eql(u8, "_initialize", entry_name)) {
2673 fatal("the entry symbol of the reactor model must be '_initialize', but found '{s}'", .{entry_name});
2674 }
2675 }
2676 }
2677 if (linker_shared_memory) {
2678 if (output_mode == .Obj) {
2679 fatal("shared memory is not allowed in object files", .{});
2680 }
2568 break :implicit_root_mod;
2569 };
26812570
2682 if (!target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.atomics)) or
2683 !target_info.target.cpu.features.isEnabled(@intFromEnum(std.Target.wasm.Feature.bulk_memory)))
2684 {
2685 fatal("'atomics' and 'bulk-memory' features must be enabled to use shared memory", .{});
2686 }
2687 break :blk;
2688 }
2571 // See duplicate logic: ModCreationGlobalFlags
2572 if (mod_opts.single_threaded == false)
2573 create_module.opts.any_non_single_threaded = true;
2574 if (mod_opts.sanitize_thread == true)
2575 create_module.opts.any_sanitize_thread = true;
2576 if (mod_opts.unwind_tables == true)
2577 create_module.opts.any_unwind_tables = true;
2578 if (mod_opts.strip == false)
2579 create_module.opts.any_non_stripped = true;
2580 if (mod_opts.error_tracing == true)
2581 create_module.opts.any_error_tracing = true;
26892582
2690 // Single-threaded is the default for WebAssembly, so only when the user specified `-fno_single-threaded`
2691 // can they enable multithreaded WebAssembly builds.
2692 const is_single_threaded = single_threaded.?;
2693 if (!is_single_threaded) {
2694 fatal("'-fno-single-threaded' requires the linker feature shared-memory to be enabled using '--shared-memory'", .{});
2695 }
2696 }
2583 const src_path = try introspect.resolvePath(arena, unresolved_src_path);
2584 const name = if (arg_mode == .zig_test)
2585 "test"
2586 else
2587 fs.path.stem(fs.path.basename(src_path));
26972588
2698 if (use_lld) |opt| {
2699 if (opt and cross_target.isDarwin()) {
2700 fatal("LLD requested with Mach-O object format. Only the self-hosted linker is supported for this target.", .{});
2701 }
2589 try create_module.modules.put(arena, name, .{
2590 .paths = .{
2591 .root = .{
2592 .root_dir = Cache.Directory.cwd(),
2593 .sub_path = fs.path.dirname(src_path) orelse "",
2594 },
2595 .root_src_path = fs.path.basename(src_path),
2596 },
2597 .cc_argv = try cc_argv.toOwnedSlice(arena),
2598 .inherited = mod_opts,
2599 .target_arch_os_abi = target_arch_os_abi,
2600 .target_mcpu = target_mcpu,
2601 .deps = try deps.toOwnedSlice(arena),
2602 .resolved = null,
2603 .c_source_files_start = c_source_files_owner_index,
2604 .c_source_files_end = create_module.c_source_files.items.len,
2605 .rc_source_files_start = rc_source_files_owner_index,
2606 .rc_source_files_end = create_module.rc_source_files.items.len,
2607 });
2608 cssan.reset();
2609 mod_opts = .{};
2610 target_arch_os_abi = null;
2611 target_mcpu = null;
2612 c_source_files_owner_index = create_module.c_source_files.items.len;
2613 rc_source_files_owner_index = create_module.rc_source_files.items.len;
27022614 }
27032615
2704 if (want_lto) |opt| {
2705 if (opt and cross_target.isDarwin()) {
2706 fatal("LTO is not yet supported with the Mach-O object format. More details: https://github.com/ziglang/zig/issues/8680", .{});
2707 }
2616 if (!create_module.opts.have_zcu and arg_mode == .zig_test) {
2617 fatal("`zig test` expects a zig source file argument", .{});
27082618 }
27092619
2710 if (comptime builtin.target.isDarwin()) {
2711 // If we want to link against frameworks, we need system headers.
2712 if (framework_dirs.items.len > 0 or frameworks.count() > 0)
2713 want_native_include_dirs = true;
2620 if (c_source_files_owner_index != create_module.c_source_files.items.len) {
2621 fatal("C source file '{s}' has no parent module", .{
2622 create_module.c_source_files.items[c_source_files_owner_index].src_path,
2623 });
27142624 }
27152625
2716 // Resolve the library path arguments with respect to sysroot.
2717 var lib_dirs = std.ArrayList([]const u8).init(arena);
2718 if (sysroot) |root| {
2719 for (lib_dir_args.items) |dir| {
2720 if (fs.path.isAbsolute(dir)) {
2721 const stripped_dir = dir[fs.path.diskDesignator(dir).len..];
2722 const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir });
2723 try lib_dirs.append(full_path);
2724 }
2725 try lib_dirs.append(dir);
2726 }
2727 } else {
2728 lib_dirs = lib_dir_args;
2626 if (rc_source_files_owner_index != create_module.rc_source_files.items.len) {
2627 fatal("resource file '{s}' has no parent module", .{
2628 create_module.rc_source_files.items[rc_source_files_owner_index].src_path,
2629 });
27292630 }
2730 lib_dir_args = undefined; // From here we use lib_dirs instead.
27312631
27322632 const self_exe_path: ?[]const u8 = if (!process.can_spawn)
27332633 null
......@@ -2757,290 +2657,119 @@ fn buildOutputType(
27572657 };
27582658 defer zig_lib_directory.handle.close();
27592659
2760 // First, remove libc, libc++, and compiler_rt libraries from the system libraries list.
2761 // We need to know whether the set of system libraries contains anything besides these
2762 // to decide whether to trigger native path detection logic.
2763 var external_system_libs: std.MultiArrayList(struct {
2764 name: []const u8,
2765 info: SystemLib,
2766 }) = .{};
2767
2768 var resolved_system_libs: std.MultiArrayList(struct {
2769 name: []const u8,
2770 lib: Compilation.SystemLib,
2771 }) = .{};
2772
2773 var libc_installation: ?LibCInstallation = null;
2774 if (libc_paths_file) |paths_file| {
2775 libc_installation = LibCInstallation.parse(arena, paths_file, cross_target) catch |err| {
2776 fatal("unable to parse libc paths file at path {s}: {s}", .{ paths_file, @errorName(err) });
2777 };
2778 }
2779
2780 for (system_libs.keys(), system_libs.values()) |lib_name, info| {
2781 if (target_util.is_libc_lib_name(target_info.target, lib_name)) {
2782 link_libc = true;
2783 continue;
2784 }
2785 if (target_util.is_libcpp_lib_name(target_info.target, lib_name)) {
2786 link_libcpp = true;
2787 continue;
2788 }
2789 switch (target_util.classifyCompilerRtLibName(target_info.target, lib_name)) {
2790 .none => {},
2791 .only_libunwind, .both => {
2792 link_libunwind = true;
2793 continue;
2794 },
2795 .only_compiler_rt => {
2796 warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name});
2797 continue;
2798 },
2799 }
2800
2801 if (target_info.target.isMinGW()) {
2802 const exists = mingw.libExists(arena, target_info.target, zig_lib_directory, lib_name) catch |err| {
2803 fatal("failed to check zig installation for DLL import libs: {s}", .{
2804 @errorName(err),
2805 });
2660 var global_cache_directory: Compilation.Directory = l: {
2661 if (override_global_cache_dir) |p| {
2662 break :l .{
2663 .handle = try fs.cwd().makeOpenPath(p, .{}),
2664 .path = p,
28062665 };
2807 if (exists) {
2808 try resolved_system_libs.append(arena, .{
2809 .name = lib_name,
2810 .lib = .{
2811 .needed = true,
2812 .weak = false,
2813 .path = null,
2814 },
2815 });
2816 continue;
2817 }
28182666 }
2819
2820 if (fs.path.isAbsolute(lib_name)) {
2821 fatal("cannot use absolute path as a system library: {s}", .{lib_name});
2822 }
2823
2824 if (target_info.target.os.tag == .wasi) {
2825 if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| {
2826 try wasi_emulated_libs.append(crt_file);
2827 continue;
2828 }
2667 if (builtin.os.tag == .wasi) {
2668 break :l getWasiPreopen("/cache");
28292669 }
2830
2831 try external_system_libs.append(arena, .{
2832 .name = lib_name,
2833 .info = info,
2834 });
2835 }
2836 // After this point, external_system_libs is used instead of system_libs.
2837
2838 // Trigger native system library path detection if necessary.
2839 if (sysroot == null and cross_target.isNativeOs() and cross_target.isNativeAbi() and
2840 (external_system_libs.len != 0 or want_native_include_dirs))
2841 {
2842 const paths = std.zig.system.NativePaths.detect(arena, target_info) catch |err| {
2843 fatal("unable to detect native system paths: {s}", .{@errorName(err)});
2670 const p = try introspect.resolveGlobalCacheDir(arena);
2671 break :l .{
2672 .handle = try fs.cwd().makeOpenPath(p, .{}),
2673 .path = p,
28442674 };
2845 for (paths.warnings.items) |warning| {
2846 warn("{s}", .{warning});
2847 }
2848
2849 try clang_argv.ensureUnusedCapacity(paths.include_dirs.items.len * 2);
2850 for (paths.include_dirs.items) |include_dir| {
2851 clang_argv.appendAssumeCapacity("-isystem");
2852 clang_argv.appendAssumeCapacity(include_dir);
2853 }
2675 };
2676 defer global_cache_directory.handle.close();
28542677
2855 try framework_dirs.appendSlice(paths.framework_dirs.items);
2856 try lib_dirs.appendSlice(paths.lib_dirs.items);
2857 try rpath_list.appendSlice(paths.rpaths.items);
2678 if (linker_optimization) |o| {
2679 warn("ignoring deprecated linker optimization setting '{s}'", .{o});
28582680 }
28592681
2860 if (builtin.target.os.tag == .windows and
2861 target_info.target.abi == .msvc and
2862 external_system_libs.len != 0)
2863 {
2864 if (libc_installation == null) {
2865 libc_installation = try LibCInstallation.findNative(.{
2866 .allocator = arena,
2867 .verbose = true,
2868 .target = cross_target.toTarget(),
2869 });
2682 create_module.global_cache_directory = global_cache_directory;
2683 create_module.opts.emit_llvm_ir = emit_llvm_ir != .no;
2684 create_module.opts.emit_llvm_bc = emit_llvm_bc != .no;
2685 create_module.opts.emit_bin = emit_bin != .no;
2686 create_module.opts.any_c_source_files = create_module.c_source_files.items.len != 0;
28702687
2871 try lib_dirs.appendSlice(&.{ libc_installation.?.msvc_lib_dir.?, libc_installation.?.kernel32_lib_dir.? });
2872 }
2688 const main_mod = try createModule(gpa, arena, &create_module, 0, null, zig_lib_directory);
2689 for (create_module.modules.keys(), create_module.modules.values()) |key, cli_mod| {
2690 if (cli_mod.resolved == null)
2691 fatal("module '{s}' declared but not used", .{key});
28732692 }
28742693
2875 // If any libs in this list are statically provided, we omit them from the
2876 // resolved list and populate the link_objects array instead.
2877 {
2878 var test_path = std.ArrayList(u8).init(gpa);
2879 defer test_path.deinit();
2880
2881 var checked_paths = std.ArrayList(u8).init(gpa);
2882 defer checked_paths.deinit();
2694 // When you're testing std, the main module is std. In that case,
2695 // we'll just set the std module to the main one, since avoiding
2696 // the errors caused by duplicating it is more effort than it's
2697 // worth.
2698 const main_mod_is_std = m: {
2699 const std_path = try fs.path.resolve(arena, &.{
2700 zig_lib_directory.path orelse ".", "std", "std.zig",
2701 });
2702 const main_path = try fs.path.resolve(arena, &.{
2703 main_mod.root.root_dir.path orelse ".",
2704 main_mod.root.sub_path,
2705 main_mod.root_src_path,
2706 });
2707 break :m mem.eql(u8, main_path, std_path);
2708 };
28832709
2884 var failed_libs = std.ArrayList(struct {
2885 name: []const u8,
2886 strategy: SystemLib.SearchStrategy,
2887 checked_paths: []const u8,
2888 preferred_mode: std.builtin.LinkMode,
2889 }).init(arena);
2710 const std_mod = m: {
2711 if (main_mod_is_std) break :m main_mod;
2712 if (create_module.modules.get("std")) |cli_mod| break :m cli_mod.resolved.?;
2713 break :m null;
2714 };
28902715
2891 syslib: for (external_system_libs.items(.name), external_system_libs.items(.info)) |lib_name, info| {
2892 // Checked in the first pass above while looking for libc libraries.
2893 assert(!fs.path.isAbsolute(lib_name));
2716 const root_mod = if (arg_mode == .zig_test) root_mod: {
2717 const test_mod = if (test_runner_path) |test_runner| test_mod: {
2718 const test_mod = try Package.Module.create(arena, .{
2719 .global_cache_directory = global_cache_directory,
2720 .paths = .{
2721 .root = .{
2722 .root_dir = Cache.Directory.cwd(),
2723 .sub_path = fs.path.dirname(test_runner) orelse "",
2724 },
2725 .root_src_path = fs.path.basename(test_runner),
2726 },
2727 .fully_qualified_name = "root",
2728 .cc_argv = &.{},
2729 .inherited = .{},
2730 .global = create_module.resolved_options,
2731 .parent = main_mod,
2732 .builtin_mod = main_mod.getBuiltinDependency(),
2733 });
2734 test_mod.deps = try main_mod.deps.clone(arena);
2735 break :test_mod test_mod;
2736 } else try Package.Module.create(arena, .{
2737 .global_cache_directory = global_cache_directory,
2738 .paths = .{
2739 .root = .{
2740 .root_dir = zig_lib_directory,
2741 },
2742 .root_src_path = "test_runner.zig",
2743 },
2744 .fully_qualified_name = "root",
2745 .cc_argv = &.{},
2746 .inherited = .{},
2747 .global = create_module.resolved_options,
2748 .parent = main_mod,
2749 .builtin_mod = main_mod.getBuiltinDependency(),
2750 });
28942751
2895 checked_paths.clearRetainingCapacity();
2752 break :root_mod test_mod;
2753 } else main_mod;
28962754
2897 switch (info.search_strategy) {
2898 .mode_first, .no_fallback => {
2899 // check for preferred mode
2900 for (lib_dirs.items) |lib_dir_path| {
2901 if (try accessLibPath(
2902 &test_path,
2903 &checked_paths,
2904 lib_dir_path,
2905 lib_name,
2906 target_info.target,
2907 info.preferred_mode,
2908 )) {
2909 const path = try arena.dupe(u8, test_path.items);
2910 switch (info.preferred_mode) {
2911 .Static => try link_objects.append(.{ .path = path }),
2912 .Dynamic => try resolved_system_libs.append(arena, .{
2913 .name = lib_name,
2914 .lib = .{
2915 .needed = info.needed,
2916 .weak = info.weak,
2917 .path = path,
2918 },
2919 }),
2920 }
2921 continue :syslib;
2922 }
2923 }
2924 // check for fallback mode
2925 if (info.search_strategy == .no_fallback) {
2926 try failed_libs.append(.{
2927 .name = lib_name,
2928 .strategy = info.search_strategy,
2929 .checked_paths = try arena.dupe(u8, checked_paths.items),
2930 .preferred_mode = info.preferred_mode,
2931 });
2932 continue :syslib;
2933 }
2934 for (lib_dirs.items) |lib_dir_path| {
2935 if (try accessLibPath(
2936 &test_path,
2937 &checked_paths,
2938 lib_dir_path,
2939 lib_name,
2940 target_info.target,
2941 info.fallbackMode(),
2942 )) {
2943 const path = try arena.dupe(u8, test_path.items);
2944 switch (info.fallbackMode()) {
2945 .Static => try link_objects.append(.{ .path = path }),
2946 .Dynamic => try resolved_system_libs.append(arena, .{
2947 .name = lib_name,
2948 .lib = .{
2949 .needed = info.needed,
2950 .weak = info.weak,
2951 .path = path,
2952 },
2953 }),
2954 }
2955 continue :syslib;
2956 }
2957 }
2958 try failed_libs.append(.{
2959 .name = lib_name,
2960 .strategy = info.search_strategy,
2961 .checked_paths = try arena.dupe(u8, checked_paths.items),
2962 .preferred_mode = info.preferred_mode,
2963 });
2964 continue :syslib;
2965 },
2966 .paths_first => {
2967 for (lib_dirs.items) |lib_dir_path| {
2968 // check for preferred mode
2969 if (try accessLibPath(
2970 &test_path,
2971 &checked_paths,
2972 lib_dir_path,
2973 lib_name,
2974 target_info.target,
2975 info.preferred_mode,
2976 )) {
2977 const path = try arena.dupe(u8, test_path.items);
2978 switch (info.preferred_mode) {
2979 .Static => try link_objects.append(.{ .path = path }),
2980 .Dynamic => try resolved_system_libs.append(arena, .{
2981 .name = lib_name,
2982 .lib = .{
2983 .needed = info.needed,
2984 .weak = info.weak,
2985 .path = path,
2986 },
2987 }),
2988 }
2989 continue :syslib;
2990 }
2755 const target = main_mod.resolved_target.result;
29912756
2992 // check for fallback mode
2993 if (try accessLibPath(
2994 &test_path,
2995 &checked_paths,
2996 lib_dir_path,
2997 lib_name,
2998 target_info.target,
2999 info.fallbackMode(),
3000 )) {
3001 const path = try arena.dupe(u8, test_path.items);
3002 switch (info.fallbackMode()) {
3003 .Static => try link_objects.append(.{ .path = path }),
3004 .Dynamic => try resolved_system_libs.append(arena, .{
3005 .name = lib_name,
3006 .lib = .{
3007 .needed = info.needed,
3008 .weak = info.weak,
3009 .path = path,
3010 },
3011 }),
3012 }
3013 continue :syslib;
3014 }
3015 }
3016 try failed_libs.append(.{
3017 .name = lib_name,
3018 .strategy = info.search_strategy,
3019 .checked_paths = try arena.dupe(u8, checked_paths.items),
3020 .preferred_mode = info.preferred_mode,
3021 });
3022 continue :syslib;
3023 },
3024 }
3025 @compileError("unreachable");
2757 if (target.ofmt != .coff) {
2758 if (manifest_file != null) {
2759 fatal("manifest file is not allowed unless the target object format is coff (Windows/UEFI)", .{});
30262760 }
3027
3028 if (failed_libs.items.len > 0) {
3029 for (failed_libs.items) |f| {
3030 const searched_paths = if (f.checked_paths.len == 0) " none" else f.checked_paths;
3031 std.log.err("unable to find {s} system library '{s}' using strategy '{s}'. searched paths:{s}", .{
3032 @tagName(f.preferred_mode), f.name, @tagName(f.strategy), searched_paths,
3033 });
3034 }
3035 process.exit(1);
2761 if (create_module.rc_source_files.items.len != 0) {
2762 fatal("rc files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
2763 }
2764 if (contains_res_file) {
2765 fatal("res files are not allowed unless the target object format is coff (Windows/UEFI)", .{});
30362766 }
30372767 }
3038 // After this point, resolved_system_libs is used instead of external_system_libs.
30392768
30402769 // We now repeat part of the process for frameworks.
30412770 var resolved_frameworks = std.ArrayList(Compilation.Framework).init(arena);
30422771
3043 if (frameworks.keys().len > 0) {
2772 if (create_module.frameworks.keys().len > 0) {
30442773 var test_path = std.ArrayList(u8).init(gpa);
30452774 defer test_path.deinit();
30462775
......@@ -3052,10 +2781,10 @@ fn buildOutputType(
30522781 checked_paths: []const u8,
30532782 }).init(arena);
30542783
3055 framework: for (frameworks.keys(), frameworks.values()) |framework_name, info| {
2784 framework: for (create_module.frameworks.keys(), create_module.frameworks.values()) |framework_name, info| {
30562785 checked_paths.clearRetainingCapacity();
30572786
3058 for (framework_dirs.items) |framework_dir_path| {
2787 for (create_module.framework_dirs.items) |framework_dir_path| {
30592788 if (try accessFrameworkPath(
30602789 &test_path,
30612790 &checked_paths,
......@@ -3090,15 +2819,15 @@ fn buildOutputType(
30902819 }
30912820 // After this point, resolved_frameworks is used instead of frameworks.
30922821
3093 const object_format = target_info.target.ofmt;
3094
3095 if (output_mode == .Obj and (object_format == .coff or object_format == .macho)) {
3096 const total_obj_count = c_source_files.items.len +
2822 if (create_module.resolved_options.output_mode == .Obj and
2823 (target.ofmt == .coff or target.ofmt == .macho))
2824 {
2825 const total_obj_count = create_module.c_source_files.items.len +
30972826 @intFromBool(root_src_file != null) +
3098 rc_source_files.items.len +
3099 link_objects.items.len;
2827 create_module.rc_source_files.items.len +
2828 create_module.link_objects.items.len;
31002829 if (total_obj_count > 1) {
3101 fatal("{s} does not support linking multiple objects into one", .{@tagName(object_format)});
2830 fatal("{s} does not support linking multiple objects into one", .{@tagName(target.ofmt)});
31022831 }
31032832 }
31042833
......@@ -3108,10 +2837,12 @@ fn buildOutputType(
31082837 const output_to_cache = listen != .none;
31092838 const optional_version = if (have_version) version else null;
31102839
2840 const root_name = if (provided_name) |n| n else main_mod.fully_qualified_name;
2841
31112842 const resolved_soname: ?[]const u8 = switch (soname) {
31122843 .yes => |explicit| explicit,
31132844 .no => null,
3114 .yes_default_value => switch (object_format) {
2845 .yes_default_value => switch (target.ofmt) {
31152846 .elf => if (have_version)
31162847 try std.fmt.allocPrint(arena, "lib{s}.so.{d}", .{ root_name, version.major })
31172848 else
......@@ -3120,7 +2851,7 @@ fn buildOutputType(
31202851 },
31212852 };
31222853
3123 const a_out_basename = switch (object_format) {
2854 const a_out_basename = switch (target.ofmt) {
31242855 .coff => "a.exe",
31252856 else => "a.out",
31262857 };
......@@ -3142,9 +2873,9 @@ fn buildOutputType(
31422873 },
31432874 .basename = try std.zig.binNameAlloc(arena, .{
31442875 .root_name = root_name,
3145 .target = target_info.target,
3146 .output_mode = output_mode,
3147 .link_mode = link_mode,
2876 .target = target,
2877 .output_mode = create_module.resolved_options.output_mode,
2878 .link_mode = create_module.resolved_options.link_mode,
31482879 .version = optional_version,
31492880 }),
31502881 },
......@@ -3262,15 +2993,15 @@ fn buildOutputType(
32622993 };
32632994 defer emit_docs_resolved.deinit();
32642995
3265 const is_exe_or_dyn_lib = switch (output_mode) {
2996 const is_exe_or_dyn_lib = switch (create_module.resolved_options.output_mode) {
32662997 .Obj => false,
3267 .Lib => (link_mode orelse .Static) == .Dynamic,
2998 .Lib => create_module.resolved_options.link_mode == .Dynamic,
32682999 .Exe => true,
32693000 };
32703001 // Note that cmake when targeting Windows will try to execute
32713002 // zig cc to make an executable and output an implib too.
32723003 const implib_eligible = is_exe_or_dyn_lib and
3273 emit_bin_loc != null and target_info.target.os.tag == .windows;
3004 emit_bin_loc != null and target.os.tag == .windows;
32743005 if (!implib_eligible) {
32753006 if (!emit_implib_arg_provided) {
32763007 emit_implib = .no;
......@@ -3296,76 +3027,10 @@ fn buildOutputType(
32963027 };
32973028 defer emit_implib_resolved.deinit();
32983029
3299 const main_mod: ?*Package.Module = if (root_src_file) |unresolved_src_path| blk: {
3300 const src_path = try introspect.resolvePath(arena, unresolved_src_path);
3301 if (main_mod_path) |unresolved_main_mod_path| {
3302 const p = try introspect.resolvePath(arena, unresolved_main_mod_path);
3303 break :blk try Package.Module.create(arena, .{
3304 .root = .{
3305 .root_dir = Cache.Directory.cwd(),
3306 .sub_path = p,
3307 },
3308 .root_src_path = if (p.len == 0)
3309 src_path
3310 else
3311 try fs.path.relative(arena, p, src_path),
3312 .fully_qualified_name = "root",
3313 });
3314 } else {
3315 break :blk try Package.Module.create(arena, .{
3316 .root = .{
3317 .root_dir = Cache.Directory.cwd(),
3318 .sub_path = fs.path.dirname(src_path) orelse "",
3319 },
3320 .root_src_path = fs.path.basename(src_path),
3321 .fully_qualified_name = "root",
3322 });
3323 }
3324 } else null;
3325
3326 // Transfer packages added with --deps to the root package
3327 if (main_mod) |mod| {
3328 var it = ModuleDepIterator.init(root_deps_str orelse "");
3329 while (it.next()) |dep| {
3330 if (dep.expose.len == 0) {
3331 fatal("root module depends on '{s}' with a blank name", .{dep.name});
3332 }
3333
3334 for ([_][]const u8{ "std", "root", "builtin" }) |name| {
3335 if (mem.eql(u8, dep.expose, name)) {
3336 fatal("unable to add module '{s}' under name '{s}': conflicts with builtin module", .{ dep.name, dep.expose });
3337 }
3338 }
3339
3340 const dep_mod = modules.get(dep.name) orelse
3341 fatal("root module depends on module '{s}' which does not exist", .{dep.name});
3342
3343 try mod.deps.put(arena, dep.expose, dep_mod.mod);
3344 }
3345 }
3346
33473030 var thread_pool: ThreadPool = undefined;
33483031 try thread_pool.init(.{ .allocator = gpa });
33493032 defer thread_pool.deinit();
33503033
3351 var global_cache_directory: Compilation.Directory = l: {
3352 if (override_global_cache_dir) |p| {
3353 break :l .{
3354 .handle = try fs.cwd().makeOpenPath(p, .{}),
3355 .path = p,
3356 };
3357 }
3358 if (builtin.os.tag == .wasi) {
3359 break :l getWasiPreopen("/cache");
3360 }
3361 const p = try introspect.resolveGlobalCacheDir(arena);
3362 break :l .{
3363 .handle = try fs.cwd().makeOpenPath(p, .{}),
3364 .path = p,
3365 };
3366 };
3367 defer global_cache_directory.handle.close();
3368
33693034 var cleanup_local_cache_dir: ?fs.Dir = null;
33703035 defer if (cleanup_local_cache_dir) |*dir| dir.close();
33713036
......@@ -3381,37 +3046,37 @@ fn buildOutputType(
33813046 if (arg_mode == .run) {
33823047 break :l global_cache_directory;
33833048 }
3384 if (main_mod != null) {
3385 // search upwards from cwd until we find directory with build.zig
3386 const cwd_path = try process.getCwdAlloc(arena);
3387 const zig_cache = "zig-cache";
3388 var dirname: []const u8 = cwd_path;
3389 while (true) {
3390 const joined_path = try fs.path.join(arena, &.{
3391 dirname, Package.build_zig_basename,
3392 });
3393 if (fs.cwd().access(joined_path, .{})) |_| {
3394 const cache_dir_path = try fs.path.join(arena, &.{ dirname, zig_cache });
3395 const dir = try fs.cwd().makeOpenPath(cache_dir_path, .{});
3396 cleanup_local_cache_dir = dir;
3397 break :l .{ .handle = dir, .path = cache_dir_path };
3398 } else |err| switch (err) {
3399 error.FileNotFound => {
3400 dirname = fs.path.dirname(dirname) orelse {
3401 break :l global_cache_directory;
3402 };
3403 continue;
3404 },
3405 else => break :l global_cache_directory,
3406 }
3049
3050 // search upwards from cwd until we find directory with build.zig
3051 const cwd_path = try process.getCwdAlloc(arena);
3052 const zig_cache = "zig-cache";
3053 var dirname: []const u8 = cwd_path;
3054 while (true) {
3055 const joined_path = try fs.path.join(arena, &.{
3056 dirname, Package.build_zig_basename,
3057 });
3058 if (fs.cwd().access(joined_path, .{})) |_| {
3059 const cache_dir_path = try fs.path.join(arena, &.{ dirname, zig_cache });
3060 const dir = try fs.cwd().makeOpenPath(cache_dir_path, .{});
3061 cleanup_local_cache_dir = dir;
3062 break :l .{ .handle = dir, .path = cache_dir_path };
3063 } else |err| switch (err) {
3064 error.FileNotFound => {
3065 dirname = fs.path.dirname(dirname) orelse {
3066 break :l global_cache_directory;
3067 };
3068 continue;
3069 },
3070 else => break :l global_cache_directory,
34073071 }
34083072 }
3073
34093074 // Otherwise we really don't have a reasonable place to put the local cache directory,
34103075 // so we utilize the global one.
34113076 break :l global_cache_directory;
34123077 };
34133078
3414 for (c_source_files.items) |*src| {
3079 for (create_module.c_source_files.items) |*src| {
34153080 if (!mem.eql(u8, src.src_path, "-")) continue;
34163081
34173082 const ext = src.ext orelse
......@@ -3420,7 +3085,7 @@ fn buildOutputType(
34203085 // "-" is stdin. Dump it to a real file.
34213086 const sep = fs.path.sep_str;
34223087 const sub_path = try std.fmt.allocPrint(arena, "tmp" ++ sep ++ "{x}-stdin{s}", .{
3423 std.crypto.random.int(u64), ext.canonicalName(target_info.target),
3088 std.crypto.random.int(u64), ext.canonicalName(target),
34243089 });
34253090 try local_cache_directory.handle.makePath("tmp");
34263091 // Note that in one of the happy paths, execve() is used to switch
......@@ -3448,20 +3113,35 @@ fn buildOutputType(
34483113 else => false,
34493114 };
34503115
3116 const disable_lld_caching = !output_to_cache;
3117
3118 const cache_mode: Compilation.CacheMode = b: {
3119 if (disable_lld_caching) break :b .incremental;
3120 if (!create_module.resolved_options.have_zcu) break :b .whole;
3121
3122 // TODO: once we support incremental compilation for the LLVM backend
3123 // via saving the LLVM module into a bitcode file and restoring it,
3124 // along with compiler state, this clause can be removed so that
3125 // incremental cache mode is used for LLVM backend too.
3126 if (create_module.resolved_options.use_llvm) break :b .whole;
3127
3128 break :b .incremental;
3129 };
3130
34513131 gimmeMoreOfThoseSweetSweetFileDescriptors();
34523132
3453 const comp = Compilation.create(gpa, .{
3133 const comp = Compilation.create(gpa, arena, .{
34543134 .zig_lib_directory = zig_lib_directory,
34553135 .local_cache_directory = local_cache_directory,
34563136 .global_cache_directory = global_cache_directory,
3137 .thread_pool = &thread_pool,
3138 .self_exe_path = self_exe_path,
3139 .config = create_module.resolved_options,
34573140 .root_name = root_name,
3458 .target = target_info.target,
3459 .is_native_os = cross_target.isNativeOs(),
3460 .is_native_abi = cross_target.isNativeAbi(),
3461 .dynamic_linker = target_info.dynamic_linker.get(),
3462 .sysroot = sysroot,
3463 .output_mode = output_mode,
3141 .sysroot = create_module.sysroot,
34643142 .main_mod = main_mod,
3143 .root_mod = root_mod,
3144 .std_mod = std_mod,
34653145 .emit_bin = emit_bin_loc,
34663146 .emit_h = emit_h_resolved.data,
34673147 .emit_asm = emit_asm_resolved.data,
......@@ -3469,45 +3149,21 @@ fn buildOutputType(
34693149 .emit_llvm_bc = emit_llvm_bc_resolved.data,
34703150 .emit_docs = emit_docs_resolved.data,
34713151 .emit_implib = emit_implib_resolved.data,
3472 .link_mode = link_mode,
3473 .dll_export_fns = dll_export_fns,
3474 .optimize_mode = optimize_mode,
3475 .keep_source_files_loaded = false,
3476 .clang_argv = clang_argv.items,
3477 .lib_dirs = lib_dirs.items,
3478 .rpath_list = rpath_list.items,
3152 .lib_dirs = create_module.lib_dirs.items,
3153 .rpath_list = create_module.rpath_list.items,
34793154 .symbol_wrap_set = symbol_wrap_set,
3480 .c_source_files = c_source_files.items,
3481 .rc_source_files = rc_source_files.items,
3155 .c_source_files = create_module.c_source_files.items,
3156 .rc_source_files = create_module.rc_source_files.items,
34823157 .manifest_file = manifest_file,
34833158 .rc_includes = rc_includes,
3484 .link_objects = link_objects.items,
3485 .framework_dirs = framework_dirs.items,
3159 .link_objects = create_module.link_objects.items,
3160 .framework_dirs = create_module.framework_dirs.items,
34863161 .frameworks = resolved_frameworks.items,
3487 .system_lib_names = resolved_system_libs.items(.name),
3488 .system_lib_infos = resolved_system_libs.items(.lib),
3489 .wasi_emulated_libs = wasi_emulated_libs.items,
3490 .link_libc = link_libc,
3491 .link_libcpp = link_libcpp,
3492 .link_libunwind = link_libunwind,
3493 .want_pic = want_pic,
3494 .want_pie = want_pie,
3495 .want_lto = want_lto,
3496 .want_unwind_tables = want_unwind_tables,
3497 .want_sanitize_c = want_sanitize_c,
3498 .want_stack_check = want_stack_check,
3499 .want_stack_protector = want_stack_protector,
3500 .want_red_zone = want_red_zone,
3501 .omit_frame_pointer = omit_frame_pointer,
3502 .want_valgrind = want_valgrind,
3503 .want_tsan = want_tsan,
3162 .system_lib_names = create_module.resolved_system_libs.items(.name),
3163 .system_lib_infos = create_module.resolved_system_libs.items(.lib),
3164 .wasi_emulated_libs = create_module.wasi_emulated_libs.items,
35043165 .want_compiler_rt = want_compiler_rt,
3505 .use_llvm = use_llvm,
3506 .use_lib_llvm = use_lib_llvm,
3507 .use_lld = use_lld,
3508 .use_clang = use_clang,
35093166 .hash_style = hash_style,
3510 .rdynamic = rdynamic,
35113167 .linker_script = linker_script,
35123168 .version_script = version_script,
35133169 .disable_c_depfile = disable_c_depfile,
......@@ -3516,18 +3172,15 @@ fn buildOutputType(
35163172 .linker_gc_sections = linker_gc_sections,
35173173 .linker_allow_shlib_undefined = linker_allow_shlib_undefined,
35183174 .linker_bind_global_refs_locally = linker_bind_global_refs_locally,
3519 .linker_import_memory = linker_import_memory,
3520 .linker_export_memory = linker_export_memory,
35213175 .linker_import_symbols = linker_import_symbols,
35223176 .linker_import_table = linker_import_table,
35233177 .linker_export_table = linker_export_table,
35243178 .linker_initial_memory = linker_initial_memory,
35253179 .linker_max_memory = linker_max_memory,
3526 .linker_shared_memory = linker_shared_memory,
35273180 .linker_print_gc_sections = linker_print_gc_sections,
35283181 .linker_print_icf_sections = linker_print_icf_sections,
35293182 .linker_print_map = linker_print_map,
3530 .linker_opt_bisect_limit = linker_opt_bisect_limit,
3183 .llvm_opt_bisect_limit = llvm_opt_bisect_limit,
35313184 .linker_global_base = linker_global_base,
35323185 .linker_export_symbol_names = linker_export_symbol_names.items,
35333186 .linker_z_nocopyreloc = linker_z_nocopyreloc,
......@@ -3542,7 +3195,6 @@ fn buildOutputType(
35423195 .linker_tsaware = linker_tsaware,
35433196 .linker_nxcompat = linker_nxcompat,
35443197 .linker_dynamicbase = linker_dynamicbase,
3545 .linker_optimization = linker_optimization,
35463198 .linker_compress_debug_sections = linker_compress_debug_sections,
35473199 .linker_module_definition_file = linker_module_definition_file,
35483200 .major_subsystem_version = major_subsystem_version,
......@@ -3551,20 +3203,16 @@ fn buildOutputType(
35513203 .link_emit_relocs = link_emit_relocs,
35523204 .entry = entry,
35533205 .force_undefined_symbols = force_undefined_symbols,
3554 .stack_size_override = stack_size_override,
3555 .image_base_override = image_base_override,
3556 .strip = strip,
3206 .stack_size = stack_size,
3207 .image_base = image_base,
35573208 .formatted_panics = formatted_panics,
3558 .single_threaded = single_threaded,
35593209 .function_sections = function_sections,
35603210 .data_sections = data_sections,
35613211 .no_builtin = no_builtin,
3562 .self_exe_path = self_exe_path,
3563 .thread_pool = &thread_pool,
35643212 .clang_passthrough_mode = clang_passthrough_mode,
35653213 .clang_preprocessor_mode = clang_preprocessor_mode,
35663214 .version = optional_version,
3567 .libc_installation = if (libc_installation) |*lci| lci else null,
3215 .libc_installation = if (create_module.libc_installation) |*lci| lci else null,
35683216 .verbose_cc = verbose_cc,
35693217 .verbose_link = verbose_link,
35703218 .verbose_air = verbose_air,
......@@ -3574,21 +3222,16 @@ fn buildOutputType(
35743222 .verbose_llvm_bc = verbose_llvm_bc,
35753223 .verbose_cimport = verbose_cimport,
35763224 .verbose_llvm_cpu_features = verbose_llvm_cpu_features,
3577 .machine_code_model = machine_code_model,
3578 .color = color,
35793225 .time_report = time_report,
35803226 .stack_report = stack_report,
3581 .is_test = arg_mode == .zig_test,
35823227 .each_lib_rpath = each_lib_rpath,
35833228 .build_id = build_id,
3584 .test_evented_io = test_evented_io,
35853229 .test_filter = test_filter,
35863230 .test_name_prefix = test_name_prefix,
35873231 .test_runner_path = test_runner_path,
3588 .disable_lld_caching = !output_to_cache,
3232 .disable_lld_caching = disable_lld_caching,
3233 .cache_mode = cache_mode,
35893234 .subsystem = subsystem,
3590 .dwarf_format = dwarf_format,
3591 .wasi_exec_model = wasi_exec_model,
35923235 .debug_compile_errors = debug_compile_errors,
35933236 .enable_link_snapshots = enable_link_snapshots,
35943237 .install_name = install_name,
......@@ -3598,13 +3241,15 @@ fn buildOutputType(
35983241 .headerpad_max_install_names = headerpad_max_install_names,
35993242 .dead_strip_dylibs = dead_strip_dylibs,
36003243 .reference_trace = reference_trace,
3601 .error_tracing = error_tracing,
36023244 .pdb_out_path = pdb_out_path,
36033245 .error_limit = error_limit,
3604 .want_structured_cfg = want_structured_cfg,
3246 .native_system_include_paths = create_module.native_system_include_paths,
3247 // Any leftover C compilation args (such as -I) apply globally rather
3248 // than to any particular module. This feature can greatly reduce CLI
3249 // noise when --search-prefix and --mod are combined.
3250 .global_cc_argv = try cc_argv.toOwnedSlice(arena),
36053251 }) catch |err| switch (err) {
36063252 error.LibCUnavailable => {
3607 const target = target_info.target;
36083253 const triple_name = try target.zigTriple(arena);
36093254 std.log.err("unable to find or provide libc for target '{s}'", .{triple_name});
36103255
......@@ -3632,7 +3277,9 @@ fn buildOutputType(
36323277 defer if (!comp_destroyed) comp.destroy();
36333278
36343279 if (show_builtin) {
3635 return std.io.getStdOut().writeAll(try comp.generateBuiltinZigSource(arena));
3280 const builtin_mod = comp.root_mod.getBuiltinDependency();
3281 const source = builtin_mod.builtin_file.?.source;
3282 return std.io.getStdOut().writeAll(source);
36363283 }
36373284 switch (listen) {
36383285 .none => {},
......@@ -3681,7 +3328,7 @@ fn buildOutputType(
36813328 return cmdTranslateC(comp, arena, null);
36823329 }
36833330
3684 updateModule(comp) catch |err| switch (err) {
3331 updateModule(comp, color) catch |err| switch (err) {
36853332 error.SemanticAnalyzeFail => {
36863333 assert(listen == .none);
36873334 saveState(comp, debug_incremental);
......@@ -3693,10 +3340,10 @@ fn buildOutputType(
36933340 try comp.makeBinFileExecutable();
36943341 saveState(comp, debug_incremental);
36953342
3696 if (test_exec_args.items.len == 0 and object_format == .c) default_exec_args: {
3343 if (test_exec_args.items.len == 0 and target.ofmt == .c) default_exec_args: {
36973344 // Default to using `zig run` to execute the produced .c code from `zig test`.
36983345 const c_code_loc = emit_bin_loc orelse break :default_exec_args;
3699 const c_code_directory = c_code_loc.directory orelse comp.bin_file.options.emit.?.directory;
3346 const c_code_directory = c_code_loc.directory orelse comp.bin_file.?.emit.directory;
37003347 const c_code_path = try fs.path.join(arena, &[_][]const u8{
37013348 c_code_directory.path orelse ".", c_code_loc.basename,
37023349 });
......@@ -3706,23 +3353,24 @@ fn buildOutputType(
37063353 try test_exec_args.appendSlice(&.{ "-I", p });
37073354 }
37083355
3709 if (link_libc) {
3356 if (create_module.resolved_options.link_libc) {
37103357 try test_exec_args.append("-lc");
3711 } else if (target_info.target.os.tag == .windows) {
3358 } else if (target.os.tag == .windows) {
37123359 try test_exec_args.appendSlice(&.{
37133360 "--subsystem", "console",
37143361 "-lkernel32", "-lntdll",
37153362 });
37163363 }
37173364
3718 if (!mem.eql(u8, target_arch_os_abi, "native")) {
3365 const first_cli_mod = create_module.modules.values()[0];
3366 if (first_cli_mod.target_arch_os_abi) |triple| {
37193367 try test_exec_args.append("-target");
3720 try test_exec_args.append(target_arch_os_abi);
3368 try test_exec_args.append(triple);
37213369 }
3722 if (target_mcpu) |mcpu| {
3370 if (first_cli_mod.target_mcpu) |mcpu| {
37233371 try test_exec_args.append(try std.fmt.allocPrint(arena, "-mcpu={s}", .{mcpu}));
37243372 }
3725 if (target_dynamic_linker) |dl| {
3373 if (create_module.dynamic_linker) |dl| {
37263374 try test_exec_args.append("--dynamic-linker");
37273375 try test_exec_args.append(dl);
37283376 }
......@@ -3742,11 +3390,11 @@ fn buildOutputType(
37423390 test_exec_args.items,
37433391 self_exe_path.?,
37443392 arg_mode,
3745 &target_info,
3393 &target,
37463394 &comp_destroyed,
37473395 all_args,
37483396 runtime_args_start,
3749 link_libc,
3397 create_module.resolved_options.link_libc,
37503398 );
37513399 }
37523400
......@@ -3754,6 +3402,522 @@ fn buildOutputType(
37543402 return cleanExit();
37553403}
37563404
3405const CreateModule = struct {
3406 global_cache_directory: Cache.Directory,
3407 modules: std.StringArrayHashMapUnmanaged(CliModule),
3408 opts: Compilation.Config.Options,
3409 dynamic_linker: ?[]const u8,
3410 object_format: ?[]const u8,
3411 /// undefined until createModule() for the root module is called.
3412 resolved_options: Compilation.Config,
3413
3414 /// This one is used while collecting CLI options. The set of libs is used
3415 /// directly after computing the target and used to compute link_libc,
3416 /// link_libcpp, and then the libraries are filtered into
3417 /// `external_system_libs` and `resolved_system_libs`.
3418 system_libs: std.StringArrayHashMapUnmanaged(SystemLib),
3419 resolved_system_libs: std.MultiArrayList(struct {
3420 name: []const u8,
3421 lib: Compilation.SystemLib,
3422 }),
3423 wasi_emulated_libs: std.ArrayListUnmanaged(wasi_libc.CRTFile),
3424
3425 c_source_files: std.ArrayListUnmanaged(Compilation.CSourceFile),
3426 rc_source_files: std.ArrayListUnmanaged(Compilation.RcSourceFile),
3427
3428 /// e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names.
3429 /// This array is populated by zig cc frontend and then has to be converted to zig-style
3430 /// CPU features.
3431 llvm_m_args: std.ArrayListUnmanaged([]const u8),
3432 sysroot: ?[]const u8,
3433 lib_dirs: std.ArrayListUnmanaged([]const u8),
3434 lib_dir_args: std.ArrayListUnmanaged([]const u8),
3435 libc_installation: ?LibCInstallation,
3436 want_native_include_dirs: bool,
3437 frameworks: std.StringArrayHashMapUnmanaged(Framework),
3438 native_system_include_paths: []const []const u8,
3439 framework_dirs: std.ArrayListUnmanaged([]const u8),
3440 rpath_list: std.ArrayListUnmanaged([]const u8),
3441 libc_paths_file: ?[]const u8,
3442 link_objects: std.ArrayListUnmanaged(Compilation.LinkObject),
3443};
3444
3445fn createModule(
3446 gpa: Allocator,
3447 arena: Allocator,
3448 create_module: *CreateModule,
3449 index: usize,
3450 parent: ?*Package.Module,
3451 zig_lib_directory: Cache.Directory,
3452) Allocator.Error!*Package.Module {
3453 const cli_mod = &create_module.modules.values()[index];
3454 if (cli_mod.resolved) |m| return m;
3455
3456 const name = create_module.modules.keys()[index];
3457
3458 cli_mod.inherited.resolved_target = t: {
3459 // If the target is not overridden, use the parent's target. Of course,
3460 // if this is the root module then we need to proceed to resolve the
3461 // target.
3462 if (cli_mod.target_arch_os_abi == null and
3463 cli_mod.target_mcpu == null and
3464 create_module.dynamic_linker == null and
3465 create_module.object_format == null)
3466 {
3467 if (parent) |p| break :t p.resolved_target;
3468 }
3469
3470 var target_parse_options: std.Target.Query.ParseOptions = .{
3471 .arch_os_abi = cli_mod.target_arch_os_abi orelse "native",
3472 .cpu_features = cli_mod.target_mcpu,
3473 .dynamic_linker = create_module.dynamic_linker,
3474 .object_format = create_module.object_format,
3475 };
3476
3477 // Before passing the mcpu string in for parsing, we convert any -m flags that were
3478 // passed in via zig cc to zig-style.
3479 if (create_module.llvm_m_args.items.len != 0) {
3480 // If this returns null, we let it fall through to the case below which will
3481 // run the full parse function and do proper error handling.
3482 if (std.Target.Query.parseCpuArch(target_parse_options)) |cpu_arch| {
3483 var llvm_to_zig_name = std.StringHashMap([]const u8).init(gpa);
3484 defer llvm_to_zig_name.deinit();
3485
3486 for (cpu_arch.allFeaturesList()) |feature| {
3487 const llvm_name = feature.llvm_name orelse continue;
3488 try llvm_to_zig_name.put(llvm_name, feature.name);
3489 }
3490
3491 var mcpu_buffer = std.ArrayList(u8).init(gpa);
3492 defer mcpu_buffer.deinit();
3493
3494 try mcpu_buffer.appendSlice(cli_mod.target_mcpu orelse "baseline");
3495
3496 for (create_module.llvm_m_args.items) |llvm_m_arg| {
3497 if (mem.startsWith(u8, llvm_m_arg, "mno-")) {
3498 const llvm_name = llvm_m_arg["mno-".len..];
3499 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {
3500 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{
3501 @tagName(cpu_arch), llvm_name,
3502 });
3503 };
3504 try mcpu_buffer.append('-');
3505 try mcpu_buffer.appendSlice(zig_name);
3506 } else if (mem.startsWith(u8, llvm_m_arg, "m")) {
3507 const llvm_name = llvm_m_arg["m".len..];
3508 const zig_name = llvm_to_zig_name.get(llvm_name) orelse {
3509 fatal("target architecture {s} has no LLVM CPU feature named '{s}'", .{
3510 @tagName(cpu_arch), llvm_name,
3511 });
3512 };
3513 try mcpu_buffer.append('+');
3514 try mcpu_buffer.appendSlice(zig_name);
3515 } else {
3516 unreachable;
3517 }
3518 }
3519
3520 const adjusted_target_mcpu = try arena.dupe(u8, mcpu_buffer.items);
3521 std.log.debug("adjusted target_mcpu: {s}", .{adjusted_target_mcpu});
3522 target_parse_options.cpu_features = adjusted_target_mcpu;
3523 }
3524 }
3525
3526 const target_query = parseTargetQueryOrReportFatalError(arena, target_parse_options);
3527 const target = resolveTargetQueryOrFatal(target_query);
3528 break :t .{
3529 .result = target,
3530 .is_native_os = target_query.isNativeOs(),
3531 .is_native_abi = target_query.isNativeAbi(),
3532 };
3533 };
3534
3535 if (parent == null) {
3536 // This block is for initializing the fields of
3537 // `Compilation.Config.Options` that require knowledge of the
3538 // target (which was just now resolved for the root module above).
3539 const resolved_target = cli_mod.inherited.resolved_target.?;
3540 create_module.opts.resolved_target = resolved_target;
3541 create_module.opts.root_optimize_mode = cli_mod.inherited.optimize_mode;
3542 create_module.opts.root_strip = cli_mod.inherited.strip;
3543 create_module.opts.root_error_tracing = cli_mod.inherited.error_tracing;
3544 const target = resolved_target.result;
3545
3546 // First, remove libc, libc++, and compiler_rt libraries from the system libraries list.
3547 // We need to know whether the set of system libraries contains anything besides these
3548 // to decide whether to trigger native path detection logic.
3549 var external_system_libs: std.MultiArrayList(struct {
3550 name: []const u8,
3551 info: SystemLib,
3552 }) = .{};
3553 for (create_module.system_libs.keys(), create_module.system_libs.values()) |lib_name, info| {
3554 if (target.is_libc_lib_name(lib_name)) {
3555 create_module.opts.link_libc = true;
3556 continue;
3557 }
3558 if (target.is_libcpp_lib_name(lib_name)) {
3559 create_module.opts.link_libcpp = true;
3560 continue;
3561 }
3562 switch (target_util.classifyCompilerRtLibName(target, lib_name)) {
3563 .none => {},
3564 .only_libunwind, .both => {
3565 create_module.opts.link_libunwind = true;
3566 continue;
3567 },
3568 .only_compiler_rt => {
3569 warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name});
3570 continue;
3571 },
3572 }
3573
3574 if (target.isMinGW()) {
3575 const exists = mingw.libExists(arena, target, zig_lib_directory, lib_name) catch |err| {
3576 fatal("failed to check zig installation for DLL import libs: {s}", .{
3577 @errorName(err),
3578 });
3579 };
3580 if (exists) {
3581 try create_module.resolved_system_libs.append(arena, .{
3582 .name = lib_name,
3583 .lib = .{
3584 .needed = true,
3585 .weak = false,
3586 .path = null,
3587 },
3588 });
3589 continue;
3590 }
3591 }
3592
3593 if (fs.path.isAbsolute(lib_name)) {
3594 fatal("cannot use absolute path as a system library: {s}", .{lib_name});
3595 }
3596
3597 if (target.os.tag == .wasi) {
3598 if (wasi_libc.getEmulatedLibCRTFile(lib_name)) |crt_file| {
3599 try create_module.wasi_emulated_libs.append(arena, crt_file);
3600 continue;
3601 }
3602 }
3603
3604 try external_system_libs.append(arena, .{
3605 .name = lib_name,
3606 .info = info,
3607 });
3608 }
3609 // After this point, external_system_libs is used instead of system_libs.
3610 if (external_system_libs.len != 0)
3611 create_module.want_native_include_dirs = true;
3612
3613 // Resolve the library path arguments with respect to sysroot.
3614 if (create_module.sysroot) |root| {
3615 try create_module.lib_dirs.ensureUnusedCapacity(arena, create_module.lib_dir_args.items.len * 2);
3616 for (create_module.lib_dir_args.items) |dir| {
3617 if (fs.path.isAbsolute(dir)) {
3618 const stripped_dir = dir[fs.path.diskDesignator(dir).len..];
3619 const full_path = try fs.path.join(arena, &[_][]const u8{ root, stripped_dir });
3620 create_module.lib_dirs.appendAssumeCapacity(full_path);
3621 }
3622 create_module.lib_dirs.appendAssumeCapacity(dir);
3623 }
3624 } else {
3625 create_module.lib_dirs = create_module.lib_dir_args;
3626 }
3627 create_module.lib_dir_args = undefined; // From here we use lib_dirs instead.
3628
3629 if (resolved_target.is_native_os and target.isDarwin()) {
3630 // If we want to link against frameworks, we need system headers.
3631 if (create_module.frameworks.count() > 0)
3632 create_module.want_native_include_dirs = true;
3633 }
3634
3635 // Trigger native system library path detection if necessary.
3636 if (create_module.sysroot == null and
3637 resolved_target.is_native_os and resolved_target.is_native_abi and
3638 create_module.want_native_include_dirs)
3639 {
3640 var paths = std.zig.system.NativePaths.detect(arena, target) catch |err| {
3641 fatal("unable to detect native system paths: {s}", .{@errorName(err)});
3642 };
3643 for (paths.warnings.items) |warning| {
3644 warn("{s}", .{warning});
3645 }
3646
3647 create_module.native_system_include_paths = try paths.include_dirs.toOwnedSlice(arena);
3648
3649 try create_module.framework_dirs.appendSlice(arena, paths.framework_dirs.items);
3650 try create_module.lib_dirs.appendSlice(arena, paths.lib_dirs.items);
3651 try create_module.rpath_list.appendSlice(arena, paths.rpaths.items);
3652 }
3653
3654 if (create_module.libc_paths_file) |paths_file| {
3655 create_module.libc_installation = LibCInstallation.parse(arena, paths_file, target) catch |err| {
3656 fatal("unable to parse libc paths file at path {s}: {s}", .{
3657 paths_file, @errorName(err),
3658 });
3659 };
3660 }
3661
3662 if (builtin.target.os.tag == .windows and target.abi == .msvc and
3663 external_system_libs.len != 0)
3664 {
3665 if (create_module.libc_installation == null) {
3666 create_module.libc_installation = LibCInstallation.findNative(.{
3667 .allocator = arena,
3668 .verbose = true,
3669 .target = target,
3670 }) catch |err| {
3671 fatal("unable to find native libc installation: {s}", .{@errorName(err)});
3672 };
3673
3674 try create_module.lib_dirs.appendSlice(arena, &.{
3675 create_module.libc_installation.?.msvc_lib_dir.?,
3676 create_module.libc_installation.?.kernel32_lib_dir.?,
3677 });
3678 }
3679 }
3680
3681 // If any libs in this list are statically provided, we omit them from the
3682 // resolved list and populate the link_objects array instead.
3683 {
3684 var test_path = std.ArrayList(u8).init(gpa);
3685 defer test_path.deinit();
3686
3687 var checked_paths = std.ArrayList(u8).init(gpa);
3688 defer checked_paths.deinit();
3689
3690 var failed_libs = std.ArrayList(struct {
3691 name: []const u8,
3692 strategy: SystemLib.SearchStrategy,
3693 checked_paths: []const u8,
3694 preferred_mode: std.builtin.LinkMode,
3695 }).init(arena);
3696
3697 syslib: for (external_system_libs.items(.name), external_system_libs.items(.info)) |lib_name, info| {
3698 // Checked in the first pass above while looking for libc libraries.
3699 assert(!fs.path.isAbsolute(lib_name));
3700
3701 checked_paths.clearRetainingCapacity();
3702
3703 switch (info.search_strategy) {
3704 .mode_first, .no_fallback => {
3705 // check for preferred mode
3706 for (create_module.lib_dirs.items) |lib_dir_path| {
3707 if (try accessLibPath(
3708 &test_path,
3709 &checked_paths,
3710 lib_dir_path,
3711 lib_name,
3712 target,
3713 info.preferred_mode,
3714 )) {
3715 const path = try arena.dupe(u8, test_path.items);
3716 switch (info.preferred_mode) {
3717 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3718 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3719 .name = lib_name,
3720 .lib = .{
3721 .needed = info.needed,
3722 .weak = info.weak,
3723 .path = path,
3724 },
3725 }),
3726 }
3727 continue :syslib;
3728 }
3729 }
3730 // check for fallback mode
3731 if (info.search_strategy == .no_fallback) {
3732 try failed_libs.append(.{
3733 .name = lib_name,
3734 .strategy = info.search_strategy,
3735 .checked_paths = try arena.dupe(u8, checked_paths.items),
3736 .preferred_mode = info.preferred_mode,
3737 });
3738 continue :syslib;
3739 }
3740 for (create_module.lib_dirs.items) |lib_dir_path| {
3741 if (try accessLibPath(
3742 &test_path,
3743 &checked_paths,
3744 lib_dir_path,
3745 lib_name,
3746 target,
3747 info.fallbackMode(),
3748 )) {
3749 const path = try arena.dupe(u8, test_path.items);
3750 switch (info.fallbackMode()) {
3751 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3752 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3753 .name = lib_name,
3754 .lib = .{
3755 .needed = info.needed,
3756 .weak = info.weak,
3757 .path = path,
3758 },
3759 }),
3760 }
3761 continue :syslib;
3762 }
3763 }
3764 try failed_libs.append(.{
3765 .name = lib_name,
3766 .strategy = info.search_strategy,
3767 .checked_paths = try arena.dupe(u8, checked_paths.items),
3768 .preferred_mode = info.preferred_mode,
3769 });
3770 continue :syslib;
3771 },
3772 .paths_first => {
3773 for (create_module.lib_dirs.items) |lib_dir_path| {
3774 // check for preferred mode
3775 if (try accessLibPath(
3776 &test_path,
3777 &checked_paths,
3778 lib_dir_path,
3779 lib_name,
3780 target,
3781 info.preferred_mode,
3782 )) {
3783 const path = try arena.dupe(u8, test_path.items);
3784 switch (info.preferred_mode) {
3785 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3786 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3787 .name = lib_name,
3788 .lib = .{
3789 .needed = info.needed,
3790 .weak = info.weak,
3791 .path = path,
3792 },
3793 }),
3794 }
3795 continue :syslib;
3796 }
3797
3798 // check for fallback mode
3799 if (try accessLibPath(
3800 &test_path,
3801 &checked_paths,
3802 lib_dir_path,
3803 lib_name,
3804 target,
3805 info.fallbackMode(),
3806 )) {
3807 const path = try arena.dupe(u8, test_path.items);
3808 switch (info.fallbackMode()) {
3809 .Static => try create_module.link_objects.append(arena, .{ .path = path }),
3810 .Dynamic => try create_module.resolved_system_libs.append(arena, .{
3811 .name = lib_name,
3812 .lib = .{
3813 .needed = info.needed,
3814 .weak = info.weak,
3815 .path = path,
3816 },
3817 }),
3818 }
3819 continue :syslib;
3820 }
3821 }
3822 try failed_libs.append(.{
3823 .name = lib_name,
3824 .strategy = info.search_strategy,
3825 .checked_paths = try arena.dupe(u8, checked_paths.items),
3826 .preferred_mode = info.preferred_mode,
3827 });
3828 continue :syslib;
3829 },
3830 }
3831 @compileError("unreachable");
3832 }
3833
3834 if (failed_libs.items.len > 0) {
3835 for (failed_libs.items) |f| {
3836 const searched_paths = if (f.checked_paths.len == 0) " none" else f.checked_paths;
3837 std.log.err("unable to find {s} system library '{s}' using strategy '{s}'. searched paths:{s}", .{
3838 @tagName(f.preferred_mode), f.name, @tagName(f.strategy), searched_paths,
3839 });
3840 }
3841 process.exit(1);
3842 }
3843 }
3844 // After this point, create_module.resolved_system_libs is used instead of
3845 // create_module.external_system_libs.
3846
3847 if (create_module.resolved_system_libs.len != 0)
3848 create_module.opts.any_dyn_libs = true;
3849
3850 create_module.resolved_options = Compilation.Config.resolve(create_module.opts) catch |err| switch (err) {
3851 error.WasiExecModelRequiresWasi => fatal("only WASI OS targets support execution model", .{}),
3852 error.SharedMemoryIsWasmOnly => fatal("only WebAssembly CPU targets support shared memory", .{}),
3853 error.ObjectFilesCannotShareMemory => fatal("object files cannot share memory", .{}),
3854 error.SharedMemoryRequiresAtomicsAndBulkMemory => fatal("shared memory requires atomics and bulk_memory CPU features", .{}),
3855 error.ThreadsRequireSharedMemory => fatal("threads require shared memory", .{}),
3856 error.EmittingLlvmModuleRequiresLlvmBackend => fatal("emitting an LLVM module requires using the LLVM backend", .{}),
3857 error.LlvmLacksTargetSupport => fatal("LLVM lacks support for the specified target", .{}),
3858 error.ZigLacksTargetSupport => fatal("compiler backend unavailable for the specified target", .{}),
3859 error.EmittingBinaryRequiresLlvmLibrary => fatal("producing machine code via LLVM requires using the LLVM library", .{}),
3860 error.LldIncompatibleObjectFormat => fatal("using LLD to link {s} files is unsupported", .{@tagName(target.ofmt)}),
3861 error.LtoRequiresLld => fatal("LTO requires using LLD", .{}),
3862 error.SanitizeThreadRequiresLibCpp => fatal("thread sanitization is (for now) implemented in C++, so it requires linking libc++", .{}),
3863 error.LibCppRequiresLibUnwind => fatal("libc++ requires linking libunwind", .{}),
3864 error.OsRequiresLibC => fatal("the target OS requires using libc as the stable syscall interface", .{}),
3865 error.LibCppRequiresLibC => fatal("libc++ requires linking libc", .{}),
3866 error.LibUnwindRequiresLibC => fatal("libunwind requires linking libc", .{}),
3867 error.TargetCannotDynamicLink => fatal("dynamic linking unavailable on the specified target", .{}),
3868 error.LibCRequiresDynamicLinking => fatal("libc of the specified target requires dynamic linking", .{}),
3869 error.SharedLibrariesRequireDynamicLinking => fatal("using shared libraries requires dynamic linking", .{}),
3870 error.ExportMemoryAndDynamicIncompatible => fatal("exporting memory is incompatible with dynamic linking", .{}),
3871 error.DynamicLibraryPrecludesPie => fatal("dynamic libraries cannot be position independent executables", .{}),
3872 error.TargetRequiresPie => fatal("the specified target requires position independent executables", .{}),
3873 error.SanitizeThreadRequiresPie => fatal("thread sanitization requires position independent executables", .{}),
3874 error.BackendLacksErrorTracing => fatal("the selected backend has not yet implemented error return tracing", .{}),
3875 error.LlvmLibraryUnavailable => fatal("zig was compiled without LLVM libraries", .{}),
3876 error.LldUnavailable => fatal("zig was compiled without LLD libraries", .{}),
3877 error.ClangUnavailable => fatal("zig was compiled without Clang libraries", .{}),
3878 error.DllExportFnsRequiresWindows => fatal("only Windows OS targets support DLLs", .{}),
3879 };
3880 }
3881
3882 const mod = Package.Module.create(arena, .{
3883 .global_cache_directory = create_module.global_cache_directory,
3884 .paths = cli_mod.paths,
3885 .fully_qualified_name = name,
3886
3887 .cc_argv = cli_mod.cc_argv,
3888 .inherited = cli_mod.inherited,
3889 .global = create_module.resolved_options,
3890 .parent = parent,
3891 .builtin_mod = null,
3892 }) catch |err| switch (err) {
3893 error.ValgrindUnsupportedOnTarget => fatal("unable to create module '{s}': valgrind does not support the selected target CPU architecture", .{name}),
3894 error.TargetRequiresSingleThreaded => fatal("unable to create module '{s}': the selected target does not support multithreading", .{name}),
3895 error.BackendRequiresSingleThreaded => fatal("unable to create module '{s}': the selected machine code backend is limited to single-threaded applications", .{name}),
3896 error.TargetRequiresPic => fatal("unable to create module '{s}': the selected target requires position independent code", .{name}),
3897 error.PieRequiresPic => fatal("unable to create module '{s}': making a Position Independent Executable requires enabling Position Independent Code", .{name}),
3898 error.DynamicLinkingRequiresPic => fatal("unable to create module '{s}': dynamic linking requires enabling Position Independent Code", .{name}),
3899 error.TargetHasNoRedZone => fatal("unable to create module '{s}': the selected target does not have a red zone", .{name}),
3900 error.StackCheckUnsupportedByTarget => fatal("unable to create module '{s}': the selected target does not support stack checking", .{name}),
3901 error.StackProtectorUnsupportedByTarget => fatal("unable to create module '{s}': the selected target does not support stack protection", .{name}),
3902 error.StackProtectorUnavailableWithoutLibC => fatal("unable to create module '{s}': enabling stack protection requires libc", .{name}),
3903 error.OutOfMemory => return error.OutOfMemory,
3904 };
3905 cli_mod.resolved = mod;
3906
3907 for (create_module.c_source_files.items[cli_mod.c_source_files_start..cli_mod.c_source_files_end]) |*item| item.owner = mod;
3908
3909 for (create_module.rc_source_files.items[cli_mod.rc_source_files_start..cli_mod.rc_source_files_end]) |*item| item.owner = mod;
3910
3911 for (cli_mod.deps) |dep| {
3912 const dep_index = create_module.modules.getIndex(dep.value) orelse
3913 fatal("module '{s}' depends on non-existent module '{s}'", .{ name, dep.key });
3914 const dep_mod = try createModule(gpa, arena, create_module, dep_index, mod, zig_lib_directory);
3915 try mod.deps.put(arena, dep.key, dep_mod);
3916 }
3917
3918 return mod;
3919}
3920
37573921fn saveState(comp: *Compilation, debug_incremental: bool) void {
37583922 if (debug_incremental) {
37593923 comp.saveState() catch |err| {
......@@ -3805,7 +3969,7 @@ fn serve(
38053969 const hdr = try server.receiveMessage();
38063970
38073971 switch (hdr.tag) {
3808 .exit => return,
3972 .exit => return cleanExit(),
38093973 .update => {
38103974 assert(main_progress_node.recently_updated_child == null);
38113975 tracy.frameMark();
......@@ -3827,7 +3991,7 @@ fn serve(
38273991 continue;
38283992 }
38293993
3830 if (comp.bin_file.options.output_mode == .Exe) {
3994 if (comp.config.output_mode == .Exe) {
38313995 try comp.makeBinFileWritable();
38323996 }
38333997
......@@ -3862,7 +4026,7 @@ fn serve(
38624026 // test_exec_args,
38634027 // self_exe_path.?,
38644028 // arg_mode,
3865 // target_info,
4029 // target,
38664030 // true,
38674031 // &comp_destroyed,
38684032 // all_args,
......@@ -3877,7 +4041,7 @@ fn serve(
38774041 try comp.hotCodeSwap(main_progress_node, pid);
38784042 try serveUpdateResults(&server, comp);
38794043 } else {
3880 if (comp.bin_file.options.output_mode == .Exe) {
4044 if (comp.config.output_mode == .Exe) {
38814045 try comp.makeBinFileWritable();
38824046 }
38834047 try comp.update(main_progress_node);
......@@ -3967,63 +4131,76 @@ fn serveUpdateResults(s: *Server, comp: *Compilation) !void {
39674131 try s.serveErrorBundle(error_bundle);
39684132 return;
39694133 }
3970 // This logic is a bit counter-intuitive because the protocol implies that
3971 // each emitted artifact could possibly be in a different location, when in
3972 // reality, there is only one artifact output directory, and the build
3973 // system depends on that fact. So, until the protocol is changed to
3974 // reflect this, this logic only needs to ensure that emit_bin_path is
3975 // emitted for at least one thing, if there are any artifacts.
3976 if (comp.bin_file.options.emit) |emit| {
4134
4135 // This logic is counter-intuitive because the protocol accounts for each
4136 // emitted artifact possibly being in a different location, which correctly
4137 // matches the behavior of the compiler, however, the build system
4138 // currently always passes flags that makes all build artifacts output to
4139 // the same local cache directory, and relies on them all being in the same
4140 // directory.
4141 //
4142 // So, until the build system and protocol are changed to reflect this,
4143 // this logic must ensure that emit_bin_path is emitted for at least one
4144 // thing, if there are any artifacts.
4145
4146 switch (comp.cache_use) {
4147 .incremental => if (comp.bin_file) |lf| {
4148 const full_path = try lf.emit.directory.join(gpa, &.{lf.emit.sub_path});
4149 defer gpa.free(full_path);
4150 try s.serveEmitBinPath(full_path, .{
4151 .flags = .{ .cache_hit = comp.last_update_was_cache_hit },
4152 });
4153 return;
4154 },
4155 .whole => |whole| if (whole.bin_sub_path) |sub_path| {
4156 const full_path = try comp.local_cache_directory.join(gpa, &.{sub_path});
4157 defer gpa.free(full_path);
4158 try s.serveEmitBinPath(full_path, .{
4159 .flags = .{ .cache_hit = comp.last_update_was_cache_hit },
4160 });
4161 return;
4162 },
4163 }
4164
4165 for ([_]?Compilation.Emit{
4166 comp.docs_emit,
4167 comp.implib_emit,
4168 }) |opt_emit| {
4169 const emit = opt_emit orelse continue;
39774170 const full_path = try emit.directory.join(gpa, &.{emit.sub_path});
39784171 defer gpa.free(full_path);
39794172 try s.serveEmitBinPath(full_path, .{
39804173 .flags = .{ .cache_hit = comp.last_update_was_cache_hit },
39814174 });
3982 } else if (comp.bin_file.options.docs_emit) |emit| {
3983 const full_path = try emit.directory.join(gpa, &.{emit.sub_path});
4175 return;
4176 }
4177
4178 for ([_]?Compilation.EmitLoc{
4179 comp.emit_asm,
4180 comp.emit_llvm_ir,
4181 comp.emit_llvm_bc,
4182 }) |opt_emit_loc| {
4183 const emit_loc = opt_emit_loc orelse continue;
4184 const directory = emit_loc.directory orelse continue;
4185 const full_path = try directory.join(gpa, &.{emit_loc.basename});
39844186 defer gpa.free(full_path);
39854187 try s.serveEmitBinPath(full_path, .{
39864188 .flags = .{ .cache_hit = comp.last_update_was_cache_hit },
39874189 });
4190 return;
39884191 }
39894192}
39904193
3991const ModuleDepIterator = struct {
3992 split: mem.SplitIterator(u8, .scalar),
3993
3994 fn init(deps_str: []const u8) ModuleDepIterator {
3995 return .{ .split = mem.splitScalar(u8, deps_str, ',') };
3996 }
3997
3998 const Dependency = struct {
3999 expose: []const u8,
4000 name: []const u8,
4001 };
4002
4003 fn next(it: *ModuleDepIterator) ?Dependency {
4004 if (it.split.buffer.len == 0) return null; // don't return "" for the first iteration on ""
4005 const str = it.split.next() orelse return null;
4006 if (mem.indexOfScalar(u8, str, '=')) |i| {
4007 return .{
4008 .expose = str[0..i],
4009 .name = str[i + 1 ..],
4010 };
4011 } else {
4012 return .{ .expose = str, .name = str };
4013 }
4014 }
4015};
4016
4017fn parseCrossTargetOrReportFatalError(
4194fn parseTargetQueryOrReportFatalError(
40184195 allocator: Allocator,
4019 opts: std.zig.CrossTarget.ParseOptions,
4020) !std.zig.CrossTarget {
4196 opts: std.Target.Query.ParseOptions,
4197) std.Target.Query {
40214198 var opts_with_diags = opts;
4022 var diags: std.zig.CrossTarget.ParseOptions.Diagnostics = .{};
4199 var diags: std.Target.Query.ParseOptions.Diagnostics = .{};
40234200 if (opts_with_diags.diagnostics == null) {
40244201 opts_with_diags.diagnostics = &diags;
40254202 }
4026 return std.zig.CrossTarget.parse(opts_with_diags) catch |err| switch (err) {
4203 return std.Target.Query.parse(opts_with_diags) catch |err| switch (err) {
40274204 error.UnknownCpuModel => {
40284205 help: {
40294206 var help_text = std.ArrayList(u8).init(allocator);
......@@ -4061,7 +4238,9 @@ fn parseCrossTargetOrReportFatalError(
40614238 }
40624239 fatal("unknown object format: '{s}'", .{opts.object_format.?});
40634240 },
4064 else => |e| return e,
4241 else => |e| fatal("unable to parse target query '{s}': {s}", .{
4242 opts.arch_os_abi, @errorName(e),
4243 }),
40654244 };
40664245}
40674246
......@@ -4072,17 +4251,17 @@ fn runOrTest(
40724251 test_exec_args: []const ?[]const u8,
40734252 self_exe_path: []const u8,
40744253 arg_mode: ArgMode,
4075 target_info: *const std.zig.system.NativeTargetInfo,
4254 target: *const std.Target,
40764255 comp_destroyed: *bool,
40774256 all_args: []const []const u8,
40784257 runtime_args_start: ?usize,
40794258 link_libc: bool,
40804259) !void {
4081 const exe_emit = comp.bin_file.options.emit orelse return;
4260 const lf = comp.bin_file orelse return;
40824261 // A naive `directory.join` here will indeed get the correct path to the binary,
40834262 // however, in the case of cwd, we actually want `./foo` so that the path can be executed.
40844263 const exe_path = try fs.path.join(arena, &[_][]const u8{
4085 exe_emit.directory.path orelse ".", exe_emit.sub_path,
4264 lf.emit.directory.path orelse ".", lf.emit.sub_path,
40864265 });
40874266
40884267 var argv = std.ArrayList([]const u8).init(gpa);
......@@ -4106,7 +4285,7 @@ fn runOrTest(
41064285 if (process.can_execv and arg_mode == .run) {
41074286 // execv releases the locks; no need to destroy the Compilation here.
41084287 const err = process.execve(gpa, argv.items, &env_map);
4109 try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc);
4288 try warnAboutForeignBinaries(arena, arg_mode, target, link_libc);
41104289 const cmd = try std.mem.join(arena, " ", argv.items);
41114290 fatal("the following command failed to execve with '{s}':\n{s}", .{ @errorName(err), cmd });
41124291 } else if (process.can_spawn) {
......@@ -4122,7 +4301,7 @@ fn runOrTest(
41224301 comp_destroyed.* = true;
41234302
41244303 const term = child.spawnAndWait() catch |err| {
4125 try warnAboutForeignBinaries(arena, arg_mode, target_info, link_libc);
4304 try warnAboutForeignBinaries(arena, arg_mode, target, link_libc);
41264305 const cmd = try std.mem.join(arena, " ", argv.items);
41274306 fatal("the following command failed with '{s}':\n{s}", .{ @errorName(err), cmd });
41284307 };
......@@ -4174,7 +4353,7 @@ fn runOrTestHotSwap(
41744353 all_args: []const []const u8,
41754354 runtime_args_start: ?usize,
41764355) !std.ChildProcess.Id {
4177 const exe_emit = comp.bin_file.options.emit.?;
4356 const lf = comp.bin_file.?;
41784357
41794358 const exe_path = switch (builtin.target.os.tag) {
41804359 // On Windows it seems impossible to perform an atomic rename of a file that is currently
......@@ -4182,16 +4361,16 @@ fn runOrTestHotSwap(
41824361 // tmp zig-cache and use it to spawn the child process. This way we are free to update
41834362 // the binary with each requested hot update.
41844363 .windows => blk: {
4185 try exe_emit.directory.handle.copyFile(exe_emit.sub_path, comp.local_cache_directory.handle, exe_emit.sub_path, .{});
4364 try lf.emit.directory.handle.copyFile(lf.emit.sub_path, comp.local_cache_directory.handle, lf.emit.sub_path, .{});
41864365 break :blk try fs.path.join(gpa, &[_][]const u8{
4187 comp.local_cache_directory.path orelse ".", exe_emit.sub_path,
4366 comp.local_cache_directory.path orelse ".", lf.emit.sub_path,
41884367 });
41894368 },
41904369
41914370 // A naive `directory.join` here will indeed get the correct path to the binary,
41924371 // however, in the case of cwd, we actually want `./foo` so that the path can be executed.
41934372 else => try fs.path.join(gpa, &[_][]const u8{
4194 exe_emit.directory.path orelse ".", exe_emit.sub_path,
4373 lf.emit.directory.path orelse ".", lf.emit.sub_path,
41954374 }),
41964375 };
41974376 defer gpa.free(exe_path);
......@@ -4263,13 +4442,13 @@ fn runOrTestHotSwap(
42634442 }
42644443}
42654444
4266fn updateModule(comp: *Compilation) !void {
4445fn updateModule(comp: *Compilation, color: Color) !void {
42674446 {
42684447 // If the terminal is dumb, we dont want to show the user all the output.
42694448 var progress: std.Progress = .{ .dont_print_on_dumb = true };
42704449 const main_progress_node = progress.start("", 0);
42714450 defer main_progress_node.end();
4272 switch (comp.color) {
4451 switch (color) {
42734452 .off => {
42744453 progress.terminal = null;
42754454 },
......@@ -4287,24 +4466,25 @@ fn updateModule(comp: *Compilation) !void {
42874466 defer errors.deinit(comp.gpa);
42884467
42894468 if (errors.errorMessageCount() > 0) {
4290 errors.renderToStdErr(renderOptions(comp.color));
4469 errors.renderToStdErr(renderOptions(color));
42914470 return error.SemanticAnalyzeFail;
42924471 }
42934472}
42944473
42954474fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilation.CImportResult) !void {
42964475 if (build_options.only_core_functionality) @panic("@translate-c is not available in a zig2.c build");
4476 const color: Color = .auto;
42974477 assert(comp.c_source_files.len == 1);
42984478 const c_source_file = comp.c_source_files[0];
42994479
4300 const translated_zig_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{comp.bin_file.options.root_name});
4480 const translated_zig_basename = try std.fmt.allocPrint(arena, "{s}.zig", .{comp.root_name});
43014481
4302 var man: Cache.Manifest = comp.obtainCObjectCacheManifest();
4482 var man: Cache.Manifest = comp.obtainCObjectCacheManifest(comp.root_mod);
43034483 man.want_shared_lock = false;
43044484 defer man.deinit();
43054485
43064486 man.hash.add(@as(u16, 0xb945)); // Random number to distinguish translate-c from compiling C objects
4307 man.hash.add(comp.c_frontend);
4487 man.hash.add(comp.config.c_frontend);
43084488 Compilation.cache_helpers.hashCSource(&man, c_source_file) catch |err| {
43094489 fatal("unable to process '{s}': {s}", .{ c_source_file.src_path, @errorName(err) });
43104490 };
......@@ -4313,14 +4493,14 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
43134493 const digest = if (try man.hit()) man.final() else digest: {
43144494 if (fancy_output) |p| p.cache_hit = false;
43154495 var argv = std.ArrayList([]const u8).init(arena);
4316 try argv.append(@tagName(comp.c_frontend)); // argv[0] is program name, actual args start at [1]
4496 try argv.append(@tagName(comp.config.c_frontend)); // argv[0] is program name, actual args start at [1]
43174497
43184498 var zig_cache_tmp_dir = try comp.local_cache_directory.handle.makeOpenPath("tmp", .{});
43194499 defer zig_cache_tmp_dir.close();
43204500
43214501 const ext = Compilation.classifyFileExt(c_source_file.src_path);
43224502 const out_dep_path: ?[]const u8 = blk: {
4323 if (comp.c_frontend == .aro or comp.disable_c_depfile or !ext.clangSupportsDepFile())
4503 if (comp.config.c_frontend == .aro or comp.disable_c_depfile or !ext.clangSupportsDepFile())
43244504 break :blk null;
43254505
43264506 const c_src_basename = fs.path.basename(c_source_file.src_path);
......@@ -4330,14 +4510,15 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
43304510 };
43314511
43324512 // TODO
4333 if (comp.c_frontend != .aro) try comp.addTranslateCCArgs(arena, &argv, ext, out_dep_path);
4513 if (comp.config.c_frontend != .aro)
4514 try comp.addTranslateCCArgs(arena, &argv, ext, out_dep_path, comp.root_mod);
43344515 try argv.append(c_source_file.src_path);
43354516
43364517 if (comp.verbose_cc) {
43374518 Compilation.dump_argv(argv.items);
43384519 }
43394520
4340 var tree = switch (comp.c_frontend) {
4521 var tree = switch (comp.config.c_frontend) {
43414522 .aro => tree: {
43424523 const aro = @import("aro");
43434524 const translate_c = @import("aro_translate_c.zig");
......@@ -4385,7 +4566,7 @@ fn cmdTranslateC(comp: *Compilation, arena: Allocator, fancy_output: ?*Compilati
43854566 p.errors = errors;
43864567 return;
43874568 } else {
4388 errors.renderToStdErr(renderOptions(comp.color));
4569 errors.renderToStdErr(renderOptions(color));
43894570 process.exit(1);
43904571 }
43914572 },
......@@ -4667,9 +4848,12 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes:
46674848 while (true) {
46684849 switch (cur_includes) {
46694850 .any, .msvc => {
4670 const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-msvc" }) catch unreachable;
4671 const target = cross_target.toTarget();
4672 const is_native_abi = cross_target.isNativeAbi();
4851 const target_query: std.Target.Query = .{
4852 .os_tag = .windows,
4853 .abi = .msvc,
4854 };
4855 const target = resolveTargetQueryOrFatal(target_query);
4856 const is_native_abi = target_query.isNativeAbi();
46734857 const detected_libc = Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null) catch |err| {
46744858 if (cur_includes == .any) {
46754859 // fall back to mingw
......@@ -4692,9 +4876,12 @@ fn detectRcIncludeDirs(arena: Allocator, zig_lib_dir: []const u8, auto_includes:
46924876 };
46934877 },
46944878 .gnu => {
4695 const cross_target = std.zig.CrossTarget.parse(.{ .arch_os_abi = "native-windows-gnu" }) catch unreachable;
4696 const target = cross_target.toTarget();
4697 const is_native_abi = cross_target.isNativeAbi();
4879 const target_query: std.Target.Query = .{
4880 .os_tag = .windows,
4881 .abi = .gnu,
4882 };
4883 const target = resolveTargetQueryOrFatal(target_query);
4884 const is_native_abi = target_query.isNativeAbi();
46984885 const detected_libc = try Compilation.detectLibCIncludeDirs(arena, zig_lib_dir, target, is_native_abi, true, null);
46994886 return .{
47004887 .include_paths = detected_libc.libc_include_dir_list,
......@@ -4755,9 +4942,10 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
47554942 }
47564943 }
47574944
4758 const cross_target = try parseCrossTargetOrReportFatalError(gpa, .{
4945 const target_query = parseTargetQueryOrReportFatalError(gpa, .{
47594946 .arch_os_abi = target_arch_os_abi,
47604947 });
4948 const target = resolveTargetQueryOrFatal(target_query);
47614949
47624950 if (print_includes) {
47634951 var arena_state = std.heap.ArenaAllocator.init(gpa);
......@@ -4767,7 +4955,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
47674955 const libc_installation: ?*LibCInstallation = libc: {
47684956 if (input_file) |libc_file| {
47694957 const libc = try arena.create(LibCInstallation);
4770 libc.* = LibCInstallation.parse(arena, libc_file, cross_target) catch |err| {
4958 libc.* = LibCInstallation.parse(arena, libc_file, target) catch |err| {
47714959 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
47724960 };
47734961 break :libc libc;
......@@ -4782,8 +4970,7 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
47824970 };
47834971 defer zig_lib_directory.handle.close();
47844972
4785 const target = cross_target.toTarget();
4786 const is_native_abi = cross_target.isNativeAbi();
4973 const is_native_abi = target_query.isNativeAbi();
47874974
47884975 const libc_dirs = Compilation.detectLibCIncludeDirs(
47894976 arena,
......@@ -4813,20 +5000,18 @@ pub fn cmdLibC(gpa: Allocator, args: []const []const u8) !void {
48135000 }
48145001
48155002 if (input_file) |libc_file| {
4816 var libc = LibCInstallation.parse(gpa, libc_file, cross_target) catch |err| {
5003 var libc = LibCInstallation.parse(gpa, libc_file, target) catch |err| {
48175004 fatal("unable to parse libc file at path {s}: {s}", .{ libc_file, @errorName(err) });
48185005 };
48195006 defer libc.deinit(gpa);
48205007 } else {
4821 if (!cross_target.isNative()) {
5008 if (!target_query.isNative()) {
48225009 fatal("unable to detect libc for non-native target", .{});
48235010 }
4824 const target_info = try detectNativeTargetInfo(cross_target);
4825
48265011 var libc = LibCInstallation.findNative(.{
48275012 .allocator = gpa,
48285013 .verbose = true,
4829 .target = target_info.target,
5014 .target = target,
48305015 }) catch |err| {
48315016 fatal("unable to detect native libc: {s}", .{@errorName(err)});
48325017 };
......@@ -4918,6 +5103,7 @@ pub const usage_build =
49185103 \\ --global-cache-dir [path] Override path to global Zig cache directory
49195104 \\ --zig-lib-dir [arg] Override path to Zig lib directory
49205105 \\ --build-runner [file] Override path to build runner
5106 \\ --prominent-compile-errors Buffer compile errors and display at end
49215107 \\ --seed [integer] For shuffling dependency traversal order (default: random)
49225108 \\ --fetch Exit after fetching dependency tree
49235109 \\ -h, --help Print this help and exit
......@@ -5024,7 +5210,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
50245210 if (!build_options.enable_logging) {
50255211 warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
50265212 } else {
5027 try log_scopes.append(gpa, args[i]);
5213 try log_scopes.append(arena, args[i]);
50285214 }
50295215 continue;
50305216 } else if (mem.eql(u8, arg, "--debug-compile-errors")) {
......@@ -5114,12 +5300,16 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
51145300
51155301 gimmeMoreOfThoseSweetSweetFileDescriptors();
51165302
5117 const cross_target: std.zig.CrossTarget = .{};
5118 const target_info = try detectNativeTargetInfo(cross_target);
5303 const target_query: std.Target.Query = .{};
5304 const resolved_target: Package.Module.ResolvedTarget = .{
5305 .result = resolveTargetQueryOrFatal(target_query),
5306 .is_native_os = true,
5307 .is_native_abi = true,
5308 };
51195309
51205310 const exe_basename = try std.zig.binNameAlloc(arena, .{
51215311 .root_name = "build",
5122 .target = target_info.target,
5312 .target = resolved_target.result,
51235313 .output_mode = .Exe,
51245314 });
51255315 const emit_bin: Compilation.EmitLoc = .{
......@@ -5130,29 +5320,62 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
51305320 try thread_pool.init(.{ .allocator = gpa });
51315321 defer thread_pool.deinit();
51325322
5133 var main_mod: Package.Module = if (override_build_runner) |build_runner_path|
5134 .{
5135 .root = .{
5136 .root_dir = Cache.Directory.cwd(),
5137 .sub_path = fs.path.dirname(build_runner_path) orelse "",
5138 },
5139 .root_src_path = fs.path.basename(build_runner_path),
5140 .fully_qualified_name = "root",
5141 }
5142 else
5143 .{
5144 .root = .{ .root_dir = zig_lib_directory },
5145 .root_src_path = "build_runner.zig",
5146 .fully_qualified_name = "root",
5147 };
5323 const main_mod_paths: Package.Module.CreateOptions.Paths = if (override_build_runner) |runner| .{
5324 .root = .{
5325 .root_dir = Cache.Directory.cwd(),
5326 .sub_path = fs.path.dirname(runner) orelse "",
5327 },
5328 .root_src_path = fs.path.basename(runner),
5329 } else .{
5330 .root = .{ .root_dir = zig_lib_directory },
5331 .root_src_path = "build_runner.zig",
5332 };
5333
5334 const config = try Compilation.Config.resolve(.{
5335 .output_mode = .Exe,
5336 .resolved_target = resolved_target,
5337 .have_zcu = true,
5338 .emit_bin = true,
5339 .is_test = false,
5340 });
5341
5342 const root_mod = try Package.Module.create(arena, .{
5343 .global_cache_directory = global_cache_directory,
5344 .paths = main_mod_paths,
5345 .fully_qualified_name = "root",
5346 .cc_argv = &.{},
5347 .inherited = .{
5348 .resolved_target = resolved_target,
5349 },
5350 .global = config,
5351 .parent = null,
5352 .builtin_mod = null,
5353 });
51485354
5149 var build_mod: Package.Module = .{
5150 .root = .{ .root_dir = build_root.directory },
5151 .root_src_path = build_root.build_zig_basename,
5355 const builtin_mod = root_mod.getBuiltinDependency();
5356
5357 const build_mod = try Package.Module.create(arena, .{
5358 .global_cache_directory = global_cache_directory,
5359 .paths = .{
5360 .root = .{ .root_dir = build_root.directory },
5361 .root_src_path = build_root.build_zig_basename,
5362 },
51525363 .fully_qualified_name = "root.@build",
5153 };
5364 .cc_argv = &.{},
5365 .inherited = .{},
5366 .global = config,
5367 .parent = root_mod,
5368 .builtin_mod = builtin_mod,
5369 });
51545370 if (build_options.only_core_functionality) {
5155 try createEmptyDependenciesModule(arena, &main_mod, local_cache_directory);
5371 try createEmptyDependenciesModule(
5372 arena,
5373 root_mod,
5374 global_cache_directory,
5375 local_cache_directory,
5376 builtin_mod,
5377 config,
5378 );
51565379 } else {
51575380 var http_client: std.http.Client = .{ .allocator = gpa };
51585381 defer http_client.deinit();
......@@ -5196,7 +5419,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
51965419 .has_build_zig = true,
51975420 .oom_flag = false,
51985421
5199 .module = &build_mod,
5422 .module = build_mod,
52005423 };
52015424 job_queue.all_fetches.appendAssumeCapacity(&fetch);
52025425
......@@ -5225,8 +5448,11 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
52255448 const deps_mod = try createDependenciesModule(
52265449 arena,
52275450 source_buf.items,
5228 &main_mod,
5451 root_mod,
5452 global_cache_directory,
52295453 local_cache_directory,
5454 builtin_mod,
5455 config,
52305456 );
52315457
52325458 {
......@@ -5242,13 +5468,21 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
52425468 if (!f.has_build_zig)
52435469 continue;
52445470 const m = try Package.Module.create(arena, .{
5245 .root = try f.package_root.clone(arena),
5246 .root_src_path = Package.build_zig_basename,
5471 .global_cache_directory = global_cache_directory,
5472 .paths = .{
5473 .root = try f.package_root.clone(arena),
5474 .root_src_path = Package.build_zig_basename,
5475 },
52475476 .fully_qualified_name = try std.fmt.allocPrint(
52485477 arena,
52495478 "root.@dependencies.{s}",
52505479 .{&hash},
52515480 ),
5481 .cc_argv = &.{},
5482 .inherited = .{},
5483 .global = config,
5484 .parent = root_mod,
5485 .builtin_mod = builtin_mod,
52525486 });
52535487 const hash_cloned = try arena.dupe(u8, &hash);
52545488 deps_mod.deps.putAssumeCapacityNoClobber(hash_cloned, m);
......@@ -5276,22 +5510,18 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
52765510 }
52775511 }
52785512
5279 try main_mod.deps.put(arena, "@build", &build_mod);
5513 try root_mod.deps.put(arena, "@build", build_mod);
52805514
5281 const comp = Compilation.create(gpa, .{
5515 const comp = Compilation.create(gpa, arena, .{
52825516 .zig_lib_directory = zig_lib_directory,
52835517 .local_cache_directory = local_cache_directory,
52845518 .global_cache_directory = global_cache_directory,
52855519 .root_name = "build",
5286 .target = target_info.target,
5287 .is_native_os = cross_target.isNativeOs(),
5288 .is_native_abi = cross_target.isNativeAbi(),
5289 .dynamic_linker = target_info.dynamic_linker.get(),
5290 .output_mode = .Exe,
5291 .main_mod = &main_mod,
5520 .config = config,
5521 .root_mod = root_mod,
5522 .main_mod = build_mod,
52925523 .emit_bin = emit_bin,
52935524 .emit_h = null,
5294 .optimize_mode = .Debug,
52955525 .self_exe_path = self_exe_path,
52965526 .thread_pool = &thread_pool,
52975527 .verbose_cc = verbose_cc,
......@@ -5311,17 +5541,16 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
53115541 };
53125542 defer comp.destroy();
53135543
5314 updateModule(comp) catch |err| switch (err) {
5544 updateModule(comp, color) catch |err| switch (err) {
53155545 error.SemanticAnalyzeFail => process.exit(2),
53165546 else => |e| return e,
53175547 };
5318 try comp.makeBinFileExecutable();
53195548
5320 const emit = comp.bin_file.options.emit.?;
5321 child_argv.items[argv_index_exe] = try emit.directory.join(
5322 arena,
5323 &[_][]const u8{emit.sub_path},
5324 );
5549 // Since incremental compilation isn't done yet, we use cache_mode = whole
5550 // above, and thus the output file is already closed.
5551 //try comp.makeBinFileExecutable();
5552 child_argv.items[argv_index_exe] =
5553 try local_cache_directory.join(arena, &.{comp.cache_use.whole.bin_sub_path.?});
53255554
53265555 break :argv child_argv.items;
53275556 };
......@@ -5515,7 +5744,7 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
55155744 .root_decl = .none,
55165745 };
55175746
5518 file.mod = try Package.Module.create(arena, .{
5747 file.mod = try Package.Module.createLimited(arena, .{
55195748 .root = Package.Path.cwd(),
55205749 .root_src_path = file.sub_file_path,
55215750 .fully_qualified_name = "root",
......@@ -5725,7 +5954,7 @@ fn fmtPathFile(
57255954 .root_decl = .none,
57265955 };
57275956
5728 file.mod = try Package.Module.create(fmt.arena, .{
5957 file.mod = try Package.Module.createLimited(fmt.arena, .{
57295958 .root = Package.Path.cwd(),
57305959 .root_src_path = file.sub_file_path,
57315960 .fully_qualified_name = "root",
......@@ -5805,15 +6034,13 @@ pub fn putAstErrorsIntoBundle(
58056034 .tree = tree,
58066035 .tree_loaded = true,
58076036 .zir = undefined,
5808 .mod = undefined,
6037 .mod = try Package.Module.createLimited(gpa, .{
6038 .root = Package.Path.cwd(),
6039 .root_src_path = path,
6040 .fully_qualified_name = "root",
6041 }),
58096042 .root_decl = .none,
58106043 };
5811
5812 file.mod = try Package.Module.create(gpa, .{
5813 .root = Package.Path.cwd(),
5814 .root_src_path = file.sub_file_path,
5815 .fully_qualified_name = "root",
5816 });
58176044 defer gpa.destroy(file.mod);
58186045
58196046 file.zir = try AstGen.generate(gpa, file.tree);
......@@ -6270,10 +6497,6 @@ test "fds" {
62706497 gimmeMoreOfThoseSweetSweetFileDescriptors();
62716498}
62726499
6273fn detectNativeTargetInfo(cross_target: std.zig.CrossTarget) !std.zig.system.NativeTargetInfo {
6274 return std.zig.system.NativeTargetInfo.detect(cross_target);
6275}
6276
62776500const usage_ast_check =
62786501 \\Usage: zig ast-check [file]
62796502 \\
......@@ -6378,7 +6601,7 @@ pub fn cmdAstCheck(
63786601 file.stat.size = source.len;
63796602 }
63806603
6381 file.mod = try Package.Module.create(arena, .{
6604 file.mod = try Package.Module.createLimited(arena, .{
63826605 .root = Package.Path.cwd(),
63836606 .root_src_path = file.sub_file_path,
63846607 .fully_qualified_name = "root",
......@@ -6551,7 +6774,7 @@ pub fn cmdChangelist(
65516774 .root_decl = .none,
65526775 };
65536776
6554 file.mod = try Package.Module.create(arena, .{
6777 file.mod = try Package.Module.createLimited(arena, .{
65556778 .root = Package.Path.cwd(),
65566779 .root_src_path = file.sub_file_path,
65576780 .fully_qualified_name = "root",
......@@ -6670,24 +6893,24 @@ fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 {
66706893fn warnAboutForeignBinaries(
66716894 arena: Allocator,
66726895 arg_mode: ArgMode,
6673 target_info: *const std.zig.system.NativeTargetInfo,
6896 target: *const std.Target,
66746897 link_libc: bool,
66756898) !void {
6676 const host_cross_target: std.zig.CrossTarget = .{};
6677 const host_target_info = try detectNativeTargetInfo(host_cross_target);
6899 const host_query: std.Target.Query = .{};
6900 const host_target = resolveTargetQueryOrFatal(host_query);
66786901
6679 switch (host_target_info.getExternalExecutor(target_info, .{ .link_libc = link_libc })) {
6902 switch (std.zig.system.getExternalExecutor(host_target, target, .{ .link_libc = link_libc })) {
66806903 .native => return,
66816904 .rosetta => {
6682 const host_name = try host_target_info.target.zigTriple(arena);
6683 const foreign_name = try target_info.target.zigTriple(arena);
6905 const host_name = try host_target.zigTriple(arena);
6906 const foreign_name = try target.zigTriple(arena);
66846907 warn("the host system ({s}) does not appear to be capable of executing binaries from the target ({s}). Consider installing Rosetta.", .{
66856908 host_name, foreign_name,
66866909 });
66876910 },
66886911 .qemu => |qemu| {
6689 const host_name = try host_target_info.target.zigTriple(arena);
6690 const foreign_name = try target_info.target.zigTriple(arena);
6912 const host_name = try host_target.zigTriple(arena);
6913 const foreign_name = try target.zigTriple(arena);
66916914 switch (arg_mode) {
66926915 .zig_test => warn(
66936916 "the host system ({s}) does not appear to be capable of executing binaries " ++
......@@ -6703,8 +6926,8 @@ fn warnAboutForeignBinaries(
67036926 }
67046927 },
67056928 .wine => |wine| {
6706 const host_name = try host_target_info.target.zigTriple(arena);
6707 const foreign_name = try target_info.target.zigTriple(arena);
6929 const host_name = try host_target.zigTriple(arena);
6930 const foreign_name = try target.zigTriple(arena);
67086931 switch (arg_mode) {
67096932 .zig_test => warn(
67106933 "the host system ({s}) does not appear to be capable of executing binaries " ++
......@@ -6720,8 +6943,8 @@ fn warnAboutForeignBinaries(
67206943 }
67216944 },
67226945 .wasmtime => |wasmtime| {
6723 const host_name = try host_target_info.target.zigTriple(arena);
6724 const foreign_name = try target_info.target.zigTriple(arena);
6946 const host_name = try host_target.zigTriple(arena);
6947 const foreign_name = try target.zigTriple(arena);
67256948 switch (arg_mode) {
67266949 .zig_test => warn(
67276950 "the host system ({s}) does not appear to be capable of executing binaries " ++
......@@ -6737,8 +6960,8 @@ fn warnAboutForeignBinaries(
67376960 }
67386961 },
67396962 .darling => |darling| {
6740 const host_name = try host_target_info.target.zigTriple(arena);
6741 const foreign_name = try target_info.target.zigTriple(arena);
6963 const host_name = try host_target.zigTriple(arena);
6964 const foreign_name = try target.zigTriple(arena);
67426965 switch (arg_mode) {
67436966 .zig_test => warn(
67446967 "the host system ({s}) does not appear to be capable of executing binaries " ++
......@@ -6754,7 +6977,7 @@ fn warnAboutForeignBinaries(
67546977 }
67556978 },
67566979 .bad_dl => |foreign_dl| {
6757 const host_dl = host_target_info.dynamic_linker.get() orelse "(none)";
6980 const host_dl = host_target.dynamic_linker.get() orelse "(none)";
67586981 const tip_suffix = switch (arg_mode) {
67596982 .zig_test => ", '--test-no-exec', or '--test-cmd'",
67606983 else => "",
......@@ -6764,8 +6987,8 @@ fn warnAboutForeignBinaries(
67646987 });
67656988 },
67666989 .bad_os_or_cpu => {
6767 const host_name = try host_target_info.target.zigTriple(arena);
6768 const foreign_name = try target_info.target.zigTriple(arena);
6990 const host_name = try host_target.zigTriple(arena);
6991 const foreign_name = try target.zigTriple(arena);
67696992 const tip_suffix = switch (arg_mode) {
67706993 .zig_test => ". Consider using '--test-no-exec' or '--test-cmd'",
67716994 else => "",
......@@ -6814,18 +7037,22 @@ fn parseSubSystem(next_arg: []const u8) !std.Target.SubSystem {
68147037/// Silently ignore superfluous search dirs.
68157038/// Warn when a dir is added to multiple searchlists.
68167039const ClangSearchSanitizer = struct {
6817 argv: *std.ArrayList([]const u8),
6818 map: std.StringHashMap(Membership),
7040 map: std.StringHashMapUnmanaged(Membership) = .{},
68197041
6820 fn init(gpa: Allocator, argv: *std.ArrayList([]const u8)) @This() {
6821 return .{
6822 .argv = argv,
6823 .map = std.StringHashMap(Membership).init(gpa),
6824 };
7042 fn reset(self: *@This()) void {
7043 self.map.clearRetainingCapacity();
68257044 }
68267045
6827 fn addIncludePath(self: *@This(), group: Group, arg: []const u8, dir: []const u8, joined: bool) !void {
6828 const gopr = try self.map.getOrPut(dir);
7046 fn addIncludePath(
7047 self: *@This(),
7048 ally: Allocator,
7049 argv: *std.ArrayListUnmanaged([]const u8),
7050 group: Group,
7051 arg: []const u8,
7052 dir: []const u8,
7053 joined: bool,
7054 ) !void {
7055 const gopr = try self.map.getOrPut(ally, dir);
68297056 const m = gopr.value_ptr;
68307057 if (!gopr.found_existing) {
68317058 // init empty membership
......@@ -6872,8 +7099,9 @@ const ClangSearchSanitizer = struct {
68727099 if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });
68737100 },
68747101 }
6875 try self.argv.append(arg);
6876 if (!joined) try self.argv.append(dir);
7102 try argv.ensureUnusedCapacity(ally, 2);
7103 argv.appendAssumeCapacity(arg);
7104 if (!joined) argv.appendAssumeCapacity(dir);
68777105 }
68787106
68797107 const Group = enum { I, isystem, iwithsysroot, idirafter, iframework, iframeworkwithsysroot };
......@@ -7249,11 +7477,22 @@ fn cmdFetch(
72497477fn createEmptyDependenciesModule(
72507478 arena: Allocator,
72517479 main_mod: *Package.Module,
7480 global_cache_directory: Cache.Directory,
72527481 local_cache_directory: Cache.Directory,
7482 builtin_mod: *Package.Module,
7483 global_options: Compilation.Config,
72537484) !void {
72547485 var source = std.ArrayList(u8).init(arena);
72557486 try Package.Fetch.JobQueue.createEmptyDependenciesSource(&source);
7256 _ = try createDependenciesModule(arena, source.items, main_mod, local_cache_directory);
7487 _ = try createDependenciesModule(
7488 arena,
7489 source.items,
7490 main_mod,
7491 global_cache_directory,
7492 local_cache_directory,
7493 builtin_mod,
7494 global_options,
7495 );
72577496}
72587497
72597498/// Creates the dependencies.zig file and corresponding `Package.Module` for the
......@@ -7262,7 +7501,10 @@ fn createDependenciesModule(
72627501 arena: Allocator,
72637502 source: []const u8,
72647503 main_mod: *Package.Module,
7504 global_cache_directory: Cache.Directory,
72657505 local_cache_directory: Cache.Directory,
7506 builtin_mod: *Package.Module,
7507 global_options: Compilation.Config,
72667508) !*Package.Module {
72677509 // Atomically create the file in a directory named after the hash of its contents.
72687510 const basename = "dependencies.zig";
......@@ -7288,25 +7530,25 @@ fn createDependenciesModule(
72887530 );
72897531
72907532 const deps_mod = try Package.Module.create(arena, .{
7291 .root = .{
7292 .root_dir = local_cache_directory,
7293 .sub_path = o_dir_sub_path,
7533 .global_cache_directory = global_cache_directory,
7534 .paths = .{
7535 .root = .{
7536 .root_dir = local_cache_directory,
7537 .sub_path = o_dir_sub_path,
7538 },
7539 .root_src_path = basename,
72947540 },
7295 .root_src_path = basename,
72967541 .fully_qualified_name = "root.@dependencies",
7542 .parent = main_mod,
7543 .builtin_mod = builtin_mod,
7544 .cc_argv = &.{},
7545 .inherited = .{},
7546 .global = global_options,
72977547 });
72987548 try main_mod.deps.put(arena, "@dependencies", deps_mod);
72997549 return deps_mod;
73007550}
73017551
7302fn defaultWasmEntryName(exec_model: ?std.builtin.WasiExecModel) []const u8 {
7303 const model = exec_model orelse .command;
7304 if (model == .reactor) {
7305 return "_initialize";
7306 }
7307 return "_start";
7308}
7309
73107552const BuildRoot = struct {
73117553 directory: Cache.Directory,
73127554 build_zig_basename: []const u8,
......@@ -7514,3 +7756,28 @@ fn findTemplates(gpa: Allocator, arena: Allocator) Templates {
75147756 .buffer = std.ArrayList(u8).init(gpa),
75157757 };
75167758}
7759
7760fn parseOptimizeMode(s: []const u8) std.builtin.OptimizeMode {
7761 return std.meta.stringToEnum(std.builtin.OptimizeMode, s) orelse
7762 fatal("unrecognized optimization mode: '{s}'", .{s});
7763}
7764
7765fn parseWasiExecModel(s: []const u8) std.builtin.WasiExecModel {
7766 return std.meta.stringToEnum(std.builtin.WasiExecModel, s) orelse
7767 fatal("expected [command|reactor] for -mexec-mode=[value], found '{s}'", .{s});
7768}
7769
7770fn resolveTargetQueryOrFatal(target_query: std.Target.Query) std.Target {
7771 return std.zig.system.resolveTargetQuery(target_query) catch |err|
7772 fatal("unable to resolve target: {s}", .{@errorName(err)});
7773}
7774
7775fn parseStackSize(s: []const u8) u64 {
7776 return std.fmt.parseUnsigned(u64, s, 0) catch |err|
7777 fatal("unable to parse stack size '{s}': {s}", .{ s, @errorName(err) });
7778}
7779
7780fn parseImageBase(s: []const u8) u64 {
7781 return std.fmt.parseUnsigned(u64, s, 0) catch |err|
7782 fatal("unable to parse image base '{s}': {s}", .{ s, @errorName(err) });
7783}
src/mingw.zig+18-5
......@@ -41,14 +41,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
4141 //"-D_UNICODE",
4242 //"-DWPRFLAG=1",
4343 });
44 return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &.{
44 var files = [_]Compilation.CSourceFile{
4545 .{
4646 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
4747 "libc", "mingw", "crt", "crtexe.c",
4848 }),
4949 .extra_flags = args.items,
50 .owner = undefined,
5051 },
51 });
52 };
53 return comp.build_crt_file("crt2", .Obj, .@"mingw-w64 crt2.o", prog_node, &files);
5254 },
5355
5456 .dllcrt2_o => {
......@@ -60,14 +62,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
6062 "-U__CRTDLL__",
6163 "-D__MSVCRT__",
6264 });
63 return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &.{
65 var files = [_]Compilation.CSourceFile{
6466 .{
6567 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
6668 "libc", "mingw", "crt", "crtdll.c",
6769 }),
6870 .extra_flags = args.items,
71 .owner = undefined,
6972 },
70 });
73 };
74 return comp.build_crt_file("dllcrt2", .Obj, .@"mingw-w64 dllcrt2.o", prog_node, &files);
7175 },
7276
7377 .mingw32_lib => {
......@@ -97,6 +101,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
97101 "libc", "mingw", "crt", dep,
98102 }),
99103 .extra_flags = args.items,
104 .owner = undefined,
100105 };
101106 }
102107 return comp.build_crt_file("mingw32", .Lib, .@"mingw-w64 mingw32.lib", prog_node, &c_source_files);
......@@ -125,6 +130,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
125130 (try c_source_files.addOne()).* = .{
126131 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "mingw", dep }),
127132 .extra_flags = extra_flags,
133 .owner = undefined,
128134 };
129135 }
130136 if (comp.getTarget().cpu.arch == .x86) {
......@@ -134,6 +140,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
134140 "libc", "mingw", dep,
135141 }),
136142 .extra_flags = extra_flags,
143 .owner = undefined,
137144 };
138145 }
139146 } else {
......@@ -143,6 +150,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
143150 "libc", "mingw", dep,
144151 }),
145152 .extra_flags = extra_flags,
153 .owner = undefined,
146154 };
147155 }
148156 }
......@@ -175,6 +183,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
175183 "libc", "mingw", dep,
176184 }),
177185 .extra_flags = extra_flags,
186 .owner = undefined,
178187 };
179188 }
180189 const target = comp.getTarget();
......@@ -185,6 +194,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
185194 "libc", "mingw", dep,
186195 }),
187196 .extra_flags = extra_flags,
197 .owner = undefined,
188198 };
189199 }
190200 } else if (target.cpu.arch.isARM()) {
......@@ -194,6 +204,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
194204 "libc", "mingw", dep,
195205 }),
196206 .extra_flags = extra_flags,
207 .owner = undefined,
197208 };
198209 }
199210 } else if (target.cpu.arch.isAARCH64()) {
......@@ -203,6 +214,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
203214 "libc", "mingw", dep,
204215 }),
205216 .extra_flags = extra_flags,
217 .owner = undefined,
206218 };
207219 }
208220 } else {
......@@ -238,6 +250,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
238250 "libc", "mingw", "libsrc", dep,
239251 }),
240252 .extra_flags = extra_flags,
253 .owner = undefined,
241254 };
242255 }
243256 return comp.build_crt_file("uuid", .Lib, .@"mingw-w64 uuid.lib", prog_node, &c_source_files);
......@@ -274,7 +287,7 @@ fn add_cc_args(
274287}
275288
276289pub fn buildImportLib(comp: *Compilation, lib_name: []const u8) !void {
277 if (build_options.only_c) @panic("building import libs not included in core functionality");
290 if (build_options.only_c) @compileError("building import libs not included in core functionality");
278291 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
279292 defer arena_allocator.deinit();
280293 const arena = arena_allocator.allocator();
src/musl.zig+80-44
......@@ -3,6 +3,7 @@ const Allocator = std.mem.Allocator;
33const mem = std.mem;
44const path = std.fs.path;
55const assert = std.debug.assert;
6const Module = @import("Package/Module.zig");
67
78const Compilation = @import("Compilation.zig");
89const build_options = @import("build_options");
......@@ -33,12 +34,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
3334 try args.appendSlice(&[_][]const u8{
3435 "-Qunused-arguments",
3536 });
36 return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &.{
37 var files = [_]Compilation.CSourceFile{
3738 .{
3839 .src_path = try start_asm_path(comp, arena, "crti.s"),
3940 .extra_flags = args.items,
41 .owner = undefined,
4042 },
41 });
43 };
44 return comp.build_crt_file("crti", .Obj, .@"musl crti.o", prog_node, &files);
4245 },
4346 .crtn_o => {
4447 var args = std.ArrayList([]const u8).init(arena);
......@@ -46,12 +49,14 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
4649 try args.appendSlice(&[_][]const u8{
4750 "-Qunused-arguments",
4851 });
49 return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &.{
52 var files = [_]Compilation.CSourceFile{
5053 .{
5154 .src_path = try start_asm_path(comp, arena, "crtn.s"),
5255 .extra_flags = args.items,
56 .owner = undefined,
5357 },
54 });
58 };
59 return comp.build_crt_file("crtn", .Obj, .@"musl crtn.o", prog_node, &files);
5560 },
5661 .crt1_o => {
5762 var args = std.ArrayList([]const u8).init(arena);
......@@ -60,14 +65,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
6065 "-fno-stack-protector",
6166 "-DCRT",
6267 });
63 return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &.{
68 var files = [_]Compilation.CSourceFile{
6469 .{
6570 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
6671 "libc", "musl", "crt", "crt1.c",
6772 }),
6873 .extra_flags = args.items,
74 .owner = undefined,
6975 },
70 });
76 };
77 return comp.build_crt_file("crt1", .Obj, .@"musl crt1.o", prog_node, &files);
7178 },
7279 .rcrt1_o => {
7380 var args = std.ArrayList([]const u8).init(arena);
......@@ -77,14 +84,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
7784 "-fno-stack-protector",
7885 "-DCRT",
7986 });
80 return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &.{
87 var files = [_]Compilation.CSourceFile{
8188 .{
8289 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
8390 "libc", "musl", "crt", "rcrt1.c",
8491 }),
8592 .extra_flags = args.items,
93 .owner = undefined,
8694 },
87 });
95 };
96 return comp.build_crt_file("rcrt1", .Obj, .@"musl rcrt1.o", prog_node, &files);
8897 },
8998 .scrt1_o => {
9099 var args = std.ArrayList([]const u8).init(arena);
......@@ -94,14 +103,16 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
94103 "-fno-stack-protector",
95104 "-DCRT",
96105 });
97 return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &.{
106 var files = [_]Compilation.CSourceFile{
98107 .{
99108 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
100109 "libc", "musl", "crt", "Scrt1.c",
101110 }),
102111 .extra_flags = args.items,
112 .owner = undefined,
103113 },
104 });
114 };
115 return comp.build_crt_file("Scrt1", .Obj, .@"musl Scrt1.o", prog_node, &files);
105116 },
106117 .libc_a => {
107118 // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
......@@ -185,57 +196,87 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
185196 c_source_file.* = .{
186197 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", src_file }),
187198 .extra_flags = args.items,
199 .owner = undefined,
188200 };
189201 }
190202 return comp.build_crt_file("c", .Lib, .@"musl libc.a", prog_node, c_source_files.items);
191203 },
192204 .libc_so => {
193 const target = comp.getTarget();
205 const optimize_mode = comp.compilerRtOptMode();
206 const strip = comp.compilerRtStrip();
207 const config = try Compilation.Config.resolve(.{
208 .output_mode = .Lib,
209 .link_mode = .Dynamic,
210 .resolved_target = comp.root_mod.resolved_target,
211 .is_test = false,
212 .have_zcu = false,
213 .emit_bin = true,
214 .root_optimize_mode = optimize_mode,
215 .root_strip = strip,
216 .link_libc = false,
217 });
218
219 const target = comp.root_mod.resolved_target.result;
194220 const arch_define = try std.fmt.allocPrint(arena, "-DARCH_{s}", .{
195221 @tagName(target.cpu.arch),
196222 });
197 const clang_argv: []const []const u8 = if (target.ptrBitWidth() == 64)
198 &[_][]const u8{ "-DPTR64", arch_define }
223 const cc_argv: []const []const u8 = if (target.ptrBitWidth() == 64)
224 &.{ "-DPTR64", arch_define }
199225 else
200 &[_][]const u8{arch_define};
226 &.{arch_define};
227
228 const root_mod = try Module.create(arena, .{
229 .global_cache_directory = comp.global_cache_directory,
230 .paths = .{
231 .root = .{ .root_dir = comp.zig_lib_directory },
232 .root_src_path = "",
233 },
234 .fully_qualified_name = "root",
235 .inherited = .{
236 .resolved_target = comp.root_mod.resolved_target,
237 .strip = strip,
238 .stack_check = false,
239 .stack_protector = 0,
240 .sanitize_c = false,
241 .sanitize_thread = false,
242 .red_zone = comp.root_mod.red_zone,
243 .omit_frame_pointer = comp.root_mod.omit_frame_pointer,
244 .valgrind = false,
245 .optimize_mode = optimize_mode,
246 .structured_cfg = comp.root_mod.structured_cfg,
247 },
248 .global = config,
249 .cc_argv = cc_argv,
250 .parent = null,
251 .builtin_mod = null,
252 });
201253
202 const sub_compilation = try Compilation.create(comp.gpa, .{
254 const sub_compilation = try Compilation.create(comp.gpa, arena, .{
203255 .local_cache_directory = comp.global_cache_directory,
204256 .global_cache_directory = comp.global_cache_directory,
205 .cache_mode = .whole,
206257 .zig_lib_directory = comp.zig_lib_directory,
207 .target = target,
208 .root_name = "c",
209 .main_mod = null,
210 .output_mode = .Lib,
211 .link_mode = .Dynamic,
258 .self_exe_path = comp.self_exe_path,
259 .cache_mode = .whole,
260 .config = config,
261 .root_mod = root_mod,
212262 .thread_pool = comp.thread_pool,
213 .libc_installation = comp.bin_file.options.libc_installation,
214 .emit_bin = Compilation.EmitLoc{ .directory = null, .basename = "libc.so" },
215 .optimize_mode = comp.compilerRtOptMode(),
216 .want_sanitize_c = false,
217 .want_stack_check = false,
218 .want_stack_protector = 0,
219 .want_red_zone = comp.bin_file.options.red_zone,
220 .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer,
221 .want_valgrind = false,
222 .want_tsan = false,
263 .root_name = "c",
264 .libc_installation = comp.libc_installation,
265 .emit_bin = .{ .directory = null, .basename = "libc.so" },
223266 .emit_h = null,
224 .strip = comp.compilerRtStrip(),
225 .is_native_os = false,
226 .is_native_abi = false,
227 .self_exe_path = comp.self_exe_path,
228267 .verbose_cc = comp.verbose_cc,
229 .verbose_link = comp.bin_file.options.verbose_link,
268 .verbose_link = comp.verbose_link,
230269 .verbose_air = comp.verbose_air,
231270 .verbose_llvm_ir = comp.verbose_llvm_ir,
232271 .verbose_cimport = comp.verbose_cimport,
233272 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
234273 .clang_passthrough_mode = comp.clang_passthrough_mode,
235274 .c_source_files = &[_]Compilation.CSourceFile{
236 .{ .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{ "libc", "musl", "libc.S" }) },
275 .{
276 .src_path = try comp.zig_lib_directory.join(arena, &.{ "libc", "musl", "libc.S" }),
277 .owner = root_mod,
278 },
237279 },
238 .clang_argv = clang_argv,
239280 .skip_linker_dependencies = true,
240281 .soname = "libc.so",
241282 });
......@@ -248,12 +289,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
248289 const basename = try comp.gpa.dupe(u8, "libc.so");
249290 errdefer comp.gpa.free(basename);
250291
251 comp.crt_files.putAssumeCapacityNoClobber(basename, .{
252 .full_object_path = try sub_compilation.bin_file.options.emit.?.directory.join(comp.gpa, &[_][]const u8{
253 sub_compilation.bin_file.options.emit.?.sub_path,
254 }),
255 .lock = sub_compilation.bin_file.toOwnedLock(),
256 });
292 comp.crt_files.putAssumeCapacityNoClobber(basename, try sub_compilation.toCrtFile());
257293 },
258294 }
259295}
src/print_env.zig+2-2
......@@ -17,8 +17,8 @@ pub fn cmdEnv(arena: Allocator, args: []const []const u8, stdout: std.fs.File.Wr
1717
1818 const global_cache_dir = try introspect.resolveGlobalCacheDir(arena);
1919
20 const info = try std.zig.system.NativeTargetInfo.detect(.{});
21 const triple = try info.target.zigTriple(arena);
20 const host = try std.zig.system.resolveTargetQuery(.{});
21 const triple = try host.zigTriple(arena);
2222
2323 var bw = std.io.bufferedWriter(stdout);
2424 const w = bw.writer();
src/target.zig+70-97
......@@ -2,6 +2,9 @@ const std = @import("std");
22const Type = @import("type.zig").Type;
33const AddressSpace = std.builtin.AddressSpace;
44const Alignment = @import("InternPool.zig").Alignment;
5const Feature = @import("Module.zig").Feature;
6
7pub const default_stack_protector_buffer_size = 4;
58
69pub const ArchOsAbi = struct {
710 arch: std.Target.Cpu.Arch,
......@@ -204,11 +207,18 @@ pub fn supports_fpic(target: std.Target) bool {
204207 return target.os.tag != .windows and target.os.tag != .uefi;
205208}
206209
207pub fn isSingleThreaded(target: std.Target) bool {
210pub fn alwaysSingleThreaded(target: std.Target) bool {
208211 _ = target;
209212 return false;
210213}
211214
215pub fn defaultSingleThreaded(target: std.Target) bool {
216 return switch (target.cpu.arch) {
217 .wasm32, .wasm64 => true,
218 else => false,
219 };
220}
221
212222/// Valgrind supports more, but Zig does not support them yet.
213223pub fn hasValgrindSupport(target: std.Target) bool {
214224 switch (target.cpu.arch) {
......@@ -314,6 +324,14 @@ pub fn hasLlvmSupport(target: std.Target, ofmt: std.Target.ObjectFormat) bool {
314324 };
315325}
316326
327/// The set of targets that Zig supports using LLD to link for.
328pub fn hasLldSupport(ofmt: std.Target.ObjectFormat) bool {
329 return switch (ofmt) {
330 .elf, .coff, .wasm => true,
331 else => false,
332 };
333}
334
317335/// The set of targets that our own self-hosted backends have robust support for.
318336/// Used to select between LLVM backend and self-hosted backend when compiling in
319337/// debug mode. A given target should only return true here if it is passing greater
......@@ -343,6 +361,13 @@ pub fn supportsStackProtector(target: std.Target, backend: std.builtin.CompilerB
343361 };
344362}
345363
364pub fn clangSupportsStackProtector(target: std.Target) bool {
365 return switch (target.cpu.arch) {
366 .spirv32, .spirv64 => return false,
367 else => true,
368 };
369}
370
346371pub fn libcProvidesStackProtector(target: std.Target) bool {
347372 return !target.isMinGW() and target.os.tag != .wasi and !target.isSpirV();
348373}
......@@ -356,96 +381,6 @@ pub fn supportsReturnAddress(target: std.Target) bool {
356381 };
357382}
358383
359fn eqlIgnoreCase(ignore_case: bool, a: []const u8, b: []const u8) bool {
360 if (ignore_case) {
361 return std.ascii.eqlIgnoreCase(a, b);
362 } else {
363 return std.mem.eql(u8, a, b);
364 }
365}
366
367pub fn is_libc_lib_name(target: std.Target, name: []const u8) bool {
368 const ignore_case = target.os.tag == .macos or target.os.tag == .windows;
369
370 if (eqlIgnoreCase(ignore_case, name, "c"))
371 return true;
372
373 if (target.isMinGW()) {
374 if (eqlIgnoreCase(ignore_case, name, "m"))
375 return true;
376 if (eqlIgnoreCase(ignore_case, name, "uuid"))
377 return true;
378 if (eqlIgnoreCase(ignore_case, name, "mingw32"))
379 return true;
380 if (eqlIgnoreCase(ignore_case, name, "msvcrt-os"))
381 return true;
382 if (eqlIgnoreCase(ignore_case, name, "mingwex"))
383 return true;
384
385 return false;
386 }
387
388 if (target.abi.isGnu() or target.abi.isMusl()) {
389 if (eqlIgnoreCase(ignore_case, name, "m"))
390 return true;
391 if (eqlIgnoreCase(ignore_case, name, "rt"))
392 return true;
393 if (eqlIgnoreCase(ignore_case, name, "pthread"))
394 return true;
395 if (eqlIgnoreCase(ignore_case, name, "util"))
396 return true;
397 if (eqlIgnoreCase(ignore_case, name, "xnet"))
398 return true;
399 if (eqlIgnoreCase(ignore_case, name, "resolv"))
400 return true;
401 if (eqlIgnoreCase(ignore_case, name, "dl"))
402 return true;
403 }
404
405 if (target.abi.isMusl()) {
406 if (eqlIgnoreCase(ignore_case, name, "crypt"))
407 return true;
408 }
409
410 if (target.os.tag.isDarwin()) {
411 if (eqlIgnoreCase(ignore_case, name, "System"))
412 return true;
413 if (eqlIgnoreCase(ignore_case, name, "c"))
414 return true;
415 if (eqlIgnoreCase(ignore_case, name, "dbm"))
416 return true;
417 if (eqlIgnoreCase(ignore_case, name, "dl"))
418 return true;
419 if (eqlIgnoreCase(ignore_case, name, "info"))
420 return true;
421 if (eqlIgnoreCase(ignore_case, name, "m"))
422 return true;
423 if (eqlIgnoreCase(ignore_case, name, "poll"))
424 return true;
425 if (eqlIgnoreCase(ignore_case, name, "proc"))
426 return true;
427 if (eqlIgnoreCase(ignore_case, name, "pthread"))
428 return true;
429 if (eqlIgnoreCase(ignore_case, name, "rpcsvc"))
430 return true;
431 }
432
433 if (target.os.isAtLeast(.macos, .{ .major = 10, .minor = 8, .patch = 0 }) orelse false) {
434 if (eqlIgnoreCase(ignore_case, name, "mx"))
435 return true;
436 }
437
438 return false;
439}
440
441pub fn is_libcpp_lib_name(target: std.Target, name: []const u8) bool {
442 const ignore_case = target.os.tag.isDarwin() or target.os.tag == .windows;
443
444 return eqlIgnoreCase(ignore_case, name, "c++") or
445 eqlIgnoreCase(ignore_case, name, "stdc++") or
446 eqlIgnoreCase(ignore_case, name, "c++abi");
447}
448
449384pub const CompilerRtClassification = enum { none, only_compiler_rt, only_libunwind, both };
450385
451386pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerRtClassification {
......@@ -465,12 +400,16 @@ pub fn classifyCompilerRtLibName(target: std.Target, name: []const u8) CompilerR
465400}
466401
467402pub fn hasDebugInfo(target: std.Target) bool {
468 if (target.cpu.arch.isNvptx()) {
469 // TODO: not sure how to test "ptx >= 7.5" with featureset
470 return std.Target.nvptx.featureSetHas(target.cpu.features, .ptx75);
471 }
472
473 return true;
403 return switch (target.cpu.arch) {
404 .nvptx, .nvptx64 => std.Target.nvptx.featureSetHas(target.cpu.features, .ptx75) or
405 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx76) or
406 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx77) or
407 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx78) or
408 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx80) or
409 std.Target.nvptx.featureSetHas(target.cpu.features, .ptx81),
410 .bpfel, .bpfeb => false,
411 else => true,
412 };
474413}
475414
476415pub fn defaultCompilerRtOptimizeMode(target: std.Target) std.builtin.OptimizeMode {
......@@ -709,3 +648,37 @@ pub fn fnCallConvAllowsZigTypes(target: std.Target, cc: std.builtin.CallingConve
709648 else => false,
710649 };
711650}
651
652pub fn zigBackend(target: std.Target, use_llvm: bool) std.builtin.CompilerBackend {
653 if (use_llvm) return .stage2_llvm;
654 if (target.ofmt == .c) return .stage2_c;
655 return switch (target.cpu.arch) {
656 .wasm32, .wasm64 => std.builtin.CompilerBackend.stage2_wasm,
657 .arm, .armeb, .thumb, .thumbeb => .stage2_arm,
658 .x86_64 => .stage2_x86_64,
659 .x86 => .stage2_x86,
660 .aarch64, .aarch64_be, .aarch64_32 => .stage2_aarch64,
661 .riscv64 => .stage2_riscv64,
662 .sparc64 => .stage2_sparc64,
663 .spirv64 => .stage2_spirv64,
664 else => .other,
665 };
666}
667
668pub fn backendSupportsFeature(
669 cpu_arch: std.Target.Cpu.Arch,
670 ofmt: std.Target.ObjectFormat,
671 use_llvm: bool,
672 feature: Feature,
673) bool {
674 return switch (feature) {
675 .panic_fn => ofmt == .c or use_llvm or cpu_arch == .x86_64,
676 .panic_unwrap_error => ofmt == .c or use_llvm,
677 .safety_check_formatted => ofmt == .c or use_llvm,
678 .error_return_trace => use_llvm,
679 .is_named_enum_value => use_llvm,
680 .error_set_has_value => use_llvm or cpu_arch.isWasm(),
681 .field_reordering => use_llvm,
682 .safety_checked_instructions => use_llvm,
683 };
684}
src/wasi_libc.zig+16-4
......@@ -74,27 +74,31 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
7474 var args = std.ArrayList([]const u8).init(arena);
7575 try addCCArgs(comp, arena, &args, .{});
7676 try addLibcBottomHalfIncludes(comp, arena, &args);
77 return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &.{
77 var files = [_]Compilation.CSourceFile{
7878 .{
7979 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
8080 "libc", try sanitize(arena, crt1_reactor_src_file),
8181 }),
8282 .extra_flags = args.items,
83 .owner = undefined,
8384 },
84 });
85 };
86 return comp.build_crt_file("crt1-reactor", .Obj, .@"wasi crt1-reactor.o", prog_node, &files);
8587 },
8688 .crt1_command_o => {
8789 var args = std.ArrayList([]const u8).init(arena);
8890 try addCCArgs(comp, arena, &args, .{});
8991 try addLibcBottomHalfIncludes(comp, arena, &args);
90 return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &.{
92 var files = [_]Compilation.CSourceFile{
9193 .{
9294 .src_path = try comp.zig_lib_directory.join(arena, &[_][]const u8{
9395 "libc", try sanitize(arena, crt1_command_src_file),
9496 }),
9597 .extra_flags = args.items,
98 .owner = undefined,
9699 },
97 });
100 };
101 return comp.build_crt_file("crt1-command", .Obj, .@"wasi crt1-command.o", prog_node, &files);
98102 },
99103 .libc_a => {
100104 var libc_sources = std.ArrayList(Compilation.CSourceFile).init(arena);
......@@ -109,6 +113,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
109113 "libc", try sanitize(arena, file_path),
110114 }),
111115 .extra_flags = args.items,
116 .owner = undefined,
112117 });
113118 }
114119 }
......@@ -125,6 +130,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
125130 "libc", try sanitize(arena, file_path),
126131 }),
127132 .extra_flags = args.items,
133 .owner = undefined,
128134 });
129135 }
130136 }
......@@ -141,6 +147,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
141147 "libc", try sanitize(arena, file_path),
142148 }),
143149 .extra_flags = args.items,
150 .owner = undefined,
144151 });
145152 }
146153 }
......@@ -159,6 +166,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
159166 "libc", try sanitize(arena, file_path),
160167 }),
161168 .extra_flags = args.items,
169 .owner = undefined,
162170 });
163171 }
164172 try comp.build_crt_file("wasi-emulated-process-clocks", .Lib, .@"libwasi-emulated-process-clocks.a", prog_node, emu_clocks_sources.items);
......@@ -175,6 +183,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
175183 "libc", try sanitize(arena, file_path),
176184 }),
177185 .extra_flags = args.items,
186 .owner = undefined,
178187 });
179188 }
180189 try comp.build_crt_file("wasi-emulated-getpid", .Lib, .@"libwasi-emulated-getpid.a", prog_node, emu_getpid_sources.items);
......@@ -191,6 +200,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
191200 "libc", try sanitize(arena, file_path),
192201 }),
193202 .extra_flags = args.items,
203 .owner = undefined,
194204 });
195205 }
196206 try comp.build_crt_file("wasi-emulated-mman", .Lib, .@"libwasi-emulated-mman.a", prog_node, emu_mman_sources.items);
......@@ -208,6 +218,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
208218 "libc", try sanitize(arena, file_path),
209219 }),
210220 .extra_flags = args.items,
221 .owner = undefined,
211222 });
212223 }
213224 }
......@@ -224,6 +235,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: *std.Progr
224235 "libc", try sanitize(arena, file_path),
225236 }),
226237 .extra_flags = args.items,
238 .owner = undefined,
227239 });
228240 }
229241 }
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/eval.zig+10-10
......@@ -876,27 +876,27 @@ test "two comptime calls with array default initialized to undefined" {
876876 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
877877
878878 const S = struct {
879 const CrossTarget = struct {
880 dynamic_linker: DynamicLinker = DynamicLinker{},
879 const A = struct {
880 c: B = B{},
881881
882 pub fn parse() void {
883 var result: CrossTarget = .{};
884 result.getCpuArch();
882 pub fn d() void {
883 var f: A = .{};
884 f.e();
885885 }
886886
887 pub fn getCpuArch(self: CrossTarget) void {
888 _ = self;
887 pub fn e(g: A) void {
888 _ = g;
889889 }
890890 };
891891
892 const DynamicLinker = struct {
892 const B = struct {
893893 buffer: [255]u8 = undefined,
894894 };
895895 };
896896
897897 comptime {
898 S.CrossTarget.parse();
899 S.CrossTarget.parse();
898 S.A.d();
899 S.A.d();
900900 }
901901}
902902
test/cases.zig+5-5
......@@ -9,9 +9,9 @@ pub const BuildOptions = struct {
99 llvm_has_xtensa: bool,
1010};
1111
12pub fn addCases(cases: *Cases, build_options: BuildOptions) !void {
13 try @import("compile_errors.zig").addCases(cases);
14 try @import("cbe.zig").addCases(cases);
15 try @import("llvm_targets.zig").addCases(cases, build_options);
16 try @import("nvptx.zig").addCases(cases);
12pub fn addCases(cases: *Cases, build_options: BuildOptions, b: *std.Build) !void {
13 try @import("compile_errors.zig").addCases(cases, b);
14 try @import("cbe.zig").addCases(cases, b);
15 try @import("llvm_targets.zig").addCases(cases, build_options, b);
16 try @import("nvptx.zig").addCases(cases, b);
1717}
test/cbe.zig+24-24
......@@ -2,16 +2,16 @@ const std = @import("std");
22const Cases = @import("src/Cases.zig");
33const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n";
44
5// These tests should work with all platforms, but we're using linux_x64 for
6// now for consistency. Will be expanded eventually.
7const linux_x64 = std.zig.CrossTarget{
8 .cpu_arch = .x86_64,
9 .os_tag = .linux,
10};
11
12pub fn addCases(ctx: *Cases) !void {
5pub fn addCases(ctx: *Cases, b: *std.Build) !void {
6 // These tests should work with all platforms, but we're using linux_x64 for
7 // now for consistency. Will be expanded eventually.
8 const linux_x64: std.Target.Query = .{
9 .cpu_arch = .x86_64,
10 .os_tag = .linux,
11 };
12
1313 {
14 var case = ctx.exeFromCompiledC("hello world with updates", .{});
14 var case = ctx.exeFromCompiledC("hello world with updates", .{}, b);
1515
1616 // Regular old hello world
1717 case.addCompareOutput(
......@@ -59,7 +59,7 @@ pub fn addCases(ctx: *Cases) !void {
5959 }
6060
6161 {
62 var case = ctx.exeFromCompiledC("var args", .{});
62 var case = ctx.exeFromCompiledC("var args", .{}, b);
6363
6464 case.addCompareOutput(
6565 \\extern fn printf(format: [*:0]const u8, ...) c_int;
......@@ -72,7 +72,7 @@ pub fn addCases(ctx: *Cases) !void {
7272 }
7373
7474 {
75 var case = ctx.exeFromCompiledC("errorFromInt", .{});
75 var case = ctx.exeFromCompiledC("errorFromInt", .{}, b);
7676
7777 case.addCompareOutput(
7878 \\pub export fn main() c_int {
......@@ -108,7 +108,7 @@ pub fn addCases(ctx: *Cases) !void {
108108 }
109109
110110 {
111 var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64);
111 var case = ctx.exeFromCompiledC("x86_64-linux inline assembly", linux_x64, b);
112112
113113 // Exit with 0
114114 case.addCompareOutput(
......@@ -202,7 +202,7 @@ pub fn addCases(ctx: *Cases) !void {
202202 }
203203
204204 {
205 var case = ctx.exeFromCompiledC("alloc and retptr", .{});
205 var case = ctx.exeFromCompiledC("alloc and retptr", .{}, b);
206206
207207 case.addCompareOutput(
208208 \\fn add(a: i32, b: i32) i32 {
......@@ -220,7 +220,7 @@ pub fn addCases(ctx: *Cases) !void {
220220 }
221221
222222 {
223 var case = ctx.exeFromCompiledC("inferred local const and var", .{});
223 var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b);
224224
225225 case.addCompareOutput(
226226 \\fn add(a: i32, b: i32) i32 {
......@@ -236,7 +236,7 @@ pub fn addCases(ctx: *Cases) !void {
236236 , "");
237237 }
238238 {
239 var case = ctx.exeFromCompiledC("control flow", .{});
239 var case = ctx.exeFromCompiledC("control flow", .{}, b);
240240
241241 // Simple while loop
242242 case.addCompareOutput(
......@@ -423,7 +423,7 @@ pub fn addCases(ctx: *Cases) !void {
423423 });
424424 }
425425 //{
426 // var case = ctx.exeFromCompiledC("optionals", .{});
426 // var case = ctx.exeFromCompiledC("optionals", .{}, b);
427427
428428 // // Simple while loop
429429 // case.addCompareOutput(
......@@ -451,7 +451,7 @@ pub fn addCases(ctx: *Cases) !void {
451451 //}
452452
453453 {
454 var case = ctx.exeFromCompiledC("errors", .{});
454 var case = ctx.exeFromCompiledC("errors", .{}, b);
455455 case.addCompareOutput(
456456 \\pub export fn main() c_int {
457457 \\ var e1 = error.Foo;
......@@ -495,7 +495,7 @@ pub fn addCases(ctx: *Cases) !void {
495495 }
496496
497497 {
498 var case = ctx.exeFromCompiledC("structs", .{});
498 var case = ctx.exeFromCompiledC("structs", .{}, b);
499499 case.addError(
500500 \\const Point = struct { x: i32, y: i32 };
501501 \\pub export fn main() c_int {
......@@ -562,7 +562,7 @@ pub fn addCases(ctx: *Cases) !void {
562562 }
563563
564564 {
565 var case = ctx.exeFromCompiledC("unions", .{});
565 var case = ctx.exeFromCompiledC("unions", .{}, b);
566566
567567 case.addError(
568568 \\const U = union {
......@@ -596,7 +596,7 @@ pub fn addCases(ctx: *Cases) !void {
596596 }
597597
598598 {
599 var case = ctx.exeFromCompiledC("enums", .{});
599 var case = ctx.exeFromCompiledC("enums", .{}, b);
600600
601601 case.addError(
602602 \\const E1 = packed enum { a, b, c };
......@@ -838,7 +838,7 @@ pub fn addCases(ctx: *Cases) !void {
838838 }
839839
840840 {
841 var case = ctx.exeFromCompiledC("shift right and left", .{});
841 var case = ctx.exeFromCompiledC("shift right and left", .{}, b);
842842 case.addCompareOutput(
843843 \\pub export fn main() c_int {
844844 \\ var i: u32 = 16;
......@@ -863,7 +863,7 @@ pub fn addCases(ctx: *Cases) !void {
863863 }
864864
865865 {
866 var case = ctx.exeFromCompiledC("inferred error sets", .{});
866 var case = ctx.exeFromCompiledC("inferred error sets", .{}, b);
867867
868868 case.addCompareOutput(
869869 \\pub export fn main() c_int {
......@@ -884,7 +884,7 @@ pub fn addCases(ctx: *Cases) !void {
884884
885885 {
886886 // TODO: add u64 tests, ran into issues with the literal generated for std.math.maxInt(u64)
887 var case = ctx.exeFromCompiledC("add and sub wrapping operations", .{});
887 var case = ctx.exeFromCompiledC("add and sub wrapping operations", .{}, b);
888888 case.addCompareOutput(
889889 \\pub export fn main() c_int {
890890 \\ // Addition
......@@ -933,7 +933,7 @@ pub fn addCases(ctx: *Cases) !void {
933933 }
934934
935935 {
936 var case = ctx.exeFromCompiledC("rem", linux_x64);
936 var case = ctx.exeFromCompiledC("rem", linux_x64, b);
937937 case.addCompareOutput(
938938 \\fn assert(ok: bool) void {
939939 \\ if (!ok) unreachable;
test/compile_errors.zig+11-11
......@@ -2,9 +2,9 @@ const std = @import("std");
22const builtin = @import("builtin");
33const Cases = @import("src/Cases.zig");
44
5pub fn addCases(ctx: *Cases) !void {
5pub fn addCases(ctx: *Cases, b: *std.Build) !void {
66 {
7 const case = ctx.obj("multiline error messages", .{});
7 const case = ctx.obj("multiline error messages", b.host);
88
99 case.addError(
1010 \\comptime {
......@@ -39,7 +39,7 @@ pub fn addCases(ctx: *Cases) !void {
3939 }
4040
4141 {
42 const case = ctx.obj("isolated carriage return in multiline string literal", .{});
42 const case = ctx.obj("isolated carriage return in multiline string literal", b.host);
4343
4444 case.addError("const foo = \\\\\test\r\r rogue carriage return\n;", &[_][]const u8{
4545 ":1:19: error: expected ';' after declaration",
......@@ -48,7 +48,7 @@ pub fn addCases(ctx: *Cases) !void {
4848 }
4949
5050 {
51 const case = ctx.obj("missing semicolon at EOF", .{});
51 const case = ctx.obj("missing semicolon at EOF", b.host);
5252 case.addError(
5353 \\const foo = 1
5454 , &[_][]const u8{
......@@ -57,7 +57,7 @@ pub fn addCases(ctx: *Cases) !void {
5757 }
5858
5959 {
60 const case = ctx.obj("argument causes error", .{});
60 const case = ctx.obj("argument causes error", b.host);
6161
6262 case.addError(
6363 \\pub export fn entry() void {
......@@ -80,7 +80,7 @@ pub fn addCases(ctx: *Cases) !void {
8080 }
8181
8282 {
83 const case = ctx.obj("astgen failure in file struct", .{});
83 const case = ctx.obj("astgen failure in file struct", b.host);
8484
8585 case.addError(
8686 \\pub export fn entry() void {
......@@ -95,7 +95,7 @@ pub fn addCases(ctx: *Cases) !void {
9595 }
9696
9797 {
98 const case = ctx.obj("invalid store to comptime field", .{});
98 const case = ctx.obj("invalid store to comptime field", b.host);
9999
100100 case.addError(
101101 \\const a = @import("a.zig");
......@@ -119,7 +119,7 @@ pub fn addCases(ctx: *Cases) !void {
119119 }
120120
121121 {
122 const case = ctx.obj("file in multiple modules", .{});
122 const case = ctx.obj("file in multiple modules", b.host);
123123 case.addDepModule("foo", "foo.zig");
124124
125125 case.addError(
......@@ -138,7 +138,7 @@ pub fn addCases(ctx: *Cases) !void {
138138 }
139139
140140 {
141 const case = ctx.obj("wrong same named struct", .{});
141 const case = ctx.obj("wrong same named struct", b.host);
142142
143143 case.addError(
144144 \\const a = @import("a.zig");
......@@ -172,7 +172,7 @@ pub fn addCases(ctx: *Cases) !void {
172172 }
173173
174174 {
175 const case = ctx.obj("non-printable invalid character", .{});
175 const case = ctx.obj("non-printable invalid character", b.host);
176176
177177 case.addError("\xff\xfe" ++
178178 \\export fn foo() bool {
......@@ -185,7 +185,7 @@ pub fn addCases(ctx: *Cases) !void {
185185 }
186186
187187 {
188 const case = ctx.obj("imported generic method call with invalid param", .{});
188 const case = ctx.obj("imported generic method call with invalid param", b.host);
189189
190190 case.addError(
191191 \\pub const import = @import("import.zig");
test/link/bss/build.zig+1
......@@ -7,6 +7,7 @@ pub fn build(b: *std.Build) void {
77 const exe = b.addExecutable(.{
88 .name = "bss",
99 .root_source_file = .{ .path = "main.zig" },
10 .target = b.host,
1011 .optimize = .Debug,
1112 });
1213
test/link/common_symbols/build.zig+1-1
......@@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1414 const lib_a = b.addStaticLibrary(.{
1515 .name = "a",
1616 .optimize = optimize,
17 .target = .{},
17 .target = b.host,
1818 });
1919 lib_a.addCSourceFiles(.{
2020 .files = &.{ "c.c", "a.c", "b.c" },
test/link/common_symbols_alignment/build.zig+1-1
......@@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1414 const lib_a = b.addStaticLibrary(.{
1515 .name = "a",
1616 .optimize = optimize,
17 .target = .{},
17 .target = b.host,
1818 });
1919 lib_a.addCSourceFiles(.{
2020 .files = &.{"a.c"},
test/link/elf.zig+664-446
......@@ -5,20 +5,20 @@
55pub fn testAll(b: *Build) *Step {
66 const elf_step = b.step("test-elf", "Run ELF tests");
77
8 const default_target = CrossTarget{
8 const default_target = b.resolveTargetQuery(.{
99 .cpu_arch = .x86_64, // TODO relax this once ELF linker is able to handle other archs
1010 .os_tag = .linux,
11 };
12 const musl_target = CrossTarget{
11 });
12 const musl_target = b.resolveTargetQuery(.{
1313 .cpu_arch = .x86_64,
1414 .os_tag = .linux,
1515 .abi = .musl,
16 };
17 const glibc_target = CrossTarget{
16 });
17 const glibc_target = b.resolveTargetQuery(.{
1818 .cpu_arch = .x86_64,
1919 .os_tag = .linux,
2020 .abi = .gnu,
21 };
21 });
2222
2323 // Exercise linker in -r mode
2424 elf_step.dependOn(testEmitRelocatable(b, .{ .use_llvm = false, .target = musl_target }));
......@@ -132,14 +132,18 @@ pub fn testAll(b: *Build) *Step {
132132fn testAbsSymbols(b: *Build, opts: Options) *Step {
133133 const test_step = addTestStep(b, "abs-symbols", opts);
134134
135 const obj = addObject(b, "obj", opts);
136 addAsmSourceBytes(obj,
135 const obj = addObject(b, opts, .{
136 .name = "obj",
137 .asm_source_bytes =
137138 \\.globl foo
138139 \\foo = 0x800008
139 );
140 \\
141 ,
142 });
140143
141 const exe = addExecutable(b, "test", opts);
142 addCSourceBytes(exe,
144 const exe = addExecutable(b, opts, .{
145 .name = "test",
146 .c_source_bytes =
143147 \\#include <signal.h>
144148 \\#include <stdio.h>
145149 \\#include <stdlib.h>
......@@ -159,7 +163,8 @@ fn testAbsSymbols(b: *Build, opts: Options) *Step {
159163 \\ foo = 5;
160164 \\ return 0;
161165 \\}
162 , &.{});
166 ,
167 });
163168 exe.addObject(obj);
164169 exe.linkLibC();
165170
......@@ -173,31 +178,36 @@ fn testAbsSymbols(b: *Build, opts: Options) *Step {
173178fn testAsNeeded(b: *Build, opts: Options) *Step {
174179 const test_step = addTestStep(b, "as-needed", opts);
175180
176 const main_o = addObject(b, "main", opts);
177 addCSourceBytes(main_o,
181 const main_o = addObject(b, opts, .{
182 .name = "main",
183 .c_source_bytes =
178184 \\#include <stdio.h>
179185 \\int baz();
180186 \\int main() {
181187 \\ printf("%d\n", baz());
182188 \\ return 0;
183189 \\}
184 , &.{});
190 \\
191 ,
192 });
185193 main_o.linkLibC();
186194
187 const libfoo = addSharedLibrary(b, "foo", opts);
195 const libfoo = addSharedLibrary(b, opts, .{ .name = "foo" });
188196 addCSourceBytes(libfoo, "int foo() { return 42; }", &.{});
189197
190 const libbar = addSharedLibrary(b, "bar", opts);
198 const libbar = addSharedLibrary(b, opts, .{ .name = "bar" });
191199 addCSourceBytes(libbar, "int bar() { return 42; }", &.{});
192200
193 const libbaz = addSharedLibrary(b, "baz", opts);
201 const libbaz = addSharedLibrary(b, opts, .{ .name = "baz" });
194202 addCSourceBytes(libbaz,
195203 \\int foo();
196204 \\int baz() { return foo(); }
197205 , &.{});
198206
199207 {
200 const exe = addExecutable(b, "test", opts);
208 const exe = addExecutable(b, opts, .{
209 .name = "test",
210 });
201211 exe.addObject(main_o);
202212 exe.linkSystemLibrary2("foo", .{ .needed = true });
203213 exe.addLibraryPath(libfoo.getEmittedBinDirectory());
......@@ -225,7 +235,9 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {
225235 }
226236
227237 {
228 const exe = addExecutable(b, "test", opts);
238 const exe = addExecutable(b, opts, .{
239 .name = "test",
240 });
229241 exe.addObject(main_o);
230242 exe.linkSystemLibrary2("foo", .{ .needed = false });
231243 exe.addLibraryPath(libfoo.getEmittedBinDirectory());
......@@ -259,7 +271,7 @@ fn testAsNeeded(b: *Build, opts: Options) *Step {
259271fn testCanonicalPlt(b: *Build, opts: Options) *Step {
260272 const test_step = addTestStep(b, "canonical-plt", opts);
261273
262 const dso = addSharedLibrary(b, "a", opts);
274 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
263275 addCSourceBytes(dso,
264276 \\void *foo() {
265277 \\ return foo;
......@@ -269,17 +281,21 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step {
269281 \\}
270282 , &.{});
271283
272 const b_o = addObject(b, "obj", opts);
273 addCSourceBytes(b_o,
284 const b_o = addObject(b, opts, .{
285 .name = "obj",
286 .c_source_bytes =
274287 \\void *bar();
275288 \\void *baz() {
276289 \\ return bar;
277290 \\}
278 , &.{});
279 b_o.force_pic = true;
291 \\
292 ,
293 .pic = true,
294 });
280295
281 const main_o = addObject(b, "main", opts);
282 addCSourceBytes(main_o,
296 const main_o = addObject(b, opts, .{
297 .name = "main",
298 .c_source_bytes =
283299 \\#include <assert.h>
284300 \\void *foo();
285301 \\void *bar();
......@@ -290,11 +306,15 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step {
290306 \\ assert(bar == baz());
291307 \\ return 0;
292308 \\}
293 , &.{});
309 \\
310 ,
311 .pic = false,
312 });
294313 main_o.linkLibC();
295 main_o.force_pic = false;
296314
297 const exe = addExecutable(b, "main", opts);
315 const exe = addExecutable(b, opts, .{
316 .name = "main",
317 });
298318 exe.addObject(main_o);
299319 exe.addObject(b_o);
300320 exe.linkLibrary(dso);
......@@ -311,7 +331,9 @@ fn testCanonicalPlt(b: *Build, opts: Options) *Step {
311331fn testCommonSymbols(b: *Build, opts: Options) *Step {
312332 const test_step = addTestStep(b, "common-symbols", opts);
313333
314 const exe = addExecutable(b, "test", opts);
334 const exe = addExecutable(b, opts, .{
335 .name = "test",
336 });
315337 addCSourceBytes(exe,
316338 \\int foo;
317339 \\int bar;
......@@ -338,8 +360,9 @@ fn testCommonSymbols(b: *Build, opts: Options) *Step {
338360fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
339361 const test_step = addTestStep(b, "common-symbols-in-archive", opts);
340362
341 const a_o = addObject(b, "a", opts);
342 addCSourceBytes(a_o,
363 const a_o = addObject(b, opts, .{
364 .name = "a",
365 .c_source_bytes =
343366 \\#include <stdio.h>
344367 \\int foo;
345368 \\int bar;
......@@ -348,28 +371,43 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
348371 \\int main() {
349372 \\ printf("%d %d %d %d\n", foo, bar, baz, two ? two() : -1);
350373 \\}
351 , &.{"-fcommon"});
374 \\
375 ,
376 .c_source_flags = &.{"-fcommon"},
377 });
352378 a_o.linkLibC();
353379
354 const b_o = addObject(b, "b", opts);
355 addCSourceBytes(b_o, "int foo = 5;", &.{"-fcommon"});
380 const b_o = addObject(b, opts, .{
381 .name = "b",
382 .c_source_bytes = "int foo = 5;",
383 .c_source_flags = &.{"-fcommon"},
384 });
356385
357386 {
358 const c_o = addObject(b, "c", opts);
359 addCSourceBytes(c_o,
387 const c_o = addObject(b, opts, .{
388 .name = "c",
389 .c_source_bytes =
360390 \\int bar;
361391 \\int two() { return 2; }
362 , &.{"-fcommon"});
363
364 const d_o = addObject(b, "d", opts);
365 addCSourceBytes(d_o, "int baz;", &.{"-fcommon"});
366
367 const lib = addStaticLibrary(b, "lib", opts);
392 \\
393 ,
394 .c_source_flags = &.{"-fcommon"},
395 });
396
397 const d_o = addObject(b, opts, .{
398 .name = "d",
399 .c_source_bytes = "int baz;",
400 .c_source_flags = &.{"-fcommon"},
401 });
402
403 const lib = addStaticLibrary(b, opts, .{ .name = "lib" });
368404 lib.addObject(b_o);
369405 lib.addObject(c_o);
370406 lib.addObject(d_o);
371407
372 const exe = addExecutable(b, "test", opts);
408 const exe = addExecutable(b, opts, .{
409 .name = "test",
410 });
373411 exe.addObject(a_o);
374412 exe.linkLibrary(lib);
375413 exe.linkLibC();
......@@ -380,18 +418,23 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
380418 }
381419
382420 {
383 const e_o = addObject(b, "e", opts);
384 addCSourceBytes(e_o,
421 const e_o = addObject(b, opts, .{
422 .name = "e",
423 .c_source_bytes =
385424 \\int bar = 0;
386425 \\int baz = 7;
387426 \\int two() { return 2; }
388 , &.{"-fcommon"});
427 ,
428 .c_source_flags = &.{"-fcommon"},
429 });
389430
390 const lib = addStaticLibrary(b, "lib", opts);
431 const lib = addStaticLibrary(b, opts, .{ .name = "lib" });
391432 lib.addObject(b_o);
392433 lib.addObject(e_o);
393434
394 const exe = addExecutable(b, "test", opts);
435 const exe = addExecutable(b, opts, .{
436 .name = "test",
437 });
395438 exe.addObject(a_o);
396439 exe.linkLibrary(lib);
397440 exe.linkLibC();
......@@ -407,21 +450,23 @@ fn testCommonSymbolsInArchive(b: *Build, opts: Options) *Step {
407450fn testCopyrel(b: *Build, opts: Options) *Step {
408451 const test_step = addTestStep(b, "copyrel", opts);
409452
410 const dso = addSharedLibrary(b, "a", opts);
453 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
411454 addCSourceBytes(dso,
412455 \\int foo = 3;
413456 \\int bar = 5;
414457 , &.{});
415458
416 const exe = addExecutable(b, "main", opts);
417 addCSourceBytes(exe,
459 const exe = addExecutable(b, opts, .{
460 .name = "main",
461 .c_source_bytes =
418462 \\#include<stdio.h>
419463 \\extern int foo, bar;
420464 \\int main() {
421465 \\ printf("%d %d\n", foo, bar);
422466 \\ return 0;
423467 \\}
424 , &.{});
468 ,
469 });
425470 exe.linkLibrary(dso);
426471 exe.linkLibC();
427472 // https://github.com/ziglang/zig/issues/17619
......@@ -437,7 +482,7 @@ fn testCopyrel(b: *Build, opts: Options) *Step {
437482fn testCopyrelAlias(b: *Build, opts: Options) *Step {
438483 const test_step = addTestStep(b, "copyrel-alias", opts);
439484
440 const dso = addSharedLibrary(b, "a", opts);
485 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
441486 addCSourceBytes(dso,
442487 \\int bruh = 31;
443488 \\int foo = 42;
......@@ -445,7 +490,10 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step {
445490 \\extern int baz __attribute__((alias("foo")));
446491 , &.{});
447492
448 const exe = addExecutable(b, "main", opts);
493 const exe = addExecutable(b, opts, .{
494 .name = "main",
495 .pic = false,
496 });
449497 addCSourceBytes(exe,
450498 \\#include<stdio.h>
451499 \\extern int foo;
......@@ -461,7 +509,6 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step {
461509 , &.{});
462510 exe.linkLibrary(dso);
463511 exe.linkLibC();
464 exe.force_pic = false;
465512 exe.pie = false;
466513
467514 const run = addRunArtifact(exe);
......@@ -474,28 +521,31 @@ fn testCopyrelAlias(b: *Build, opts: Options) *Step {
474521fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
475522 const test_step = addTestStep(b, "copyrel-alignment", opts);
476523
477 const a_so = addSharedLibrary(b, "a", opts);
524 const a_so = addSharedLibrary(b, opts, .{ .name = "a" });
478525 addCSourceBytes(a_so, "__attribute__((aligned(32))) int foo = 5;", &.{});
479526
480 const b_so = addSharedLibrary(b, "b", opts);
527 const b_so = addSharedLibrary(b, opts, .{ .name = "b" });
481528 addCSourceBytes(b_so, "__attribute__((aligned(8))) int foo = 5;", &.{});
482529
483 const c_so = addSharedLibrary(b, "c", opts);
530 const c_so = addSharedLibrary(b, opts, .{ .name = "c" });
484531 addCSourceBytes(c_so, "__attribute__((aligned(256))) int foo = 5;", &.{});
485532
486 const obj = addObject(b, "main", opts);
487 addCSourceBytes(obj,
533 const obj = addObject(b, opts, .{
534 .name = "main",
535 .c_source_bytes =
488536 \\#include <stdio.h>
489537 \\extern int foo;
490538 \\int main() { printf("%d\n", foo); }
491 , &.{});
539 \\
540 ,
541 .pic = false,
542 });
492543 obj.linkLibC();
493 obj.force_pic = false;
494544
495545 const exp_stdout = "5\n";
496546
497547 {
498 const exe = addExecutable(b, "main", opts);
548 const exe = addExecutable(b, opts, .{ .name = "main" });
499549 exe.addObject(obj);
500550 exe.linkLibrary(a_so);
501551 exe.linkLibC();
......@@ -514,7 +564,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
514564 }
515565
516566 {
517 const exe = addExecutable(b, "main", opts);
567 const exe = addExecutable(b, opts, .{ .name = "main" });
518568 exe.addObject(obj);
519569 exe.linkLibrary(b_so);
520570 exe.linkLibC();
......@@ -533,7 +583,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
533583 }
534584
535585 {
536 const exe = addExecutable(b, "main", opts);
586 const exe = addExecutable(b, opts, .{ .name = "main" });
537587 exe.addObject(obj);
538588 exe.linkLibrary(c_so);
539589 exe.linkLibC();
......@@ -557,7 +607,7 @@ fn testCopyrelAlignment(b: *Build, opts: Options) *Step {
557607fn testDsoPlt(b: *Build, opts: Options) *Step {
558608 const test_step = addTestStep(b, "dso-plt", opts);
559609
560 const dso = addSharedLibrary(b, "dso", opts);
610 const dso = addSharedLibrary(b, opts, .{ .name = "dso" });
561611 addCSourceBytes(dso,
562612 \\#include<stdio.h>
563613 \\void world() {
......@@ -573,7 +623,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {
573623 , &.{});
574624 dso.linkLibC();
575625
576 const exe = addExecutable(b, "test", opts);
626 const exe = addExecutable(b, opts, .{ .name = "test" });
577627 addCSourceBytes(exe,
578628 \\#include<stdio.h>
579629 \\void world() {
......@@ -599,7 +649,7 @@ fn testDsoPlt(b: *Build, opts: Options) *Step {
599649fn testDsoUndef(b: *Build, opts: Options) *Step {
600650 const test_step = addTestStep(b, "dso-undef", opts);
601651
602 const dso = addSharedLibrary(b, "dso", opts);
652 const dso = addSharedLibrary(b, opts, .{ .name = "dso" });
603653 addCSourceBytes(dso,
604654 \\extern int foo;
605655 \\int bar = 5;
......@@ -607,13 +657,15 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {
607657 , &.{});
608658 dso.linkLibC();
609659
610 const obj = addObject(b, "obj", opts);
611 addCSourceBytes(obj, "int foo = 3;", &.{});
660 const obj = addObject(b, opts, .{
661 .name = "obj",
662 .c_source_bytes = "int foo = 3;",
663 });
612664
613 const lib = addStaticLibrary(b, "lib", opts);
665 const lib = addStaticLibrary(b, opts, .{ .name = "lib" });
614666 lib.addObject(obj);
615667
616 const exe = addExecutable(b, "test", opts);
668 const exe = addExecutable(b, opts, .{ .name = "test" });
617669 exe.linkLibrary(dso);
618670 exe.linkLibrary(lib);
619671 addCSourceBytes(exe,
......@@ -641,8 +693,9 @@ fn testDsoUndef(b: *Build, opts: Options) *Step {
641693fn testEmitRelocatable(b: *Build, opts: Options) *Step {
642694 const test_step = addTestStep(b, "emit-relocatable", opts);
643695
644 const obj1 = addObject(b, "obj1", opts);
645 addZigSourceBytes(obj1,
696 const obj1 = addObject(b, opts, .{
697 .name = "obj1",
698 .zig_source_bytes =
646699 \\const std = @import("std");
647700 \\extern var bar: i32;
648701 \\export fn foo() i32 {
......@@ -651,18 +704,20 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {
651704 \\export fn printFoo() void {
652705 \\ std.debug.print("foo={d}\n", .{foo()});
653706 \\}
654 );
655 addCSourceBytes(obj1,
707 ,
708 .c_source_bytes =
656709 \\#include <stdio.h>
657710 \\int bar = 42;
658711 \\void printBar() {
659712 \\ fprintf(stderr, "bar=%d\n", bar);
660713 \\}
661 , &.{});
714 ,
715 });
662716 obj1.linkLibC();
663717
664 const exe = addExecutable(b, "test", opts);
665 addZigSourceBytes(exe,
718 const exe = addExecutable(b, opts, .{
719 .name = "test",
720 .zig_source_bytes =
666721 \\const std = @import("std");
667722 \\extern fn printFoo() void;
668723 \\extern fn printBar() void;
......@@ -670,7 +725,8 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {
670725 \\ printFoo();
671726 \\ printBar();
672727 \\}
673 );
728 ,
729 });
674730 exe.addObject(obj1);
675731 exe.linkLibC();
676732
......@@ -688,20 +744,26 @@ fn testEmitRelocatable(b: *Build, opts: Options) *Step {
688744fn testEmitStaticLib(b: *Build, opts: Options) *Step {
689745 const test_step = addTestStep(b, "emit-static-lib", opts);
690746
691 const obj1 = addObject(b, "obj1", opts);
692 addCSourceBytes(obj1,
747 const obj1 = addObject(b, opts, .{
748 .name = "obj1",
749 .c_source_bytes =
693750 \\int foo = 0;
694751 \\int bar = 2;
695752 \\int fooBar() {
696753 \\ return foo + bar;
697754 \\}
698 , &.{});
755 ,
756 });
699757
700 const obj2 = addObject(b, "obj2", opts);
701 addCSourceBytes(obj2, "int tentative;", &.{"-fcommon"});
758 const obj2 = addObject(b, opts, .{
759 .name = "obj2",
760 .c_source_bytes = "int tentative;",
761 .c_source_flags = &.{"-fcommon"},
762 });
702763
703 const obj3 = addObject(b, "a_very_long_file_name_so_that_it_ends_up_in_strtab", opts);
704 addZigSourceBytes(obj3,
764 const obj3 = addObject(b, opts, .{
765 .name = "a_very_long_file_name_so_that_it_ends_up_in_strtab",
766 .zig_source_bytes =
705767 \\fn weakFoo() callconv(.C) usize {
706768 \\ return 42;
707769 \\}
......@@ -710,9 +772,10 @@ fn testEmitStaticLib(b: *Build, opts: Options) *Step {
710772 \\ @export(weakFoo, .{ .name = "weakFoo", .linkage = .Weak });
711773 \\ @export(strongBar, .{ .name = "strongBarAlias", .linkage = .Strong });
712774 \\}
713 );
775 ,
776 });
714777
715 const lib = addStaticLibrary(b, "lib", opts);
778 const lib = addStaticLibrary(b, opts, .{ .name = "lib" });
716779 lib.addObject(obj1);
717780 lib.addObject(obj2);
718781 lib.addObject(obj3);
......@@ -747,30 +810,36 @@ fn testEmitStaticLib(b: *Build, opts: Options) *Step {
747810fn testEmitStaticLibZig(b: *Build, opts: Options) *Step {
748811 const test_step = addTestStep(b, "emit-static-lib-zig", opts);
749812
750 const obj1 = addObject(b, "obj1", opts);
751 addZigSourceBytes(obj1,
813 const obj1 = addObject(b, opts, .{
814 .name = "obj1",
815 .zig_source_bytes =
752816 \\export var foo: i32 = 42;
753817 \\export var bar: i32 = 2;
754 );
818 ,
819 });
755820
756 const lib = addStaticLibrary(b, "lib", opts);
757 addZigSourceBytes(lib,
821 const lib = addStaticLibrary(b, opts, .{
822 .name = "lib",
823 .zig_source_bytes =
758824 \\extern var foo: i32;
759825 \\extern var bar: i32;
760826 \\export fn fooBar() i32 {
761827 \\ return foo + bar;
762828 \\}
763 );
829 ,
830 });
764831 lib.addObject(obj1);
765832
766 const exe = addExecutable(b, "test", opts);
767 addZigSourceBytes(exe,
833 const exe = addExecutable(b, opts, .{
834 .name = "test",
835 .zig_source_bytes =
768836 \\const std = @import("std");
769837 \\extern fn fooBar() i32;
770838 \\pub fn main() void {
771839 \\ std.debug.print("{d}", .{fooBar()});
772840 \\}
773 );
841 ,
842 });
774843 exe.linkLibrary(lib);
775844
776845 const run = addRunArtifact(exe);
......@@ -783,7 +852,7 @@ fn testEmitStaticLibZig(b: *Build, opts: Options) *Step {
783852fn testEmptyObject(b: *Build, opts: Options) *Step {
784853 const test_step = addTestStep(b, "empty-object", opts);
785854
786 const exe = addExecutable(b, "test", opts);
855 const exe = addExecutable(b, opts, .{ .name = "test" });
787856 addCSourceBytes(exe, "int main() { return 0; }", &.{});
788857 addCSourceBytes(exe, "", &.{});
789858 exe.linkLibC();
......@@ -798,18 +867,23 @@ fn testEmptyObject(b: *Build, opts: Options) *Step {
798867fn testEntryPoint(b: *Build, opts: Options) *Step {
799868 const test_step = addTestStep(b, "entry-point", opts);
800869
801 const a_o = addObject(b, "a", opts);
802 addAsmSourceBytes(a_o,
870 const a_o = addObject(b, opts, .{
871 .name = "a",
872 .asm_source_bytes =
803873 \\.globl foo, bar
804874 \\foo = 0x1000
805875 \\bar = 0x2000
806 );
876 \\
877 ,
878 });
807879
808 const b_o = addObject(b, "b", opts);
809 addCSourceBytes(b_o, "int main() { return 0; }", &.{});
880 const b_o = addObject(b, opts, .{
881 .name = "b",
882 .c_source_bytes = "int main() { return 0; }",
883 });
810884
811885 {
812 const exe = addExecutable(b, "main", opts);
886 const exe = addExecutable(b, opts, .{ .name = "main" });
813887 exe.addObject(a_o);
814888 exe.addObject(b_o);
815889 exe.entry = .{ .symbol_name = "foo" };
......@@ -825,7 +899,7 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
825899 // TODO looks like not assigning a unique name to this executable will
826900 // cause an artifact collision taking the cached executable from the above
827901 // step instead of generating a new one.
828 const exe = addExecutable(b, "other", opts);
902 const exe = addExecutable(b, opts, .{ .name = "other" });
829903 exe.addObject(a_o);
830904 exe.addObject(b_o);
831905 exe.entry = .{ .symbol_name = "bar" };
......@@ -843,8 +917,9 @@ fn testEntryPoint(b: *Build, opts: Options) *Step {
843917fn testExportDynamic(b: *Build, opts: Options) *Step {
844918 const test_step = addTestStep(b, "export-dynamic", opts);
845919
846 const obj = addObject(b, "obj", opts);
847 addAsmSourceBytes(obj,
920 const obj = addObject(b, opts, .{
921 .name = "obj",
922 .asm_source_bytes =
848923 \\.text
849924 \\ .globl foo
850925 \\ .hidden foo
......@@ -856,12 +931,14 @@ fn testExportDynamic(b: *Build, opts: Options) *Step {
856931 \\ .globl _start
857932 \\_start:
858933 \\ nop
859 );
934 \\
935 ,
936 });
860937
861 const dso = addSharedLibrary(b, "a", opts);
938 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
862939 addCSourceBytes(dso, "int baz = 10;", &.{});
863940
864 const exe = addExecutable(b, "main", opts);
941 const exe = addExecutable(b, opts, .{ .name = "main" });
865942 addCSourceBytes(exe,
866943 \\extern int baz;
867944 \\int callBaz() {
......@@ -885,7 +962,7 @@ fn testExportDynamic(b: *Build, opts: Options) *Step {
885962fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step {
886963 const test_step = addTestStep(b, "export-symbols-from-exe", opts);
887964
888 const dso = addSharedLibrary(b, "a", opts);
965 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
889966 addCSourceBytes(dso,
890967 \\void expfn1();
891968 \\void expfn2() {}
......@@ -895,7 +972,7 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step {
895972 \\}
896973 , &.{});
897974
898 const exe = addExecutable(b, "main", opts);
975 const exe = addExecutable(b, opts, .{ .name = "main" });
899976 addCSourceBytes(exe,
900977 \\void expfn1() {}
901978 \\void expfn2() {}
......@@ -923,10 +1000,10 @@ fn testExportSymbolsFromExe(b: *Build, opts: Options) *Step {
9231000fn testFuncAddress(b: *Build, opts: Options) *Step {
9241001 const test_step = addTestStep(b, "func-address", opts);
9251002
926 const dso = addSharedLibrary(b, "a", opts);
1003 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
9271004 addCSourceBytes(dso, "void fn() {}", &.{});
9281005
929 const exe = addExecutable(b, "main", opts);
1006 const exe = addExecutable(b, opts, .{ .name = "main" });
9301007 addCSourceBytes(exe,
9311008 \\#include <assert.h>
9321009 \\typedef void Func();
......@@ -937,7 +1014,7 @@ fn testFuncAddress(b: *Build, opts: Options) *Step {
9371014 \\}
9381015 , &.{});
9391016 exe.linkLibrary(dso);
940 exe.force_pic = false;
1017 exe.root_module.pic = false;
9411018 exe.pie = false;
9421019
9431020 const run = addRunArtifact(exe);
......@@ -950,8 +1027,9 @@ fn testFuncAddress(b: *Build, opts: Options) *Step {
9501027fn testGcSections(b: *Build, opts: Options) *Step {
9511028 const test_step = addTestStep(b, "gc-sections", opts);
9521029
953 const obj = addObject(b, "obj", opts);
954 addCppSourceBytes(obj,
1030 const obj = addObject(b, opts, .{
1031 .name = "obj",
1032 .cpp_source_bytes =
9551033 \\#include <stdio.h>
9561034 \\int two() { return 2; }
9571035 \\int live_var1 = 1;
......@@ -966,14 +1044,15 @@ fn testGcSections(b: *Build, opts: Options) *Step {
9661044 \\ printf("%d %d\n", live_var1, live_var2);
9671045 \\ live_fn2();
9681046 \\}
969 , &.{});
1047 ,
1048 });
9701049 obj.link_function_sections = true;
9711050 obj.link_data_sections = true;
9721051 obj.linkLibC();
9731052 obj.linkLibCpp();
9741053
9751054 {
976 const exe = addExecutable(b, "test", opts);
1055 const exe = addExecutable(b, opts, .{ .name = "test" });
9771056 exe.addObject(obj);
9781057 exe.link_gc_sections = false;
9791058 exe.linkLibC();
......@@ -1004,7 +1083,7 @@ fn testGcSections(b: *Build, opts: Options) *Step {
10041083 }
10051084
10061085 {
1007 const exe = addExecutable(b, "test", opts);
1086 const exe = addExecutable(b, opts, .{ .name = "test" });
10081087 exe.addObject(obj);
10091088 exe.link_gc_sections = true;
10101089 exe.linkLibC();
......@@ -1040,11 +1119,12 @@ fn testGcSections(b: *Build, opts: Options) *Step {
10401119fn testGcSectionsZig(b: *Build, opts: Options) *Step {
10411120 const test_step = addTestStep(b, "gc-sections-zig", opts);
10421121
1043 const obj = addObject(b, "obj", .{
1122 const obj = addObject(b, .{
10441123 .target = opts.target,
10451124 .use_llvm = true,
1046 });
1047 addCSourceBytes(obj,
1125 }, .{
1126 .name = "obj",
1127 .c_source_bytes =
10481128 \\int live_var1 = 1;
10491129 \\int live_var2 = 2;
10501130 \\int dead_var1 = 3;
......@@ -1053,13 +1133,15 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step {
10531133 \\void live_fn2() { live_fn1(); }
10541134 \\void dead_fn1() {}
10551135 \\void dead_fn2() { dead_fn1(); }
1056 , &.{});
1136 ,
1137 });
10571138 obj.link_function_sections = true;
10581139 obj.link_data_sections = true;
10591140
10601141 {
1061 const exe = addExecutable(b, "test1", opts);
1062 addZigSourceBytes(exe,
1142 const exe = addExecutable(b, opts, .{
1143 .name = "test1",
1144 .zig_source_bytes =
10631145 \\const std = @import("std");
10641146 \\extern var live_var1: i32;
10651147 \\extern var live_var2: i32;
......@@ -1069,7 +1151,8 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step {
10691151 \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable;
10701152 \\ live_fn2();
10711153 \\}
1072 );
1154 ,
1155 });
10731156 exe.addObject(obj);
10741157 exe.link_gc_sections = false;
10751158
......@@ -1098,8 +1181,9 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step {
10981181 }
10991182
11001183 {
1101 const exe = addExecutable(b, "test2", opts);
1102 addZigSourceBytes(exe,
1184 const exe = addExecutable(b, opts, .{
1185 .name = "test2",
1186 .zig_source_bytes =
11031187 \\const std = @import("std");
11041188 \\extern var live_var1: i32;
11051189 \\extern var live_var2: i32;
......@@ -1109,7 +1193,8 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step {
11091193 \\ stdout.writer().print("{d} {d}\n", .{ live_var1, live_var2 }) catch unreachable;
11101194 \\ live_fn2();
11111195 \\}
1112 );
1196 ,
1197 });
11131198 exe.addObject(obj);
11141199 exe.link_gc_sections = true;
11151200
......@@ -1143,7 +1228,7 @@ fn testGcSectionsZig(b: *Build, opts: Options) *Step {
11431228fn testHiddenWeakUndef(b: *Build, opts: Options) *Step {
11441229 const test_step = addTestStep(b, "hidden-weak-undef", opts);
11451230
1146 const dso = addSharedLibrary(b, "a", opts);
1231 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
11471232 addCSourceBytes(dso,
11481233 \\__attribute__((weak, visibility("hidden"))) void foo();
11491234 \\void bar() { foo(); }
......@@ -1162,7 +1247,7 @@ fn testHiddenWeakUndef(b: *Build, opts: Options) *Step {
11621247fn testIFuncAlias(b: *Build, opts: Options) *Step {
11631248 const test_step = addTestStep(b, "ifunc-alias", opts);
11641249
1165 const exe = addExecutable(b, "main", opts);
1250 const exe = addExecutable(b, opts, .{ .name = "main" });
11661251 addCSourceBytes(exe,
11671252 \\#include <assert.h>
11681253 \\void foo() {}
......@@ -1173,7 +1258,7 @@ fn testIFuncAlias(b: *Build, opts: Options) *Step {
11731258 \\ assert(bar == bar2);
11741259 \\}
11751260 , &.{});
1176 exe.force_pic = true;
1261 exe.root_module.pic = true;
11771262 exe.linkLibC();
11781263 // https://github.com/ziglang/zig/issues/17619
11791264 exe.pie = true;
......@@ -1188,7 +1273,7 @@ fn testIFuncAlias(b: *Build, opts: Options) *Step {
11881273fn testIFuncDlopen(b: *Build, opts: Options) *Step {
11891274 const test_step = addTestStep(b, "ifunc-dlopen", opts);
11901275
1191 const dso = addSharedLibrary(b, "a", opts);
1276 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
11921277 addCSourceBytes(dso,
11931278 \\__attribute__((ifunc("resolve_foo")))
11941279 \\void foo(void);
......@@ -1200,7 +1285,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step {
12001285 \\}
12011286 , &.{});
12021287
1203 const exe = addExecutable(b, "main", opts);
1288 const exe = addExecutable(b, opts, .{ .name = "main" });
12041289 addCSourceBytes(exe,
12051290 \\#include <dlfcn.h>
12061291 \\#include <assert.h>
......@@ -1219,7 +1304,7 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step {
12191304 exe.linkLibrary(dso);
12201305 exe.linkLibC();
12211306 exe.linkSystemLibrary2("dl", .{});
1222 exe.force_pic = false;
1307 exe.root_module.pic = false;
12231308 exe.pie = false;
12241309
12251310 const run = addRunArtifact(exe);
......@@ -1232,8 +1317,9 @@ fn testIFuncDlopen(b: *Build, opts: Options) *Step {
12321317fn testIFuncDso(b: *Build, opts: Options) *Step {
12331318 const test_step = addTestStep(b, "ifunc-dso", opts);
12341319
1235 const dso = addSharedLibrary(b, "a", opts);
1236 addCSourceBytes(dso,
1320 const dso = addSharedLibrary(b, opts, .{
1321 .name = "a",
1322 .c_source_bytes =
12371323 \\#include<stdio.h>
12381324 \\__attribute__((ifunc("resolve_foobar")))
12391325 \\void foobar(void);
......@@ -1244,16 +1330,19 @@ fn testIFuncDso(b: *Build, opts: Options) *Step {
12441330 \\static Func *resolve_foobar(void) {
12451331 \\ return real_foobar;
12461332 \\}
1247 , &.{});
1333 ,
1334 });
12481335 dso.linkLibC();
12491336
1250 const exe = addExecutable(b, "main", opts);
1251 addCSourceBytes(exe,
1337 const exe = addExecutable(b, opts, .{
1338 .name = "main",
1339 .c_source_bytes =
12521340 \\void foobar(void);
12531341 \\int main() {
12541342 \\ foobar();
12551343 \\}
1256 , &.{});
1344 ,
1345 });
12571346 exe.linkLibrary(dso);
12581347
12591348 const run = addRunArtifact(exe);
......@@ -1283,7 +1372,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step {
12831372 ;
12841373
12851374 {
1286 const exe = addExecutable(b, "main", opts);
1375 const exe = addExecutable(b, opts, .{ .name = "main" });
12871376 addCSourceBytes(exe, main_c, &.{});
12881377 exe.linkLibC();
12891378 exe.link_z_lazy = true;
......@@ -1295,7 +1384,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step {
12951384 test_step.dependOn(&run.step);
12961385 }
12971386 {
1298 const exe = addExecutable(b, "other", opts);
1387 const exe = addExecutable(b, opts, .{ .name = "other" });
12991388 addCSourceBytes(exe, main_c, &.{});
13001389 exe.linkLibC();
13011390 // https://github.com/ziglang/zig/issues/17619
......@@ -1312,7 +1401,7 @@ fn testIFuncDynamic(b: *Build, opts: Options) *Step {
13121401fn testIFuncExport(b: *Build, opts: Options) *Step {
13131402 const test_step = addTestStep(b, "ifunc-export", opts);
13141403
1315 const dso = addSharedLibrary(b, "a", opts);
1404 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
13161405 addCSourceBytes(dso,
13171406 \\#include <stdio.h>
13181407 \\__attribute__((ifunc("resolve_foobar")))
......@@ -1338,7 +1427,7 @@ fn testIFuncExport(b: *Build, opts: Options) *Step {
13381427fn testIFuncFuncPtr(b: *Build, opts: Options) *Step {
13391428 const test_step = addTestStep(b, "ifunc-func-ptr", opts);
13401429
1341 const exe = addExecutable(b, "main", opts);
1430 const exe = addExecutable(b, opts, .{ .name = "main" });
13421431 addCSourceBytes(exe,
13431432 \\typedef int Fn();
13441433 \\int foo() __attribute__((ifunc("resolve_foo")));
......@@ -1361,7 +1450,7 @@ fn testIFuncFuncPtr(b: *Build, opts: Options) *Step {
13611450 \\ printf("%d\n", f());
13621451 \\}
13631452 , &.{});
1364 exe.force_pic = true;
1453 exe.root_module.pic = true;
13651454 exe.linkLibC();
13661455 // https://github.com/ziglang/zig/issues/17619
13671456 exe.pie = true;
......@@ -1376,7 +1465,7 @@ fn testIFuncFuncPtr(b: *Build, opts: Options) *Step {
13761465fn testIFuncNoPlt(b: *Build, opts: Options) *Step {
13771466 const test_step = addTestStep(b, "ifunc-noplt", opts);
13781467
1379 const exe = addExecutable(b, "main", opts);
1468 const exe = addExecutable(b, opts, .{ .name = "main" });
13801469 addCSourceBytes(exe,
13811470 \\#include <stdio.h>
13821471 \\__attribute__((ifunc("resolve_foo")))
......@@ -1392,7 +1481,7 @@ fn testIFuncNoPlt(b: *Build, opts: Options) *Step {
13921481 \\ foo();
13931482 \\}
13941483 , &.{"-fno-plt"});
1395 exe.force_pic = true;
1484 exe.root_module.pic = true;
13961485 exe.linkLibC();
13971486 // https://github.com/ziglang/zig/issues/17619
13981487 exe.pie = true;
......@@ -1407,7 +1496,7 @@ fn testIFuncNoPlt(b: *Build, opts: Options) *Step {
14071496fn testIFuncStatic(b: *Build, opts: Options) *Step {
14081497 const test_step = addTestStep(b, "ifunc-static", opts);
14091498
1410 const exe = addExecutable(b, "main", opts);
1499 const exe = addExecutable(b, opts, .{ .name = "main" });
14111500 addCSourceBytes(exe,
14121501 \\#include <stdio.h>
14131502 \\void foo() __attribute__((ifunc("resolve_foo")));
......@@ -1435,7 +1524,7 @@ fn testIFuncStatic(b: *Build, opts: Options) *Step {
14351524fn testIFuncStaticPie(b: *Build, opts: Options) *Step {
14361525 const test_step = addTestStep(b, "ifunc-static-pie", opts);
14371526
1438 const exe = addExecutable(b, "main", opts);
1527 const exe = addExecutable(b, opts, .{ .name = "main" });
14391528 addCSourceBytes(exe,
14401529 \\#include <stdio.h>
14411530 \\void foo() __attribute__((ifunc("resolve_foo")));
......@@ -1451,7 +1540,7 @@ fn testIFuncStaticPie(b: *Build, opts: Options) *Step {
14511540 \\}
14521541 , &.{});
14531542 exe.linkage = .static;
1454 exe.force_pic = true;
1543 exe.root_module.pic = true;
14551544 exe.pie = true;
14561545 exe.linkLibC();
14571546
......@@ -1478,7 +1567,7 @@ fn testImageBase(b: *Build, opts: Options) *Step {
14781567 const test_step = addTestStep(b, "image-base", opts);
14791568
14801569 {
1481 const exe = addExecutable(b, "main1", opts);
1570 const exe = addExecutable(b, opts, .{ .name = "main1" });
14821571 addCSourceBytes(exe,
14831572 \\#include <stdio.h>
14841573 \\int main() {
......@@ -1502,7 +1591,7 @@ fn testImageBase(b: *Build, opts: Options) *Step {
15021591 }
15031592
15041593 {
1505 const exe = addExecutable(b, "main2", opts);
1594 const exe = addExecutable(b, opts, .{ .name = "main2" });
15061595 addCSourceBytes(exe, "void _start() {}", &.{});
15071596 exe.image_base = 0xffffffff8000000;
15081597
......@@ -1520,22 +1609,26 @@ fn testImageBase(b: *Build, opts: Options) *Step {
15201609fn testImportingDataDynamic(b: *Build, opts: Options) *Step {
15211610 const test_step = addTestStep(b, "importing-data-dynamic", opts);
15221611
1523 const dso = addSharedLibrary(b, "a", .{
1612 const dso = addSharedLibrary(b, .{
15241613 .target = opts.target,
15251614 .optimize = opts.optimize,
15261615 .use_llvm = true,
1616 }, .{
1617 .name = "a",
1618 .c_source_bytes = "int foo = 42;",
15271619 });
1528 addCSourceBytes(dso, "int foo = 42;", &.{});
15291620
1530 const main = addExecutable(b, "main", opts);
1531 addZigSourceBytes(main,
1621 const main = addExecutable(b, opts, .{
1622 .name = "main",
1623 .zig_source_bytes =
15321624 \\extern var foo: i32;
15331625 \\pub fn main() void {
15341626 \\ @import("std").debug.print("{d}\n", .{foo});
15351627 \\}
1536 );
1628 ,
1629 .strip = true, // TODO temp hack
1630 });
15371631 main.pie = true;
1538 main.strip = true; // TODO temp hack
15391632 main.linkLibrary(dso);
15401633 main.linkLibC();
15411634
......@@ -1549,28 +1642,34 @@ fn testImportingDataDynamic(b: *Build, opts: Options) *Step {
15491642fn testImportingDataStatic(b: *Build, opts: Options) *Step {
15501643 const test_step = addTestStep(b, "importing-data-static", opts);
15511644
1552 const obj = addObject(b, "a", .{
1645 const obj = addObject(b, .{
15531646 .target = opts.target,
15541647 .optimize = opts.optimize,
15551648 .use_llvm = true,
1649 }, .{
1650 .name = "a",
1651 .c_source_bytes = "int foo = 42;",
15561652 });
1557 addCSourceBytes(obj, "int foo = 42;", &.{});
15581653
1559 const lib = addStaticLibrary(b, "a", .{
1654 const lib = addStaticLibrary(b, .{
15601655 .target = opts.target,
15611656 .optimize = opts.optimize,
15621657 .use_llvm = true,
1658 }, .{
1659 .name = "a",
15631660 });
15641661 lib.addObject(obj);
15651662
1566 const main = addExecutable(b, "main", opts);
1567 addZigSourceBytes(main,
1663 const main = addExecutable(b, opts, .{
1664 .name = "main",
1665 .zig_source_bytes =
15681666 \\extern var foo: i32;
15691667 \\pub fn main() void {
15701668 \\ @import("std").debug.print("{d}\n", .{foo});
15711669 \\}
1572 );
1573 main.strip = true; // TODO temp hack
1670 ,
1671 .strip = true, // TODO temp hack
1672 });
15741673 main.linkLibrary(lib);
15751674 main.linkLibC();
15761675
......@@ -1584,63 +1683,76 @@ fn testImportingDataStatic(b: *Build, opts: Options) *Step {
15841683fn testInitArrayOrder(b: *Build, opts: Options) *Step {
15851684 const test_step = addTestStep(b, "init-array-order", opts);
15861685
1587 const a_o = addObject(b, "a", opts);
1588 addCSourceBytes(a_o,
1686 const a_o = addObject(b, opts, .{
1687 .name = "a",
1688 .c_source_bytes =
15891689 \\#include <stdio.h>
15901690 \\__attribute__((constructor(10000))) void init4() { printf("1"); }
1591 , &.{});
1691 ,
1692 });
15921693 a_o.linkLibC();
15931694
1594 const b_o = addObject(b, "b", opts);
1595 addCSourceBytes(b_o,
1695 const b_o = addObject(b, opts, .{
1696 .name = "b",
1697 .c_source_bytes =
15961698 \\#include <stdio.h>
15971699 \\__attribute__((constructor(1000))) void init3() { printf("2"); }
1598 , &.{});
1700 ,
1701 });
15991702 b_o.linkLibC();
16001703
1601 const c_o = addObject(b, "c", opts);
1602 addCSourceBytes(c_o,
1704 const c_o = addObject(b, opts, .{
1705 .name = "c",
1706 .c_source_bytes =
16031707 \\#include <stdio.h>
16041708 \\__attribute__((constructor)) void init1() { printf("3"); }
1605 , &.{});
1709 ,
1710 });
16061711 c_o.linkLibC();
16071712
1608 const d_o = addObject(b, "d", opts);
1609 addCSourceBytes(d_o,
1713 const d_o = addObject(b, opts, .{
1714 .name = "d",
1715 .c_source_bytes =
16101716 \\#include <stdio.h>
16111717 \\__attribute__((constructor)) void init2() { printf("4"); }
1612 , &.{});
1718 ,
1719 });
16131720 d_o.linkLibC();
16141721
1615 const e_o = addObject(b, "e", opts);
1616 addCSourceBytes(e_o,
1722 const e_o = addObject(b, opts, .{
1723 .name = "e",
1724 .c_source_bytes =
16171725 \\#include <stdio.h>
16181726 \\__attribute__((destructor(10000))) void fini4() { printf("5"); }
1619 , &.{});
1727 ,
1728 });
16201729 e_o.linkLibC();
16211730
1622 const f_o = addObject(b, "f", opts);
1623 addCSourceBytes(f_o,
1731 const f_o = addObject(b, opts, .{
1732 .name = "f",
1733 .c_source_bytes =
16241734 \\#include <stdio.h>
16251735 \\__attribute__((destructor(1000))) void fini3() { printf("6"); }
1626 , &.{});
1736 ,
1737 });
16271738 f_o.linkLibC();
16281739
1629 const g_o = addObject(b, "g", opts);
1630 addCSourceBytes(g_o,
1740 const g_o = addObject(b, opts, .{
1741 .name = "g",
1742 .c_source_bytes =
16311743 \\#include <stdio.h>
16321744 \\__attribute__((destructor)) void fini1() { printf("7"); }
1633 , &.{});
1745 ,
1746 });
16341747 g_o.linkLibC();
16351748
1636 const h_o = addObject(b, "h", opts);
1637 addCSourceBytes(h_o,
1638 \\#include <stdio.h>
1639 \\__attribute__((destructor)) void fini2() { printf("8"); }
1640 , &.{});
1749 const h_o = addObject(b, opts, .{ .name = "h", .c_source_bytes =
1750 \\#include <stdio.h>
1751 \\__attribute__((destructor)) void fini2() { printf("8"); }
1752 });
16411753 h_o.linkLibC();
16421754
1643 const exe = addExecutable(b, "main", opts);
1755 const exe = addExecutable(b, opts, .{ .name = "main" });
16441756 addCSourceBytes(exe, "int main() { return 0; }", &.{});
16451757 exe.addObject(a_o);
16461758 exe.addObject(b_o);
......@@ -1651,7 +1763,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step {
16511763 exe.addObject(g_o);
16521764 exe.addObject(h_o);
16531765
1654 if (opts.target.isGnuLibC()) {
1766 if (opts.target.result.isGnuLibC()) {
16551767 // TODO I think we need to clarify our use of `-fPIC -fPIE` flags for different targets
16561768 exe.pie = true;
16571769 }
......@@ -1666,7 +1778,7 @@ fn testInitArrayOrder(b: *Build, opts: Options) *Step {
16661778fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
16671779 const test_step = addTestStep(b, "large-alignment-dso", opts);
16681780
1669 const dso = addSharedLibrary(b, "dso", opts);
1781 const dso = addSharedLibrary(b, opts, .{ .name = "dso" });
16701782 addCSourceBytes(dso,
16711783 \\#include <stdio.h>
16721784 \\#include <stdint.h>
......@@ -1695,7 +1807,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
16951807 check.checkComputeCompare("addr2 16 %", .{ .op = .eq, .value = .{ .literal = 0 } });
16961808 test_step.dependOn(&check.step);
16971809
1698 const exe = addExecutable(b, "test", opts);
1810 const exe = addExecutable(b, opts, .{ .name = "test" });
16991811 addCSourceBytes(exe,
17001812 \\void greet();
17011813 \\int main() { greet(); }
......@@ -1715,7 +1827,7 @@ fn testLargeAlignmentDso(b: *Build, opts: Options) *Step {
17151827fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {
17161828 const test_step = addTestStep(b, "large-alignment-exe", opts);
17171829
1718 const exe = addExecutable(b, "test", opts);
1830 const exe = addExecutable(b, opts, .{ .name = "test" });
17191831 addCSourceBytes(exe,
17201832 \\#include <stdio.h>
17211833 \\#include <stdint.h>
......@@ -1760,7 +1872,7 @@ fn testLargeAlignmentExe(b: *Build, opts: Options) *Step {
17601872fn testLargeBss(b: *Build, opts: Options) *Step {
17611873 const test_step = addTestStep(b, "large-bss", opts);
17621874
1763 const exe = addExecutable(b, "main", opts);
1875 const exe = addExecutable(b, opts, .{ .name = "main" });
17641876 addCSourceBytes(exe,
17651877 \\char arr[0x100000000];
17661878 \\int main() {
......@@ -1781,27 +1893,31 @@ fn testLargeBss(b: *Build, opts: Options) *Step {
17811893fn testLinkOrder(b: *Build, opts: Options) *Step {
17821894 const test_step = addTestStep(b, "link-order", opts);
17831895
1784 const obj = addObject(b, "obj", opts);
1785 addCSourceBytes(obj, "void foo() {}", &.{});
1786 obj.force_pic = true;
1896 const obj = addObject(b, opts, .{
1897 .name = "obj",
1898 .c_source_bytes = "void foo() {}",
1899 .pic = true,
1900 });
17871901
1788 const dso = addSharedLibrary(b, "a", opts);
1902 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
17891903 dso.addObject(obj);
17901904
1791 const lib = addStaticLibrary(b, "b", opts);
1905 const lib = addStaticLibrary(b, opts, .{ .name = "b" });
17921906 lib.addObject(obj);
17931907
1794 const main_o = addObject(b, "main", opts);
1795 addCSourceBytes(main_o,
1908 const main_o = addObject(b, opts, .{
1909 .name = "main",
1910 .c_source_bytes =
17961911 \\void foo();
17971912 \\int main() {
17981913 \\ foo();
17991914 \\}
1800 , &.{});
1915 ,
1916 });
18011917
18021918 // https://github.com/ziglang/zig/issues/17450
18031919 // {
1804 // const exe = addExecutable(b, "main1", opts);
1920 // const exe = addExecutable(b, opts, .{ .name = "main1"});
18051921 // exe.addObject(main_o);
18061922 // exe.linkSystemLibrary2("a", .{});
18071923 // exe.addLibraryPath(dso.getEmittedBinDirectory());
......@@ -1818,7 +1934,7 @@ fn testLinkOrder(b: *Build, opts: Options) *Step {
18181934 // }
18191935
18201936 {
1821 const exe = addExecutable(b, "main2", opts);
1937 const exe = addExecutable(b, opts, .{ .name = "main2" });
18221938 exe.addObject(main_o);
18231939 exe.linkSystemLibrary2("b", .{});
18241940 exe.addLibraryPath(lib.getEmittedBinDirectory());
......@@ -1840,14 +1956,14 @@ fn testLinkOrder(b: *Build, opts: Options) *Step {
18401956fn testLdScript(b: *Build, opts: Options) *Step {
18411957 const test_step = addTestStep(b, "ld-script", opts);
18421958
1843 const dso = addSharedLibrary(b, "bar", opts);
1959 const dso = addSharedLibrary(b, opts, .{ .name = "bar" });
18441960 addCSourceBytes(dso, "int foo() { return 42; }", &.{});
18451961
18461962 const scripts = WriteFile.create(b);
18471963 _ = scripts.add("liba.so", "INPUT(libfoo.so)");
18481964 _ = scripts.add("libfoo.so", "GROUP(AS_NEEDED(-lbar))");
18491965
1850 const exe = addExecutable(b, "main", opts);
1966 const exe = addExecutable(b, opts, .{ .name = "main" });
18511967 addCSourceBytes(exe,
18521968 \\int foo();
18531969 \\int main() {
......@@ -1875,7 +1991,7 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step {
18751991 const scripts = WriteFile.create(b);
18761992 _ = scripts.add("liba.so", "INPUT(libfoo.so)");
18771993
1878 const exe = addExecutable(b, "main", opts);
1994 const exe = addExecutable(b, opts, .{ .name = "main" });
18791995 addCSourceBytes(exe, "int main() { return 0; }", &.{});
18801996 exe.linkSystemLibrary2("a", .{});
18811997 exe.addLibraryPath(scripts.getDirectory());
......@@ -1895,13 +2011,15 @@ fn testLdScriptPathError(b: *Build, opts: Options) *Step {
18952011fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step {
18962012 const test_step = addTestStep(b, "mismatched-cpu-architecture-error", opts);
18972013
1898 const obj = addObject(b, "a", .{
1899 .target = .{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .gnu },
2014 const obj = addObject(b, .{
2015 .target = b.resolveTargetQuery(.{ .cpu_arch = .aarch64, .os_tag = .linux, .abi = .gnu }),
2016 }, .{
2017 .name = "a",
2018 .c_source_bytes = "int foo;",
2019 .strip = true,
19002020 });
1901 addCSourceBytes(obj, "int foo;", &.{});
1902 obj.strip = true;
19032021
1904 const exe = addExecutable(b, "main", opts);
2022 const exe = addExecutable(b, opts, .{ .name = "main" });
19052023 addCSourceBytes(exe,
19062024 \\extern int foo;
19072025 \\int main() {
......@@ -1922,7 +2040,7 @@ fn testMismatchedCpuArchitectureError(b: *Build, opts: Options) *Step {
19222040fn testLinkingC(b: *Build, opts: Options) *Step {
19232041 const test_step = addTestStep(b, "linking-c", opts);
19242042
1925 const exe = addExecutable(b, "test", opts);
2043 const exe = addExecutable(b, opts, .{ .name = "test" });
19262044 addCSourceBytes(exe,
19272045 \\#include <stdio.h>
19282046 \\int main() {
......@@ -1951,7 +2069,7 @@ fn testLinkingC(b: *Build, opts: Options) *Step {
19512069fn testLinkingCpp(b: *Build, opts: Options) *Step {
19522070 const test_step = addTestStep(b, "linking-cpp", opts);
19532071
1954 const exe = addExecutable(b, "test", opts);
2072 const exe = addExecutable(b, opts, .{ .name = "test" });
19552073 addCppSourceBytes(exe,
19562074 \\#include <iostream>
19572075 \\int main() {
......@@ -1981,24 +2099,28 @@ fn testLinkingCpp(b: *Build, opts: Options) *Step {
19812099fn testLinkingObj(b: *Build, opts: Options) *Step {
19822100 const test_step = addTestStep(b, "linking-obj", opts);
19832101
1984 const obj = addObject(b, "aobj", opts);
1985 addZigSourceBytes(obj,
2102 const obj = addObject(b, opts, .{
2103 .name = "aobj",
2104 .zig_source_bytes =
19862105 \\extern var mod: usize;
19872106 \\export fn callMe() usize {
19882107 \\ return me * mod;
19892108 \\}
19902109 \\var me: usize = 42;
1991 );
2110 ,
2111 });
19922112
1993 const exe = addExecutable(b, "testobj", opts);
1994 addZigSourceBytes(exe,
2113 const exe = addExecutable(b, opts, .{
2114 .name = "testobj",
2115 .zig_source_bytes =
19952116 \\const std = @import("std");
19962117 \\extern fn callMe() usize;
19972118 \\export var mod: usize = 2;
19982119 \\pub fn main() void {
19992120 \\ std.debug.print("{d}\n", .{callMe()});
20002121 \\}
2001 );
2122 ,
2123 });
20022124 exe.addObject(obj);
20032125
20042126 const run = addRunArtifact(exe);
......@@ -2011,26 +2133,32 @@ fn testLinkingObj(b: *Build, opts: Options) *Step {
20112133fn testLinkingStaticLib(b: *Build, opts: Options) *Step {
20122134 const test_step = addTestStep(b, "linking-static-lib", opts);
20132135
2014 const obj = addObject(b, "bobj", opts);
2015 addZigSourceBytes(obj, "export var bar: i32 = -42;");
2136 const obj = addObject(b, opts, .{
2137 .name = "bobj",
2138 .zig_source_bytes = "export var bar: i32 = -42;",
2139 });
20162140
2017 const lib = addStaticLibrary(b, "alib", opts);
2018 addZigSourceBytes(lib,
2141 const lib = addStaticLibrary(b, opts, .{
2142 .name = "alib",
2143 .zig_source_bytes =
20192144 \\export fn foo() i32 {
20202145 \\ return 42;
20212146 \\}
2022 );
2147 ,
2148 });
20232149 lib.addObject(obj);
20242150
2025 const exe = addExecutable(b, "testlib", opts);
2026 addZigSourceBytes(exe,
2151 const exe = addExecutable(b, opts, .{
2152 .name = "testlib",
2153 .zig_source_bytes =
20272154 \\const std = @import("std");
20282155 \\extern fn foo() i32;
20292156 \\extern var bar: i32;
20302157 \\pub fn main() void {
20312158 \\ std.debug.print("{d}\n", .{foo() + bar});
20322159 \\}
2033 );
2160 ,
2161 });
20342162 exe.linkLibrary(lib);
20352163
20362164 const run = addRunArtifact(exe);
......@@ -2043,12 +2171,14 @@ fn testLinkingStaticLib(b: *Build, opts: Options) *Step {
20432171fn testLinkingZig(b: *Build, opts: Options) *Step {
20442172 const test_step = addTestStep(b, "linking-zig-static", opts);
20452173
2046 const exe = addExecutable(b, "test", opts);
2047 addZigSourceBytes(exe,
2174 const exe = addExecutable(b, opts, .{
2175 .name = "test",
2176 .zig_source_bytes =
20482177 \\pub fn main() void {
20492178 \\ @import("std").debug.print("Hello World!\n", .{});
20502179 \\}
2051 );
2180 ,
2181 });
20522182
20532183 const run = addRunArtifact(exe);
20542184 run.expectStdErrEqual("Hello World!\n");
......@@ -2069,7 +2199,7 @@ fn testLinkingZig(b: *Build, opts: Options) *Step {
20692199fn testNoEhFrameHdr(b: *Build, opts: Options) *Step {
20702200 const test_step = addTestStep(b, "no-eh-frame-hdr", opts);
20712201
2072 const exe = addExecutable(b, "main", opts);
2202 const exe = addExecutable(b, opts, .{ .name = "main" });
20732203 addCSourceBytes(exe, "int main() { return 0; }", &.{});
20742204 exe.link_eh_frame_hdr = false;
20752205 exe.linkLibC();
......@@ -2086,7 +2216,7 @@ fn testNoEhFrameHdr(b: *Build, opts: Options) *Step {
20862216fn testPie(b: *Build, opts: Options) *Step {
20872217 const test_step = addTestStep(b, "hello-pie", opts);
20882218
2089 const exe = addExecutable(b, "main", opts);
2219 const exe = addExecutable(b, opts, .{ .name = "main" });
20902220 addCSourceBytes(exe,
20912221 \\#include <stdio.h>
20922222 \\int main() {
......@@ -2095,7 +2225,7 @@ fn testPie(b: *Build, opts: Options) *Step {
20952225 \\}
20962226 , &.{});
20972227 exe.linkLibC();
2098 exe.force_pic = true;
2228 exe.root_module.pic = true;
20992229 exe.pie = true;
21002230
21012231 const run = addRunArtifact(exe);
......@@ -2117,7 +2247,7 @@ fn testPie(b: *Build, opts: Options) *Step {
21172247fn testPltGot(b: *Build, opts: Options) *Step {
21182248 const test_step = addTestStep(b, "plt-got", opts);
21192249
2120 const dso = addSharedLibrary(b, "a", opts);
2250 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
21212251 addCSourceBytes(dso,
21222252 \\#include <stdio.h>
21232253 \\void ignore(void *foo) {}
......@@ -2127,7 +2257,7 @@ fn testPltGot(b: *Build, opts: Options) *Step {
21272257 , &.{});
21282258 dso.linkLibC();
21292259
2130 const exe = addExecutable(b, "main", opts);
2260 const exe = addExecutable(b, opts, .{ .name = "main" });
21312261 addCSourceBytes(exe,
21322262 \\void ignore(void *);
21332263 \\int hello();
......@@ -2135,7 +2265,7 @@ fn testPltGot(b: *Build, opts: Options) *Step {
21352265 \\int main() { hello(); }
21362266 , &.{});
21372267 exe.linkLibrary(dso);
2138 exe.force_pic = true;
2268 exe.root_module.pic = true;
21392269 exe.linkLibC();
21402270 // https://github.com/ziglang/zig/issues/17619
21412271 exe.pie = true;
......@@ -2151,10 +2281,12 @@ fn testPreinitArray(b: *Build, opts: Options) *Step {
21512281 const test_step = addTestStep(b, "preinit-array", opts);
21522282
21532283 {
2154 const obj = addObject(b, "obj", opts);
2155 addCSourceBytes(obj, "void _start() {}", &.{});
2284 const obj = addObject(b, opts, .{
2285 .name = "obj",
2286 .c_source_bytes = "void _start() {}",
2287 });
21562288
2157 const exe = addExecutable(b, "main1", opts);
2289 const exe = addExecutable(b, opts, .{ .name = "main1" });
21582290 exe.addObject(obj);
21592291
21602292 const check = exe.checkObject();
......@@ -2163,7 +2295,7 @@ fn testPreinitArray(b: *Build, opts: Options) *Step {
21632295 }
21642296
21652297 {
2166 const exe = addExecutable(b, "main2", opts);
2298 const exe = addExecutable(b, opts, .{ .name = "main2" });
21672299 addCSourceBytes(exe,
21682300 \\void preinit_fn() {}
21692301 \\int main() {}
......@@ -2183,38 +2315,48 @@ fn testPreinitArray(b: *Build, opts: Options) *Step {
21832315fn testRelocatableArchive(b: *Build, opts: Options) *Step {
21842316 const test_step = addTestStep(b, "relocatable-archive", opts);
21852317
2186 const obj1 = addObject(b, "obj1", opts);
2187 addCSourceBytes(obj1,
2318 const obj1 = addObject(b, opts, .{
2319 .name = "obj1",
2320 .c_source_bytes =
21882321 \\void bar();
21892322 \\void foo() {
21902323 \\ bar();
21912324 \\}
2192 , &.{});
2325 ,
2326 });
21932327
2194 const obj2 = addObject(b, "obj2", opts);
2195 addCSourceBytes(obj2,
2328 const obj2 = addObject(b, opts, .{
2329 .name = "obj2",
2330 .c_source_bytes =
21962331 \\void bar() {}
2197 , &.{});
2332 ,
2333 });
21982334
2199 const obj3 = addObject(b, "obj3", opts);
2200 addCSourceBytes(obj3,
2335 const obj3 = addObject(b, opts, .{
2336 .name = "obj3",
2337 .c_source_bytes =
22012338 \\void baz();
2202 , &.{});
2339 ,
2340 });
22032341
2204 const obj4 = addObject(b, "obj4", opts);
2205 addCSourceBytes(obj4,
2342 const obj4 = addObject(b, opts, .{
2343 .name = "obj4",
2344 .c_source_bytes =
22062345 \\void foo();
22072346 \\int main() {
22082347 \\ foo();
22092348 \\}
2210 , &.{});
2349 ,
2350 });
22112351
2212 const lib = addStaticLibrary(b, "lib", opts);
2352 const lib = addStaticLibrary(b, opts, .{ .name = "lib" });
22132353 lib.addObject(obj1);
22142354 lib.addObject(obj2);
22152355 lib.addObject(obj3);
22162356
2217 const obj5 = addObject(b, "obj5", opts);
2357 const obj5 = addObject(b, opts, .{
2358 .name = "obj5",
2359 });
22182360 obj5.addObject(obj4);
22192361 obj5.linkLibrary(lib);
22202362
......@@ -2234,13 +2376,15 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {
22342376 const test_step = addTestStep(b, "relocatable-eh-frame", opts);
22352377
22362378 {
2237 const obj = addObject(b, "obj1", opts);
2238 addCppSourceBytes(obj,
2379 const obj = addObject(b, opts, .{
2380 .name = "obj1",
2381 .cpp_source_bytes =
22392382 \\#include <stdexcept>
22402383 \\int try_me() {
22412384 \\ throw std::runtime_error("Oh no!");
22422385 \\}
2243 , &.{});
2386 ,
2387 });
22442388 addCppSourceBytes(obj,
22452389 \\extern int try_me();
22462390 \\int try_again() {
......@@ -2249,7 +2393,7 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {
22492393 , &.{});
22502394 obj.linkLibCpp();
22512395
2252 const exe = addExecutable(b, "test1", opts);
2396 const exe = addExecutable(b, opts, .{ .name = "test1" });
22532397 addCppSourceBytes(exe,
22542398 \\#include <iostream>
22552399 \\#include <stdexcept>
......@@ -2273,13 +2417,15 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {
22732417
22742418 {
22752419 // Let's make the object file COMDAT group heavy!
2276 const obj = addObject(b, "obj2", opts);
2277 addCppSourceBytes(obj,
2420 const obj = addObject(b, opts, .{
2421 .name = "obj2",
2422 .cpp_source_bytes =
22782423 \\#include <stdexcept>
22792424 \\int try_me() {
22802425 \\ throw std::runtime_error("Oh no!");
22812426 \\}
2282 , &.{});
2427 ,
2428 });
22832429 addCppSourceBytes(obj,
22842430 \\extern int try_me();
22852431 \\int try_again() {
......@@ -2301,7 +2447,7 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {
23012447 , &.{});
23022448 obj.linkLibCpp();
23032449
2304 const exe = addExecutable(b, "test2", opts);
2450 const exe = addExecutable(b, opts, .{ .name = "test2" });
23052451 exe.addObject(obj);
23062452 exe.linkLibCpp();
23072453
......@@ -2316,13 +2462,18 @@ fn testRelocatableEhFrame(b: *Build, opts: Options) *Step {
23162462fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step {
23172463 const test_step = addTestStep(b, "relocatable-no-eh-frame", opts);
23182464
2319 const obj1 = addObject(b, "obj1", opts);
2320 addCSourceBytes(obj1, "int bar() { return 42; }", &.{
2321 "-fno-unwind-tables",
2322 "-fno-asynchronous-unwind-tables",
2465 const obj1 = addObject(b, opts, .{
2466 .name = "obj1",
2467 .c_source_bytes = "int bar() { return 42; }",
2468 .c_source_flags = &.{
2469 "-fno-unwind-tables",
2470 "-fno-asynchronous-unwind-tables",
2471 },
23232472 });
23242473
2325 const obj2 = addObject(b, "obj2", opts);
2474 const obj2 = addObject(b, opts, .{
2475 .name = "obj2",
2476 });
23262477 obj2.addObject(obj1);
23272478
23282479 const check1 = obj1.checkObject();
......@@ -2343,23 +2494,25 @@ fn testRelocatableNoEhFrame(b: *Build, opts: Options) *Step {
23432494fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {
23442495 const test_step = addTestStep(b, "shared-abs-symbol", opts);
23452496
2346 const dso = addSharedLibrary(b, "a", opts);
2497 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
23472498 addAsmSourceBytes(dso,
23482499 \\.globl foo
23492500 \\foo = 3;
23502501 );
23512502
2352 const obj = addObject(b, "obj", opts);
2353 addCSourceBytes(obj,
2503 const obj = addObject(b, opts, .{
2504 .name = "obj",
2505 .c_source_bytes =
23542506 \\#include <stdio.h>
23552507 \\extern char foo;
23562508 \\int main() { printf("foo=%p\n", &foo); }
2357 , &.{});
2358 obj.force_pic = true;
2509 ,
2510 .pic = true,
2511 });
23592512 obj.linkLibC();
23602513
23612514 {
2362 const exe = addExecutable(b, "main1", opts);
2515 const exe = addExecutable(b, opts, .{ .name = "main1" });
23632516 exe.addObject(obj);
23642517 exe.linkLibrary(dso);
23652518 exe.pie = true;
......@@ -2380,7 +2533,7 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {
23802533
23812534 // https://github.com/ziglang/zig/issues/17430
23822535 // {
2383 // const exe = addExecutable(b, "main2", opts);
2536 // const exe = addExecutable(b, opts, .{ .name = "main2"});
23842537 // exe.addObject(obj);
23852538 // exe.linkLibrary(dso);
23862539 // exe.pie = false;
......@@ -2405,20 +2558,22 @@ fn testSharedAbsSymbol(b: *Build, opts: Options) *Step {
24052558fn testStrip(b: *Build, opts: Options) *Step {
24062559 const test_step = addTestStep(b, "strip", opts);
24072560
2408 const obj = addObject(b, "obj", opts);
2409 addCSourceBytes(obj,
2561 const obj = addObject(b, opts, .{
2562 .name = "obj",
2563 .c_source_bytes =
24102564 \\#include <stdio.h>
24112565 \\int main() {
24122566 \\ printf("Hello!\n");
24132567 \\ return 0;
24142568 \\}
2415 , &.{});
2569 ,
2570 });
24162571 obj.linkLibC();
24172572
24182573 {
2419 const exe = addExecutable(b, "main1", opts);
2574 const exe = addExecutable(b, opts, .{ .name = "main1" });
24202575 exe.addObject(obj);
2421 exe.strip = false;
2576 exe.root_module.strip = false;
24222577 exe.linkLibC();
24232578
24242579 const check = exe.checkObject();
......@@ -2429,9 +2584,9 @@ fn testStrip(b: *Build, opts: Options) *Step {
24292584 }
24302585
24312586 {
2432 const exe = addExecutable(b, "main2", opts);
2587 const exe = addExecutable(b, opts, .{ .name = "main2" });
24332588 exe.addObject(obj);
2434 exe.strip = true;
2589 exe.root_module.strip = true;
24352590 exe.linkLibC();
24362591
24372592 const check = exe.checkObject();
......@@ -2447,16 +2602,19 @@ fn testStrip(b: *Build, opts: Options) *Step {
24472602fn testTlsDfStaticTls(b: *Build, opts: Options) *Step {
24482603 const test_step = addTestStep(b, "tls-df-static-tls", opts);
24492604
2450 const obj = addObject(b, "obj", opts);
2451 addCSourceBytes(obj,
2605 const obj = addObject(b, opts, .{
2606 .name = "obj",
2607 .c_source_bytes =
24522608 \\static _Thread_local int foo = 5;
24532609 \\void mutate() { ++foo; }
24542610 \\int bar() { return foo; }
2455 , &.{"-ftls-model=initial-exec"});
2456 obj.force_pic = true;
2611 ,
2612 .c_source_flags = &.{"-ftls-model=initial-exec"},
2613 .pic = true,
2614 });
24572615
24582616 {
2459 const dso = addSharedLibrary(b, "a", opts);
2617 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
24602618 dso.addObject(obj);
24612619 // dso.link_relax = true;
24622620
......@@ -2468,7 +2626,7 @@ fn testTlsDfStaticTls(b: *Build, opts: Options) *Step {
24682626
24692627 // TODO add -Wl,--no-relax
24702628 // {
2471 // const dso = addSharedLibrary(b, "a", opts);
2629 // const dso = addSharedLibrary(b, opts, .{ .name = "a"});
24722630 // dso.addObject(obj);
24732631 // dso.link_relax = false;
24742632
......@@ -2484,7 +2642,7 @@ fn testTlsDfStaticTls(b: *Build, opts: Options) *Step {
24842642fn testTlsDso(b: *Build, opts: Options) *Step {
24852643 const test_step = addTestStep(b, "tls-dso", opts);
24862644
2487 const dso = addSharedLibrary(b, "a", opts);
2645 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
24882646 addCSourceBytes(dso,
24892647 \\extern _Thread_local int foo;
24902648 \\_Thread_local int bar;
......@@ -2492,7 +2650,7 @@ fn testTlsDso(b: *Build, opts: Options) *Step {
24922650 \\int get_bar1() { return bar; }
24932651 , &.{});
24942652
2495 const exe = addExecutable(b, "main", opts);
2653 const exe = addExecutable(b, opts, .{ .name = "main" });
24962654 addCSourceBytes(exe,
24972655 \\#include <stdio.h>
24982656 \\_Thread_local int foo;
......@@ -2526,8 +2684,9 @@ fn testTlsDso(b: *Build, opts: Options) *Step {
25262684fn testTlsGd(b: *Build, opts: Options) *Step {
25272685 const test_step = addTestStep(b, "tls-gd", opts);
25282686
2529 const main_o = addObject(b, "main", opts);
2530 addCSourceBytes(main_o,
2687 const main_o = addObject(b, opts, .{
2688 .name = "main",
2689 .c_source_bytes =
25312690 \\#include <stdio.h>
25322691 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1;
25332692 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x2;
......@@ -2540,37 +2699,42 @@ fn testTlsGd(b: *Build, opts: Options) *Step {
25402699 \\ printf("%d %d %d %d %d %d\n", x1, x2, x3, x4, get_x5(), get_x6());
25412700 \\ return 0;
25422701 \\}
2543 , &.{});
2702 ,
2703 .pic = true,
2704 });
25442705 main_o.linkLibC();
2545 main_o.force_pic = true;
25462706
2547 const a_o = addObject(b, "a", opts);
2548 addCSourceBytes(a_o,
2707 const a_o = addObject(b, opts, .{
2708 .name = "a",
2709 .c_source_bytes =
25492710 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x3 = 3;
25502711 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x5 = 5;
25512712 \\int get_x5() { return x5; }
2552 , &.{});
2553 a_o.force_pic = true;
2713 ,
2714 .pic = true,
2715 });
25542716
2555 const b_o = addObject(b, "b", opts);
2556 addCSourceBytes(b_o,
2717 const b_o = addObject(b, opts, .{
2718 .name = "b",
2719 .c_source_bytes =
25572720 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x4 = 4;
25582721 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x6 = 6;
25592722 \\int get_x6() { return x6; }
2560 , &.{});
2561 b_o.force_pic = true;
2723 ,
2724 .pic = true,
2725 });
25622726
25632727 const exp_stdout = "1 2 3 4 5 6\n";
25642728
2565 const dso1 = addSharedLibrary(b, "a", opts);
2729 const dso1 = addSharedLibrary(b, opts, .{ .name = "a" });
25662730 dso1.addObject(a_o);
25672731
2568 const dso2 = addSharedLibrary(b, "b", opts);
2732 const dso2 = addSharedLibrary(b, opts, .{ .name = "b" });
25692733 dso2.addObject(b_o);
25702734 // dso2.link_relax = false; // TODO
25712735
25722736 {
2573 const exe = addExecutable(b, "main1", opts);
2737 const exe = addExecutable(b, opts, .{ .name = "main1" });
25742738 exe.addObject(main_o);
25752739 exe.linkLibrary(dso1);
25762740 exe.linkLibrary(dso2);
......@@ -2581,7 +2745,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step {
25812745 }
25822746
25832747 {
2584 const exe = addExecutable(b, "main2", opts);
2748 const exe = addExecutable(b, opts, .{ .name = "main2" });
25852749 exe.addObject(main_o);
25862750 // exe.link_relax = false; // TODO
25872751 exe.linkLibrary(dso1);
......@@ -2594,7 +2758,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step {
25942758
25952759 // https://github.com/ziglang/zig/issues/17430 ??
25962760 // {
2597 // const exe = addExecutable(b, "main3", opts);
2761 // const exe = addExecutable(b, opts, .{ .name = "main3"});
25982762 // exe.addObject(main_o);
25992763 // exe.linkLibrary(dso1);
26002764 // exe.linkLibrary(dso2);
......@@ -2606,7 +2770,7 @@ fn testTlsGd(b: *Build, opts: Options) *Step {
26062770 // }
26072771
26082772 // {
2609 // const exe = addExecutable(b, "main4", opts);
2773 // const exe = addExecutable(b, opts, .{ .name = "main4"});
26102774 // exe.addObject(main_o);
26112775 // // exe.link_relax = false; // TODO
26122776 // exe.linkLibrary(dso1);
......@@ -2624,8 +2788,9 @@ fn testTlsGd(b: *Build, opts: Options) *Step {
26242788fn testTlsGdNoPlt(b: *Build, opts: Options) *Step {
26252789 const test_step = addTestStep(b, "tls-gd-no-plt", opts);
26262790
2627 const obj = addObject(b, "obj", opts);
2628 addCSourceBytes(obj,
2791 const obj = addObject(b, opts, .{
2792 .name = "obj",
2793 .c_source_bytes =
26292794 \\#include <stdio.h>
26302795 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1;
26312796 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x2;
......@@ -2639,18 +2804,20 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step {
26392804 \\ printf("%d %d %d %d %d %d\n", x1, x2, x3, x4, get_x5(), get_x6());
26402805 \\ return 0;
26412806 \\}
2642 , &.{"-fno-plt"});
2643 obj.force_pic = true;
2807 ,
2808 .c_source_flags = &.{"-fno-plt"},
2809 .pic = true,
2810 });
26442811 obj.linkLibC();
26452812
2646 const a_so = addSharedLibrary(b, "a", opts);
2813 const a_so = addSharedLibrary(b, opts, .{ .name = "a" });
26472814 addCSourceBytes(a_so,
26482815 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x3 = 3;
26492816 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x5 = 5;
26502817 \\int get_x5() { return x5; }
26512818 , &.{"-fno-plt"});
26522819
2653 const b_so = addSharedLibrary(b, "b", opts);
2820 const b_so = addSharedLibrary(b, opts, .{ .name = "b" });
26542821 addCSourceBytes(b_so,
26552822 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x4 = 4;
26562823 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x6 = 6;
......@@ -2659,7 +2826,7 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step {
26592826 // b_so.link_relax = false; // TODO
26602827
26612828 {
2662 const exe = addExecutable(b, "main1", opts);
2829 const exe = addExecutable(b, opts, .{ .name = "main1" });
26632830 exe.addObject(obj);
26642831 exe.linkLibrary(a_so);
26652832 exe.linkLibrary(b_so);
......@@ -2673,7 +2840,7 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step {
26732840 }
26742841
26752842 {
2676 const exe = addExecutable(b, "main2", opts);
2843 const exe = addExecutable(b, opts, .{ .name = "main2" });
26772844 exe.addObject(obj);
26782845 exe.linkLibrary(a_so);
26792846 exe.linkLibrary(b_so);
......@@ -2693,8 +2860,9 @@ fn testTlsGdNoPlt(b: *Build, opts: Options) *Step {
26932860fn testTlsGdToIe(b: *Build, opts: Options) *Step {
26942861 const test_step = addTestStep(b, "tls-gd-to-ie", opts);
26952862
2696 const a_o = addObject(b, "a", opts);
2697 addCSourceBytes(a_o,
2863 const a_o = addObject(b, opts, .{
2864 .name = "a",
2865 .c_source_bytes =
26982866 \\#include <stdio.h>
26992867 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int x1 = 1;
27002868 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int x2 = 2;
......@@ -2705,22 +2873,25 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step {
27052873 \\ printf("%d %d %d\n", x1, x2, x3);
27062874 \\ return 0;
27072875 \\}
2708 , &.{});
2876 ,
2877 .pic = true,
2878 });
27092879 a_o.linkLibC();
2710 a_o.force_pic = true;
27112880
2712 const b_o = addObject(b, "b", opts);
2713 addCSourceBytes(b_o,
2881 const b_o = addObject(b, opts, .{
2882 .name = "b",
2883 .c_source_bytes =
27142884 \\int foo();
27152885 \\int main() { foo(); }
2716 , &.{});
2717 b_o.force_pic = true;
2886 ,
2887 .pic = true,
2888 });
27182889
27192890 {
2720 const dso = addSharedLibrary(b, "a1", opts);
2891 const dso = addSharedLibrary(b, opts, .{ .name = "a1" });
27212892 dso.addObject(a_o);
27222893
2723 const exe = addExecutable(b, "main1", opts);
2894 const exe = addExecutable(b, opts, .{ .name = "main1" });
27242895 exe.addObject(b_o);
27252896 exe.linkLibrary(dso);
27262897 exe.linkLibC();
......@@ -2733,11 +2904,11 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step {
27332904 }
27342905
27352906 {
2736 const dso = addSharedLibrary(b, "a2", opts);
2907 const dso = addSharedLibrary(b, opts, .{ .name = "a2" });
27372908 dso.addObject(a_o);
27382909 // dso.link_relax = false; // TODO
27392910
2740 const exe = addExecutable(b, "main2", opts);
2911 const exe = addExecutable(b, opts, .{ .name = "main2" });
27412912 exe.addObject(b_o);
27422913 exe.linkLibrary(dso);
27432914 exe.linkLibC();
......@@ -2750,11 +2921,11 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step {
27502921 }
27512922
27522923 // {
2753 // const dso = addSharedLibrary(b, "a", opts);
2924 // const dso = addSharedLibrary(b, opts, .{ .name = "a"});
27542925 // dso.addObject(a_o);
27552926 // dso.link_z_nodlopen = true;
27562927
2757 // const exe = addExecutable(b, "main", opts);
2928 // const exe = addExecutable(b, opts, .{ .name = "main"});
27582929 // exe.addObject(b_o);
27592930 // exe.linkLibrary(dso);
27602931
......@@ -2764,12 +2935,12 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step {
27642935 // }
27652936
27662937 // {
2767 // const dso = addSharedLibrary(b, "a", opts);
2938 // const dso = addSharedLibrary(b, opts, .{ .name = "a"});
27682939 // dso.addObject(a_o);
27692940 // dso.link_relax = false;
27702941 // dso.link_z_nodlopen = true;
27712942
2772 // const exe = addExecutable(b, "main", opts);
2943 // const exe = addExecutable(b, opts, .{ .name = "main"});
27732944 // exe.addObject(b_o);
27742945 // exe.linkLibrary(dso);
27752946
......@@ -2784,7 +2955,7 @@ fn testTlsGdToIe(b: *Build, opts: Options) *Step {
27842955fn testTlsIe(b: *Build, opts: Options) *Step {
27852956 const test_step = addTestStep(b, "tls-ie", opts);
27862957
2787 const dso = addSharedLibrary(b, "a", opts);
2958 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
27882959 addCSourceBytes(dso,
27892960 \\#include <stdio.h>
27902961 \\__attribute__((tls_model("initial-exec"))) static _Thread_local int foo;
......@@ -2799,8 +2970,9 @@ fn testTlsIe(b: *Build, opts: Options) *Step {
27992970 , &.{});
28002971 dso.linkLibC();
28012972
2802 const main_o = addObject(b, "main", opts);
2803 addCSourceBytes(main_o,
2973 const main_o = addObject(b, opts, .{
2974 .name = "main",
2975 .c_source_bytes =
28042976 \\#include <stdio.h>
28052977 \\_Thread_local int baz;
28062978 \\void set();
......@@ -2812,13 +2984,14 @@ fn testTlsIe(b: *Build, opts: Options) *Step {
28122984 \\ print();
28132985 \\ printf("%d\n", baz);
28142986 \\}
2815 , &.{});
2987 ,
2988 });
28162989 main_o.linkLibC();
28172990
28182991 const exp_stdout = "0 0 3 5 7\n";
28192992
28202993 {
2821 const exe = addExecutable(b, "main1", opts);
2994 const exe = addExecutable(b, opts, .{ .name = "main1" });
28222995 exe.addObject(main_o);
28232996 exe.linkLibrary(dso);
28242997 exe.linkLibC();
......@@ -2831,7 +3004,7 @@ fn testTlsIe(b: *Build, opts: Options) *Step {
28313004 }
28323005
28333006 {
2834 const exe = addExecutable(b, "main2", opts);
3007 const exe = addExecutable(b, opts, .{ .name = "main2" });
28353008 exe.addObject(main_o);
28363009 exe.linkLibrary(dso);
28373010 exe.linkLibC();
......@@ -2850,38 +3023,46 @@ fn testTlsIe(b: *Build, opts: Options) *Step {
28503023fn testTlsLargeAlignment(b: *Build, opts: Options) *Step {
28513024 const test_step = addTestStep(b, "tls-large-alignment", opts);
28523025
2853 const a_o = addObject(b, "a", opts);
2854 addCSourceBytes(a_o,
3026 const a_o = addObject(b, opts, .{
3027 .name = "a",
3028 .c_source_bytes =
28553029 \\__attribute__((section(".tdata1")))
28563030 \\_Thread_local int x = 42;
2857 , &.{"-std=c11"});
2858 a_o.force_pic = true;
3031 ,
3032 .c_source_flags = &.{"-std=c11"},
3033 .pic = true,
3034 });
28593035
2860 const b_o = addObject(b, "b", opts);
2861 addCSourceBytes(b_o,
3036 const b_o = addObject(b, opts, .{
3037 .name = "b",
3038 .c_source_bytes =
28623039 \\__attribute__((section(".tdata2")))
28633040 \\_Alignas(256) _Thread_local int y[] = { 1, 2, 3 };
2864 , &.{"-std=c11"});
2865 b_o.force_pic = true;
3041 ,
3042 .c_source_flags = &.{"-std=c11"},
3043 .pic = true,
3044 });
28663045
2867 const c_o = addObject(b, "c", opts);
2868 addCSourceBytes(c_o,
3046 const c_o = addObject(b, opts, .{
3047 .name = "c",
3048 .c_source_bytes =
28693049 \\#include <stdio.h>
28703050 \\extern _Thread_local int x;
28713051 \\extern _Thread_local int y[];
28723052 \\int main() {
28733053 \\ printf("%d %d %d %d\n", x, y[0], y[1], y[2]);
28743054 \\}
2875 , &.{});
2876 c_o.force_pic = true;
3055 ,
3056 .pic = true,
3057 });
28773058 c_o.linkLibC();
28783059
28793060 {
2880 const dso = addSharedLibrary(b, "a", opts);
3061 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
28813062 dso.addObject(a_o);
28823063 dso.addObject(b_o);
28833064
2884 const exe = addExecutable(b, "main", opts);
3065 const exe = addExecutable(b, opts, .{ .name = "main" });
28853066 exe.addObject(c_o);
28863067 exe.linkLibrary(dso);
28873068 exe.linkLibC();
......@@ -2894,7 +3075,7 @@ fn testTlsLargeAlignment(b: *Build, opts: Options) *Step {
28943075 }
28953076
28963077 {
2897 const exe = addExecutable(b, "main", opts);
3078 const exe = addExecutable(b, opts, .{ .name = "main" });
28983079 exe.addObject(a_o);
28993080 exe.addObject(b_o);
29003081 exe.addObject(c_o);
......@@ -2913,7 +3094,7 @@ fn testTlsLargeAlignment(b: *Build, opts: Options) *Step {
29133094fn testTlsLargeTbss(b: *Build, opts: Options) *Step {
29143095 const test_step = addTestStep(b, "tls-large-tbss", opts);
29153096
2916 const exe = addExecutable(b, "main", opts);
3097 const exe = addExecutable(b, opts, .{ .name = "main" });
29173098 addAsmSourceBytes(exe,
29183099 \\.globl x, y
29193100 \\.section .tbss,"awT",@nobits
......@@ -2947,7 +3128,7 @@ fn testTlsLargeTbss(b: *Build, opts: Options) *Step {
29473128fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step {
29483129 const test_step = addTestStep(b, "tls-large-static-image", opts);
29493130
2950 const exe = addExecutable(b, "main", opts);
3131 const exe = addExecutable(b, opts, .{ .name = "main" });
29513132 addCSourceBytes(exe, "_Thread_local int x[] = { 1, 2, 3, [10000] = 5 };", &.{});
29523133 addCSourceBytes(exe,
29533134 \\#include <stdio.h>
......@@ -2956,7 +3137,7 @@ fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step {
29563137 \\ printf("%d %d %d %d %d\n", x[0], x[1], x[2], x[3], x[10000]);
29573138 \\}
29583139 , &.{});
2959 exe.force_pic = true;
3140 exe.root_module.pic = true;
29603141 exe.linkLibC();
29613142 // https://github.com/ziglang/zig/issues/17619
29623143 exe.pie = true;
......@@ -2971,8 +3152,9 @@ fn testTlsLargeStaticImage(b: *Build, opts: Options) *Step {
29713152fn testTlsLd(b: *Build, opts: Options) *Step {
29723153 const test_step = addTestStep(b, "tls-ld", opts);
29733154
2974 const main_o = addObject(b, "main", opts);
2975 addCSourceBytes(main_o,
3155 const main_o = addObject(b, opts, .{
3156 .name = "main",
3157 .c_source_bytes =
29763158 \\#include <stdio.h>
29773159 \\extern _Thread_local int foo;
29783160 \\static _Thread_local int bar;
......@@ -2983,18 +3165,23 @@ fn testTlsLd(b: *Build, opts: Options) *Step {
29833165 \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar);
29843166 \\ return 0;
29853167 \\}
2986 , &.{"-ftls-model=local-dynamic"});
2987 main_o.force_pic = true;
3168 ,
3169 .c_source_flags = &.{"-ftls-model=local-dynamic"},
3170 .pic = true,
3171 });
29883172 main_o.linkLibC();
29893173
2990 const a_o = addObject(b, "a", opts);
2991 addCSourceBytes(a_o, "_Thread_local int foo = 3;", &.{"-ftls-model=local-dynamic"});
2992 a_o.force_pic = true;
3174 const a_o = addObject(b, opts, .{
3175 .name = "a",
3176 .c_source_bytes = "_Thread_local int foo = 3;",
3177 .c_source_flags = &.{"-ftls-model=local-dynamic"},
3178 .pic = true,
3179 });
29933180
29943181 const exp_stdout = "3 5 3 5\n";
29953182
29963183 {
2997 const exe = addExecutable(b, "main1", opts);
3184 const exe = addExecutable(b, opts, .{ .name = "main1" });
29983185 exe.addObject(main_o);
29993186 exe.addObject(a_o);
30003187 exe.linkLibC();
......@@ -3007,7 +3194,7 @@ fn testTlsLd(b: *Build, opts: Options) *Step {
30073194 }
30083195
30093196 {
3010 const exe = addExecutable(b, "main2", opts);
3197 const exe = addExecutable(b, opts, .{ .name = "main2" });
30113198 exe.addObject(main_o);
30123199 exe.addObject(a_o);
30133200 exe.linkLibC();
......@@ -3026,14 +3213,14 @@ fn testTlsLd(b: *Build, opts: Options) *Step {
30263213fn testTlsLdDso(b: *Build, opts: Options) *Step {
30273214 const test_step = addTestStep(b, "tls-ld-dso", opts);
30283215
3029 const dso = addSharedLibrary(b, "a", opts);
3216 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
30303217 addCSourceBytes(dso,
30313218 \\static _Thread_local int def, def1;
30323219 \\int f0() { return ++def; }
30333220 \\int f1() { return ++def1 + def; }
30343221 , &.{"-ftls-model=local-dynamic"});
30353222
3036 const exe = addExecutable(b, "main", opts);
3223 const exe = addExecutable(b, opts, .{ .name = "main" });
30373224 addCSourceBytes(exe,
30383225 \\#include <stdio.h>
30393226 \\extern int f0();
......@@ -3060,8 +3247,9 @@ fn testTlsLdDso(b: *Build, opts: Options) *Step {
30603247fn testTlsLdNoPlt(b: *Build, opts: Options) *Step {
30613248 const test_step = addTestStep(b, "tls-ld-no-plt", opts);
30623249
3063 const a_o = addObject(b, "a", opts);
3064 addCSourceBytes(a_o,
3250 const a_o = addObject(b, opts, .{
3251 .name = "a",
3252 .c_source_bytes =
30653253 \\#include <stdio.h>
30663254 \\extern _Thread_local int foo;
30673255 \\static _Thread_local int bar;
......@@ -3073,16 +3261,21 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step {
30733261 \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar);
30743262 \\ return 0;
30753263 \\}
3076 , &.{ "-ftls-model=local-dynamic", "-fno-plt" });
3264 ,
3265 .c_source_flags = &.{ "-ftls-model=local-dynamic", "-fno-plt" },
3266 .pic = true,
3267 });
30773268 a_o.linkLibC();
3078 a_o.force_pic = true;
30793269
3080 const b_o = addObject(b, "b", opts);
3081 addCSourceBytes(b_o, "_Thread_local int foo = 3;", &.{ "-ftls-model=local-dynamic", "-fno-plt" });
3082 b_o.force_pic = true;
3270 const b_o = addObject(b, opts, .{
3271 .name = "b",
3272 .c_source_bytes = "_Thread_local int foo = 3;",
3273 .c_source_flags = &.{ "-ftls-model=local-dynamic", "-fno-plt" },
3274 .pic = true,
3275 });
30833276
30843277 {
3085 const exe = addExecutable(b, "main1", opts);
3278 const exe = addExecutable(b, opts, .{ .name = "main1" });
30863279 exe.addObject(a_o);
30873280 exe.addObject(b_o);
30883281 exe.linkLibC();
......@@ -3095,7 +3288,7 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step {
30953288 }
30963289
30973290 {
3098 const exe = addExecutable(b, "main2", opts);
3291 const exe = addExecutable(b, opts, .{ .name = "main2" });
30993292 exe.addObject(a_o);
31003293 exe.addObject(b_o);
31013294 exe.linkLibC();
......@@ -3114,7 +3307,7 @@ fn testTlsLdNoPlt(b: *Build, opts: Options) *Step {
31143307fn testTlsNoPic(b: *Build, opts: Options) *Step {
31153308 const test_step = addTestStep(b, "tls-no-pic", opts);
31163309
3117 const exe = addExecutable(b, "main", opts);
3310 const exe = addExecutable(b, opts, .{ .name = "main" });
31183311 addCSourceBytes(exe,
31193312 \\#include <stdio.h>
31203313 \\__attribute__((tls_model("global-dynamic"))) extern _Thread_local int foo;
......@@ -3132,7 +3325,7 @@ fn testTlsNoPic(b: *Build, opts: Options) *Step {
31323325 addCSourceBytes(exe,
31333326 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int foo;
31343327 , &.{});
3135 exe.force_pic = false;
3328 exe.root_module.pic = false;
31363329 exe.linkLibC();
31373330
31383331 const run = addRunArtifact(exe);
......@@ -3145,7 +3338,7 @@ fn testTlsNoPic(b: *Build, opts: Options) *Step {
31453338fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step {
31463339 const test_step = addTestStep(b, "tls-offset-alignment", opts);
31473340
3148 const dso = addSharedLibrary(b, "a", opts);
3341 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
31493342 addCSourceBytes(dso,
31503343 \\#include <assert.h>
31513344 \\#include <stdlib.h>
......@@ -3163,7 +3356,7 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step {
31633356 , &.{});
31643357 dso.linkLibC();
31653358
3166 const exe = addExecutable(b, "main", opts);
3359 const exe = addExecutable(b, opts, .{ .name = "main" });
31673360 addCSourceBytes(exe,
31683361 \\#include <pthread.h>
31693362 \\#include <dlfcn.h>
......@@ -3186,7 +3379,7 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step {
31863379 , &.{});
31873380 exe.addRPath(dso.getEmittedBinDirectory());
31883381 exe.linkLibC();
3189 exe.force_pic = true;
3382 exe.root_module.pic = true;
31903383 // https://github.com/ziglang/zig/issues/17619
31913384 exe.pie = true;
31923385
......@@ -3200,8 +3393,9 @@ fn testTlsOffsetAlignment(b: *Build, opts: Options) *Step {
32003393fn testTlsPic(b: *Build, opts: Options) *Step {
32013394 const test_step = addTestStep(b, "tls-pic", opts);
32023395
3203 const obj = addObject(b, "obj", opts);
3204 addCSourceBytes(obj,
3396 const obj = addObject(b, opts, .{
3397 .name = "obj",
3398 .c_source_bytes =
32053399 \\#include <stdio.h>
32063400 \\__attribute__((tls_model("global-dynamic"))) extern _Thread_local int foo;
32073401 \\__attribute__((tls_model("global-dynamic"))) static _Thread_local int bar;
......@@ -3213,11 +3407,12 @@ fn testTlsPic(b: *Build, opts: Options) *Step {
32133407 \\ printf("%d %d %d %d\n", *get_foo_addr(), *get_bar_addr(), foo, bar);
32143408 \\ return 0;
32153409 \\}
3216 , &.{});
3410 ,
3411 .pic = true,
3412 });
32173413 obj.linkLibC();
3218 obj.force_pic = true;
32193414
3220 const exe = addExecutable(b, "main", opts);
3415 const exe = addExecutable(b, opts, .{ .name = "main" });
32213416 addCSourceBytes(exe,
32223417 \\__attribute__((tls_model("global-dynamic"))) _Thread_local int foo = 3;
32233418 , &.{});
......@@ -3236,30 +3431,38 @@ fn testTlsPic(b: *Build, opts: Options) *Step {
32363431fn testTlsSmallAlignment(b: *Build, opts: Options) *Step {
32373432 const test_step = addTestStep(b, "tls-small-alignment", opts);
32383433
3239 const a_o = addObject(b, "a", opts);
3240 addAsmSourceBytes(a_o,
3434 const a_o = addObject(b, opts, .{
3435 .name = "a",
3436 .asm_source_bytes =
32413437 \\.text
32423438 \\.byte 0
3243 );
3244 a_o.force_pic = true;
3439 \\
3440 ,
3441 .pic = true,
3442 });
32453443
3246 const b_o = addObject(b, "b", opts);
3247 addCSourceBytes(b_o, "_Thread_local char x = 42;", &.{"-std=c11"});
3248 b_o.force_pic = true;
3444 const b_o = addObject(b, opts, .{
3445 .name = "b",
3446 .c_source_bytes = "_Thread_local char x = 42;",
3447 .c_source_flags = &.{"-std=c11"},
3448 .pic = true,
3449 });
32493450
3250 const c_o = addObject(b, "c", opts);
3251 addCSourceBytes(c_o,
3451 const c_o = addObject(b, opts, .{
3452 .name = "c",
3453 .c_source_bytes =
32523454 \\#include <stdio.h>
32533455 \\extern _Thread_local char x;
32543456 \\int main() {
32553457 \\ printf("%d\n", x);
32563458 \\}
3257 , &.{});
3459 ,
3460 .pic = true,
3461 });
32583462 c_o.linkLibC();
3259 c_o.force_pic = true;
32603463
32613464 {
3262 const exe = addExecutable(b, "main", opts);
3465 const exe = addExecutable(b, opts, .{ .name = "main" });
32633466 exe.addObject(a_o);
32643467 exe.addObject(b_o);
32653468 exe.addObject(c_o);
......@@ -3273,11 +3476,11 @@ fn testTlsSmallAlignment(b: *Build, opts: Options) *Step {
32733476 }
32743477
32753478 {
3276 const dso = addSharedLibrary(b, "a", opts);
3479 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
32773480 dso.addObject(a_o);
32783481 dso.addObject(b_o);
32793482
3280 const exe = addExecutable(b, "main", opts);
3483 const exe = addExecutable(b, opts, .{ .name = "main" });
32813484 exe.addObject(c_o);
32823485 exe.linkLibrary(dso);
32833486 exe.linkLibC();
......@@ -3295,7 +3498,7 @@ fn testTlsSmallAlignment(b: *Build, opts: Options) *Step {
32953498fn testTlsStatic(b: *Build, opts: Options) *Step {
32963499 const test_step = addTestStep(b, "tls-static", opts);
32973500
3298 const exe = addExecutable(b, "test", opts);
3501 const exe = addExecutable(b, opts, .{ .name = "test" });
32993502 addCSourceBytes(exe,
33003503 \\#include <stdio.h>
33013504 \\_Thread_local int a = 10;
......@@ -3326,12 +3529,14 @@ fn testTlsStatic(b: *Build, opts: Options) *Step {
33263529fn testUnknownFileTypeError(b: *Build, opts: Options) *Step {
33273530 const test_step = addTestStep(b, "unknown-file-type-error", opts);
33283531
3329 const dylib = addSharedLibrary(b, "a", .{
3330 .target = .{ .cpu_arch = .x86_64, .os_tag = .macos },
3532 const dylib = addSharedLibrary(b, .{
3533 .target = b.resolveTargetQuery(.{ .cpu_arch = .x86_64, .os_tag = .macos }),
3534 }, .{
3535 .name = "a",
3536 .zig_source_bytes = "export var foo: i32 = 0;",
33313537 });
3332 addZigSourceBytes(dylib, "export var foo: i32 = 0;");
33333538
3334 const exe = addExecutable(b, "main", opts);
3539 const exe = addExecutable(b, opts, .{ .name = "main" });
33353540 addCSourceBytes(exe,
33363541 \\extern int foo;
33373542 \\int main() {
......@@ -3354,28 +3559,34 @@ fn testUnknownFileTypeError(b: *Build, opts: Options) *Step {
33543559fn testUnresolvedError(b: *Build, opts: Options) *Step {
33553560 const test_step = addTestStep(b, "unresolved-error", opts);
33563561
3357 const obj1 = addObject(b, "a", opts);
3358 addCSourceBytes(obj1,
3562 const obj1 = addObject(b, opts, .{
3563 .name = "a",
3564 .c_source_bytes =
33593565 \\#include <stdio.h>
33603566 \\int foo();
33613567 \\int bar() {
33623568 \\ return foo() + 1;
33633569 \\}
3364 , &.{"-ffunction-sections"});
3570 ,
3571 .c_source_flags = &.{"-ffunction-sections"},
3572 });
33653573 obj1.linkLibC();
33663574
3367 const obj2 = addObject(b, "b", opts);
3368 addCSourceBytes(obj2,
3575 const obj2 = addObject(b, opts, .{
3576 .name = "b",
3577 .c_source_bytes =
33693578 \\#include <stdio.h>
33703579 \\int foo();
33713580 \\int bar();
33723581 \\int main() {
33733582 \\ return foo() + bar();
33743583 \\}
3375 , &.{"-ffunction-sections"});
3584 ,
3585 .c_source_flags = &.{"-ffunction-sections"},
3586 });
33763587 obj2.linkLibC();
33773588
3378 const exe = addExecutable(b, "main", opts);
3589 const exe = addExecutable(b, opts, .{ .name = "main" });
33793590 exe.addObject(obj1);
33803591 exe.addObject(obj2);
33813592 exe.linkLibC();
......@@ -3392,19 +3603,21 @@ fn testUnresolvedError(b: *Build, opts: Options) *Step {
33923603fn testWeakExports(b: *Build, opts: Options) *Step {
33933604 const test_step = addTestStep(b, "weak-exports", opts);
33943605
3395 const obj = addObject(b, "obj", opts);
3396 addCSourceBytes(obj,
3606 const obj = addObject(b, opts, .{
3607 .name = "obj",
3608 .c_source_bytes =
33973609 \\#include <stdio.h>
33983610 \\__attribute__((weak)) int foo();
33993611 \\int main() {
34003612 \\ printf("%d\n", foo ? foo() : 3);
34013613 \\}
3402 , &.{});
3614 ,
3615 .pic = true,
3616 });
34033617 obj.linkLibC();
3404 obj.force_pic = true;
34053618
34063619 {
3407 const dso = addSharedLibrary(b, "a", opts);
3620 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
34083621 dso.addObject(obj);
34093622 dso.linkLibC();
34103623
......@@ -3415,7 +3628,7 @@ fn testWeakExports(b: *Build, opts: Options) *Step {
34153628 }
34163629
34173630 {
3418 const exe = addExecutable(b, "main", opts);
3631 const exe = addExecutable(b, opts, .{ .name = "main" });
34193632 exe.addObject(obj);
34203633 exe.linkLibC();
34213634 // https://github.com/ziglang/zig/issues/17619
......@@ -3437,14 +3650,14 @@ fn testWeakExports(b: *Build, opts: Options) *Step {
34373650fn testWeakUndefsDso(b: *Build, opts: Options) *Step {
34383651 const test_step = addTestStep(b, "weak-undef-dso", opts);
34393652
3440 const dso = addSharedLibrary(b, "a", opts);
3653 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
34413654 addCSourceBytes(dso,
34423655 \\__attribute__((weak)) int foo();
34433656 \\int bar() { return foo ? foo() : -1; }
34443657 , &.{});
34453658
34463659 {
3447 const exe = addExecutable(b, "main", opts);
3660 const exe = addExecutable(b, opts, .{ .name = "main" });
34483661 addCSourceBytes(exe,
34493662 \\#include <stdio.h>
34503663 \\int bar();
......@@ -3461,7 +3674,7 @@ fn testWeakUndefsDso(b: *Build, opts: Options) *Step {
34613674 }
34623675
34633676 {
3464 const exe = addExecutable(b, "main", opts);
3677 const exe = addExecutable(b, opts, .{ .name = "main" });
34653678 addCSourceBytes(exe,
34663679 \\#include <stdio.h>
34673680 \\int foo() { return 5; }
......@@ -3484,12 +3697,14 @@ fn testWeakUndefsDso(b: *Build, opts: Options) *Step {
34843697fn testZNow(b: *Build, opts: Options) *Step {
34853698 const test_step = addTestStep(b, "z-now", opts);
34863699
3487 const obj = addObject(b, "obj", opts);
3488 addCSourceBytes(obj, "int main() { return 0; }", &.{});
3489 obj.force_pic = true;
3700 const obj = addObject(b, opts, .{
3701 .name = "obj",
3702 .c_source_bytes = "int main() { return 0; }",
3703 .pic = true,
3704 });
34903705
34913706 {
3492 const dso = addSharedLibrary(b, "a", opts);
3707 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
34933708 dso.addObject(obj);
34943709
34953710 const check = dso.checkObject();
......@@ -3499,7 +3714,7 @@ fn testZNow(b: *Build, opts: Options) *Step {
34993714 }
35003715
35013716 {
3502 const dso = addSharedLibrary(b, "a", opts);
3717 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
35033718 dso.addObject(obj);
35043719 dso.link_z_lazy = true;
35053720
......@@ -3515,7 +3730,7 @@ fn testZNow(b: *Build, opts: Options) *Step {
35153730fn testZStackSize(b: *Build, opts: Options) *Step {
35163731 const test_step = addTestStep(b, "z-stack-size", opts);
35173732
3518 const exe = addExecutable(b, "main", opts);
3733 const exe = addExecutable(b, opts, .{ .name = "main" });
35193734 addCSourceBytes(exe, "int main() { return 0; }", &.{});
35203735 exe.stack_size = 0x800000;
35213736 exe.linkLibC();
......@@ -3540,8 +3755,9 @@ fn testZText(b: *Build, opts: Options) *Step {
35403755 // musl supports only a very limited number of text relocations and only in DSOs (and
35413756 // rightly so!).
35423757
3543 const a_o = addObject(b, "a", opts);
3544 addAsmSourceBytes(a_o,
3758 const a_o = addObject(b, opts, .{
3759 .name = "a",
3760 .asm_source_bytes =
35453761 \\.globl fn1
35463762 \\fn1:
35473763 \\ sub $8, %rsp
......@@ -3549,10 +3765,13 @@ fn testZText(b: *Build, opts: Options) *Step {
35493765 \\ call *%rax
35503766 \\ add $8, %rsp
35513767 \\ ret
3552 );
3768 \\
3769 ,
3770 });
35533771
3554 const b_o = addObject(b, "b", opts);
3555 addCSourceBytes(b_o,
3772 const b_o = addObject(b, opts, .{
3773 .name = "b",
3774 .c_source_bytes =
35563775 \\int fn1();
35573776 \\int fn2() {
35583777 \\ return 3;
......@@ -3561,15 +3780,16 @@ fn testZText(b: *Build, opts: Options) *Step {
35613780 \\int fnn() {
35623781 \\ return fn1();
35633782 \\}
3564 , &.{});
3565 b_o.force_pic = true;
3783 ,
3784 .pic = true,
3785 });
35663786
3567 const dso = addSharedLibrary(b, "a", opts);
3787 const dso = addSharedLibrary(b, opts, .{ .name = "a" });
35683788 dso.addObject(a_o);
35693789 dso.addObject(b_o);
35703790 dso.link_z_notext = true;
35713791
3572 const exe = addExecutable(b, "main", opts);
3792 const exe = addExecutable(b, opts, .{ .name = "main" });
35733793 addCSourceBytes(exe,
35743794 \\#include <stdio.h>
35753795 \\int fnn();
......@@ -3608,13 +3828,11 @@ const addObject = link.addObject;
36083828const addRunArtifact = link.addRunArtifact;
36093829const addSharedLibrary = link.addSharedLibrary;
36103830const addStaticLibrary = link.addStaticLibrary;
3611const addZigSourceBytes = link.addZigSourceBytes;
36123831const expectLinkErrors = link.expectLinkErrors;
36133832const link = @import("link.zig");
36143833const std = @import("std");
36153834
36163835const Build = std.Build;
3617const CrossTarget = std.zig.CrossTarget;
36183836const Options = link.Options;
36193837const Step = Build.Step;
36203838const WriteFile = Step.WriteFile;
test/link/glibc_compat/build.zig+3-3
......@@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void {
77 for ([_][]const u8{ "aarch64-linux-gnu.2.27", "aarch64-linux-gnu.2.34" }) |t| {
88 const exe = b.addExecutable(.{
99 .name = t,
10 .root_source_file = .{ .path = "main.c" },
11 .target = std.zig.CrossTarget.parse(
10 .target = b.resolveTargetQuery(std.Target.Query.parse(
1211 .{ .arch_os_abi = t },
13 ) catch unreachable,
12 ) catch unreachable),
1413 });
14 exe.addCSourceFile(.{ .file = .{ .path = "main.c" } });
1515 exe.linkLibC();
1616 // TODO: actually test the output
1717 _ = exe.getEmittedBin();
test/link/interdependent_static_c_libs/build.zig+2-2
......@@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1414 const lib_a = b.addStaticLibrary(.{
1515 .name = "a",
1616 .optimize = optimize,
17 .target = .{},
17 .target = b.host,
1818 });
1919 lib_a.addCSourceFile(.{ .file = .{ .path = "a.c" }, .flags = &[_][]const u8{} });
2020 lib_a.addIncludePath(.{ .path = "." });
......@@ -22,7 +22,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2222 const lib_b = b.addStaticLibrary(.{
2323 .name = "b",
2424 .optimize = optimize,
25 .target = .{},
25 .target = b.host,
2626 });
2727 lib_b.addCSourceFile(.{ .file = .{ .path = "b.c" }, .flags = &[_][]const u8{} });
2828 lib_b.addIncludePath(.{ .path = "." });
test/link/link.zig+133-43
......@@ -7,62 +7,160 @@ pub fn build(b: *Build) void {
77}
88
99pub const Options = struct {
10 target: CrossTarget,
10 target: std.Build.ResolvedTarget,
1111 optimize: std.builtin.OptimizeMode = .Debug,
1212 use_llvm: bool = true,
1313 use_lld: bool = false,
1414};
1515
16pub fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
17 const target = opts.target.zigTriple(b.allocator) catch @panic("OOM");
16pub fn addTestStep(b: *Build, prefix: []const u8, opts: Options) *Step {
17 const target = opts.target.result.zigTriple(b.allocator) catch @panic("OOM");
1818 const optimize = @tagName(opts.optimize);
1919 const use_llvm = if (opts.use_llvm) "llvm" else "no-llvm";
20 const name = std.fmt.allocPrint(b.allocator, "test-" ++ prefix ++ "-{s}-{s}-{s}", .{
21 target,
22 optimize,
23 use_llvm,
20 const name = std.fmt.allocPrint(b.allocator, "test-{s}-{s}-{s}-{s}", .{
21 prefix, target, optimize, use_llvm,
2422 }) catch @panic("OOM");
2523 return b.step(name, "");
2624}
2725
28pub fn addExecutable(b: *Build, name: []const u8, opts: Options) *Compile {
29 return b.addExecutable(.{
30 .name = name,
31 .target = opts.target,
32 .optimize = opts.optimize,
33 .use_llvm = opts.use_llvm,
34 .use_lld = opts.use_lld,
26const OverlayOptions = struct {
27 name: []const u8,
28 asm_source_bytes: ?[]const u8 = null,
29 c_source_bytes: ?[]const u8 = null,
30 c_source_flags: []const []const u8 = &.{},
31 cpp_source_bytes: ?[]const u8 = null,
32 cpp_source_flags: []const []const u8 = &.{},
33 zig_source_bytes: ?[]const u8 = null,
34 pic: ?bool = null,
35 strip: ?bool = null,
36};
37
38pub fn addExecutable(b: *std.Build, base: Options, overlay: OverlayOptions) *Step.Compile {
39 const compile_step = b.addExecutable(.{
40 .name = overlay.name,
41 .root_source_file = rsf: {
42 const bytes = overlay.zig_source_bytes orelse break :rsf null;
43 break :rsf b.addWriteFiles().add("a.zig", bytes);
44 },
45 .target = base.target,
46 .optimize = base.optimize,
47 .use_llvm = base.use_llvm,
48 .use_lld = base.use_lld,
49 .pic = overlay.pic,
50 .strip = overlay.strip,
3551 });
52 if (overlay.cpp_source_bytes) |bytes| {
53 compile_step.addCSourceFile(.{
54 .file = b.addWriteFiles().add("a.cpp", bytes),
55 .flags = overlay.cpp_source_flags,
56 });
57 }
58 if (overlay.c_source_bytes) |bytes| {
59 compile_step.addCSourceFile(.{
60 .file = b.addWriteFiles().add("a.c", bytes),
61 .flags = overlay.c_source_flags,
62 });
63 }
64 if (overlay.asm_source_bytes) |bytes| {
65 compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
66 }
67 return compile_step;
3668}
3769
38pub fn addObject(b: *Build, name: []const u8, opts: Options) *Compile {
39 return b.addObject(.{
40 .name = name,
41 .target = opts.target,
42 .optimize = opts.optimize,
43 .use_llvm = opts.use_llvm,
44 .use_lld = opts.use_lld,
70pub fn addObject(b: *Build, base: Options, overlay: OverlayOptions) *Step.Compile {
71 const compile_step = b.addObject(.{
72 .name = overlay.name,
73 .root_source_file = rsf: {
74 const bytes = overlay.zig_source_bytes orelse break :rsf null;
75 break :rsf b.addWriteFiles().add("a.zig", bytes);
76 },
77 .target = base.target,
78 .optimize = base.optimize,
79 .use_llvm = base.use_llvm,
80 .use_lld = base.use_lld,
81 .pic = overlay.pic,
82 .strip = overlay.strip,
4583 });
84 if (overlay.cpp_source_bytes) |bytes| {
85 compile_step.addCSourceFile(.{
86 .file = b.addWriteFiles().add("a.cpp", bytes),
87 .flags = overlay.cpp_source_flags,
88 });
89 }
90 if (overlay.c_source_bytes) |bytes| {
91 compile_step.addCSourceFile(.{
92 .file = b.addWriteFiles().add("a.c", bytes),
93 .flags = overlay.c_source_flags,
94 });
95 }
96 if (overlay.asm_source_bytes) |bytes| {
97 compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
98 }
99 return compile_step;
46100}
47101
48pub fn addStaticLibrary(b: *Build, name: []const u8, opts: Options) *Compile {
49 return b.addStaticLibrary(.{
50 .name = name,
51 .target = opts.target,
52 .optimize = opts.optimize,
53 .use_llvm = opts.use_llvm,
54 .use_lld = opts.use_lld,
102pub fn addStaticLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
103 const compile_step = b.addStaticLibrary(.{
104 .name = overlay.name,
105 .root_source_file = rsf: {
106 const bytes = overlay.zig_source_bytes orelse break :rsf null;
107 break :rsf b.addWriteFiles().add("a.zig", bytes);
108 },
109 .target = base.target,
110 .optimize = base.optimize,
111 .use_llvm = base.use_llvm,
112 .use_lld = base.use_lld,
113 .pic = overlay.pic,
114 .strip = overlay.strip,
55115 });
116 if (overlay.cpp_source_bytes) |bytes| {
117 compile_step.addCSourceFile(.{
118 .file = b.addWriteFiles().add("a.cpp", bytes),
119 .flags = overlay.cpp_source_flags,
120 });
121 }
122 if (overlay.c_source_bytes) |bytes| {
123 compile_step.addCSourceFile(.{
124 .file = b.addWriteFiles().add("a.c", bytes),
125 .flags = overlay.c_source_flags,
126 });
127 }
128 if (overlay.asm_source_bytes) |bytes| {
129 compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
130 }
131 return compile_step;
56132}
57133
58pub fn addSharedLibrary(b: *Build, name: []const u8, opts: Options) *Compile {
59 return b.addSharedLibrary(.{
60 .name = name,
61 .target = opts.target,
62 .optimize = opts.optimize,
63 .use_llvm = opts.use_llvm,
64 .use_lld = opts.use_lld,
134pub fn addSharedLibrary(b: *Build, base: Options, overlay: OverlayOptions) *Compile {
135 const compile_step = b.addSharedLibrary(.{
136 .name = overlay.name,
137 .root_source_file = rsf: {
138 const bytes = overlay.zig_source_bytes orelse break :rsf null;
139 break :rsf b.addWriteFiles().add("a.zig", bytes);
140 },
141 .target = base.target,
142 .optimize = base.optimize,
143 .use_llvm = base.use_llvm,
144 .use_lld = base.use_lld,
145 .pic = overlay.pic,
146 .strip = overlay.strip,
65147 });
148 if (overlay.cpp_source_bytes) |bytes| {
149 compile_step.addCSourceFile(.{
150 .file = b.addWriteFiles().add("a.cpp", bytes),
151 .flags = overlay.cpp_source_flags,
152 });
153 }
154 if (overlay.c_source_bytes) |bytes| {
155 compile_step.addCSourceFile(.{
156 .file = b.addWriteFiles().add("a.c", bytes),
157 .flags = overlay.c_source_flags,
158 });
159 }
160 if (overlay.asm_source_bytes) |bytes| {
161 compile_step.addAssemblyFile(b.addWriteFiles().add("a.s", bytes));
162 }
163 return compile_step;
66164}
67165
68166pub fn addRunArtifact(comp: *Compile) *Run {
......@@ -72,13 +170,6 @@ pub fn addRunArtifact(comp: *Compile) *Run {
72170 return run;
73171}
74172
75pub fn addZigSourceBytes(comp: *Compile, bytes: []const u8) void {
76 const b = comp.step.owner;
77 const file = WriteFile.create(b).add("a.zig", bytes);
78 file.addStepDependencies(&comp.step);
79 comp.root_src = file;
80}
81
82173pub fn addCSourceBytes(comp: *Compile, bytes: []const u8, flags: []const []const u8) void {
83174 const b = comp.step.owner;
84175 const file = WriteFile.create(b).add("a.c", bytes);
......@@ -108,7 +199,6 @@ const std = @import("std");
108199
109200const Build = std.Build;
110201const Compile = Step.Compile;
111const CrossTarget = std.zig.CrossTarget;
112202const Run = Step.Run;
113203const Step = Build.Step;
114204const WriteFile = Step.WriteFile;
test/link/macho.zig+32-29
......@@ -1,26 +1,29 @@
11//! Here we test our MachO linker for correctness and functionality.
22//! TODO migrate standalone tests from test/link/macho/* to here.
33
4pub fn testAll(b: *Build) *Step {
4pub fn testAll(b: *std.Build) *Step {
55 const macho_step = b.step("test-macho", "Run MachO tests");
66
7 const default_target = CrossTarget{ .os_tag = .macos };
8
9 macho_step.dependOn(testResolvingBoundarySymbols(b, .{ .target = default_target }));
7 macho_step.dependOn(testResolvingBoundarySymbols(b, .{
8 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
9 }));
1010
1111 return macho_step;
1212}
1313
14fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
14fn testResolvingBoundarySymbols(b: *std.Build, opts: Options) *Step {
1515 const test_step = addTestStep(b, "macho-resolving-boundary-symbols", opts);
1616
17 const obj1 = addObject(b, "obj1", opts);
18 addCppSourceBytes(obj1,
17 const obj1 = addObject(b, opts, .{
18 .name = "obj1",
19 .cpp_source_bytes =
1920 \\constexpr const char* MESSAGE __attribute__((used, section("__DATA_CONST,__message_ptr"))) = "codebase";
20 , &.{});
21 ,
22 });
2123
22 const main_o = addObject(b, "main", opts);
23 addZigSourceBytes(main_o,
24 const main_o = addObject(b, opts, .{
25 .name = "main",
26 .zig_source_bytes =
2427 \\const std = @import("std");
2528 \\extern fn interop() [*:0]const u8;
2629 \\pub fn main() !void {
......@@ -28,23 +31,27 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
2831 \\ std.mem.span(interop()),
2932 \\ });
3033 \\}
31 );
34 ,
35 });
3236
3337 {
34 const obj2 = addObject(b, "obj2", opts);
35 addCppSourceBytes(obj2,
38 const obj2 = addObject(b, opts, .{
39 .name = "obj2",
40 .cpp_source_bytes =
3641 \\extern const char* message_pointer __asm("section$start$__DATA_CONST$__message_ptr");
3742 \\extern "C" const char* interop() {
3843 \\ return message_pointer;
3944 \\}
40 , &.{});
45 ,
46 });
4147
42 const exe = addExecutable(b, "test", opts);
48 const exe = addExecutable(b, opts, .{ .name = "test" });
4349 exe.addObject(obj1);
4450 exe.addObject(obj2);
4551 exe.addObject(main_o);
4652
47 const run = addRunArtifact(exe);
53 const run = b.addRunArtifact(exe);
54 run.skip_foreign_checks = true;
4855 run.expectStdErrEqual("All your codebase are belong to us.\n");
4956 test_step.dependOn(&run.step);
5057
......@@ -55,15 +62,17 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
5562 }
5663
5764 {
58 const obj3 = addObject(b, "obj3", opts);
59 addCppSourceBytes(obj3,
65 const obj3 = addObject(b, opts, .{
66 .name = "obj3",
67 .cpp_source_bytes =
6068 \\extern const char* message_pointer __asm("section$start$__DATA$__message_ptr");
6169 \\extern "C" const char* interop() {
6270 \\ return message_pointer;
6371 \\}
64 , &.{});
72 ,
73 });
6574
66 const exe = addExecutable(b, "test", opts);
75 const exe = addExecutable(b, opts, .{ .name = "test" });
6776 exe.addObject(obj1);
6877 exe.addObject(obj3);
6978 exe.addObject(main_o);
......@@ -77,20 +86,14 @@ fn testResolvingBoundarySymbols(b: *Build, opts: Options) *Step {
7786 return test_step;
7887}
7988
80fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
89fn addTestStep(b: *std.Build, comptime prefix: []const u8, opts: Options) *Step {
8190 return link.addTestStep(b, "macho-" ++ prefix, opts);
8291}
8392
84const addCppSourceBytes = link.addCppSourceBytes;
85const addExecutable = link.addExecutable;
8693const addObject = link.addObject;
87const addRunArtifact = link.addRunArtifact;
88const addZigSourceBytes = link.addZigSourceBytes;
94const addExecutable = link.addExecutable;
8995const expectLinkErrors = link.expectLinkErrors;
9096const link = @import("link.zig");
9197const std = @import("std");
92
93const Build = std.Build;
94const CrossTarget = std.zig.CrossTarget;
9598const Options = link.Options;
96const Step = Build.Step;
99const Step = std.Build.Step;
test/link/macho/bugs/13056/build.zig+3-3
......@@ -14,14 +14,14 @@ pub fn build(b: *std.Build) void {
1414}
1515
1616fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
17 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
18 const target_info = std.zig.system.NativeTargetInfo.detect(target) catch unreachable;
19 const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse
17 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
18 const sdk = std.zig.system.darwin.getSdk(b.allocator, target.result) orelse
2019 @panic("macOS SDK is required to run the test");
2120
2221 const exe = b.addExecutable(.{
2322 .name = "test",
2423 .optimize = optimize,
24 .target = b.host,
2525 });
2626 exe.addSystemIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include" }) });
2727 exe.addIncludePath(.{ .path = b.pathJoin(&.{ sdk, "/usr/include/c++/v1" }) });
test/link/macho/bugs/13457/build.zig+1-1
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const exe = b.addExecutable(.{
1919 .name = "test",
test/link/macho/bugs/16308/build.zig+1-1
......@@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
66 const test_step = b.step("test", "Test it");
77 b.default_step = test_step;
88
9 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
9 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1010
1111 const lib = b.addSharedLibrary(.{
1212 .name = "a",
test/link/macho/bugs/16628/build.zig+1-1
......@@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void {
1515}
1616
1717fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
18 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
18 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1919
2020 const exe = b.addExecutable(.{
2121 .name = "test",
test/link/macho/dead_strip/build.zig+2-2
......@@ -4,7 +4,7 @@ pub const requires_symlinks = true;
44
55pub fn build(b: *std.Build) void {
66 const optimize: std.builtin.OptimizeMode = .Debug;
7 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
7 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
88
99 const test_step = b.step("test", "Test the program");
1010 b.default_step = test_step;
......@@ -44,7 +44,7 @@ pub fn build(b: *std.Build) void {
4444fn createScenario(
4545 b: *std.Build,
4646 optimize: std.builtin.OptimizeMode,
47 target: std.zig.CrossTarget,
47 target: std.Build.ResolvedTarget,
4848 name: []const u8,
4949) *std.Build.Step.Compile {
5050 const exe = b.addExecutable(.{
test/link/macho/dead_strip_dylibs/build.zig+1
......@@ -52,6 +52,7 @@ fn createScenario(
5252 const exe = b.addExecutable(.{
5353 .name = name,
5454 .optimize = optimize,
55 .target = b.host,
5556 });
5657 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
5758 exe.linkLibC();
test/link/macho/dylib/build.zig+2-2
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const dylib = b.addSharedLibrary(.{
1919 .name = "a",
......@@ -55,7 +55,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
5555
5656 check_exe.checkInHeaders();
5757 check_exe.checkExact("cmd RPATH");
58 check_exe.checkExactPath("path", dylib.getOutputDirectorySource());
58 check_exe.checkExactPath("path", dylib.getEmittedBinDirectory());
5959 test_step.dependOn(&check_exe.step);
6060
6161 const run = b.addRunArtifact(exe);
test/link/macho/empty/build.zig+1-1
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const exe = b.addExecutable(.{
1919 .name = "test",
test/link/macho/entry/build.zig+1-1
......@@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const exe = b.addExecutable(.{
1717 .name = "main",
1818 .optimize = optimize,
19 .target = .{ .os_tag = .macos },
19 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
2020 });
2121 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
2222 exe.linkLibC();
test/link/macho/entry_in_archive/build.zig+2-2
......@@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const lib = b.addStaticLibrary(.{
1717 .name = "main",
1818 .optimize = optimize,
19 .target = .{ .os_tag = .macos },
19 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
2020 });
2121 lib.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
2222 lib.linkLibC();
......@@ -24,7 +24,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2424 const exe = b.addExecutable(.{
2525 .name = "main",
2626 .optimize = optimize,
27 .target = .{ .os_tag = .macos },
27 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
2828 });
2929 exe.linkLibrary(lib);
3030 exe.linkLibC();
test/link/macho/entry_in_dylib/build.zig+2-2
......@@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const lib = b.addSharedLibrary(.{
1717 .name = "bootstrap",
1818 .optimize = optimize,
19 .target = .{ .os_tag = .macos },
19 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
2020 });
2121 lib.addCSourceFile(.{ .file = .{ .path = "bootstrap.c" }, .flags = &.{} });
2222 lib.linkLibC();
......@@ -25,7 +25,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2525 const exe = b.addExecutable(.{
2626 .name = "main",
2727 .optimize = optimize,
28 .target = .{ .os_tag = .macos },
28 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
2929 });
3030 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
3131 exe.linkLibrary(lib);
test/link/macho/headerpad/build.zig+1
......@@ -112,6 +112,7 @@ fn simpleExe(
112112 const exe = b.addExecutable(.{
113113 .name = name,
114114 .optimize = optimize,
115 .target = b.host,
115116 });
116117 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
117118 exe.linkLibC();
test/link/macho/linksection/build.zig+1-1
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target = std.zig.CrossTarget{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const obj = b.addObject(.{
1919 .name = "test",
test/link/macho/needed_framework/build.zig+1
......@@ -19,6 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1919 const exe = b.addExecutable(.{
2020 .name = "test",
2121 .optimize = optimize,
22 .target = b.host,
2223 });
2324 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
2425 exe.linkLibC();
test/link/macho/needed_library/build.zig+2-2
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const dylib = b.addSharedLibrary(.{
1919 .name = "a",
......@@ -33,7 +33,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
3333 });
3434 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
3535 exe.linkLibC();
36 exe.linkSystemLibraryNeeded("a");
36 exe.root_module.linkSystemLibrary("a", .{ .needed = true });
3737 exe.addLibraryPath(dylib.getEmittedBinDirectory());
3838 exe.addRPath(dylib.getEmittedBinDirectory());
3939 exe.dead_strip_dylibs = true;
test/link/macho/objc/build.zig+1
......@@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1717 const exe = b.addExecutable(.{
1818 .name = "test",
1919 .optimize = optimize,
20 .target = b.host,
2021 });
2122 exe.addIncludePath(.{ .path = "." });
2223 exe.addCSourceFile(.{ .file = .{ .path = "Foo.m" }, .flags = &[0][]const u8{} });
test/link/macho/objcpp/build.zig+1
......@@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1717 const exe = b.addExecutable(.{
1818 .name = "test",
1919 .optimize = optimize,
20 .target = b.host,
2021 });
2122 b.default_step.dependOn(&exe.step);
2223 exe.addIncludePath(.{ .path = "." });
test/link/macho/pagezero/build.zig+1-1
......@@ -7,7 +7,7 @@ pub fn build(b: *std.Build) void {
77 b.default_step = test_step;
88
99 const optimize: std.builtin.OptimizeMode = .Debug;
10 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
10 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1111
1212 {
1313 const exe = b.addExecutable(.{
test/link/macho/reexports/build.zig+1-1
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const lib = b.addStaticLibrary(.{
1919 .name = "a",
test/link/macho/search_strategy/build.zig+3-3
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 {
1919 // -search_dylibs_first
......@@ -45,9 +45,9 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
4545fn createScenario(
4646 b: *std.Build,
4747 optimize: std.builtin.OptimizeMode,
48 target: std.zig.CrossTarget,
48 target: std.Build.ResolvedTarget,
4949 name: []const u8,
50 search_strategy: std.Build.Step.Compile.SystemLib.SearchStrategy,
50 search_strategy: std.Build.Module.SystemLib.SearchStrategy,
5151) *std.Build.Step.Compile {
5252 const static = b.addStaticLibrary(.{
5353 .name = name,
test/link/macho/stack_size/build.zig+1-1
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const exe = b.addExecutable(.{
1919 .name = "main",
test/link/macho/strict_validation/build.zig+1-1
......@@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void {
1414}
1515
1616fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
17 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
17 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1818
1919 const exe = b.addExecutable(.{
2020 .name = "main",
test/link/macho/tbdv3/build.zig+1-1
......@@ -15,7 +15,7 @@ pub fn build(b: *std.Build) void {
1515}
1616
1717fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
18 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
18 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1919
2020 const lib = b.addSharedLibrary(.{
2121 .name = "a",
test/link/macho/tls/build.zig+1-1
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const lib = b.addSharedLibrary(.{
1919 .name = "a",
test/link/macho/unwind_info/build.zig+3-3
......@@ -14,7 +14,7 @@ pub fn build(b: *std.Build) void {
1414}
1515
1616fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
17 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
17 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1818
1919 testUnwindInfo(b, test_step, optimize, target, false, "no-dead-strip");
2020 testUnwindInfo(b, test_step, optimize, target, true, "yes-dead-strip");
......@@ -24,7 +24,7 @@ fn testUnwindInfo(
2424 b: *std.Build,
2525 test_step: *std.Build.Step,
2626 optimize: std.builtin.OptimizeMode,
27 target: std.zig.CrossTarget,
27 target: std.Build.ResolvedTarget,
2828 dead_strip: bool,
2929 name: []const u8,
3030) void {
......@@ -66,7 +66,7 @@ fn testUnwindInfo(
6666fn createScenario(
6767 b: *std.Build,
6868 optimize: std.builtin.OptimizeMode,
69 target: std.zig.CrossTarget,
69 target: std.Build.ResolvedTarget,
7070 name: []const u8,
7171) *std.Build.Step.Compile {
7272 const exe = b.addExecutable(.{
test/link/macho/weak_framework/build.zig+1
......@@ -17,6 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1717 const exe = b.addExecutable(.{
1818 .name = "test",
1919 .optimize = optimize,
20 .target = b.host,
2021 });
2122 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
2223 exe.linkLibC();
test/link/macho/weak_library/build.zig+2-2
......@@ -13,7 +13,7 @@ pub fn build(b: *std.Build) void {
1313}
1414
1515fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const target: std.zig.CrossTarget = .{ .os_tag = .macos };
16 const target = b.resolveTargetQuery(.{ .os_tag = .macos });
1717
1818 const dylib = b.addSharedLibrary(.{
1919 .name = "a",
......@@ -32,7 +32,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
3232 });
3333 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &[0][]const u8{} });
3434 exe.linkLibC();
35 exe.linkSystemLibraryWeak("a");
35 exe.root_module.linkSystemLibrary("a", .{ .weak = true });
3636 exe.addLibraryPath(dylib.getEmittedBinDirectory());
3737 exe.addRPath(dylib.getEmittedBinDirectory());
3838
test/link/static_libs_from_object_files/build.zig+8-6
......@@ -59,7 +59,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
5959 .name = "test1",
6060 .root_source_file = .{ .path = "main.zig" },
6161 .optimize = optimize,
62 .target = .{},
62 .target = b.host,
6363 });
6464
6565 for (files) |file| {
......@@ -77,12 +77,12 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
7777 {
7878 const lib_a = b.addStaticLibrary(.{
7979 .name = "test2_a",
80 .target = .{},
80 .target = b.host,
8181 .optimize = optimize,
8282 });
8383 const lib_b = b.addStaticLibrary(.{
8484 .name = "test2_b",
85 .target = .{},
85 .target = b.host,
8686 .optimize = optimize,
8787 });
8888
......@@ -94,6 +94,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
9494 const exe = b.addExecutable(.{
9595 .name = "test2",
9696 .root_source_file = .{ .path = "main.zig" },
97 .target = b.host,
9798 .optimize = optimize,
9899 });
99100 exe.linkLibrary(lib_a);
......@@ -110,19 +111,19 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
110111 {
111112 const lib_a = b.addStaticLibrary(.{
112113 .name = "test3_a",
113 .target = .{},
114 .target = b.host,
114115 .optimize = optimize,
115116 });
116117 const lib_b = b.addStaticLibrary(.{
117118 .name = "test3_b",
118 .target = .{},
119 .target = b.host,
119120 .optimize = optimize,
120121 });
121122
122123 for (files, 1..) |file, i| {
123124 const obj = b.addObject(.{
124125 .name = b.fmt("obj_{}", .{i}),
125 .target = .{},
126 .target = b.host,
126127 .optimize = optimize,
127128 });
128129 obj.addCSourceFile(.{ .file = file, .flags = &flags });
......@@ -134,6 +135,7 @@ fn add(b: *Build, test_step: *Step, files: []const LazyPath, optimize: std.built
134135 const exe = b.addExecutable(.{
135136 .name = "test3",
136137 .root_source_file = .{ .path = "main.zig" },
138 .target = b.host,
137139 .optimize = optimize,
138140 });
139141 exe.linkLibrary(lib_a);
test/link/wasm/archive/build.zig+1-1
......@@ -20,11 +20,11 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2020 .root_source_file = .{ .path = "main.zig" },
2121 .optimize = optimize,
2222 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
23 .strip = false,
2324 });
2425 lib.entry = .disabled;
2526 lib.use_llvm = false;
2627 lib.use_lld = false;
27 lib.strip = false;
2828
2929 const check = lib.checkObject();
3030 check.checkInHeaders();
test/link/wasm/basic-features/build.zig+2-2
......@@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void {
88 .name = "lib",
99 .root_source_file = .{ .path = "main.zig" },
1010 .optimize = .Debug,
11 .target = .{
11 .target = b.resolveTargetQuery(.{
1212 .cpu_arch = .wasm32,
1313 .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
1414 .cpu_features_add = std.Target.wasm.featureSet(&.{.atomics}),
1515 .os_tag = .freestanding,
16 },
16 }),
1717 });
1818 lib.entry = .disabled;
1919 lib.use_llvm = false;
test/link/wasm/bss/build.zig+4-4
......@@ -17,13 +17,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
1717 const lib = b.addExecutable(.{
1818 .name = "lib",
1919 .root_source_file = .{ .path = "lib.zig" },
20 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
20 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2121 .optimize = optimize_mode,
22 .strip = false,
2223 });
2324 lib.entry = .disabled;
2425 lib.use_llvm = false;
2526 lib.use_lld = false;
26 lib.strip = false;
2727 // to make sure the bss segment is emitted, we must import memory
2828 lib.import_memory = true;
2929 lib.link_gc_sections = false;
......@@ -65,13 +65,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
6565 const lib = b.addExecutable(.{
6666 .name = "lib",
6767 .root_source_file = .{ .path = "lib2.zig" },
68 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
68 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
6969 .optimize = optimize_mode,
70 .strip = false,
7071 });
7172 lib.entry = .disabled;
7273 lib.use_llvm = false;
7374 lib.use_lld = false;
74 lib.strip = false;
7575 // to make sure the bss segment is emitted, we must import memory
7676 lib.import_memory = true;
7777 lib.link_gc_sections = false;
test/link/wasm/export-data/build.zig+1-1
......@@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void {
1717 });
1818 lib.entry = .disabled;
1919 lib.use_lld = false;
20 lib.export_symbol_names = &.{ "foo", "bar" };
20 lib.root_module.export_symbol_names = &.{ "foo", "bar" };
2121 lib.global_base = 0; // put data section at address 0 to make data symbols easier to parse
2222
2323 const check_lib = lib.checkObject();
test/link/wasm/export/build.zig+4-4
......@@ -17,7 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1717 .name = "no-export",
1818 .root_source_file = .{ .path = "main.zig" },
1919 .optimize = optimize,
20 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
20 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2121 });
2222 no_export.entry = .disabled;
2323 no_export.use_llvm = false;
......@@ -27,7 +27,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2727 .name = "dynamic",
2828 .root_source_file = .{ .path = "main.zig" },
2929 .optimize = optimize,
30 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
30 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
3131 });
3232 dynamic_export.entry = .disabled;
3333 dynamic_export.rdynamic = true;
......@@ -38,10 +38,10 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
3838 .name = "force",
3939 .root_source_file = .{ .path = "main.zig" },
4040 .optimize = optimize,
41 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
41 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
4242 });
4343 force_export.entry = .disabled;
44 force_export.export_symbol_names = &.{"foo"};
44 force_export.root_module.export_symbol_names = &.{"foo"};
4545 force_export.use_llvm = false;
4646 force_export.use_lld = false;
4747
test/link/wasm/extern-mangle/build.zig+1-1
......@@ -14,7 +14,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1414 const lib = b.addExecutable(.{
1515 .name = "lib",
1616 .root_source_file = .{ .path = "lib.zig" },
17 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
17 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
1818 .optimize = optimize,
1919 });
2020 lib.entry = .disabled;
test/link/wasm/extern/build.zig+1-1
......@@ -17,7 +17,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1717 .name = "extern",
1818 .root_source_file = .{ .path = "main.zig" },
1919 .optimize = optimize,
20 .target = .{ .cpu_arch = .wasm32, .os_tag = .wasi },
20 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .wasi }),
2121 });
2222 exe.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} });
2323 exe.use_llvm = false;
test/link/wasm/function-table/build.zig+3-3
......@@ -16,7 +16,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const import_table = b.addExecutable(.{
1717 .name = "import_table",
1818 .root_source_file = .{ .path = "lib.zig" },
19 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
19 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2020 .optimize = optimize,
2121 });
2222 import_table.entry = .disabled;
......@@ -28,7 +28,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
2828 const export_table = b.addExecutable(.{
2929 .name = "export_table",
3030 .root_source_file = .{ .path = "lib.zig" },
31 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
31 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
3232 .optimize = optimize,
3333 });
3434 export_table.entry = .disabled;
......@@ -40,7 +40,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
4040 const regular_table = b.addExecutable(.{
4141 .name = "regular_table",
4242 .root_source_file = .{ .path = "lib.zig" },
43 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
43 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
4444 .optimize = optimize,
4545 });
4646 regular_table.entry = .disabled;
test/link/wasm/infer-features/build.zig+4-4
......@@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void {
77 const c_obj = b.addObject(.{
88 .name = "c_obj",
99 .optimize = .Debug,
10 .target = .{
10 .target = b.resolveTargetQuery(.{
1111 .cpu_arch = .wasm32,
1212 .cpu_model = .{ .explicit = &std.Target.wasm.cpu.bleeding_edge },
1313 .os_tag = .freestanding,
14 },
14 }),
1515 });
1616 c_obj.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &.{} });
1717
......@@ -21,11 +21,11 @@ pub fn build(b: *std.Build) void {
2121 .name = "lib",
2222 .root_source_file = .{ .path = "main.zig" },
2323 .optimize = .Debug,
24 .target = .{
24 .target = b.resolveTargetQuery(.{
2525 .cpu_arch = .wasm32,
2626 .cpu_model = .{ .explicit = &std.Target.wasm.cpu.mvp },
2727 .os_tag = .freestanding,
28 },
28 }),
2929 });
3030 lib.entry = .disabled;
3131 lib.use_llvm = false;
test/link/wasm/producers/build.zig+2-2
......@@ -17,13 +17,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1717 const lib = b.addExecutable(.{
1818 .name = "lib",
1919 .root_source_file = .{ .path = "lib.zig" },
20 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
20 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2121 .optimize = optimize,
22 .strip = false,
2223 });
2324 lib.entry = .disabled;
2425 lib.use_llvm = false;
2526 lib.use_lld = false;
26 lib.strip = false;
2727 b.installArtifact(lib);
2828
2929 const version_fmt = "version " ++ builtin.zig_version_string;
test/link/wasm/segments/build.zig+2-2
......@@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const lib = b.addExecutable(.{
1717 .name = "lib",
1818 .root_source_file = .{ .path = "lib.zig" },
19 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
19 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2020 .optimize = optimize,
21 .strip = false,
2122 });
2223 lib.entry = .disabled;
2324 lib.use_llvm = false;
2425 lib.use_lld = false;
25 lib.strip = false;
2626 lib.link_gc_sections = false; // so data is not garbage collected and we can verify data section
2727 b.installArtifact(lib);
2828
test/link/wasm/shared-memory/build.zig+3-3
......@@ -21,16 +21,16 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize_mode: std.builtin.Opt
2121 .os_tag = .freestanding,
2222 },
2323 .optimize = optimize_mode,
24 .strip = false,
25 .single_threaded = false,
2426 });
2527 lib.entry = .disabled;
2628 lib.use_lld = false;
27 lib.strip = false;
2829 lib.import_memory = true;
2930 lib.export_memory = true;
3031 lib.shared_memory = true;
3132 lib.max_memory = 67108864;
32 lib.single_threaded = false;
33 lib.export_symbol_names = &.{"foo"};
33 lib.root_module.export_symbol_names = &.{"foo"};
3434
3535 const check_lib = lib.checkObject();
3636
test/link/wasm/stack_pointer/build.zig+2-2
......@@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const lib = b.addExecutable(.{
1717 .name = "lib",
1818 .root_source_file = .{ .path = "lib.zig" },
19 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
19 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2020 .optimize = optimize,
21 .strip = false,
2122 });
2223 lib.entry = .disabled;
2324 lib.use_llvm = false;
2425 lib.use_lld = false;
25 lib.strip = false;
2626 lib.stack_size = std.wasm.page_size * 2; // set an explicit stack size
2727 lib.link_gc_sections = false;
2828 b.installArtifact(lib);
test/link/wasm/type/build.zig+2-2
......@@ -16,13 +16,13 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1616 const lib = b.addExecutable(.{
1717 .name = "lib",
1818 .root_source_file = .{ .path = "lib.zig" },
19 .target = .{ .cpu_arch = .wasm32, .os_tag = .freestanding },
19 .target = b.resolveTargetQuery(.{ .cpu_arch = .wasm32, .os_tag = .freestanding }),
2020 .optimize = optimize,
21 .strip = false,
2122 });
2223 lib.entry = .disabled;
2324 lib.use_llvm = false;
2425 lib.use_lld = false;
25 lib.strip = false;
2626 b.installArtifact(lib);
2727
2828 const check_lib = lib.checkObject();
test/llvm_targets.zig+9-5
......@@ -1,7 +1,7 @@
11const std = @import("std");
22const Cases = @import("src/Cases.zig");
33
4const targets = [_]std.zig.CrossTarget{
4const targets = [_]std.Target.Query{
55 .{ .cpu_arch = .aarch64, .os_tag = .freestanding, .abi = .none },
66 .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .none },
77 .{ .cpu_arch = .aarch64, .os_tag = .ios, .abi = .simulator },
......@@ -127,17 +127,21 @@ const targets = [_]std.zig.CrossTarget{
127127 .{ .cpu_arch = .xtensa, .os_tag = .linux, .abi = .none },
128128};
129129
130pub fn addCases(ctx: *Cases, build_options: @import("cases.zig").BuildOptions) !void {
130pub fn addCases(
131 ctx: *Cases,
132 build_options: @import("cases.zig").BuildOptions,
133 b: *std.Build,
134) !void {
131135 if (!build_options.enable_llvm) return;
132 for (targets) |target| {
133 if (target.cpu_arch) |arch| switch (arch) {
136 for (targets) |target_query| {
137 if (target_query.cpu_arch) |arch| switch (arch) {
134138 .m68k => if (!build_options.llvm_has_m68k) continue,
135139 .csky => if (!build_options.llvm_has_csky) continue,
136140 .arc => if (!build_options.llvm_has_arc) continue,
137141 .xtensa => if (!build_options.llvm_has_xtensa) continue,
138142 else => {},
139143 };
140 var case = ctx.noEmitUsingLlvmBackend("llvm_targets", target);
144 var case = ctx.noEmitUsingLlvmBackend("llvm_targets", b.resolveTargetQuery(target_query));
141145 case.addCompile("");
142146 }
143147}
test/nvptx.zig+12-15
......@@ -1,9 +1,14 @@
11const std = @import("std");
22const Cases = @import("src/Cases.zig");
33
4pub fn addCases(ctx: *Cases) !void {
4pub fn addCases(ctx: *Cases, b: *std.Build) !void {
5 const target = b.resolveTargetQuery(.{
6 .cpu_arch = .nvptx64,
7 .os_tag = .cuda,
8 });
9
510 {
6 var case = addPtx(ctx, "simple addition and subtraction");
11 var case = addPtx(ctx, target, "simple addition and subtraction");
712
813 case.addCompile(
914 \\fn add(a: i32, b: i32) i32 {
......@@ -20,7 +25,7 @@ pub fn addCases(ctx: *Cases) !void {
2025 }
2126
2227 {
23 var case = addPtx(ctx, "read special registers");
28 var case = addPtx(ctx, target, "read special registers");
2429
2530 case.addCompile(
2631 \\fn threadIdX() u32 {
......@@ -37,7 +42,7 @@ pub fn addCases(ctx: *Cases) !void {
3742 }
3843
3944 {
40 var case = addPtx(ctx, "address spaces");
45 var case = addPtx(ctx, target, "address spaces");
4146
4247 case.addCompile(
4348 \\var x: i32 addrspace(.global) = 0;
......@@ -50,7 +55,7 @@ pub fn addCases(ctx: *Cases) !void {
5055 }
5156
5257 {
53 var case = addPtx(ctx, "reduce in shared mem");
58 var case = addPtx(ctx, target, "reduce in shared mem");
5459 case.addCompile(
5560 \\fn threadIdX() u32 {
5661 \\ return asm ("mov.u32 \t%[r], %tid.x;"
......@@ -82,18 +87,10 @@ pub fn addCases(ctx: *Cases) !void {
8287 }
8388}
8489
85const nvptx_target = std.zig.CrossTarget{
86 .cpu_arch = .nvptx64,
87 .os_tag = .cuda,
88};
89
90pub fn addPtx(
91 ctx: *Cases,
92 name: []const u8,
93) *Cases.Case {
90fn addPtx(ctx: *Cases, target: std.Build.ResolvedTarget, name: []const u8) *Cases.Case {
9491 ctx.cases.append(.{
9592 .name = name,
96 .target = nvptx_target,
93 .target = target,
9794 .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),
9895 .output_mode = .Obj,
9996 .deps = std.ArrayList(Cases.DepModule).init(ctx.cases.allocator),
test/src/Cases.zig+66-59
......@@ -76,7 +76,7 @@ pub const Case = struct {
7676 name: []const u8,
7777 /// The platform the test targets. For non-native platforms, an emulator
7878 /// such as QEMU is required for tests to complete.
79 target: CrossTarget,
79 target: std.Build.ResolvedTarget,
8080 /// In order to be able to run e.g. Execution updates, this must be set
8181 /// to Executable.
8282 output_mode: std.builtin.OutputMode,
......@@ -155,7 +155,7 @@ pub const Translate = struct {
155155 name: []const u8,
156156
157157 input: [:0]const u8,
158 target: CrossTarget,
158 target: std.Build.ResolvedTarget,
159159 link_libc: bool,
160160 c_frontend: CFrontend,
161161 kind: union(enum) {
......@@ -171,7 +171,7 @@ pub const Translate = struct {
171171pub fn addExe(
172172 ctx: *Cases,
173173 name: []const u8,
174 target: CrossTarget,
174 target: std.Build.ResolvedTarget,
175175) *Case {
176176 ctx.cases.append(Case{
177177 .name = name,
......@@ -184,16 +184,16 @@ pub fn addExe(
184184}
185185
186186/// Adds a test case for Zig input, producing an executable
187pub fn exe(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
187pub fn exe(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
188188 return ctx.addExe(name, target);
189189}
190190
191pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
192 var target_adjusted = target;
193 target_adjusted.ofmt = .c;
191pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target_query: std.Target.Query, b: *std.Build) *Case {
192 var adjusted_query = target_query;
193 adjusted_query.ofmt = .c;
194194 ctx.cases.append(Case{
195195 .name = name,
196 .target = target_adjusted,
196 .target = b.resolveTargetQuery(adjusted_query),
197197 .updates = std.ArrayList(Update).init(ctx.cases.allocator),
198198 .output_mode = .Exe,
199199 .deps = std.ArrayList(DepModule).init(ctx.arena),
......@@ -202,7 +202,7 @@ pub fn exeFromCompiledC(ctx: *Cases, name: []const u8, target: CrossTarget) *Cas
202202 return &ctx.cases.items[ctx.cases.items.len - 1];
203203}
204204
205pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
205pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
206206 ctx.cases.append(Case{
207207 .name = name,
208208 .target = target,
......@@ -217,7 +217,7 @@ pub fn noEmitUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget
217217
218218/// Adds a test case that uses the LLVM backend to emit an executable.
219219/// Currently this implies linking libc, because only then we can generate a testable executable.
220pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
220pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
221221 ctx.cases.append(Case{
222222 .name = name,
223223 .target = target,
......@@ -233,7 +233,7 @@ pub fn exeUsingLlvmBackend(ctx: *Cases, name: []const u8, target: CrossTarget) *
233233pub fn addObj(
234234 ctx: *Cases,
235235 name: []const u8,
236 target: CrossTarget,
236 target: std.Build.ResolvedTarget,
237237) *Case {
238238 ctx.cases.append(Case{
239239 .name = name,
......@@ -248,7 +248,7 @@ pub fn addObj(
248248pub fn addTest(
249249 ctx: *Cases,
250250 name: []const u8,
251 target: CrossTarget,
251 target: std.Build.ResolvedTarget,
252252) *Case {
253253 ctx.cases.append(Case{
254254 .name = name,
......@@ -262,17 +262,17 @@ pub fn addTest(
262262}
263263
264264/// Adds a test case for Zig input, producing an object file.
265pub fn obj(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
265pub fn obj(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
266266 return ctx.addObj(name, target);
267267}
268268
269269/// Adds a test case for ZIR input, producing an object file.
270pub fn objZIR(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
270pub fn objZIR(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
271271 return ctx.addObj(name, target, .ZIR);
272272}
273273
274274/// Adds a test case for Zig or ZIR input, producing C code.
275pub fn addC(ctx: *Cases, name: []const u8, target: CrossTarget) *Case {
275pub fn addC(ctx: *Cases, name: []const u8, target: std.Build.ResolvedTarget) *Case {
276276 var target_adjusted = target;
277277 target_adjusted.ofmt = std.Target.ObjectFormat.c;
278278 ctx.cases.append(Case{
......@@ -308,7 +308,7 @@ pub fn compareOutput(
308308pub fn addTransform(
309309 ctx: *Cases,
310310 name: []const u8,
311 target: CrossTarget,
311 target: std.Build.ResolvedTarget,
312312 src: [:0]const u8,
313313 result: [:0]const u8,
314314) void {
......@@ -320,7 +320,7 @@ pub fn addTransform(
320320pub fn transform(
321321 ctx: *Cases,
322322 name: []const u8,
323 target: CrossTarget,
323 target: std.Build.ResolvedTarget,
324324 src: [:0]const u8,
325325 result: [:0]const u8,
326326) void {
......@@ -330,7 +330,7 @@ pub fn transform(
330330pub fn addError(
331331 ctx: *Cases,
332332 name: []const u8,
333 target: CrossTarget,
333 target: std.Build.ResolvedTarget,
334334 src: [:0]const u8,
335335 expected_errors: []const []const u8,
336336) void {
......@@ -343,7 +343,7 @@ pub fn addError(
343343pub fn compileError(
344344 ctx: *Cases,
345345 name: []const u8,
346 target: CrossTarget,
346 target: std.Build.ResolvedTarget,
347347 src: [:0]const u8,
348348 expected_errors: []const []const u8,
349349) void {
......@@ -355,7 +355,7 @@ pub fn compileError(
355355pub fn addCompile(
356356 ctx: *Cases,
357357 name: []const u8,
358 target: CrossTarget,
358 target: std.Build.ResolvedTarget,
359359 src: [:0]const u8,
360360) void {
361361 ctx.addObj(name, target).addCompile(src);
......@@ -368,9 +368,9 @@ pub fn addCompile(
368368/// Each file should include a test manifest as a contiguous block of comments at
369369/// the end of the file. The first line should be the test type, followed by a set of
370370/// key-value config values, followed by a blank line, then the expected output.
371pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir) void {
371pub fn addFromDir(ctx: *Cases, dir: std.fs.Dir, b: *std.Build) void {
372372 var current_file: []const u8 = "none";
373 ctx.addFromDirInner(dir, &current_file) catch |err| {
373 ctx.addFromDirInner(dir, &current_file, b) catch |err| {
374374 std.debug.panicExtra(
375375 @errorReturnTrace(),
376376 @returnAddress(),
......@@ -386,6 +386,7 @@ fn addFromDirInner(
386386 /// This is kept up to date with the currently being processed file so
387387 /// that if any errors occur the caller knows it happened during this file.
388388 current_file: *[]const u8,
389 b: *std.Build,
389390) !void {
390391 var it = try iterable_dir.walk(ctx.arena);
391392 var filenames = std.ArrayList([]const u8).init(ctx.arena);
......@@ -422,7 +423,7 @@ fn addFromDirInner(
422423 var manifest = try TestManifest.parse(ctx.arena, src);
423424
424425 const backends = try manifest.getConfigForKeyAlloc(ctx.arena, "backend", Backend);
425 const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", CrossTarget);
426 const targets = try manifest.getConfigForKeyAlloc(ctx.arena, "target", std.Target.Query);
426427 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
427428 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
428429 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
......@@ -430,12 +431,12 @@ fn addFromDirInner(
430431
431432 if (manifest.type == .translate_c) {
432433 for (c_frontends) |c_frontend| {
433 for (targets) |target| {
434 for (targets) |target_query| {
434435 const output = try manifest.trailingLinesSplit(ctx.arena);
435436 try ctx.translate.append(.{
436437 .name = std.fs.path.stem(filename),
437438 .c_frontend = c_frontend,
438 .target = target,
439 .target = b.resolveTargetQuery(target_query),
439440 .link_libc = link_libc,
440441 .input = src,
441442 .kind = .{ .translate = output },
......@@ -446,12 +447,12 @@ fn addFromDirInner(
446447 }
447448 if (manifest.type == .run_translated_c) {
448449 for (c_frontends) |c_frontend| {
449 for (targets) |target| {
450 for (targets) |target_query| {
450451 const output = try manifest.trailingSplit(ctx.arena);
451452 try ctx.translate.append(.{
452453 .name = std.fs.path.stem(filename),
453454 .c_frontend = c_frontend,
454 .target = target,
455 .target = b.resolveTargetQuery(target_query),
455456 .link_libc = link_libc,
456457 .input = src,
457458 .kind = .{ .run = output },
......@@ -464,16 +465,18 @@ fn addFromDirInner(
464465 var cases = std.ArrayList(usize).init(ctx.arena);
465466
466467 // Cross-product to get all possible test combinations
467 for (backends) |backend| {
468 for (targets) |target| {
468 for (targets) |target_query| {
469 const resolved_target = b.resolveTargetQuery(target_query);
470 const target = resolved_target.result;
471 for (backends) |backend| {
469472 if (backend == .stage2 and
470 target.getCpuArch() != .wasm32 and target.getCpuArch() != .x86_64)
473 target.cpu.arch != .wasm32 and target.cpu.arch != .x86_64)
471474 {
472475 // Other backends don't support new liveness format
473476 continue;
474477 }
475 if (backend == .stage2 and target.getOsTag() == .macos and
476 target.getCpuArch() == .x86_64 and builtin.cpu.arch == .aarch64)
478 if (backend == .stage2 and target.os.tag == .macos and
479 target.cpu.arch == .x86_64 and builtin.cpu.arch == .aarch64)
477480 {
478481 // Rosetta has issues with ZLD
479482 continue;
......@@ -482,7 +485,7 @@ fn addFromDirInner(
482485 const next = ctx.cases.items.len;
483486 try ctx.cases.append(.{
484487 .name = std.fs.path.stem(filename),
485 .target = target,
488 .target = resolved_target,
486489 .backend = backend,
487490 .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),
488491 .is_test = is_test,
......@@ -538,7 +541,7 @@ pub fn lowerToBuildSteps(
538541 cases_dir_path: []const u8,
539542 incremental_exe: *std.Build.Step.Compile,
540543) void {
541 const host = std.zig.system.NativeTargetInfo.detect(.{}) catch |err|
544 const host = std.zig.system.resolveTargetQuery(.{}) catch |err|
542545 std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)});
543546
544547 for (self.incremental_cases.items) |incr_case| {
......@@ -622,8 +625,8 @@ pub fn lowerToBuildSteps(
622625 }
623626
624627 for (case.deps.items) |dep| {
625 artifact.addAnonymousModule(dep.name, .{
626 .source_file = file_sources.get(dep.path).?,
628 artifact.root_module.addAnonymousImport(dep.name, .{
629 .root_source_file = file_sources.get(dep.path).?,
627630 });
628631 }
629632
......@@ -644,10 +647,8 @@ pub fn lowerToBuildSteps(
644647 parent_step.dependOn(&artifact.step);
645648 },
646649 .Execution => |expected_stdout| no_exec: {
647 const run = if (case.target.ofmt == .c) run_step: {
648 const target_info = std.zig.system.NativeTargetInfo.detect(case.target) catch |err|
649 std.debug.panic("unable to detect target host: {s}\n", .{@errorName(err)});
650 if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) {
650 const run = if (case.target.result.ofmt == .c) run_step: {
651 if (getExternalExecutor(host, &case.target.result, .{ .link_libc = true }) != .native) {
651652 // We wouldn't be able to run the compiled C code.
652653 break :no_exec;
653654 }
......@@ -666,7 +667,7 @@ pub fn lowerToBuildSteps(
666667 "--",
667668 "-lc",
668669 "-target",
669 case.target.zigTriple(b.allocator) catch @panic("OOM"),
670 case.target.result.zigTriple(b.allocator) catch @panic("OOM"),
670671 });
671672 run_c.addArtifactArg(artifact);
672673 break :run_step run_c;
......@@ -692,9 +693,7 @@ pub fn lowerToBuildSteps(
692693 continue; // Pass test.
693694 }
694695
695 const target_info = std.zig.system.NativeTargetInfo.detect(case.target) catch |err|
696 std.debug.panic("unable to detect target host: {s}\n", .{@errorName(err)});
697 if (host.getExternalExecutor(&target_info, .{ .link_libc = true }) != .native) {
696 if (getExternalExecutor(host, &case.target.result, .{ .link_libc = true }) != .native) {
698697 // We wouldn't be able to run the compiled C code.
699698 continue; // Pass test.
700699 }
......@@ -1159,9 +1158,9 @@ const TestManifest = struct {
11591158 }
11601159
11611160 fn getDefaultParser(comptime T: type) ParseFn(T) {
1162 if (T == CrossTarget) return struct {
1161 if (T == std.Target.Query) return struct {
11631162 fn parse(str: []const u8) anyerror!T {
1164 return CrossTarget.parse(.{ .arch_os_abi = str });
1163 return std.Target.Query.parse(.{ .arch_os_abi = str });
11651164 }
11661165 }.parse;
11671166
......@@ -1198,7 +1197,8 @@ const builtin = @import("builtin");
11981197const std = @import("std");
11991198const assert = std.debug.assert;
12001199const Allocator = std.mem.Allocator;
1201const CrossTarget = std.zig.CrossTarget;
1200const getExternalExecutor = std.zig.system.getExternalExecutor;
1201
12021202const Compilation = @import("../../src/Compilation.zig");
12031203const zig_h = @import("../../src/link.zig").File.C.zig_h;
12041204const introspect = @import("../../src/introspect.zig");
......@@ -1287,7 +1287,7 @@ pub fn main() !void {
12871287
12881288 if (cases.items.len == 0) {
12891289 const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend);
1290 const targets = try manifest.getConfigForKeyAlloc(arena, "target", CrossTarget);
1290 const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.Target.Query);
12911291 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
12921292 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
12931293 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
......@@ -1295,12 +1295,12 @@ pub fn main() !void {
12951295
12961296 if (manifest.type == .translate_c) {
12971297 for (c_frontends) |c_frontend| {
1298 for (targets) |target| {
1298 for (targets) |target_query| {
12991299 const output = try manifest.trailingLinesSplit(ctx.arena);
13001300 try ctx.translate.append(.{
13011301 .name = std.fs.path.stem(filename),
13021302 .c_frontend = c_frontend,
1303 .target = target,
1303 .target = resolveTargetQuery(target_query),
13041304 .is_test = is_test,
13051305 .link_libc = link_libc,
13061306 .input = src,
......@@ -1312,12 +1312,12 @@ pub fn main() !void {
13121312 }
13131313 if (manifest.type == .run_translated_c) {
13141314 for (c_frontends) |c_frontend| {
1315 for (targets) |target| {
1315 for (targets) |target_query| {
13161316 const output = try manifest.trailingSplit(ctx.arena);
13171317 try ctx.translate.append(.{
13181318 .name = std.fs.path.stem(filename),
13191319 .c_frontend = c_frontend,
1320 .target = target,
1320 .target = resolveTargetQuery(target_query),
13211321 .is_test = is_test,
13221322 .link_libc = link_libc,
13231323 .output = output,
......@@ -1385,8 +1385,16 @@ pub fn main() !void {
13851385 return runCases(&ctx, zig_exe_path);
13861386}
13871387
1388fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {
1389 return .{
1390 .query = query,
1391 .target = std.zig.system.resolveTargetQuery(query) catch
1392 @panic("unable to resolve target query"),
1393 };
1394}
1395
13881396fn runCases(self: *Cases, zig_exe_path: []const u8) !void {
1389 const host = try std.zig.system.NativeTargetInfo.detect(.{});
1397 const host = try std.zig.system.resolveTargetQuery(.{});
13901398
13911399 var progress = std.Progress{};
13921400 const root_node = progress.start("compiler", self.cases.items.len);
......@@ -1467,7 +1475,7 @@ fn runOneCase(
14671475 zig_exe_path: []const u8,
14681476 thread_pool: *ThreadPool,
14691477 global_cache_directory: Compilation.Directory,
1470 host: std.zig.system.NativeTargetInfo,
1478 host: std.Target,
14711479) !void {
14721480 const tmp_src_path = "tmp.zig";
14731481 const enable_rosetta = build_options.enable_rosetta;
......@@ -1477,8 +1485,7 @@ fn runOneCase(
14771485 const enable_darling = build_options.enable_darling;
14781486 const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir;
14791487
1480 const target_info = try std.zig.system.NativeTargetInfo.detect(case.target);
1481 const target = target_info.target;
1488 const target = try std.zig.system.resolveTargetQuery(case.target);
14821489
14831490 var arena_allocator = std.heap.ArenaAllocator.init(allocator);
14841491 defer arena_allocator.deinit();
......@@ -1568,7 +1575,7 @@ fn runOneCase(
15681575 .keep_source_files_loaded = true,
15691576 .is_native_os = case.target.isNativeOs(),
15701577 .is_native_abi = case.target.isNativeAbi(),
1571 .dynamic_linker = target_info.dynamic_linker.get(),
1578 .dynamic_linker = target.dynamic_linker.get(),
15721579 .link_libc = case.link_libc,
15731580 .use_llvm = use_llvm,
15741581 .self_exe_path = zig_exe_path,
......@@ -1704,7 +1711,7 @@ fn runOneCase(
17041711 .{ &tmp.sub_path, bin_name },
17051712 );
17061713 if (case.target.ofmt != null and case.target.ofmt.? == .c) {
1707 if (host.getExternalExecutor(target_info, .{ .link_libc = true }) != .native) {
1714 if (getExternalExecutor(host, &target, .{ .link_libc = true }) != .native) {
17081715 // We wouldn't be able to run the compiled C code.
17091716 continue :update; // Pass test.
17101717 }
......@@ -1723,7 +1730,7 @@ fn runOneCase(
17231730 if (zig_lib_directory.path) |p| {
17241731 try argv.appendSlice(&.{ "-I", p });
17251732 }
1726 } else switch (host.getExternalExecutor(target_info, .{ .link_libc = case.link_libc })) {
1733 } else switch (getExternalExecutor(host, &target, .{ .link_libc = case.link_libc })) {
17271734 .native => {
17281735 if (case.backend == .stage2 and case.target.getCpuArch().isArmOrThumb()) {
17291736 // https://github.com/ziglang/zig/issues/13623
test/src/CompareOutput.zig+3-3
......@@ -96,7 +96,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
9696
9797 const exe = b.addExecutable(.{
9898 .name = "test",
99 .target = .{},
99 .target = b.host,
100100 .optimize = .Debug,
101101 });
102102 exe.addAssemblyFile(write_src.files.items[0].getPath());
......@@ -121,7 +121,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
121121 .name = "test",
122122 .root_source_file = write_src.files.items[0].getPath(),
123123 .optimize = optimize,
124 .target = .{},
124 .target = b.host,
125125 });
126126 if (case.link_libc) {
127127 exe.linkSystemLibrary("c");
......@@ -146,7 +146,7 @@ pub fn addCase(self: *CompareOutput, case: TestCase) void {
146146 const exe = b.addExecutable(.{
147147 .name = "test",
148148 .root_source_file = write_src.files.items[0].getPath(),
149 .target = .{},
149 .target = b.host,
150150 .optimize = .Debug,
151151 });
152152 if (case.link_libc) {
test/src/StackTrace.zig+30-50
......@@ -5,44 +5,33 @@ test_filter: ?[]const u8,
55optimize_modes: []const OptimizeMode,
66check_exe: *std.Build.Step.Compile,
77
8const Expect = [@typeInfo(OptimizeMode).Enum.fields.len][]const u8;
8const Config = struct {
9 name: []const u8,
10 source: []const u8,
11 Debug: ?PerMode = null,
12 ReleaseSmall: ?PerMode = null,
13 ReleaseSafe: ?PerMode = null,
14 ReleaseFast: ?PerMode = null,
915
10pub fn addCase(self: *StackTrace, config: anytype) void {
11 if (@hasField(@TypeOf(config), "exclude")) {
12 if (config.exclude.exclude()) return;
13 }
14 if (@hasField(@TypeOf(config), "exclude_arch")) {
15 const exclude_arch: []const std.Target.Cpu.Arch = &config.exclude_arch;
16 for (exclude_arch) |arch| if (arch == builtin.cpu.arch) return;
17 }
18 if (@hasField(@TypeOf(config), "exclude_os")) {
19 const exclude_os: []const std.Target.Os.Tag = &config.exclude_os;
20 for (exclude_os) |os| if (os == builtin.os.tag) return;
21 }
22 for (self.optimize_modes) |optimize_mode| {
23 switch (optimize_mode) {
24 .Debug => {
25 if (@hasField(@TypeOf(config), "Debug")) {
26 self.addExpect(config.name, config.source, optimize_mode, config.Debug);
27 }
28 },
29 .ReleaseSafe => {
30 if (@hasField(@TypeOf(config), "ReleaseSafe")) {
31 self.addExpect(config.name, config.source, optimize_mode, config.ReleaseSafe);
32 }
33 },
34 .ReleaseFast => {
35 if (@hasField(@TypeOf(config), "ReleaseFast")) {
36 self.addExpect(config.name, config.source, optimize_mode, config.ReleaseFast);
37 }
38 },
39 .ReleaseSmall => {
40 if (@hasField(@TypeOf(config), "ReleaseSmall")) {
41 self.addExpect(config.name, config.source, optimize_mode, config.ReleaseSmall);
42 }
43 },
44 }
45 }
16 const PerMode = struct {
17 expect: []const u8,
18 exclude_os: []const std.Target.Os.Tag = &.{},
19 error_tracing: ?bool = null,
20 };
21};
22
23pub fn addCase(self: *StackTrace, config: Config) void {
24 if (config.Debug) |per_mode|
25 self.addExpect(config.name, config.source, .Debug, per_mode);
26
27 if (config.ReleaseSmall) |per_mode|
28 self.addExpect(config.name, config.source, .ReleaseSmall, per_mode);
29
30 if (config.ReleaseFast) |per_mode|
31 self.addExpect(config.name, config.source, .ReleaseFast, per_mode);
32
33 if (config.ReleaseSafe) |per_mode|
34 self.addExpect(config.name, config.source, .ReleaseSafe, per_mode);
4635}
4736
4837fn addExpect(
......@@ -50,19 +39,9 @@ fn addExpect(
5039 name: []const u8,
5140 source: []const u8,
5241 optimize_mode: OptimizeMode,
53 mode_config: anytype,
42 mode_config: Config.PerMode,
5443) void {
55 if (@hasField(@TypeOf(mode_config), "exclude")) {
56 if (mode_config.exclude.exclude()) return;
57 }
58 if (@hasField(@TypeOf(mode_config), "exclude_arch")) {
59 const exclude_arch: []const std.Target.Cpu.Arch = &mode_config.exclude_arch;
60 for (exclude_arch) |arch| if (arch == builtin.cpu.arch) return;
61 }
62 if (@hasField(@TypeOf(mode_config), "exclude_os")) {
63 const exclude_os: []const std.Target.Os.Tag = &mode_config.exclude_os;
64 for (exclude_os) |os| if (os == builtin.os.tag) return;
65 }
44 for (mode_config.exclude_os) |tag| if (tag == builtin.os.tag) return;
6645
6746 const b = self.b;
6847 const annotated_case_name = fmt.allocPrint(b.allocator, "check {s} ({s})", .{
......@@ -77,7 +56,8 @@ fn addExpect(
7756 .name = "test",
7857 .root_source_file = write_src.files.items[0].getPath(),
7958 .optimize = optimize_mode,
80 .target = .{},
59 .target = b.host,
60 .error_tracing = mode_config.error_tracing,
8161 });
8262
8363 const run = b.addRunArtifact(exe);
test/src/run_translated_c.zig+2-2
......@@ -11,7 +11,7 @@ pub const RunTranslatedCContext = struct {
1111 step: *std.Build.Step,
1212 test_index: usize,
1313 test_filter: ?[]const u8,
14 target: std.zig.CrossTarget,
14 target: std.Build.ResolvedTarget,
1515
1616 const TestCase = struct {
1717 name: []const u8,
......@@ -86,7 +86,7 @@ pub const RunTranslatedCContext = struct {
8686 }
8787 const translate_c = b.addTranslateC(.{
8888 .source_file = write_src.files.items[0].getPath(),
89 .target = .{},
89 .target = b.host,
9090 .optimize = .Debug,
9191 });
9292
test/src/translate_c.zig+3-4
......@@ -5,7 +5,6 @@ const ArrayList = std.ArrayList;
55const fmt = std.fmt;
66const mem = std.mem;
77const fs = std.fs;
8const CrossTarget = std.zig.CrossTarget;
98
109pub const TranslateCContext = struct {
1110 b: *std.Build,
......@@ -18,7 +17,7 @@ pub const TranslateCContext = struct {
1817 sources: ArrayList(SourceFile),
1918 expected_lines: ArrayList([]const u8),
2019 allow_warnings: bool,
21 target: CrossTarget = CrossTarget{},
20 target: std.Target.Query = .{},
2221
2322 const SourceFile = struct {
2423 filename: []const u8,
......@@ -74,7 +73,7 @@ pub const TranslateCContext = struct {
7473 pub fn addWithTarget(
7574 self: *TranslateCContext,
7675 name: []const u8,
77 target: CrossTarget,
76 target: std.Target.Query,
7877 source: []const u8,
7978 expected_lines: []const []const u8,
8079 ) void {
......@@ -109,7 +108,7 @@ pub const TranslateCContext = struct {
109108
110109 const translate_c = b.addTranslateC(.{
111110 .source_file = write_src.files.items[0].getPath(),
112 .target = case.target,
111 .target = b.resolveTargetQuery(case.target),
113112 .optimize = .Debug,
114113 });
115114
test/stack_traces.zig+30-17
......@@ -20,7 +20,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
2020 ,
2121 },
2222 .ReleaseSafe = .{
23 .exclude_os = .{
23 .exclude_os = &.{
2424 .windows, // TODO
2525 .linux, // defeated by aggressive inlining
2626 },
......@@ -31,6 +31,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
3131 \\ ^
3232 \\
3333 ,
34 .error_tracing = true,
3435 },
3536 .ReleaseFast = .{
3637 .expect =
......@@ -70,7 +71,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
7071 ,
7172 },
7273 .ReleaseSafe = .{
73 .exclude_os = .{
74 .exclude_os = &.{
7475 .windows, // TODO
7576 },
7677 .expect =
......@@ -83,6 +84,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
8384 \\ ^
8485 \\
8586 ,
87 .error_tracing = true,
8688 },
8789 .ReleaseFast = .{
8890 .expect =
......@@ -125,7 +127,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
125127 ,
126128 },
127129 .ReleaseSafe = .{
128 .exclude_os = .{
130 .exclude_os = &.{
129131 .windows, // TODO
130132 .linux, // defeated by aggressive inlining
131133 },
......@@ -136,6 +138,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
136138 \\ ^
137139 \\
138140 ,
141 .error_tracing = true,
139142 },
140143 .ReleaseFast = .{
141144 .expect =
......@@ -176,7 +179,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
176179 ,
177180 },
178181 .ReleaseSafe = .{
179 .exclude_os = .{
182 .exclude_os = &.{
180183 .windows, // TODO
181184 .linux, // defeated by aggressive inlining
182185 },
......@@ -187,6 +190,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
187190 \\ ^
188191 \\
189192 ,
193 .error_tracing = true,
190194 },
191195 .ReleaseFast = .{
192196 .expect =
......@@ -230,7 +234,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
230234 ,
231235 },
232236 .ReleaseSafe = .{
233 .exclude_os = .{
237 .exclude_os = &.{
234238 .windows, // TODO
235239 .linux, // defeated by aggressive inlining
236240 },
......@@ -244,6 +248,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
244248 \\ ^
245249 \\
246250 ,
251 .error_tracing = true,
247252 },
248253 .ReleaseFast = .{
249254 .expect =
......@@ -286,7 +291,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
286291 ,
287292 },
288293 .ReleaseSafe = .{
289 .exclude_os = .{
294 .exclude_os = &.{
290295 .windows, // TODO
291296 .linux, // defeated by aggressive inlining
292297 },
......@@ -297,6 +302,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
297302 \\ ^
298303 \\
299304 ,
305 .error_tracing = true,
300306 },
301307 .ReleaseFast = .{
302308 .expect =
......@@ -336,7 +342,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
336342 ,
337343 },
338344 .ReleaseSafe = .{
339 .exclude_os = .{
345 .exclude_os = &.{
340346 .windows, // TODO
341347 .linux, // defeated by aggressive inlining
342348 },
......@@ -350,6 +356,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
350356 \\ ^
351357 \\
352358 ,
359 .error_tracing = true,
353360 },
354361 .ReleaseFast = .{
355362 .expect =
......@@ -391,7 +398,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
391398 ,
392399 },
393400 .ReleaseSafe = .{
394 .exclude_os = .{
401 .exclude_os = &.{
395402 .windows, // TODO
396403 .linux, // defeated by aggressive inlining
397404 },
......@@ -402,6 +409,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
402409 \\ ^
403410 \\
404411 ,
412 .error_tracing = true,
405413 },
406414 .ReleaseFast = .{
407415 .expect =
......@@ -461,7 +469,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
461469 ,
462470 },
463471 .ReleaseSafe = .{
464 .exclude_os = .{
472 .exclude_os = &.{
465473 .windows, // TODO
466474 .linux, // defeated by aggressive inlining
467475 },
......@@ -478,6 +486,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
478486 \\ ^
479487 \\
480488 ,
489 .error_tracing = true,
481490 },
482491 .ReleaseFast = .{
483492 .expect =
......@@ -531,7 +540,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
531540 ,
532541 },
533542 .ReleaseSafe = .{
534 .exclude_os = .{
543 .exclude_os = &.{
535544 .windows, // TODO
536545 },
537546 .expect =
......@@ -547,6 +556,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
547556 \\ ^
548557 \\
549558 ,
559 .error_tracing = true,
550560 },
551561 .ReleaseFast = .{
552562 .expect =
......@@ -595,7 +605,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
595605 ,
596606 },
597607 .ReleaseSafe = .{
598 .exclude_os = .{
608 .exclude_os = &.{
599609 .windows, // TODO
600610 },
601611 .expect =
......@@ -611,6 +621,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
611621 \\ ^
612622 \\
613623 ,
624 .error_tracing = true,
614625 },
615626 .ReleaseFast = .{
616627 .expect =
......@@ -659,7 +670,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
659670 ,
660671 },
661672 .ReleaseSafe = .{
662 .exclude_os = .{
673 .exclude_os = &.{
663674 .windows, // TODO
664675 },
665676 .expect =
......@@ -675,6 +686,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
675686 \\ ^
676687 \\
677688 ,
689 .error_tracing = true,
678690 },
679691 .ReleaseFast = .{
680692 .expect =
......@@ -728,7 +740,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
728740 ,
729741 },
730742 .ReleaseSafe = .{
731 .exclude_os = .{
743 .exclude_os = &.{
732744 .windows, // TODO
733745 },
734746 .expect =
......@@ -747,6 +759,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
747759 \\ ^
748760 \\
749761 ,
762 .error_tracing = true,
750763 },
751764 .ReleaseFast = .{
752765 .expect =
......@@ -763,10 +776,6 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
763776 });
764777
765778 cases.addCase(.{
766 .exclude_os = .{
767 .openbsd, // integer overflow
768 .windows, // TODO intermittent failures
769 },
770779 .name = "dumpCurrentStackTrace",
771780 .source =
772781 \\const std = @import("std");
......@@ -783,6 +792,10 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
783792 \\}
784793 ,
785794 .Debug = .{
795 .exclude_os = &.{
796 .openbsd, // integer overflow
797 .windows, // TODO intermittent failures
798 },
786799 .expect =
787800 \\source.zig:7:8: [address] in foo (test)
788801 \\ bar();
test/standalone.zig+5-5
......@@ -2,7 +2,7 @@ pub const SimpleCase = struct {
22 src_path: []const u8,
33 link_libc: bool = false,
44 all_modes: bool = false,
5 target: std.zig.CrossTarget = .{},
5 target: std.Target.Query = .{},
66 is_test: bool = false,
77 is_exe: bool = true,
88 /// Run only on this OS.
......@@ -89,10 +89,6 @@ pub const build_cases = [_]BuildCase{
8989 // .build_root = "test/standalone/issue_13970",
9090 // .import = @import("standalone/issue_13970/build.zig"),
9191 //},
92 .{
93 .build_root = "test/standalone/main_pkg_path",
94 .import = @import("standalone/main_pkg_path/build.zig"),
95 },
9692 .{
9793 .build_root = "test/standalone/shared_library",
9894 .import = @import("standalone/shared_library/build.zig"),
......@@ -262,6 +258,10 @@ pub const build_cases = [_]BuildCase{
262258 .build_root = "test/standalone/ios",
263259 .import = @import("standalone/ios/build.zig"),
264260 },
261 .{
262 .build_root = "test/standalone/depend_on_main_mod",
263 .import = @import("standalone/depend_on_main_mod/build.zig"),
264 },
265265};
266266
267267const std = @import("std");
test/standalone/c_compiler/build.zig+2-2
......@@ -23,7 +23,7 @@ fn add(
2323 cpp_name: []const u8,
2424 optimize: std.builtin.OptimizeMode,
2525) void {
26 const target: std.zig.CrossTarget = .{};
26 const target = b.host;
2727
2828 const exe_c = b.addExecutable(.{
2929 .name = c_name,
......@@ -42,7 +42,7 @@ fn add(
4242 exe_cpp.addCSourceFile(.{ .file = .{ .path = "test.cpp" }, .flags = &[0][]const u8{} });
4343 exe_cpp.linkLibCpp();
4444
45 switch (target.getOsTag()) {
45 switch (target.result.os.tag) {
4646 .windows => {
4747 // https://github.com/ziglang/zig/issues/8531
4848 exe_cpp.want_lto = false;
test/standalone/child_process/build.zig+1-1
......@@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
66 b.default_step = test_step;
77
88 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{};
9 const target = b.host;
1010
1111 if (builtin.os.tag == .wasi) return;
1212
test/standalone/coff_dwarf/build.zig+5
......@@ -11,6 +11,11 @@ pub fn build(b: *std.Build) void {
1111
1212 if (builtin.os.tag != .windows) return;
1313
14 if (builtin.cpu.arch == .aarch64) {
15 // https://github.com/ziglang/zig/issues/18427
16 return;
17 }
18
1419 const exe = b.addExecutable(.{
1520 .name = "main",
1621 .root_source_file = .{ .path = "main.zig" },
test/standalone/compiler_rt_panic/build.zig+2-2
......@@ -7,8 +7,8 @@ pub fn build(b: *std.Build) void {
77 const target = b.standardTargetOptions(.{});
88 const optimize = b.standardOptimizeOption(.{});
99
10 const abi = target.getAbi();
11 if (target.getObjectFormat() != .elf or !(abi.isMusl() or abi.isGnu())) return;
10 if (target.result.ofmt != .elf or !(target.result.abi.isMusl() or target.result.abi.isGnu()))
11 return;
1212
1313 const exe = b.addExecutable(.{
1414 .name = "main",
test/standalone/dep_diamond/build.zig+8-7
......@@ -7,21 +7,22 @@ pub fn build(b: *std.Build) void {
77 const optimize: std.builtin.OptimizeMode = .Debug;
88
99 const shared = b.createModule(.{
10 .source_file = .{ .path = "shared.zig" },
10 .root_source_file = .{ .path = "shared.zig" },
1111 });
1212
1313 const exe = b.addExecutable(.{
1414 .name = "test",
1515 .root_source_file = .{ .path = "test.zig" },
16 .target = b.host,
1617 .optimize = optimize,
1718 });
18 exe.addAnonymousModule("foo", .{
19 .source_file = .{ .path = "foo.zig" },
20 .dependencies = &.{.{ .name = "shared", .module = shared }},
19 exe.root_module.addAnonymousImport("foo", .{
20 .root_source_file = .{ .path = "foo.zig" },
21 .imports = &.{.{ .name = "shared", .module = shared }},
2122 });
22 exe.addAnonymousModule("bar", .{
23 .source_file = .{ .path = "bar.zig" },
24 .dependencies = &.{.{ .name = "shared", .module = shared }},
23 exe.root_module.addAnonymousImport("bar", .{
24 .root_source_file = .{ .path = "bar.zig" },
25 .imports = &.{.{ .name = "shared", .module = shared }},
2526 });
2627
2728 const run = b.addRunArtifact(exe);
test/standalone/dep_mutually_recursive/build.zig+6-5
......@@ -7,20 +7,21 @@ pub fn build(b: *std.Build) void {
77 const optimize: std.builtin.OptimizeMode = .Debug;
88
99 const foo = b.createModule(.{
10 .source_file = .{ .path = "foo.zig" },
10 .root_source_file = .{ .path = "foo.zig" },
1111 });
1212 const bar = b.createModule(.{
13 .source_file = .{ .path = "bar.zig" },
13 .root_source_file = .{ .path = "bar.zig" },
1414 });
15 foo.dependencies.put("bar", bar) catch @panic("OOM");
16 bar.dependencies.put("foo", foo) catch @panic("OOM");
15 foo.addImport("bar", bar);
16 bar.addImport("foo", foo);
1717
1818 const exe = b.addExecutable(.{
1919 .name = "test",
2020 .root_source_file = .{ .path = "test.zig" },
21 .target = b.host,
2122 .optimize = optimize,
2223 });
23 exe.addModule("foo", foo);
24 exe.root_module.addImport("foo", foo);
2425
2526 const run = b.addRunArtifact(exe);
2627 test_step.dependOn(&run.step);
test/standalone/dep_recursive/build.zig+4-3
......@@ -7,16 +7,17 @@ pub fn build(b: *std.Build) void {
77 const optimize: std.builtin.OptimizeMode = .Debug;
88
99 const foo = b.createModule(.{
10 .source_file = .{ .path = "foo.zig" },
10 .root_source_file = .{ .path = "foo.zig" },
1111 });
12 foo.dependencies.put("foo", foo) catch @panic("OOM");
12 foo.addImport("foo", foo);
1313
1414 const exe = b.addExecutable(.{
1515 .name = "test",
1616 .root_source_file = .{ .path = "test.zig" },
17 .target = b.host,
1718 .optimize = optimize,
1819 });
19 exe.addModule("foo", foo);
20 exe.root_module.addImport("foo", foo);
2021
2122 const run = b.addRunArtifact(exe);
2223 test_step.dependOn(&run.step);
test/standalone/dep_shared_builtin/build.zig+3-2
......@@ -9,10 +9,11 @@ pub fn build(b: *std.Build) void {
99 const exe = b.addExecutable(.{
1010 .name = "test",
1111 .root_source_file = .{ .path = "test.zig" },
12 .target = b.host,
1213 .optimize = optimize,
1314 });
14 exe.addAnonymousModule("foo", .{
15 .source_file = .{ .path = "foo.zig" },
15 exe.root_module.addAnonymousImport("foo", .{
16 .root_source_file = .{ .path = "foo.zig" },
1617 });
1718
1819 const run = b.addRunArtifact(exe);
test/standalone/dep_triangle/build.zig+6-5
......@@ -7,19 +7,20 @@ pub fn build(b: *std.Build) void {
77 const optimize: std.builtin.OptimizeMode = .Debug;
88
99 const shared = b.createModule(.{
10 .source_file = .{ .path = "shared.zig" },
10 .root_source_file = .{ .path = "shared.zig" },
1111 });
1212
1313 const exe = b.addExecutable(.{
1414 .name = "test",
1515 .root_source_file = .{ .path = "test.zig" },
16 .target = b.host,
1617 .optimize = optimize,
1718 });
18 exe.addAnonymousModule("foo", .{
19 .source_file = .{ .path = "foo.zig" },
20 .dependencies = &.{.{ .name = "shared", .module = shared }},
19 exe.root_module.addAnonymousImport("foo", .{
20 .root_source_file = .{ .path = "foo.zig" },
21 .imports = &.{.{ .name = "shared", .module = shared }},
2122 });
22 exe.addModule("shared", shared);
23 exe.root_module.addImport("shared", shared);
2324
2425 const run = b.addRunArtifact(exe);
2526 test_step.dependOn(&run.step);
test/standalone/depend_on_main_mod/build.zig created+28
......@@ -0,0 +1,28 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const target = b.standardTargetOptions(.{});
8 const optimize = b.standardOptimizeOption(.{});
9
10 const exe = b.addExecutable(.{
11 .name = "depend_on_main_mod",
12 .root_source_file = .{ .path = "src/main.zig" },
13 .target = target,
14 .optimize = optimize,
15 });
16
17 const foo_module = b.addModule("foo", .{
18 .root_source_file = .{ .path = "src/foo.zig" },
19 });
20
21 foo_module.addImport("root2", &exe.root_module);
22 exe.root_module.addImport("foo", foo_module);
23
24 const run_cmd = b.addRunArtifact(exe);
25 run_cmd.expectExitCode(0);
26
27 test_step.dependOn(&run_cmd.step);
28}
test/standalone/depend_on_main_mod/src/foo.zig created+6
......@@ -0,0 +1,6 @@
1const std = @import("std");
2const assert = std.debug.assert;
3
4pub fn run() void {
5 comptime assert(@import("root") == @import("root2"));
6}
test/standalone/depend_on_main_mod/src/main.zig created+5
......@@ -0,0 +1,5 @@
1const std = @import("std");
2
3pub fn main() !void {
4 @import("foo").run();
5}
test/standalone/embed_generated_file/build.zig+4-4
......@@ -7,10 +7,10 @@ pub fn build(b: *std.Build) void {
77 const bootloader = b.addExecutable(.{
88 .name = "bootloader",
99 .root_source_file = .{ .path = "bootloader.zig" },
10 .target = .{
10 .target = b.resolveTargetQuery(.{
1111 .cpu_arch = .x86,
1212 .os_tag = .freestanding,
13 },
13 }),
1414 .optimize = .ReleaseSmall,
1515 });
1616
......@@ -18,8 +18,8 @@ pub fn build(b: *std.Build) void {
1818 .root_source_file = .{ .path = "main.zig" },
1919 .optimize = .Debug,
2020 });
21 exe.addAnonymousModule("bootloader.elf", .{
22 .source_file = bootloader.getEmittedBin(),
21 exe.root_module.addAnonymousImport("bootloader.elf", .{
22 .root_source_file = bootloader.getEmittedBin(),
2323 });
2424
2525 // TODO: actually check the output
test/standalone/empty_env/build.zig+1
......@@ -15,6 +15,7 @@ pub fn build(b: *std.Build) void {
1515 const main = b.addExecutable(.{
1616 .name = "main",
1717 .root_source_file = .{ .path = "main.zig" },
18 .target = b.host,
1819 .optimize = optimize,
1920 });
2021
test/standalone/extern/build.zig+1-1
......@@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
66 const obj = b.addObject(.{
77 .name = "exports",
88 .root_source_file = .{ .path = "exports.zig" },
9 .target = .{},
9 .target = b.host,
1010 .optimize = optimize,
1111 });
1212 const main = b.addTest(.{
test/standalone/global_linkage/build.zig+1-1
......@@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
55 b.default_step = test_step;
66
77 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
8 const target = b.host;
99
1010 const obj1 = b.addStaticLibrary(.{
1111 .name = "obj1",
test/standalone/install_raw_hex/build.zig+2-2
......@@ -5,12 +5,12 @@ pub fn build(b: *std.Build) void {
55 const test_step = b.step("test", "Test it");
66 b.default_step = test_step;
77
8 const target = .{
8 const target = b.resolveTargetQuery(.{
99 .cpu_arch = .thumb,
1010 .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_m4 },
1111 .os_tag = .freestanding,
1212 .abi = .gnueabihf,
13 };
13 });
1414
1515 const optimize: std.builtin.OptimizeMode = .Debug;
1616
test/standalone/ios/build.zig+4-4
......@@ -8,12 +8,12 @@ pub fn build(b: *std.Build) void {
88 b.default_step = test_step;
99
1010 const optimize: std.builtin.OptimizeMode = .Debug;
11 const target: std.zig.CrossTarget = .{
11 const target = b.resolveTargetQuery(.{
1212 .cpu_arch = .aarch64,
1313 .os_tag = .ios,
14 };
15 const target_info = std.zig.system.NativeTargetInfo.detect(target) catch @panic("couldn't detect native target");
16 const sdk = std.zig.system.darwin.getSdk(b.allocator, target_info.target) orelse @panic("no iOS SDK found");
14 });
15 const sdk = std.zig.system.darwin.getSdk(b.allocator, target.result) orelse
16 @panic("no iOS SDK found");
1717 b.sysroot = sdk;
1818
1919 const exe = b.addExecutable(.{
test/standalone/issue_11595/build.zig+1-1
......@@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
66 b.default_step = test_step;
77
88 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{};
9 const target = b.host;
1010
1111 if (builtin.os.tag == .windows) {
1212 // https://github.com/ziglang/zig/issues/12419
test/standalone/issue_12588/build.zig+1-2
......@@ -5,13 +5,12 @@ pub fn build(b: *std.Build) void {
55 b.default_step = test_step;
66
77 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
98
109 const obj = b.addObject(.{
1110 .name = "main",
1211 .root_source_file = .{ .path = "main.zig" },
1312 .optimize = optimize,
14 .target = target,
13 .target = b.host,
1514 });
1615 _ = obj.getEmittedLlvmIr();
1716 _ = obj.getEmittedLlvmBc();
test/standalone/issue_12706/build.zig+1-2
......@@ -1,13 +1,12 @@
11const std = @import("std");
22const builtin = @import("builtin");
3const CrossTarget = std.zig.CrossTarget;
43
54pub fn build(b: *std.Build) void {
65 const test_step = b.step("test", "Test it");
76 b.default_step = test_step;
87
98 const optimize: std.builtin.OptimizeMode = .Debug;
10 const target: std.zig.CrossTarget = .{};
9 const target = b.host;
1110
1211 const exe = b.addExecutable(.{
1312 .name = "main",
test/standalone/issue_339/build.zig+1-1
......@@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
55 b.default_step = test_step;
66
77 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
8 const target = b.host;
99
1010 const obj = b.addObject(.{
1111 .name = "test",
test/standalone/issue_5825/build.zig+2-2
......@@ -8,11 +8,11 @@ pub fn build(b: *std.Build) void {
88 // Building for the msvc abi requires a native MSVC installation
99 if (builtin.os.tag != .windows or builtin.cpu.arch != .x86_64) return;
1010
11 const target = .{
11 const target = b.resolveTargetQuery(.{
1212 .cpu_arch = .x86_64,
1313 .os_tag = .windows,
1414 .abi = .msvc,
15 };
15 });
1616 const optimize: std.builtin.OptimizeMode = .Debug;
1717 const obj = b.addObject(.{
1818 .name = "issue_5825",
test/standalone/issue_8550/build.zig+2-2
......@@ -5,13 +5,13 @@ pub fn build(b: *std.Build) !void {
55 b.default_step = test_step;
66
77 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target = std.zig.CrossTarget{
8 const target = b.resolveTargetQuery(.{
99 .os_tag = .freestanding,
1010 .cpu_arch = .arm,
1111 .cpu_model = .{
1212 .explicit = &std.Target.arm.cpu.arm1176jz_s,
1313 },
14 };
14 });
1515
1616 const kernel = b.addExecutable(.{
1717 .name = "kernel",
test/standalone/load_dynamic_library/build.zig+1-1
......@@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
66 b.default_step = test_step;
77
88 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{};
9 const target = b.host;
1010
1111 if (builtin.os.tag == .wasi) return;
1212
test/standalone/main_pkg_path/a/test.zig deleted-5
......@@ -1,5 +0,0 @@
1const b = @import("../b.zig");
2
3test "main pkg path" {
4 b.foo();
5}
test/standalone/main_pkg_path/b.zig deleted-1
......@@ -1 +0,0 @@
1pub fn foo() void {}
test/standalone/main_pkg_path/build.zig deleted-13
......@@ -1,13 +0,0 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const test_exe = b.addTest(.{
8 .root_source_file = .{ .path = "a/test.zig" },
9 .main_pkg_path = .{ .path = "." },
10 });
11
12 test_step.dependOn(&b.addRunArtifact(test_exe).step);
13}
test/standalone/mix_c_files/build.zig+1
......@@ -19,6 +19,7 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize
1919 const exe = b.addExecutable(.{
2020 .name = "test",
2121 .root_source_file = .{ .path = "main.zig" },
22 .target = b.host,
2223 .optimize = optimize,
2324 });
2425 exe.addCSourceFile(.{ .file = .{ .path = "test.c" }, .flags = &[_][]const u8{"-std=c11"} });
test/standalone/mix_o_files/build.zig+1-1
......@@ -5,7 +5,7 @@ pub fn build(b: *std.Build) void {
55 b.default_step = test_step;
66
77 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{};
8 const target = b.host;
99
1010 const obj = b.addObject(.{
1111 .name = "base64",
test/standalone/options/build.zig+1-1
......@@ -3,7 +3,7 @@ const std = @import("std");
33pub fn build(b: *std.Build) void {
44 const main = b.addTest(.{
55 .root_source_file = .{ .path = "src/main.zig" },
6 .target = .{},
6 .target = b.host,
77 .optimize = .Debug,
88 });
99
test/standalone/pie/build.zig+2-2
......@@ -5,10 +5,10 @@ pub fn build(b: *std.Build) void {
55 b.default_step = test_step;
66
77 const optimize: std.builtin.OptimizeMode = .Debug;
8 const target: std.zig.CrossTarget = .{
8 const target = b.resolveTargetQuery(.{
99 .os_tag = .linux,
1010 .cpu_arch = .x86_64,
11 };
11 });
1212
1313 const main = b.addTest(.{
1414 .root_source_file = .{ .path = "main.zig" },
test/standalone/pkg_import/build.zig+2-1
......@@ -10,8 +10,9 @@ pub fn build(b: *std.Build) void {
1010 .name = "test",
1111 .root_source_file = .{ .path = "test.zig" },
1212 .optimize = optimize,
13 .target = b.host,
1314 });
14 exe.addAnonymousModule("my_pkg", .{ .source_file = .{ .path = "pkg.zig" } });
15 exe.root_module.addAnonymousImport("my_pkg", .{ .root_source_file = .{ .path = "pkg.zig" } });
1516
1617 const run = b.addRunArtifact(exe);
1718 test_step.dependOn(&run.step);
test/standalone/self_exe_symlink/build.zig+2-2
......@@ -7,11 +7,11 @@ pub fn build(b: *std.Build) void {
77 b.default_step = test_step;
88
99 const optimize: std.builtin.OptimizeMode = .Debug;
10 const target: std.zig.CrossTarget = .{};
10 const target = b.host;
1111
1212 // The test requires getFdPath in order to to get the path of the
1313 // File returned by openSelfExe
14 if (!std.os.isGetFdPathSupportedOnTarget(target.getOs())) return;
14 if (!std.os.isGetFdPathSupportedOnTarget(target.result.os)) return;
1515
1616 const main = b.addExecutable(.{
1717 .name = "main",
test/standalone/shared_library/build.zig+1-1
......@@ -10,7 +10,7 @@ pub fn build(b: *std.Build) void {
1010 }
1111
1212 const optimize: std.builtin.OptimizeMode = .Debug;
13 const target: std.zig.CrossTarget = .{};
13 const target = b.host;
1414 const lib = b.addSharedLibrary(.{
1515 .name = "mathtest",
1616 .root_source_file = .{ .path = "mathtest.zig" },
test/standalone/stack_iterator/build.zig+9-10
......@@ -22,11 +22,10 @@ pub fn build(b: *std.Build) void {
2222 .root_source_file = .{ .path = "unwind.zig" },
2323 .target = target,
2424 .optimize = optimize,
25 .unwind_tables = if (target.result.isDarwin()) true else null,
26 .omit_frame_pointer = false,
2527 });
2628
27 if (target.isDarwin()) exe.unwind_tables = true;
28 exe.omit_frame_pointer = false;
29
3029 const run_cmd = b.addRunArtifact(exe);
3130 test_step.dependOn(&run_cmd.step);
3231 }
......@@ -46,11 +45,10 @@ pub fn build(b: *std.Build) void {
4645 .root_source_file = .{ .path = "unwind.zig" },
4746 .target = target,
4847 .optimize = optimize,
48 .unwind_tables = true,
49 .omit_frame_pointer = true,
4950 });
5051
51 exe.omit_frame_pointer = true;
52 exe.unwind_tables = true;
53
5452 const run_cmd = b.addRunArtifact(exe);
5553 test_step.dependOn(&run_cmd.step);
5654 }
......@@ -69,11 +67,12 @@ pub fn build(b: *std.Build) void {
6967 .name = "c_shared_lib",
7068 .target = target,
7169 .optimize = optimize,
70 .strip = false,
7271 });
7372
74 if (target.isWindows()) c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)");
73 if (target.result.os.tag == .windows)
74 c_shared_lib.defineCMacro("LIB_API", "__declspec(dllexport)");
7575
76 c_shared_lib.strip = false;
7776 c_shared_lib.addCSourceFile(.{
7877 .file = .{ .path = "shared_lib.c" },
7978 .flags = &.{"-fomit-frame-pointer"},
......@@ -85,10 +84,10 @@ pub fn build(b: *std.Build) void {
8584 .root_source_file = .{ .path = "shared_lib_unwind.zig" },
8685 .target = target,
8786 .optimize = optimize,
87 .unwind_tables = if (target.result.isDarwin()) true else null,
88 .omit_frame_pointer = true,
8889 });
8990
90 if (target.isDarwin()) exe.unwind_tables = true;
91 exe.omit_frame_pointer = true;
9291 exe.linkLibrary(c_shared_lib);
9392
9493 const run_cmd = b.addRunArtifact(exe);
test/standalone/static_c_lib/build.zig+1-1
......@@ -9,7 +9,7 @@ pub fn build(b: *std.Build) void {
99 const foo = b.addStaticLibrary(.{
1010 .name = "foo",
1111 .optimize = optimize,
12 .target = .{},
12 .target = b.host,
1313 });
1414 foo.addCSourceFile(.{ .file = .{ .path = "foo.c" }, .flags = &[_][]const u8{} });
1515 foo.addIncludePath(.{ .path = "." });
test/standalone/strip_empty_loop/build.zig+2-2
......@@ -5,15 +5,15 @@ pub fn build(b: *std.Build) void {
55 b.default_step = test_step;
66
77 const optimize = std.builtin.OptimizeMode.Debug;
8 const target = std.zig.CrossTarget{};
8 const target = b.host;
99
1010 const main = b.addExecutable(.{
1111 .name = "main",
1212 .root_source_file = .{ .path = "main.zig" },
1313 .optimize = optimize,
1414 .target = target,
15 .strip = true,
1516 });
16 main.strip = true;
1717
1818 // TODO: actually check the output
1919 _ = main.getEmittedBin();
test/standalone/strip_struct_init/build.zig+1-1
......@@ -9,8 +9,8 @@ pub fn build(b: *std.Build) void {
99 const main = b.addTest(.{
1010 .root_source_file = .{ .path = "main.zig" },
1111 .optimize = optimize,
12 .strip = true,
1213 });
13 main.strip = true;
1414
1515 test_step.dependOn(&b.addRunArtifact(main).step);
1616}
test/standalone/test_runner_module_imports/build.zig+4-4
......@@ -6,13 +6,13 @@ pub fn build(b: *std.Build) void {
66 .test_runner = "test_runner/main.zig",
77 });
88
9 const module1 = b.createModule(.{ .source_file = .{ .path = "module1/main.zig" } });
9 const module1 = b.createModule(.{ .root_source_file = .{ .path = "module1/main.zig" } });
1010 const module2 = b.createModule(.{
11 .source_file = .{ .path = "module2/main.zig" },
12 .dependencies = &.{.{ .name = "module1", .module = module1 }},
11 .root_source_file = .{ .path = "module2/main.zig" },
12 .imports = &.{.{ .name = "module1", .module = module1 }},
1313 });
1414
15 t.addModule("module2", module2);
15 t.root_module.addImport("module2", module2);
1616
1717 const test_step = b.step("test", "Run unit tests");
1818 test_step.dependOn(&b.addRunArtifact(t).step);
test/standalone/windows_resources/build.zig+12-8
......@@ -4,21 +4,25 @@ pub fn build(b: *std.Build) void {
44 const test_step = b.step("test", "Test it");
55 b.default_step = test_step;
66
7 const native_target: std.zig.CrossTarget = .{};
8 const cross_target = .{
7 const target = b.resolveTargetQuery(.{
98 .cpu_arch = .x86_64,
109 .os_tag = .windows,
1110 .abi = .gnu,
12 };
11 });
1312
14 add(b, native_target, .any, test_step);
15 add(b, cross_target, .any, test_step);
13 add(b, b.host, .any, test_step);
14 add(b, target, .any, test_step);
1615
17 add(b, native_target, .gnu, test_step);
18 add(b, cross_target, .gnu, test_step);
16 add(b, b.host, .gnu, test_step);
17 add(b, target, .gnu, test_step);
1918}
2019
21fn add(b: *std.Build, target: std.zig.CrossTarget, rc_includes: enum { any, gnu }, test_step: *std.Build.Step) void {
20fn add(
21 b: *std.Build,
22 target: std.Build.ResolvedTarget,
23 rc_includes: enum { any, gnu },
24 test_step: *std.Build.Step,
25) void {
2226 const exe = b.addExecutable(.{
2327 .name = "zig_resource_test",
2428 .root_source_file = .{ .path = "main.zig" },
test/standalone/windows_spawn/build.zig+1-1
......@@ -6,7 +6,7 @@ pub fn build(b: *std.Build) void {
66 b.default_step = test_step;
77
88 const optimize: std.builtin.OptimizeMode = .Debug;
9 const target: std.zig.CrossTarget = .{};
9 const target = b.host;
1010
1111 if (builtin.os.tag != .windows) return;
1212
test/standalone/zerolength_check/build.zig+2-2
......@@ -13,11 +13,11 @@ pub fn build(b: *std.Build) void {
1313fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
1414 const unit_tests = b.addTest(.{
1515 .root_source_file = .{ .path = "src/main.zig" },
16 .target = .{
16 .target = b.resolveTargetQuery(.{
1717 .os_tag = .wasi,
1818 .cpu_arch = .wasm32,
1919 .cpu_features_add = std.Target.wasm.featureSet(&.{.bulk_memory}),
20 },
20 }),
2121 .optimize = optimize,
2222 });
2323
test/tests.zig+55-58
......@@ -1,7 +1,6 @@
11const std = @import("std");
22const builtin = @import("builtin");
33const assert = std.debug.assert;
4const CrossTarget = std.zig.CrossTarget;
54const mem = std.mem;
65const OptimizeMode = std.builtin.OptimizeMode;
76const Step = std.Build.Step;
......@@ -22,13 +21,13 @@ pub const CompareOutputContext = @import("src/CompareOutput.zig");
2221pub const StackTracesContext = @import("src/StackTrace.zig");
2322
2423const TestTarget = struct {
25 target: CrossTarget = .{},
24 target: std.Target.Query = .{},
2625 optimize_mode: std.builtin.OptimizeMode = .Debug,
2726 link_libc: ?bool = null,
2827 single_threaded: ?bool = null,
2928 use_llvm: ?bool = null,
3029 use_lld: ?bool = null,
31 force_pic: ?bool = null,
30 pic: ?bool = null,
3231 strip: ?bool = null,
3332};
3433
......@@ -105,7 +104,7 @@ const test_targets = blk: {
105104 },
106105 .use_llvm = false,
107106 .use_lld = false,
108 .force_pic = true,
107 .pic = true,
109108 },
110109 .{
111110 .target = .{
......@@ -146,7 +145,7 @@ const test_targets = blk: {
146145 //},
147146 // https://github.com/ziglang/zig/issues/13623
148147 //.{
149 // .target = CrossTarget.parse(.{
148 // .target = std.Target.Query.parse(.{
150149 // .arch_os_abi = "arm-linux-none",
151150 // .cpu_features = "generic+v8a",
152151 // }) catch unreachable,
......@@ -287,13 +286,13 @@ const test_targets = blk: {
287286 },
288287
289288 .{
290 .target = CrossTarget.parse(.{
289 .target = std.Target.Query.parse(.{
291290 .arch_os_abi = "arm-linux-none",
292291 .cpu_features = "generic+v8a",
293292 }) catch unreachable,
294293 },
295294 .{
296 .target = CrossTarget.parse(.{
295 .target = std.Target.Query.parse(.{
297296 .arch_os_abi = "arm-linux-musleabihf",
298297 .cpu_features = "generic+v8a",
299298 }) catch unreachable,
......@@ -301,7 +300,7 @@ const test_targets = blk: {
301300 },
302301 // https://github.com/ziglang/zig/issues/3287
303302 //.{
304 // .target = CrossTarget.parse(.{
303 // .target = std.Target.Query.parse(.{
305304 // .arch_os_abi = "arm-linux-gnueabihf",
306305 // .cpu_features = "generic+v8a",
307306 // }) catch unreachable,
......@@ -495,10 +494,10 @@ const test_targets = blk: {
495494};
496495
497496const CAbiTarget = struct {
498 target: CrossTarget = .{},
497 target: std.Target.Query = .{},
499498 use_llvm: ?bool = null,
500499 use_lld: ?bool = null,
501 force_pic: ?bool = null,
500 pic: ?bool = null,
502501 strip: ?bool = null,
503502 c_defines: []const []const u8 = &.{},
504503};
......@@ -543,7 +542,7 @@ const c_abi_targets = [_]CAbiTarget{
543542 },
544543 .use_llvm = false,
545544 .use_lld = false,
546 .force_pic = true,
545 .pic = true,
547546 .c_defines = &.{"ZIG_BACKEND_STAGE2_X86_64"},
548547 },
549548 .{
......@@ -645,7 +644,7 @@ pub fn addStackTraceTests(
645644 const check_exe = b.addExecutable(.{
646645 .name = "check-stack-trace",
647646 .root_source_file = .{ .path = "test/src/check-stack-trace.zig" },
648 .target = .{},
647 .target = b.host,
649648 .optimize = .Debug,
650649 });
651650
......@@ -682,12 +681,14 @@ pub fn addStandaloneTests(
682681 if (os_tag != builtin.os.tag) continue;
683682 }
684683
684 const resolved_target = b.resolveTargetQuery(case.target);
685
685686 if (case.is_exe) {
686687 const exe = b.addExecutable(.{
687688 .name = std.fs.path.stem(case.src_path),
688689 .root_source_file = .{ .path = case.src_path },
689690 .optimize = optimize,
690 .target = case.target,
691 .target = resolved_target,
691692 });
692693 if (case.link_libc) exe.linkLibC();
693694
......@@ -701,7 +702,7 @@ pub fn addStandaloneTests(
701702 .name = std.fs.path.stem(case.src_path),
702703 .root_source_file = .{ .path = case.src_path },
703704 .optimize = optimize,
704 .target = case.target,
705 .target = resolved_target,
705706 });
706707 if (case.link_libc) exe.linkLibC();
707708
......@@ -1001,7 +1002,7 @@ pub fn addTranslateCTests(b: *std.Build, test_filter: ?[]const u8) *Step {
10011002pub fn addRunTranslatedCTests(
10021003 b: *std.Build,
10031004 test_filter: ?[]const u8,
1004 target: std.zig.CrossTarget,
1005 target: std.Build.ResolvedTarget,
10051006) *Step {
10061007 const cases = b.allocator.create(RunTranslatedCContext) catch @panic("OOM");
10071008 cases.* = .{
......@@ -1035,14 +1036,17 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10351036
10361037 for (test_targets) |test_target| {
10371038 const is_native = test_target.target.isNative() or
1038 (test_target.target.getOsTag() == builtin.os.tag and
1039 test_target.target.getCpuArch() == builtin.cpu.arch);
1039 (test_target.target.os_tag == builtin.os.tag and
1040 test_target.target.cpu_arch == builtin.cpu.arch);
10401041
10411042 if (options.skip_non_native and !is_native)
10421043 continue;
10431044
1045 const resolved_target = b.resolveTargetQuery(test_target.target);
1046 const target = resolved_target.result;
1047
10441048 if (options.skip_cross_glibc and !test_target.target.isNative() and
1045 test_target.target.isGnuLibC() and test_target.link_libc == true)
1049 target.isGnuLibC() and test_target.link_libc == true)
10461050 continue;
10471051
10481052 if (options.skip_libc and test_target.link_libc == true)
......@@ -1052,35 +1056,30 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10521056 continue;
10531057
10541058 // TODO get compiler-rt tests passing for self-hosted backends.
1055 if ((test_target.target.getCpuArch() != .x86_64 or
1056 test_target.target.getObjectFormat() != .elf) and
1059 if ((target.cpu.arch != .x86_64 or target.ofmt != .elf) and
10571060 test_target.use_llvm == false and mem.eql(u8, options.name, "compiler-rt"))
10581061 continue;
10591062
10601063 // TODO get compiler-rt tests passing for wasm32-wasi
10611064 // currently causes "LLVM ERROR: Unable to expand fixed point multiplication."
1062 if (test_target.target.getCpuArch() == .wasm32 and
1063 test_target.target.getOsTag() == .wasi and
1065 if (target.cpu.arch == .wasm32 and target.os.tag == .wasi and
10641066 mem.eql(u8, options.name, "compiler-rt"))
10651067 {
10661068 continue;
10671069 }
10681070
10691071 // TODO get universal-libc tests passing for other self-hosted backends.
1070 if (test_target.target.getCpuArch() != .x86_64 and
1072 if (target.cpu.arch != .x86_64 and
10711073 test_target.use_llvm == false and mem.eql(u8, options.name, "universal-libc"))
10721074 continue;
10731075
10741076 // TODO get std lib tests passing for other self-hosted backends.
1075 if ((test_target.target.getCpuArch() != .x86_64 or
1076 test_target.target.getOsTag() != .linux) and
1077 if ((target.cpu.arch != .x86_64 or target.os.tag != .linux) and
10771078 test_target.use_llvm == false and mem.eql(u8, options.name, "std"))
10781079 continue;
10791080
1080 if (test_target.target.getCpuArch() == .x86_64 and
1081 test_target.target.getOsTag() == .windows and
1082 test_target.target.cpu_arch == null and
1083 test_target.optimize_mode != .Debug and
1081 if (target.cpu.arch == .x86_64 and target.os.tag == .windows and
1082 test_target.target.cpu_arch == null and test_target.optimize_mode != .Debug and
10841083 mem.eql(u8, options.name, "std"))
10851084 {
10861085 // https://github.com/ziglang/zig/issues/17902
......@@ -1093,11 +1092,11 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
10931092 if (!want_this_mode) continue;
10941093
10951094 const libc_suffix = if (test_target.link_libc == true) "-libc" else "";
1096 const triple_txt = test_target.target.zigTriple(b.allocator) catch @panic("OOM");
1097 const model_txt = test_target.target.getCpuModel().name;
1095 const triple_txt = target.zigTriple(b.allocator) catch @panic("OOM");
1096 const model_txt = target.cpu.model.name;
10981097
10991098 // wasm32-wasi builds need more RAM, idk why
1100 const max_rss = if (test_target.target.getOs().tag == .wasi)
1099 const max_rss = if (target.os.tag == .wasi)
11011100 options.max_rss * 2
11021101 else
11031102 options.max_rss;
......@@ -1105,7 +1104,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
11051104 const these_tests = b.addTest(.{
11061105 .root_source_file = .{ .path = options.root_src },
11071106 .optimize = test_target.optimize_mode,
1108 .target = test_target.target,
1107 .target = resolved_target,
11091108 .max_rss = max_rss,
11101109 .filter = options.test_filter,
11111110 .link_libc = test_target.link_libc,
......@@ -1113,24 +1112,24 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
11131112 .use_llvm = test_target.use_llvm,
11141113 .use_lld = test_target.use_lld,
11151114 .zig_lib_dir = .{ .path = "lib" },
1115 .pic = test_target.pic,
1116 .strip = test_target.strip,
11161117 });
1117 these_tests.force_pic = test_target.force_pic;
1118 these_tests.strip = test_target.strip;
11191118 const single_threaded_suffix = if (test_target.single_threaded == true) "-single" else "";
11201119 const backend_suffix = if (test_target.use_llvm == true)
11211120 "-llvm"
1122 else if (test_target.target.ofmt == std.Target.ObjectFormat.c)
1121 else if (target.ofmt == std.Target.ObjectFormat.c)
11231122 "-cbe"
11241123 else if (test_target.use_llvm == false)
11251124 "-selfhosted"
11261125 else
11271126 "";
11281127 const use_lld = if (test_target.use_lld == false) "-no-lld" else "";
1129 const use_pic = if (test_target.force_pic == true) "-pic" else "";
1128 const use_pic = if (test_target.pic == true) "-pic" else "";
11301129
11311130 these_tests.addIncludePath(.{ .path = "test" });
11321131
1133 if (test_target.target.getOs().tag == .wasi) {
1132 if (target.os.tag == .wasi) {
11341133 // WASI's default stack size can be too small for some big tests.
11351134 these_tests.stack_size = 2 * 1024 * 1024;
11361135 }
......@@ -1147,14 +1146,14 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
11471146 use_pic,
11481147 });
11491148
1150 if (test_target.target.ofmt == std.Target.ObjectFormat.c) {
1151 var altered_target = test_target.target;
1152 altered_target.ofmt = null;
1149 if (target.ofmt == std.Target.ObjectFormat.c) {
1150 var altered_query = test_target.target;
1151 altered_query.ofmt = null;
11531152
11541153 const compile_c = b.addExecutable(.{
11551154 .name = qualified_name,
11561155 .link_libc = test_target.link_libc,
1157 .target = altered_target,
1156 .target = b.resolveTargetQuery(altered_query),
11581157 .zig_lib_dir = .{ .path = "lib" },
11591158 });
11601159 compile_c.addCSourceFile(.{
......@@ -1178,7 +1177,7 @@ pub fn addModuleTests(b: *std.Build, options: ModuleTestOptions) *Step {
11781177 },
11791178 });
11801179 compile_c.addIncludePath(.{ .path = "lib" }); // for zig.h
1181 if (test_target.target.getOsTag() == .windows) {
1180 if (target.os.tag == .windows) {
11821181 if (true) {
11831182 // Unfortunately this requires about 8G of RAM for clang to compile
11841183 // and our Windows CI runners do not have this much.
......@@ -1229,41 +1228,39 @@ pub fn addCAbiTests(b: *std.Build, skip_non_native: bool, skip_release: bool) *S
12291228 for (c_abi_targets) |c_abi_target| {
12301229 if (skip_non_native and !c_abi_target.target.isNative()) continue;
12311230
1232 if (c_abi_target.target.isWindows() and c_abi_target.target.getCpuArch() == .aarch64) {
1231 const resolved_target = b.resolveTargetQuery(c_abi_target.target);
1232 const target = resolved_target.result;
1233
1234 if (target.os.tag == .windows and target.cpu.arch == .aarch64) {
12331235 // https://github.com/ziglang/zig/issues/14908
12341236 continue;
12351237 }
12361238
12371239 const test_step = b.addTest(.{
12381240 .name = b.fmt("test-c-abi-{s}-{s}-{s}{s}{s}{s}", .{
1239 c_abi_target.target.zigTriple(b.allocator) catch @panic("OOM"),
1240 c_abi_target.target.getCpuModel().name,
1241 target.zigTriple(b.allocator) catch @panic("OOM"),
1242 target.cpu.model.name,
12411243 @tagName(optimize_mode),
12421244 if (c_abi_target.use_llvm == true)
12431245 "-llvm"
1244 else if (c_abi_target.target.ofmt == std.Target.ObjectFormat.c)
1246 else if (target.ofmt == .c)
12451247 "-cbe"
12461248 else if (c_abi_target.use_llvm == false)
12471249 "-selfhosted"
12481250 else
12491251 "",
12501252 if (c_abi_target.use_lld == false) "-no-lld" else "",
1251 if (c_abi_target.force_pic == true) "-pic" else "",
1253 if (c_abi_target.pic == true) "-pic" else "",
12521254 }),
12531255 .root_source_file = .{ .path = "test/c_abi/main.zig" },
1254 .target = c_abi_target.target,
1256 .target = resolved_target,
12551257 .optimize = optimize_mode,
12561258 .link_libc = true,
12571259 .use_llvm = c_abi_target.use_llvm,
12581260 .use_lld = c_abi_target.use_lld,
1261 .pic = c_abi_target.pic,
1262 .strip = c_abi_target.strip,
12591263 });
1260 test_step.force_pic = c_abi_target.force_pic;
1261 test_step.strip = c_abi_target.strip;
1262 if (c_abi_target.target.abi != null and c_abi_target.target.abi.?.isMusl()) {
1263 // TODO NativeTargetInfo insists on dynamically linking musl
1264 // for some reason?
1265 test_step.target_info.dynamic_linker.max_byte = null;
1266 }
12671264 test_step.addCSourceFile(.{
12681265 .file = .{ .path = "test/c_abi/cfuncs.c" },
12691266 .flags = &.{"-std=c99"},
......@@ -1297,8 +1294,8 @@ pub fn addCases(
12971294 var dir = try b.build_root.handle.openDir("test/cases", .{ .iterate = true });
12981295 defer dir.close();
12991296
1300 cases.addFromDir(dir);
1301 try @import("cases.zig").addCases(&cases, build_options);
1297 cases.addFromDir(dir, b);
1298 try @import("cases.zig").addCases(&cases, build_options, b);
13021299
13031300 const cases_dir_path = try b.build_root.join(b.allocator, &.{ "test", "cases" });
13041301 cases.lowerToBuildSteps(
test/translate_c.zig+2-3
......@@ -1,7 +1,6 @@
11const std = @import("std");
22const builtin = @import("builtin");
33const tests = @import("tests.zig");
4const CrossTarget = std.zig.CrossTarget;
54
65// ********************************************************
76// * *
......@@ -1846,7 +1845,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18461845 \\pub extern fn foo5(a: [*c]f32) callconv(.Thiscall) void;
18471846 });
18481847
1849 cases.addWithTarget("Calling convention", CrossTarget.parse(.{
1848 cases.addWithTarget("Calling convention", std.Target.Query.parse(.{
18501849 .arch_os_abi = "arm-linux-none",
18511850 .cpu_features = "generic+v8_5a",
18521851 }) catch unreachable,
......@@ -1857,7 +1856,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
18571856 \\pub extern fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;
18581857 });
18591858
1860 cases.addWithTarget("Calling convention", CrossTarget.parse(.{
1859 cases.addWithTarget("Calling convention", std.Target.Query.parse(.{
18611860 .arch_os_abi = "aarch64-linux-none",
18621861 .cpu_features = "generic+v8_5a",
18631862 }) catch unreachable,
tools/docgen.zig+13-12
......@@ -9,13 +9,12 @@ const print = std.debug.print;
99const mem = std.mem;
1010const testing = std.testing;
1111const Allocator = std.mem.Allocator;
12const getExternalExecutor = std.zig.system.getExternalExecutor;
1213
1314const max_doc_file_size = 10 * 1024 * 1024;
1415
15const exe_ext = @as(std.zig.CrossTarget, .{}).exeFileExt();
1616const obj_ext = builtin.object_format.fileExt(builtin.cpu.arch);
1717const tmp_dir_name = "docgen_tmp";
18const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;
1918
2019const usage =
2120 \\Usage: docgen [--zig] [--skip-code-tests] input output"
......@@ -1309,7 +1308,7 @@ fn genHtml(
13091308 var env_map = try process.getEnvMap(allocator);
13101309 try env_map.put("YES_COLOR", "1");
13111310
1312 const host = try std.zig.system.NativeTargetInfo.detect(.{});
1311 const host = try std.zig.system.resolveTargetQuery(.{});
13131312 const builtin_code = try getBuiltinCode(allocator, &env_map, zig_exe, opt_zig_lib_dir);
13141313
13151314 for (toc.nodes) |node| {
......@@ -1424,9 +1423,7 @@ fn genHtml(
14241423 try build_args.append("-lc");
14251424 try shell_out.print("-lc ", .{});
14261425 }
1427 const target = try std.zig.CrossTarget.parse(.{
1428 .arch_os_abi = code.target_str orelse "native",
1429 });
1426
14301427 if (code.target_str) |triple| {
14311428 try build_args.appendSlice(&[_][]const u8{ "-target", triple });
14321429 try shell_out.print("-target {s} ", .{triple});
......@@ -1490,9 +1487,13 @@ fn genHtml(
14901487 }
14911488 }
14921489
1490 const target_query = try std.Target.Query.parse(.{
1491 .arch_os_abi = code.target_str orelse "native",
1492 });
1493 const target = try std.zig.system.resolveTargetQuery(target_query);
1494
14931495 const path_to_exe = try std.fmt.allocPrint(allocator, "./{s}{s}", .{
1494 code.name,
1495 target.exeFileExt(),
1496 code.name, target.exeFileExt(),
14961497 });
14971498 const run_args = &[_][]const u8{path_to_exe};
14981499
......@@ -1565,13 +1566,13 @@ fn genHtml(
15651566 try test_args.appendSlice(&[_][]const u8{ "-target", triple });
15661567 try shell_out.print("-target {s} ", .{triple});
15671568
1568 const cross_target = try std.zig.CrossTarget.parse(.{
1569 const target_query = try std.Target.Query.parse(.{
15691570 .arch_os_abi = triple,
15701571 });
1571 const target_info = try std.zig.system.NativeTargetInfo.detect(
1572 cross_target,
1572 const target = try std.zig.system.resolveTargetQuery(
1573 target_query,
15731574 );
1574 switch (host.getExternalExecutor(&target_info, .{
1575 switch (getExternalExecutor(host, &target, .{
15751576 .link_libc = code.link_libc,
15761577 })) {
15771578 .native => {},